Skip to content

Commit 7926d81

Browse files
committed
Fix discovery listener invocation
Prior to this commit `EngineDiscoveryListener.selectorProcessed` was not called for listeners registered via `LauncherConfig` or `Launcher`.
1 parent e20643b commit 7926d81

File tree

4 files changed

+130
-11
lines changed

4 files changed

+130
-11
lines changed

Diff for: documentation/src/docs/asciidoc/release-notes/release-notes-5.13.0-M1.adoc

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ repository on GitHub.
1616
[[release-notes-5.13.0-M1-junit-platform-bug-fixes]]
1717
==== Bug Fixes
1818

19-
* ❓
19+
* Notify `LauncherDiscoveryListener` implementation registered via `LaucherConfig` or on
20+
the `Launcher` of `selectorProcessed` events.
2021

2122
[[release-notes-5.13.0-M1-junit-platform-deprecations-and-breaking-changes]]
2223
==== Deprecations and Breaking Changes
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2015-2025 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* https://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
11+
package org.junit.platform.launcher.core;
12+
13+
import java.util.List;
14+
15+
import org.junit.platform.engine.ConfigurationParameters;
16+
import org.junit.platform.engine.DiscoveryFilter;
17+
import org.junit.platform.engine.DiscoverySelector;
18+
import org.junit.platform.engine.reporting.OutputDirectoryProvider;
19+
import org.junit.platform.launcher.EngineFilter;
20+
import org.junit.platform.launcher.LauncherDiscoveryListener;
21+
import org.junit.platform.launcher.LauncherDiscoveryRequest;
22+
import org.junit.platform.launcher.PostDiscoveryFilter;
23+
24+
/**
25+
* @since 5.13
26+
*/
27+
class DelegatingLauncherDiscoveryRequest implements LauncherDiscoveryRequest {
28+
29+
private final LauncherDiscoveryRequest request;
30+
31+
DelegatingLauncherDiscoveryRequest(LauncherDiscoveryRequest request) {
32+
this.request = request;
33+
}
34+
35+
public List<EngineFilter> getEngineFilters() {
36+
return this.request.getEngineFilters();
37+
}
38+
39+
public List<PostDiscoveryFilter> getPostDiscoveryFilters() {
40+
return this.request.getPostDiscoveryFilters();
41+
}
42+
43+
public LauncherDiscoveryListener getDiscoveryListener() {
44+
return this.request.getDiscoveryListener();
45+
}
46+
47+
public <T extends DiscoverySelector> List<T> getSelectorsByType(Class<T> selectorType) {
48+
return this.request.getSelectorsByType(selectorType);
49+
}
50+
51+
public <T extends DiscoveryFilter<?>> List<T> getFiltersByType(Class<T> filterType) {
52+
return this.request.getFiltersByType(filterType);
53+
}
54+
55+
public ConfigurationParameters getConfigurationParameters() {
56+
return this.request.getConfigurationParameters();
57+
}
58+
59+
public OutputDirectoryProvider getOutputDirectoryProvider() {
60+
return this.request.getOutputDirectoryProvider();
61+
}
62+
}

Diff for: junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/EngineDiscoveryOrchestrator.java

+11-4
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,15 @@ public LauncherDiscoveryResult discover(LauncherDiscoveryRequest request, Phase
100100
private LauncherDiscoveryResult discover(LauncherDiscoveryRequest request, Phase phase,
101101
Function<String, UniqueId> uniqueIdCreator) {
102102
LauncherDiscoveryListener listener = getLauncherDiscoveryListener(request);
103+
LauncherDiscoveryRequest delegatingRequest = new DelegatingLauncherDiscoveryRequest(request) {
104+
@Override
105+
public LauncherDiscoveryListener getDiscoveryListener() {
106+
return listener;
107+
}
108+
};
103109
listener.launcherDiscoveryStarted(request);
104110
try {
105-
Map<TestEngine, TestDescriptor> testEngines = discoverSafely(request, phase, listener, uniqueIdCreator);
111+
Map<TestEngine, TestDescriptor> testEngines = discoverSafely(delegatingRequest, phase, uniqueIdCreator);
106112
return new LauncherDiscoveryResult(testEngines, request.getConfigurationParameters(),
107113
request.getOutputDirectoryProvider());
108114
}
@@ -112,7 +118,7 @@ private LauncherDiscoveryResult discover(LauncherDiscoveryRequest request, Phase
112118
}
113119

114120
private Map<TestEngine, TestDescriptor> discoverSafely(LauncherDiscoveryRequest request, Phase phase,
115-
LauncherDiscoveryListener listener, Function<String, UniqueId> uniqueIdCreator) {
121+
Function<String, UniqueId> uniqueIdCreator) {
116122
Map<TestEngine, TestDescriptor> testEngineDescriptors = new LinkedHashMap<>();
117123
EngineFilterer engineFilterer = new EngineFilterer(request.getEngineFilters());
118124

@@ -129,7 +135,7 @@ private Map<TestEngine, TestDescriptor> discoverSafely(LauncherDiscoveryRequest
129135
logger.debug(() -> String.format("Discovering tests during Launcher %s phase in engine '%s'.", phase,
130136
testEngine.getId()));
131137

132-
TestDescriptor rootDescriptor = discoverEngineRoot(testEngine, request, listener, uniqueIdCreator);
138+
TestDescriptor rootDescriptor = discoverEngineRoot(testEngine, request, uniqueIdCreator);
133139
testEngineDescriptors.put(testEngine, rootDescriptor);
134140
}
135141

@@ -145,8 +151,9 @@ private Map<TestEngine, TestDescriptor> discoverSafely(LauncherDiscoveryRequest
145151
}
146152

147153
private TestDescriptor discoverEngineRoot(TestEngine testEngine, LauncherDiscoveryRequest request,
148-
LauncherDiscoveryListener listener, Function<String, UniqueId> uniqueIdCreator) {
154+
Function<String, UniqueId> uniqueIdCreator) {
149155
UniqueId uniqueEngineId = uniqueIdCreator.apply(testEngine.getId());
156+
LauncherDiscoveryListener listener = request.getDiscoveryListener();
150157
try {
151158
listener.engineDiscoveryStarted(uniqueEngineId);
152159
TestDescriptor engineRoot = testEngine.discover(request, uniqueEngineId);

Diff for: platform-tests/src/test/java/org/junit/platform/launcher/core/DefaultLauncherTests.java

+55-6
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
package org.junit.platform.launcher.core;
1212

1313
import static org.assertj.core.api.Assertions.assertThat;
14+
import static org.junit.jupiter.api.Assertions.assertAll;
1415
import static org.junit.jupiter.api.Assertions.assertEquals;
1516
import static org.junit.jupiter.api.Assertions.assertThrows;
1617
import static org.junit.jupiter.api.Assertions.assertTrue;
1718
import static org.junit.platform.commons.util.CollectionUtils.getOnlyElement;
19+
import static org.junit.platform.engine.SelectorResolutionResult.unresolved;
1820
import static org.junit.platform.engine.TestExecutionResult.successful;
1921
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage;
2022
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUniqueId;
@@ -42,6 +44,7 @@
4244
import org.junit.platform.commons.PreconditionViolationException;
4345
import org.junit.platform.commons.logging.LogRecordListener;
4446
import org.junit.platform.commons.util.ExceptionUtils;
47+
import org.junit.platform.engine.DiscoverySelector;
4548
import org.junit.platform.engine.EngineDiscoveryRequest;
4649
import org.junit.platform.engine.ExecutionRequest;
4750
import org.junit.platform.engine.FilterResult;
@@ -64,6 +67,7 @@
6467
import org.junit.platform.launcher.TestPlan;
6568
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
6669
import org.mockito.ArgumentCaptor;
70+
import org.mockito.InOrder;
6771

6872
/**
6973
* @since 1.0
@@ -121,7 +125,7 @@ public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId
121125
.configurationParameter(DEFAULT_DISCOVERY_LISTENER_CONFIGURATION_PROPERTY_NAME, "logging") //
122126
.build());
123127
assertThat(testPlan.getRoots()).hasSize(1);
124-
assertDiscoveryFailed(engine, discoveryListener);
128+
assertDiscoveryFailed(engine, inOrder(discoveryListener), discoveryListener);
125129
}
126130

127131
@ParameterizedTest
@@ -152,9 +156,11 @@ public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId
152156
assertThat(testPlan.getRoots()).hasSize(1);
153157
var engineIdentifier = getOnlyElement(testPlan.getRoots());
154158
assertThat(getOnlyElement(testPlan.getRoots()).getDisplayName()).isEqualTo("my-engine-id");
155-
verify(discoveryListener).launcherDiscoveryStarted(request);
156-
verify(discoveryListener).launcherDiscoveryFinished(request);
157-
assertDiscoveryFailed(engine, discoveryListener);
159+
160+
InOrder inOrder = inOrder(discoveryListener);
161+
inOrder.verify(discoveryListener).launcherDiscoveryStarted(request);
162+
assertDiscoveryFailed(engine, inOrder, discoveryListener);
163+
inOrder.verify(discoveryListener).launcherDiscoveryFinished(request);
158164

159165
var listener = mock(TestExecutionListener.class);
160166
launcher.execute(testPlan, listener);
@@ -167,10 +173,13 @@ public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId
167173
.hasMessage("TestEngine with ID 'my-engine-id' failed to discover tests");
168174
}
169175

170-
private void assertDiscoveryFailed(TestEngine testEngine, LauncherDiscoveryListener discoveryListener) {
176+
private void assertDiscoveryFailed(TestEngine testEngine, InOrder inOrder,
177+
LauncherDiscoveryListener discoveryListener) {
171178
var engineId = testEngine.getId();
172179
var failureCaptor = ArgumentCaptor.forClass(EngineDiscoveryResult.class);
173-
verify(discoveryListener).engineDiscoveryFinished(eq(UniqueId.forEngine(engineId)), failureCaptor.capture());
180+
inOrder.verify(discoveryListener).engineDiscoveryStarted(UniqueId.forEngine(engineId));
181+
inOrder.verify(discoveryListener).engineDiscoveryFinished(eq(UniqueId.forEngine(engineId)),
182+
failureCaptor.capture());
174183
var result = failureCaptor.getValue();
175184
assertThat(result.getStatus()).isEqualTo(EngineDiscoveryResult.Status.FAILED);
176185
assertThat(result.getThrowable()).isPresent();
@@ -651,4 +660,44 @@ void dryRunModeReportsEventsForAllTestsButDoesNotExecuteThem() {
651660
inOrder.verify(listener).testPlanExecutionFinished(any());
652661
inOrder.verifyNoMoreInteractions();
653662
}
663+
664+
@Test
665+
void notifiesDiscoveryListenersOfProcessedSelectors() {
666+
TestEngine engine = new TestEngineStub("some-engine-id") {
667+
668+
@Override
669+
public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) {
670+
discoveryRequest.getSelectorsByType(DiscoverySelector.class).forEach(selector -> {
671+
discoveryRequest.getDiscoveryListener().selectorProcessed(uniqueId, selector, unresolved());
672+
});
673+
return new EngineDescriptor(uniqueId, uniqueId.getLastSegment().getValue());
674+
}
675+
};
676+
var engineId = UniqueId.forEngine(engine.getId());
677+
678+
var discoveryListenerOnConfig = mock(LauncherDiscoveryListener.class, "discoveryListenerOnConfig");
679+
var discoveryListenerOnLauncher = mock(LauncherDiscoveryListener.class, "discoveryListenerOnLauncher");
680+
var discoveryListenerOnRequest = mock(LauncherDiscoveryListener.class, "discoveryListenerOnRequest");
681+
var selector = mock(DiscoverySelector.class);
682+
683+
var launcherConfig = LauncherFactoryForTestingPurposesOnly.createLauncherConfigBuilderWithDisabledServiceLoading() //
684+
.addTestEngines(engine) //
685+
.addLauncherDiscoveryListeners(discoveryListenerOnConfig) //
686+
.build();
687+
688+
var launcher = LauncherFactory.create(launcherConfig);
689+
launcher.registerLauncherDiscoveryListeners(discoveryListenerOnLauncher);
690+
691+
launcher.discover(request() //
692+
.selectors(selector) //
693+
.listeners(discoveryListenerOnRequest) //
694+
.build());
695+
696+
assertAll( //
697+
() -> verify(discoveryListenerOnConfig).selectorProcessed(engineId, selector, unresolved()), //
698+
() -> verify(discoveryListenerOnLauncher).selectorProcessed(engineId, selector, unresolved()), //
699+
() -> verify(discoveryListenerOnRequest).selectorProcessed(engineId, selector, unresolved()) //
700+
);
701+
}
702+
654703
}

0 commit comments

Comments
 (0)