Skip to content

Commit 3365072

Browse files
committed
Call EngineExecutionListener.executionFinished method in reverse order
Issue: #3082
1 parent 90a0ccf commit 3365072

File tree

2 files changed

+51
-33
lines changed

2 files changed

+51
-33
lines changed

junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/CompositeEngineExecutionListener.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,38 +35,41 @@ class CompositeEngineExecutionListener implements EngineExecutionListener {
3535

3636
@Override
3737
public void dynamicTestRegistered(TestDescriptor testDescriptor) {
38-
notifyEach(engineExecutionListeners, listener -> listener.dynamicTestRegistered(testDescriptor),
38+
notifyEach(engineExecutionListeners, IterationOrder.ORIGINAL,
39+
listener -> listener.dynamicTestRegistered(testDescriptor),
3940
() -> "dynamicTestRegistered(" + testDescriptor + ")");
4041
}
4142

4243
@Override
4344
public void executionSkipped(TestDescriptor testDescriptor, String reason) {
44-
notifyEach(engineExecutionListeners, listener -> listener.executionSkipped(testDescriptor, reason),
45+
notifyEach(engineExecutionListeners, IterationOrder.ORIGINAL,
46+
listener -> listener.executionSkipped(testDescriptor, reason),
4547
() -> "executionSkipped(" + testDescriptor + ", " + reason + ")");
4648
}
4749

4850
@Override
4951
public void executionStarted(TestDescriptor testDescriptor) {
50-
notifyEach(engineExecutionListeners, listener -> listener.executionStarted(testDescriptor),
51-
() -> "executionStarted(" + testDescriptor + ")");
52+
notifyEach(engineExecutionListeners, IterationOrder.ORIGINAL,
53+
listener -> listener.executionStarted(testDescriptor), () -> "executionStarted(" + testDescriptor + ")");
5254
}
5355

5456
@Override
5557
public void executionFinished(TestDescriptor testDescriptor, TestExecutionResult testExecutionResult) {
56-
notifyEach(engineExecutionListeners,
58+
notifyEach(engineExecutionListeners, IterationOrder.REVERSED,
5759
listener -> listener.executionFinished(testDescriptor, testExecutionResult),
5860
() -> "executionFinished(" + testDescriptor + ", " + testExecutionResult + ")");
5961
}
6062

6163
@Override
6264
public void reportingEntryPublished(TestDescriptor testDescriptor, ReportEntry entry) {
63-
notifyEach(engineExecutionListeners, listener -> listener.reportingEntryPublished(testDescriptor, entry),
65+
notifyEach(engineExecutionListeners, IterationOrder.ORIGINAL,
66+
listener -> listener.reportingEntryPublished(testDescriptor, entry),
6467
() -> "reportingEntryPublished(" + testDescriptor + ", " + entry + ")");
6568
}
6669

67-
private static <T extends EngineExecutionListener> void notifyEach(List<T> listeners, Consumer<T> consumer,
68-
Supplier<String> description) {
69-
listeners.forEach(listener -> {
70+
private static <T extends EngineExecutionListener> void notifyEach(List<T> listeners, IterationOrder iterationOrder,
71+
Consumer<T> consumer, Supplier<String> description) {
72+
iterationOrder.forEach(listeners, listener -> {
7073
try {
7174
consumer.accept(listener);
7275
}

platform-tests/src/test/java/org/junit/platform/launcher/core/CompositeEngineExecutionListenerTests.java

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import static org.assertj.core.api.Assertions.assertThat;
1414
import static org.assertj.core.api.Assertions.assertThatThrownBy;
15+
import static org.mockito.Mockito.inOrder;
1516
import static org.mockito.Mockito.mock;
1617

1718
import java.util.ArrayList;
@@ -29,6 +30,7 @@
2930
import org.junit.platform.engine.UniqueId;
3031
import org.junit.platform.engine.reporting.ReportEntry;
3132
import org.junit.platform.engine.support.descriptor.DemoMethodTestDescriptor;
33+
import org.mockito.InOrder;
3234

3335
@TrackLogRecords
3436
class CompositeEngineExecutionListenerTests {
@@ -38,37 +40,29 @@ class CompositeEngineExecutionListenerTests {
3840

3941
@Test
4042
void shouldNotThrowExceptionButLogIfDynamicTestRegisteredListenerMethodFails(LogRecordListener logRecordListener) {
41-
var testDescriptor = getSampleMethodTestDescriptor();
42-
43-
compositeTestExecutionListener().dynamicTestRegistered(testDescriptor);
43+
compositeEngineExecutionListener().dynamicTestRegistered(anyTestDescriptor());
4444

4545
assertThatTestListenerErrorLogged(logRecordListener, ThrowingEngineExecutionListener.class,
4646
"dynamicTestRegistered");
4747
}
4848

4949
@Test
5050
void shouldNotThrowExceptionButLogIfExecutionStartedListenerMethodFails(LogRecordListener logRecordListener) {
51-
var testDescriptor = getSampleMethodTestDescriptor();
52-
53-
compositeTestExecutionListener().executionStarted(testDescriptor);
51+
compositeEngineExecutionListener().executionStarted(anyTestDescriptor());
5452

5553
assertThatTestListenerErrorLogged(logRecordListener, ThrowingEngineExecutionListener.class, "executionStarted");
5654
}
5755

5856
@Test
5957
void shouldNotThrowExceptionButLogIfExecutionSkippedListenerMethodFails(LogRecordListener logRecordListener) {
60-
var testDescriptor = getSampleMethodTestDescriptor();
61-
62-
compositeTestExecutionListener().executionSkipped(testDescriptor, "deliberately skipped container");
58+
compositeEngineExecutionListener().executionSkipped(anyTestDescriptor(), "deliberately skipped container");
6359

6460
assertThatTestListenerErrorLogged(logRecordListener, ThrowingEngineExecutionListener.class, "executionSkipped");
6561
}
6662

6763
@Test
6864
void shouldNotThrowExceptionButLogIfExecutionFinishedListenerMethodFails(LogRecordListener logRecordListener) {
69-
var testDescriptor = getSampleMethodTestDescriptor();
70-
71-
compositeTestExecutionListener().executionFinished(testDescriptor, mock(TestExecutionResult.class));
65+
compositeEngineExecutionListener().executionFinished(anyTestDescriptor(), anyTestExecutionResult());
7266

7367
assertThatTestListenerErrorLogged(logRecordListener, ThrowingEngineExecutionListener.class,
7468
"executionFinished");
@@ -77,9 +71,7 @@ void shouldNotThrowExceptionButLogIfExecutionFinishedListenerMethodFails(LogReco
7771
@Test
7872
void shouldNotThrowExceptionButLogIfReportingEntryPublishedListenerMethodFails(
7973
LogRecordListener logRecordListener) {
80-
var testDescriptor = getSampleMethodTestDescriptor();
81-
82-
compositeTestExecutionListener().reportingEntryPublished(testDescriptor, ReportEntry.from("one", "two"));
74+
compositeEngineExecutionListener().reportingEntryPublished(anyTestDescriptor(), ReportEntry.from("one", "two"));
8375

8476
assertThatTestListenerErrorLogged(logRecordListener, ThrowingEngineExecutionListener.class,
8577
"reportingEntryPublished");
@@ -94,14 +86,37 @@ public void executionStarted(TestDescriptor testDescriptor) {
9486
throw new OutOfMemoryError();
9587
}
9688
});
97-
var testDescriptor = getSampleMethodTestDescriptor();
98-
assertThatThrownBy(() -> compositeTestExecutionListener().executionStarted(testDescriptor)).isInstanceOf(
89+
var testDescriptor = anyTestDescriptor();
90+
91+
assertThatThrownBy(() -> compositeEngineExecutionListener().executionStarted(testDescriptor)).isInstanceOf(
9992
OutOfMemoryError.class);
10093

10194
assertNotLogs(logRecordListener);
10295
}
10396

104-
private EngineExecutionListener compositeTestExecutionListener() {
97+
@Test
98+
void callsListenersInReverseOrderForFinishedEvents() {
99+
listeners.clear();
100+
var firstListener = mock(EngineExecutionListener.class, "firstListener");
101+
var secondListener = mock(EngineExecutionListener.class, "secondListener");
102+
listeners.add(firstListener);
103+
listeners.add(secondListener);
104+
105+
var testDescriptor = anyTestDescriptor();
106+
var testExecutionResult = anyTestExecutionResult();
107+
108+
var composite = compositeEngineExecutionListener();
109+
composite.executionStarted(testDescriptor);
110+
composite.executionFinished(testDescriptor, testExecutionResult);
111+
112+
InOrder inOrder = inOrder(firstListener, secondListener);
113+
inOrder.verify(firstListener).executionStarted(testDescriptor);
114+
inOrder.verify(secondListener).executionStarted(testDescriptor);
115+
inOrder.verify(secondListener).executionFinished(testDescriptor, testExecutionResult);
116+
inOrder.verify(firstListener).executionFinished(testDescriptor, testExecutionResult);
117+
}
118+
119+
private EngineExecutionListener compositeEngineExecutionListener() {
105120
return new CompositeEngineExecutionListener(listeners);
106121
}
107122

@@ -114,8 +129,8 @@ private void assertNotLogs(LogRecordListener logRecordListener) throws Assertion
114129
assertThat(logRecordListener.stream(CompositeEngineExecutionListener.class, Level.WARNING).count()).isZero();
115130
}
116131

117-
private TestDescriptor getSampleMethodTestDescriptor() {
118-
return getDemoMethodTestDescriptor();
132+
private static TestExecutionResult anyTestExecutionResult() {
133+
return mock(TestExecutionResult.class);
119134
}
120135

121136
private void assertThatTestListenerErrorLogged(LogRecordListener logRecordListener, Class<?> listenerClass,
@@ -124,10 +139,10 @@ private void assertThatTestListenerErrorLogged(LogRecordListener logRecordListen
124139
"EngineExecutionListener [" + listenerClass.getName() + "] threw exception for method: " + methodName);
125140
}
126141

127-
private DemoMethodTestDescriptor getDemoMethodTestDescriptor() {
128-
var method = ReflectionUtils.findMethod(this.getClass(), "getDemoMethodTestDescriptor",
129-
new Class<?>[0]).orElseThrow();
130-
return new DemoMethodTestDescriptor(UniqueId.root("method", "unique_id"), this.getClass(), method);
142+
private static TestDescriptor anyTestDescriptor() {
143+
var testClass = CompositeEngineExecutionListenerTests.class;
144+
var method = ReflectionUtils.findMethod(testClass, "anyTestDescriptor", new Class<?>[0]).orElseThrow();
145+
return new DemoMethodTestDescriptor(UniqueId.root("method", "unique_id"), testClass, method);
131146
}
132147

133148
private static class ThrowingEngineExecutionListener implements EngineExecutionListener {

0 commit comments

Comments
 (0)