From 219c14b784382a9ad304bc94c812863e1f245f61 Mon Sep 17 00:00:00 2001 From: fabriciorby Date: Fri, 19 Jun 2026 02:26:17 +0200 Subject: [PATCH 1/2] [Issue-3380] Send sourceQualifiedName to forked clients (#3380) The sourceQualifiedName should also be sent to forked clients, so it's added on ForkClient, the EventChannelEncoder and EventDecoder. It should also be used in the CategorizedReportEntry and implemented properly in WrappedReportEntry. --- .../booterclient/output/ForkClient.java | 1 + .../surefire/report/WrappedReportEntry.java | 5 ++ .../maven/surefire/stream/EventDecoder.java | 37 ++++---- .../surefire/stream/EventDecoderTest.java | 90 ++++++++++++++++--- .../api/report/CategorizedReportEntry.java | 31 +++++++ .../booter/spi/EventChannelEncoder.java | 2 + .../booter/spi/EventChannelEncoderTest.java | 52 +++++++++++ 7 files changed, 190 insertions(+), 28 deletions(-) diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java index 34af87db04..edfe0a2b61 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java @@ -133,6 +133,7 @@ public void handle(TestSetReportEntry reportEntry) { reportEntry.getTestRunId(), reportEntry.getSourceName(), reportEntry.getSourceText(), + reportEntry.getSourceQualifiedName(), reportEntry.getName(), reportEntry.getNameText(), reportEntry.getGroup(), diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java index ceb92b40ea..0cd423244f 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java @@ -125,6 +125,11 @@ public String getSourceText() { return original.getSourceText(); } + @Override + public String getSourceQualifiedName() { + return getSourceQualifiedName(null); + } + @Override public String getName() { return original.getName(); diff --git a/maven-surefire-common/src/main/java/org/apache/maven/surefire/stream/EventDecoder.java b/maven-surefire-common/src/main/java/org/apache/maven/surefire/stream/EventDecoder.java index 2fa314bc19..2f641778ad 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/surefire/stream/EventDecoder.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/surefire/stream/EventDecoder.java @@ -104,6 +104,7 @@ public class EventDecoder extends AbstractStreamDecoder args) { // ReportEntry: String source = (String) args.get(2); String sourceText = (String) args.get(3); - String name = (String) args.get(4); - String nameText = (String) args.get(5); - String group = (String) args.get(6); - String message = (String) args.get(7); - Integer timeElapsed = (Integer) args.get(8); + String sourceQualifiedName = (String) args.get(4); + String name = (String) args.get(5); + String nameText = (String) args.get(6); + String group = (String) args.get(7); + String message = (String) args.get(8); + Integer timeElapsed = (Integer) args.get(9); // StackTraceWriter: - String traceMessage = (String) args.get(9); - String smartTrimmedStackTrace = (String) args.get(10); - String stackTrace = (String) args.get(11); + String traceMessage = (String) args.get(10); + String smartTrimmedStackTrace = (String) args.get(11); + String stackTrace = (String) args.get(12); return newReportEntry( runMode, testRunId, source, sourceText, + sourceQualifiedName, name, nameText, group, @@ -348,6 +351,7 @@ static TestSetReportEntry newReportEntry( // ReportEntry: long testRunId, String source, String sourceText, + String sourceQualifiedName, String name, String nameText, String group, @@ -364,6 +368,7 @@ static TestSetReportEntry newReportEntry( // ReportEntry: testRunId, source, sourceText, + sourceQualifiedName, name, nameText, group, diff --git a/maven-surefire-common/src/test/java/org/apache/maven/surefire/stream/EventDecoderTest.java b/maven-surefire-common/src/test/java/org/apache/maven/surefire/stream/EventDecoderTest.java index 8ca716de83..9a64499cbe 100644 --- a/maven-surefire-common/src/test/java/org/apache/maven/surefire/stream/EventDecoderTest.java +++ b/maven-surefire-common/src/test/java/org/apache/maven/surefire/stream/EventDecoderTest.java @@ -183,7 +183,7 @@ public void shouldMapEventTypeToSegmentType() { }); segmentTypes = decoder.nextSegmentType(BOOTERCODE_TESTSET_STARTING); - assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] { + assertThat(segmentTypes).hasSize(15).isEqualTo(new SegmentType[] { RUN_MODE, TEST_RUN_ID, STRING_ENCODING, @@ -193,6 +193,7 @@ public void shouldMapEventTypeToSegmentType() { DATA_STRING, DATA_STRING, DATA_STRING, + DATA_STRING, DATA_INTEGER, DATA_STRING, DATA_STRING, @@ -201,7 +202,7 @@ public void shouldMapEventTypeToSegmentType() { }); segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TESTSET_COMPLETED); - assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] { + assertThat(segmentTypes).hasSize(15).isEqualTo(new SegmentType[] { RUN_MODE, TEST_RUN_ID, STRING_ENCODING, @@ -211,6 +212,7 @@ public void shouldMapEventTypeToSegmentType() { DATA_STRING, DATA_STRING, DATA_STRING, + DATA_STRING, DATA_INTEGER, DATA_STRING, DATA_STRING, @@ -219,7 +221,7 @@ public void shouldMapEventTypeToSegmentType() { }); segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TEST_STARTING); - assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] { + assertThat(segmentTypes).hasSize(15).isEqualTo(new SegmentType[] { RUN_MODE, TEST_RUN_ID, STRING_ENCODING, @@ -229,6 +231,7 @@ public void shouldMapEventTypeToSegmentType() { DATA_STRING, DATA_STRING, DATA_STRING, + DATA_STRING, DATA_INTEGER, DATA_STRING, DATA_STRING, @@ -237,7 +240,7 @@ public void shouldMapEventTypeToSegmentType() { }); segmentTypes = decoder.nextSegmentType(BOOTERCODE_TEST_SUCCEEDED); - assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] { + assertThat(segmentTypes).hasSize(15).isEqualTo(new SegmentType[] { RUN_MODE, TEST_RUN_ID, STRING_ENCODING, @@ -247,6 +250,7 @@ public void shouldMapEventTypeToSegmentType() { DATA_STRING, DATA_STRING, DATA_STRING, + DATA_STRING, DATA_INTEGER, DATA_STRING, DATA_STRING, @@ -255,7 +259,7 @@ public void shouldMapEventTypeToSegmentType() { }); segmentTypes = decoder.nextSegmentType(BOOTERCODE_TEST_FAILED); - assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] { + assertThat(segmentTypes).hasSize(15).isEqualTo(new SegmentType[] { RUN_MODE, TEST_RUN_ID, STRING_ENCODING, @@ -265,6 +269,7 @@ public void shouldMapEventTypeToSegmentType() { DATA_STRING, DATA_STRING, DATA_STRING, + DATA_STRING, DATA_INTEGER, DATA_STRING, DATA_STRING, @@ -273,7 +278,7 @@ public void shouldMapEventTypeToSegmentType() { }); segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TEST_SKIPPED); - assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] { + assertThat(segmentTypes).hasSize(15).isEqualTo(new SegmentType[] { RUN_MODE, TEST_RUN_ID, STRING_ENCODING, @@ -283,6 +288,7 @@ public void shouldMapEventTypeToSegmentType() { DATA_STRING, DATA_STRING, DATA_STRING, + DATA_STRING, DATA_INTEGER, DATA_STRING, DATA_STRING, @@ -291,7 +297,7 @@ public void shouldMapEventTypeToSegmentType() { }); segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TEST_ERROR); - assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] { + assertThat(segmentTypes).hasSize(15).isEqualTo(new SegmentType[] { RUN_MODE, TEST_RUN_ID, STRING_ENCODING, @@ -301,6 +307,7 @@ public void shouldMapEventTypeToSegmentType() { DATA_STRING, DATA_STRING, DATA_STRING, + DATA_STRING, DATA_INTEGER, DATA_STRING, DATA_STRING, @@ -309,7 +316,7 @@ public void shouldMapEventTypeToSegmentType() { }); segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TEST_ASSUMPTIONFAILURE); - assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] { + assertThat(segmentTypes).hasSize(15).isEqualTo(new SegmentType[] { RUN_MODE, TEST_RUN_ID, STRING_ENCODING, @@ -319,6 +326,7 @@ public void shouldMapEventTypeToSegmentType() { DATA_STRING, DATA_STRING, DATA_STRING, + DATA_STRING, DATA_INTEGER, DATA_STRING, DATA_STRING, @@ -448,6 +456,7 @@ public void shouldCreateEvent() throws Exception { 1L, "source", "sourceText", + "sourceQualifiedName", "name", "nameText", "group", @@ -465,6 +474,8 @@ public void shouldCreateEvent() throws Exception { .isEqualTo("source"); assertThat(((TestsetStartingEvent) event).getReportEntry().getSourceText()) .isEqualTo("sourceText"); + assertThat(((TestsetStartingEvent) event).getReportEntry().getSourceQualifiedName()) + .isEqualTo("sourceQualifiedName"); assertThat(((TestsetStartingEvent) event).getReportEntry().getName()).isEqualTo("name"); assertThat(((TestsetStartingEvent) event).getReportEntry().getNameText()) .isEqualTo("nameText"); @@ -495,6 +506,7 @@ public void shouldCreateEvent() throws Exception { 1L, "source", "sourceText", + "sourceQualifiedName", "name", "nameText", "group", @@ -513,6 +525,8 @@ public void shouldCreateEvent() throws Exception { .isEqualTo("source"); assertThat(((TestsetCompletedEvent) event).getReportEntry().getSourceText()) .isEqualTo("sourceText"); + assertThat(((TestsetCompletedEvent) event).getReportEntry().getSourceQualifiedName()) + .isEqualTo("sourceQualifiedName"); assertThat(((TestsetCompletedEvent) event).getReportEntry().getName()).isEqualTo("name"); assertThat(((TestsetCompletedEvent) event).getReportEntry().getNameText()) .isEqualTo("nameText"); @@ -545,6 +559,7 @@ public void shouldCreateEvent() throws Exception { 1L, "source", "sourceText", + "sourceQualifiedName", "name", "nameText", "group", @@ -559,6 +574,8 @@ public void shouldCreateEvent() throws Exception { assertThat(((TestStartingEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L); assertThat(((TestStartingEvent) event).getReportEntry().getSourceName()).isEqualTo("source"); assertThat(((TestStartingEvent) event).getReportEntry().getSourceText()).isEqualTo("sourceText"); + assertThat(((TestStartingEvent) event).getReportEntry().getSourceQualifiedName()) + .isEqualTo("sourceQualifiedName"); assertThat(((TestStartingEvent) event).getReportEntry().getName()).isEqualTo("name"); assertThat(((TestStartingEvent) event).getReportEntry().getNameText()).isEqualTo("nameText"); assertThat(((TestStartingEvent) event).getReportEntry().getGroup()).isEqualTo("group"); @@ -588,6 +605,7 @@ public void shouldCreateEvent() throws Exception { 1L, "source", "sourceText", + "sourceQualifiedName", "name", "nameText", "group", @@ -604,6 +622,8 @@ public void shouldCreateEvent() throws Exception { .isEqualTo("source"); assertThat(((TestSucceededEvent) event).getReportEntry().getSourceText()) .isEqualTo("sourceText"); + assertThat(((TestSucceededEvent) event).getReportEntry().getSourceQualifiedName()) + .isEqualTo("sourceQualifiedName"); assertThat(((TestSucceededEvent) event).getReportEntry().getName()).isEqualTo("name"); assertThat(((TestSucceededEvent) event).getReportEntry().getNameText()).isEqualTo("nameText"); assertThat(((TestSucceededEvent) event).getReportEntry().getGroup()).isEqualTo("group"); @@ -619,6 +639,7 @@ public void shouldCreateEvent() throws Exception { 1L, "source", null, + null, "name", null, "group", @@ -633,6 +654,8 @@ public void shouldCreateEvent() throws Exception { assertThat(((TestFailedEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L); assertThat(((TestFailedEvent) event).getReportEntry().getSourceName()).isEqualTo("source"); assertThat(((TestFailedEvent) event).getReportEntry().getSourceText()).isNull(); + assertThat(((TestFailedEvent) event).getReportEntry().getSourceQualifiedName()) + .isNull(); assertThat(((TestFailedEvent) event).getReportEntry().getName()).isEqualTo("name"); assertThat(((TestFailedEvent) event).getReportEntry().getNameText()).isNull(); assertThat(((TestFailedEvent) event).getReportEntry().getGroup()).isEqualTo("group"); @@ -657,13 +680,16 @@ public void shouldCreateEvent() throws Exception { memento = decoder.new Memento(); memento.getData() - .addAll(asList(NORMAL_RUN, 1L, "source", null, "name", null, null, null, 5, null, null, "stackTrace")); + .addAll(asList( + NORMAL_RUN, 1L, "source", null, null, "name", null, null, null, 5, null, null, "stackTrace")); event = decoder.toMessage(BOOTERCODE_TEST_SKIPPED, memento); assertThat(event).isInstanceOf(TestSkippedEvent.class); assertThat(((TestSkippedEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN); assertThat(((TestSkippedEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L); assertThat(((TestSkippedEvent) event).getReportEntry().getSourceName()).isEqualTo("source"); assertThat(((TestSkippedEvent) event).getReportEntry().getSourceText()).isNull(); + assertThat(((TestSkippedEvent) event).getReportEntry().getSourceQualifiedName()) + .isNull(); assertThat(((TestSkippedEvent) event).getReportEntry().getName()).isEqualTo("name"); assertThat(((TestSkippedEvent) event).getReportEntry().getNameText()).isNull(); assertThat(((TestSkippedEvent) event).getReportEntry().getGroup()).isNull(); @@ -689,13 +715,27 @@ public void shouldCreateEvent() throws Exception { memento = decoder.new Memento(); memento.getData() .addAll(asList( - NORMAL_RUN, 1L, "source", null, "name", "nameText", null, null, 0, null, null, "stackTrace")); + NORMAL_RUN, + 1L, + "source", + null, + null, + "name", + "nameText", + null, + null, + 0, + null, + null, + "stackTrace")); event = decoder.toMessage(BOOTERCODE_TEST_ERROR, memento); assertThat(event).isInstanceOf(TestErrorEvent.class); assertThat(((TestErrorEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN); assertThat(((TestErrorEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L); assertThat(((TestErrorEvent) event).getReportEntry().getSourceName()).isEqualTo("source"); assertThat(((TestErrorEvent) event).getReportEntry().getSourceText()).isNull(); + assertThat(((TestErrorEvent) event).getReportEntry().getSourceQualifiedName()) + .isNull(); assertThat(((TestErrorEvent) event).getReportEntry().getName()).isEqualTo("name"); assertThat(((TestErrorEvent) event).getReportEntry().getNameText()).isEqualTo("nameText"); assertThat(((TestErrorEvent) event).getReportEntry().getGroup()).isNull(); @@ -721,7 +761,19 @@ public void shouldCreateEvent() throws Exception { memento = decoder.new Memento(); memento.getData() .addAll(asList( - NORMAL_RUN, 1L, "source", null, "name", null, "group", null, 5, null, null, "stackTrace")); + NORMAL_RUN, + 1L, + "source", + null, + null, + "name", + null, + "group", + null, + 5, + null, + null, + "stackTrace")); event = decoder.toMessage(BOOTERCODE_TEST_ASSUMPTIONFAILURE, memento); assertThat(event).isInstanceOf(TestAssumptionFailureEvent.class); assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getRunMode()) @@ -732,6 +784,8 @@ public void shouldCreateEvent() throws Exception { .isEqualTo("source"); assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getSourceText()) .isNull(); + assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getSourceQualifiedName()) + .isNull(); assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getName()) .isEqualTo("name"); assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getNameText()) @@ -762,7 +816,7 @@ public void shouldCreateEvent() throws Exception { @Test public void shouldRecognizeEmptyStream4ReportEntry() { - ReportEntry reportEntry = newReportEntry(NORMAL_RUN, 1L, "", "", "", "", "", "", null, "", "", ""); + ReportEntry reportEntry = newReportEntry(NORMAL_RUN, 1L, "", "", "", "", "", "", "", null, "", "", ""); assertThat(reportEntry).isNotNull(); assertThat(reportEntry.getRunMode()).isEqualTo(NORMAL_RUN); assertThat(reportEntry.getTestRunId()).isEqualTo(1L); @@ -773,6 +827,7 @@ public void shouldRecognizeEmptyStream4ReportEntry() { .isEmpty(); assertThat(reportEntry.getSourceName()).isEmpty(); assertThat(reportEntry.getSourceText()).isEmpty(); + assertThat(reportEntry.getSourceQualifiedName()).isEmpty(); assertThat(reportEntry.getName()).isEmpty(); assertThat(reportEntry.getNameText()).isEmpty(); assertThat(reportEntry.getGroup()).isEmpty(); @@ -805,6 +860,7 @@ public void testCreatingReportEntry() { when(reportEntry.getNameWithGroup()).thenReturn("name with group"); when(reportEntry.getSourceName()).thenReturn("pkg.MyTest"); when(reportEntry.getSourceText()).thenReturn("test class display name"); + when(reportEntry.getSourceQualifiedName()).thenReturn("pkg.MyTest$innerClass"); when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter); ReportEntry decodedReportEntry = newReportEntry( @@ -812,6 +868,7 @@ public void testCreatingReportEntry() { 1L, reportEntry.getSourceName(), reportEntry.getSourceText(), + reportEntry.getSourceQualifiedName(), reportEntry.getName(), reportEntry.getNameText(), reportEntry.getGroup(), @@ -824,6 +881,7 @@ public void testCreatingReportEntry() { assertThat(decodedReportEntry).isNotNull(); assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName()); assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText()); + assertThat(decodedReportEntry.getSourceQualifiedName()).isEqualTo(reportEntry.getSourceQualifiedName()); assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName()); assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText()); assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup()); @@ -835,6 +893,7 @@ public void testCreatingReportEntry() { 1L, reportEntry.getSourceName(), reportEntry.getSourceText(), + reportEntry.getSourceQualifiedName(), reportEntry.getName(), reportEntry.getNameText(), reportEntry.getGroup(), @@ -847,6 +906,7 @@ public void testCreatingReportEntry() { assertThat(decodedReportEntry).isNotNull(); assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName()); assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText()); + assertThat(decodedReportEntry.getSourceQualifiedName()).isEqualTo(reportEntry.getSourceQualifiedName()); assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName()); assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText()); assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup()); @@ -865,6 +925,7 @@ public void testCreatingReportEntry() { 1L, reportEntry.getSourceName(), reportEntry.getSourceText(), + reportEntry.getSourceQualifiedName(), reportEntry.getName(), reportEntry.getNameText(), reportEntry.getGroup(), @@ -877,6 +938,7 @@ public void testCreatingReportEntry() { assertThat(decodedReportEntry).isNotNull(); assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName()); assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText()); + assertThat(decodedReportEntry.getSourceQualifiedName()).isEqualTo(reportEntry.getSourceQualifiedName()); assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName()); assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText()); assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup()); @@ -895,6 +957,7 @@ public void testCreatingReportEntry() { 1L, reportEntry.getSourceName(), reportEntry.getSourceText(), + reportEntry.getSourceQualifiedName(), reportEntry.getName(), reportEntry.getNameText(), reportEntry.getGroup(), @@ -907,6 +970,7 @@ public void testCreatingReportEntry() { assertThat(decodedReportEntry).isNotNull(); assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName()); assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText()); + assertThat(decodedReportEntry.getSourceQualifiedName()).isEqualTo(reportEntry.getSourceQualifiedName()); assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName()); assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText()); assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup()); @@ -929,6 +993,7 @@ public void testCreatingReportEntry() { 1L, reportEntry.getSourceName(), reportEntry.getSourceText(), + reportEntry.getSourceQualifiedName(), reportEntry.getName(), reportEntry.getNameText(), reportEntry.getGroup(), @@ -941,6 +1006,7 @@ public void testCreatingReportEntry() { assertThat(decodedReportEntry).isNotNull(); assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName()); assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText()); + assertThat(decodedReportEntry.getSourceQualifiedName()).isEqualTo(reportEntry.getSourceQualifiedName()); assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName()); assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText()); assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup()); diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/CategorizedReportEntry.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/CategorizedReportEntry.java index 44a0054009..0155d67883 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/CategorizedReportEntry.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/CategorizedReportEntry.java @@ -103,11 +103,40 @@ public CategorizedReportEntry( this.group = group; } + public CategorizedReportEntry( + @Nonnull RunMode runMode, + @Nonnegative Long testRunId, + String source, + String sourceText, + String sourceQualifiedName, + String name, + String nameText, + String group, + StackTraceWriter stackTraceWriter, + Integer elapsed, + String message, + Map systemProperties) { + super( + runMode, + testRunId, + source, + sourceText, + sourceQualifiedName, + name, + nameText, + stackTraceWriter, + elapsed, + message, + systemProperties); + this.group = group; + } + public static TestSetReportEntry reportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId, String source, String sourceText, + String sourceQualifiedName, String name, String nameText, String group, @@ -121,6 +150,7 @@ public static TestSetReportEntry reportEntry( testRunId, source, sourceText, + sourceQualifiedName, name, nameText, group, @@ -133,6 +163,7 @@ public static TestSetReportEntry reportEntry( testRunId, source, sourceText, + sourceQualifiedName, name, nameText, stackTraceWriter, diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/EventChannelEncoder.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/EventChannelEncoder.java index 0e793f69c8..c7d322a6f9 100644 --- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/EventChannelEncoder.java +++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/EventChannelEncoder.java @@ -346,6 +346,7 @@ ByteBuffer encode(ForkedProcessEventType operation, ReportEntry reportEntry, boo 1, reportEntry.getSourceName(), reportEntry.getSourceText(), + reportEntry.getSourceQualifiedName(), reportEntry.getName(), reportEntry.getNameText(), reportEntry.getGroup(), @@ -361,6 +362,7 @@ ByteBuffer encode(ForkedProcessEventType operation, ReportEntry reportEntry, boo encodeString(encoder, result, reportEntry.getSourceName()); encodeString(encoder, result, reportEntry.getSourceText()); + encodeString(encoder, result, reportEntry.getSourceQualifiedName()); encodeString(encoder, result, reportEntry.getName()); encodeString(encoder, result, reportEntry.getNameText()); encodeString(encoder, result, reportEntry.getGroup()); diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/EventChannelEncoderTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/EventChannelEncoderTest.java index a99b6d7973..76823b8704 100644 --- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/EventChannelEncoderTest.java +++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/EventChannelEncoderTest.java @@ -84,6 +84,7 @@ public void reportEntry() throws IOException { when(reportEntry.getName()).thenReturn("my test"); when(reportEntry.getNameWithGroup()).thenReturn("name with group"); when(reportEntry.getSourceName()).thenReturn("pkg.MyTest"); + when(reportEntry.getSourceQualifiedName()).thenReturn("pkg.MyTest$innerClass"); when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter); Stream out = Stream.newStream(); @@ -107,6 +108,10 @@ public void reportEntry() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -164,6 +169,10 @@ public void reportEntry() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -221,6 +230,10 @@ public void reportEntry() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -277,6 +290,10 @@ public void reportEntry() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -337,6 +354,7 @@ public void testSetCompleted() throws IOException { when(reportEntry.getName()).thenReturn("my test"); when(reportEntry.getNameWithGroup()).thenReturn("name with group"); when(reportEntry.getSourceName()).thenReturn("pkg.MyTest"); + when(reportEntry.getSourceQualifiedName()).thenReturn("pkg.MyTest$innerClass"); when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter); when(reportEntry.getSystemProperties()).thenReturn(props); @@ -391,6 +409,10 @@ public void testSetCompleted() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -450,6 +472,7 @@ public void testStarting() throws IOException { when(reportEntry.getName()).thenReturn("my test"); when(reportEntry.getNameWithGroup()).thenReturn("name with group"); when(reportEntry.getSourceName()).thenReturn("pkg.MyTest"); + when(reportEntry.getSourceQualifiedName()).thenReturn("pkg.MyTest$innerClass"); when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter); Stream out = Stream.newStream(); @@ -475,6 +498,10 @@ public void testStarting() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -533,6 +560,7 @@ public void testSuccess() throws IOException { when(reportEntry.getName()).thenReturn("my test"); when(reportEntry.getNameWithGroup()).thenReturn("name with group"); when(reportEntry.getSourceName()).thenReturn("pkg.MyTest"); + when(reportEntry.getSourceQualifiedName()).thenReturn("pkg.MyTest$innerClass"); when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter); Stream out = Stream.newStream(); @@ -557,6 +585,10 @@ public void testSuccess() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -615,6 +647,7 @@ public void testFailed() throws IOException { when(reportEntry.getName()).thenReturn("my test"); when(reportEntry.getNameWithGroup()).thenReturn("name with group"); when(reportEntry.getSourceName()).thenReturn("pkg.MyTest"); + when(reportEntry.getSourceQualifiedName()).thenReturn("pkg.MyTest$innerClass"); when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter); Stream out = Stream.newStream(); @@ -639,6 +672,10 @@ public void testFailed() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -696,6 +733,7 @@ public void testSkipped() throws IOException { when(reportEntry.getName()).thenReturn("my test"); when(reportEntry.getNameWithGroup()).thenReturn("name with group"); when(reportEntry.getSourceName()).thenReturn("pkg.MyTest"); + when(reportEntry.getSourceQualifiedName()).thenReturn("pkg.MyTest$innerClass"); when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter); Stream out = Stream.newStream(); @@ -720,6 +758,10 @@ public void testSkipped() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -777,6 +819,7 @@ public void testError() throws IOException { when(reportEntry.getName()).thenReturn("my test"); when(reportEntry.getNameWithGroup()).thenReturn("name with group"); when(reportEntry.getSourceName()).thenReturn("pkg.MyTest"); + when(reportEntry.getSourceQualifiedName()).thenReturn("pkg.MyTest$innerClass"); when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter); Stream out = Stream.newStream(); @@ -800,6 +843,10 @@ public void testError() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); @@ -856,6 +903,7 @@ public void testAssumptionFailure() throws IOException { when(reportEntry.getName()).thenReturn("my test"); when(reportEntry.getNameWithGroup()).thenReturn("name with group"); when(reportEntry.getSourceName()).thenReturn("pkg.MyTest"); + when(reportEntry.getSourceQualifiedName()).thenReturn("pkg.MyTest$innerClass"); when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter); Stream out = Stream.newStream(); @@ -880,6 +928,10 @@ public void testAssumptionFailure() throws IOException { expectedFrame.write(':'); expectedFrame.write(0); expectedFrame.write(':'); + expectedFrame.write(new byte[] {0, 0, 0, 21}); + expectedFrame.write(':'); + expectedFrame.write(reportEntry.getSourceQualifiedName().getBytes(UTF_8)); + expectedFrame.write(':'); expectedFrame.write(new byte[] {0, 0, 0, 7}); expectedFrame.write(':'); expectedFrame.write(reportEntry.getName().getBytes(UTF_8)); From 62c5f5db65e272e48452843812b100fe252774b1 Mon Sep 17 00:00:00 2001 From: fabriciorby Date: Sat, 20 Jun 2026 07:39:28 +0200 Subject: [PATCH 2/2] [Issue-3380] Add integration tests --- ...refire3380ForkedSourceQualifiedNameIT.java | 81 ++++++++++++++++++ .../pom.xml | 84 +++++++++++++++++++ .../java/issue3380/NestedDisplayNameTest.java | 50 +++++++++++ .../java/issue3380/NestedJupiterTest.java | 56 +++++++++++++ 4 files changed, 271 insertions(+) create mode 100644 surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire3380ForkedSourceQualifiedNameIT.java create mode 100644 surefire-its/src/test/resources/surefire-3380-forked-source-qualified-name/pom.xml create mode 100644 surefire-its/src/test/resources/surefire-3380-forked-source-qualified-name/src/test/java/issue3380/NestedDisplayNameTest.java create mode 100644 surefire-its/src/test/resources/surefire-3380-forked-source-qualified-name/src/test/java/issue3380/NestedJupiterTest.java diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire3380ForkedSourceQualifiedNameIT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire3380ForkedSourceQualifiedNameIT.java new file mode 100644 index 0000000000..69281dab46 --- /dev/null +++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire3380ForkedSourceQualifiedNameIT.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.surefire.its.jiras; + +import java.util.Arrays; + +import org.apache.maven.surefire.its.fixture.OutputValidator; +import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Integration Test for #3380 + */ +@SuppressWarnings("checkstyle:magicnumber") +public class Surefire3380ForkedSourceQualifiedNameIT extends SurefireJUnit4IntegrationTestCase { + static Iterable junitJupiterVersions() { + return Arrays.asList("5.8.2", "5.9.1", "5.13.4"); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("junitJupiterVersions") + void testXmlReport(String jupiterVersion) { + OutputValidator validator = unpack("surefire-3380-forked-source-qualified-name", "-" + jupiterVersion) + .setForkJvm() + .sysProp("junit5.version", jupiterVersion) + .executeTest() + .verifyErrorFree(9); + + validator + .getSurefireReportsFile("TEST-issue3380.NestedJupiterTest.xml", UTF_8) + .assertContainsText(" + + + + 4.0.0 + + org.apache.maven.plugins.surefire + surefire-3380-forked-source-qualified-name + 1.0 + Test for: Sending sourceQualifiedName for forkedClients + + + 1.8 + 1.8 + UTF-8 + + + + + + org.junit.jupiter + junit-jupiter-engine + ${junit5.version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit5.version} + test + + + + + + + maven-compiler-plugin + 3.8.0 + + UTF-8 + + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.version} + + 1.0C + true + + false + 3.0 + false + + + + + + + diff --git a/surefire-its/src/test/resources/surefire-3380-forked-source-qualified-name/src/test/java/issue3380/NestedDisplayNameTest.java b/surefire-its/src/test/resources/surefire-3380-forked-source-qualified-name/src/test/java/issue3380/NestedDisplayNameTest.java new file mode 100644 index 0000000000..6a54b82c49 --- /dev/null +++ b/surefire-its/src/test/resources/surefire-3380-forked-source-qualified-name/src/test/java/issue3380/NestedDisplayNameTest.java @@ -0,0 +1,50 @@ +package issue3380; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@DisplayName( "Display name of the main test class" ) +class NestedDisplayNameTest +{ + @Nested + @DisplayName( "Display name of level 1 nested class A" ) + class A + { + @Test + void level1_test_without_display_name() + { + } + + @Test + @DisplayName( "Display name of level 1 test method" ) + void level1_test_with_display_name() + { + } + } + + @Nested + @DisplayName( "Display name of level 1 nested class B" ) + class B + { + @Nested + @DisplayName( "Display name of level 2 nested class C" ) + class C + { + @Test + @DisplayName( "Display name of non-parameterized level 2 test method" ) + void level2_test_nonparameterized() + { + } + + @ParameterizedTest + @ValueSource(strings = {"paramValue1", "paramValue2"}) + @DisplayName( "Display name of parameterized level 2 test method" ) + void level2_test_parameterized(String paramValue) + { + } + } + } +} diff --git a/surefire-its/src/test/resources/surefire-3380-forked-source-qualified-name/src/test/java/issue3380/NestedJupiterTest.java b/surefire-its/src/test/resources/surefire-3380-forked-source-qualified-name/src/test/java/issue3380/NestedJupiterTest.java new file mode 100644 index 0000000000..754d35f6c8 --- /dev/null +++ b/surefire-its/src/test/resources/surefire-3380-forked-source-qualified-name/src/test/java/issue3380/NestedJupiterTest.java @@ -0,0 +1,56 @@ +package issue3380; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +class NestedJupiterTest +{ + @Nested + class A + { + @Test + void level1_test() + { + } + } + + @Nested + class B + { + @Nested + class C + { + @Test + void level2_test_nonparameterized() + { + } + + @ParameterizedTest + @ValueSource(strings = {"paramValue1", "paramValue2"}) + void level2_test_parameterized(String paramValue) + { + } + } + } +}