Skip to content

Commit 95a48ad

Browse files
committed
Create interceptors before launcher
So they can influence the class loader used to load test engines etc.
1 parent c8e666e commit 95a48ad

File tree

22 files changed

+293
-182
lines changed

22 files changed

+293
-182
lines changed

junit-platform-engine/src/testFixtures/java/org/junit/platform/fakes/TestEngineSpy.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,27 @@
2121
*/
2222
public class TestEngineSpy implements TestEngine {
2323

24-
public static final String ID = TestEngineSpy.class.getSimpleName();
24+
private final String id;
2525

2626
public ExecutionRequest requestForExecution;
2727

28+
public TestEngineSpy() {
29+
this(TestEngineSpy.class.getSimpleName());
30+
}
31+
32+
public TestEngineSpy(String id) {
33+
this.id = id;
34+
}
35+
2836
@Override
2937
public String getId() {
30-
return ID;
38+
return id;
3139
}
3240

3341
@Override
3442
public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) {
35-
var engineUniqueId = UniqueId.forEngine(ID);
36-
var engineDescriptor = new TestDescriptorStub(engineUniqueId, ID);
43+
var engineUniqueId = UniqueId.forEngine(id);
44+
var engineDescriptor = new TestDescriptorStub(engineUniqueId, id);
3745
var testDescriptor = new TestDescriptorStub(engineUniqueId.append("test", "test"), "test");
3846
engineDescriptor.addChild(testDescriptor);
3947
return engineDescriptor;
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010

1111
package org.junit.platform.launcher.core;
1212

13+
import org.junit.platform.launcher.Launcher;
14+
1315
/**
1416
* @since 1.10
1517
*/
16-
interface CloseableInternalLauncher extends InternalLauncher, AutoCloseable {
18+
interface CloseableLauncher extends Launcher, AutoCloseable {
1719
@Override
1820
void close();
1921
}

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

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,11 @@
3535
* @see Launcher
3636
* @see LauncherFactory
3737
*/
38-
class DefaultLauncher implements InternalLauncher {
38+
class DefaultLauncher implements Launcher {
3939

40-
private final ListenerRegistry<LauncherDiscoveryListener> launcherDiscoveryListenerRegistry = ListenerRegistry.forLauncherDiscoveryListeners();
41-
private final ListenerRegistry<TestExecutionListener> testExecutionListenerRegistry = ListenerRegistry.forTestExecutionListeners();
40+
private final LauncherListenerRegistry listenerRegistry = new LauncherListenerRegistry();
4241
private final EngineExecutionOrchestrator executionOrchestrator = new EngineExecutionOrchestrator(
43-
testExecutionListenerRegistry);
42+
listenerRegistry.testExecutionListeners);;
4443
private final EngineDiscoveryOrchestrator discoveryOrchestrator;
4544

4645
/**
@@ -59,17 +58,17 @@ class DefaultLauncher implements InternalLauncher {
5958
Preconditions.containsNoNullElements(postDiscoveryFilters,
6059
"PostDiscoveryFilter array must not contain null elements");
6160
this.discoveryOrchestrator = new EngineDiscoveryOrchestrator(testEngines,
62-
unmodifiableCollection(postDiscoveryFilters), launcherDiscoveryListenerRegistry);
61+
unmodifiableCollection(postDiscoveryFilters), listenerRegistry.launcherDiscoveryListeners);
6362
}
6463

6564
@Override
6665
public void registerLauncherDiscoveryListeners(LauncherDiscoveryListener... listeners) {
67-
this.launcherDiscoveryListenerRegistry.addAll(listeners);
66+
this.listenerRegistry.launcherDiscoveryListeners.addAll(listeners);
6867
}
6968

7069
@Override
7170
public void registerTestExecutionListeners(TestExecutionListener... listeners) {
72-
this.testExecutionListenerRegistry.addAll(listeners);
71+
this.listenerRegistry.testExecutionListeners.addAll(listeners);
7372
}
7473

7574
@Override
@@ -95,16 +94,6 @@ public void execute(TestPlan testPlan, TestExecutionListener... listeners) {
9594
execute((InternalTestPlan) testPlan, listeners);
9695
}
9796

98-
@Override
99-
public ListenerRegistry<TestExecutionListener> getTestExecutionListenerRegistry() {
100-
return testExecutionListenerRegistry;
101-
}
102-
103-
@Override
104-
public ListenerRegistry<LauncherDiscoveryListener> getLauncherDiscoveryListenerRegistry() {
105-
return launcherDiscoveryListenerRegistry;
106-
}
107-
10897
private LauncherDiscoveryResult discover(LauncherDiscoveryRequest discoveryRequest,
10998
EngineDiscoveryOrchestrator.Phase phase) {
11099
return discoveryOrchestrator.discover(discoveryRequest, phase);

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

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
package org.junit.platform.launcher.core;
1212

1313
import java.util.List;
14+
import java.util.function.Supplier;
1415

1516
import org.junit.platform.commons.PreconditionViolationException;
1617
import org.junit.platform.launcher.Launcher;
@@ -27,12 +28,16 @@
2728
*/
2829
class DefaultLauncherSession implements LauncherSession {
2930

30-
private final DelegatingLauncher launcher;
31+
private final DelegatingCloseableLauncher<CloseableLauncher> launcher;
3132
private final LauncherSessionListener listener;
3233

33-
DefaultLauncherSession(InternalLauncher launcher, LauncherSessionListener listener,
34-
List<LauncherInterceptor> interceptors) {
35-
this.launcher = new DelegatingLauncher(InterceptingInternalLauncher.decorate(launcher, interceptors));
34+
DefaultLauncherSession(Supplier<Launcher> launcherSupplier, List<LauncherInterceptor> interceptors,
35+
LauncherSessionListener listener) {
36+
CloseableLauncher closeableLauncher = InterceptingClosableLauncher.decorate(launcherSupplier, interceptors);
37+
this.launcher = new DelegatingCloseableLauncher<>(closeableLauncher, delegate -> {
38+
delegate.close();
39+
return ClosedLauncher.INSTANCE;
40+
});
3641
this.listener = listener;
3742
listener.launcherSessionOpened(this);
3843
}
@@ -48,31 +53,13 @@ LauncherSessionListener getListener() {
4853

4954
@Override
5055
public void close() {
51-
if (launcher.isClosed()) {
56+
if (!launcher.isClosed()) {
5257
launcher.close();
5358
listener.launcherSessionClosed(this);
5459
}
5560
}
5661

57-
private static class DelegatingLauncher extends DelegatingInternalLauncher<CloseableInternalLauncher>
58-
implements CloseableInternalLauncher {
59-
60-
DelegatingLauncher(CloseableInternalLauncher delegate) {
61-
super(delegate);
62-
}
63-
64-
boolean isClosed() {
65-
return delegate != ClosedLauncher.INSTANCE;
66-
}
67-
68-
@Override
69-
public void close() {
70-
delegate.close();
71-
delegate = ClosedLauncher.INSTANCE;
72-
}
73-
}
74-
75-
private static class ClosedLauncher implements CloseableInternalLauncher {
62+
private static class ClosedLauncher implements CloseableLauncher {
7663

7764
static final ClosedLauncher INSTANCE = new ClosedLauncher();
7865

@@ -104,16 +91,6 @@ public void execute(TestPlan testPlan, TestExecutionListener... listeners) {
10491
throw new PreconditionViolationException("Launcher session has already been closed");
10592
}
10693

107-
@Override
108-
public ListenerRegistry<TestExecutionListener> getTestExecutionListenerRegistry() {
109-
throw new PreconditionViolationException("Launcher session has already been closed");
110-
}
111-
112-
@Override
113-
public ListenerRegistry<LauncherDiscoveryListener> getLauncherDiscoveryListenerRegistry() {
114-
throw new PreconditionViolationException("Launcher session has already been closed");
115-
}
116-
11794
@Override
11895
public void close() {
11996
// do nothing

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

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2015-2022 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.function.Function;
14+
15+
import org.junit.platform.launcher.Launcher;
16+
17+
/**
18+
* @since 1.10
19+
*/
20+
class DelegatingCloseableLauncher<T extends Launcher> extends DelegatingLauncher<T> implements CloseableLauncher {
21+
22+
private final Function<? super T, ? extends T> onClose;
23+
private boolean closed;
24+
25+
public DelegatingCloseableLauncher(T delegate, Function<? super T, ? extends T> onClose) {
26+
super(delegate);
27+
this.onClose = onClose;
28+
}
29+
30+
@Override
31+
public final void close() {
32+
if (!closed) {
33+
this.closed = true;
34+
delegate = this.onClose.apply(this.delegate);
35+
}
36+
}
37+
38+
public boolean isClosed() {
39+
return closed;
40+
}
41+
}
Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
package org.junit.platform.launcher.core;
1212

13+
import org.junit.platform.launcher.Launcher;
1314
import org.junit.platform.launcher.LauncherDiscoveryListener;
1415
import org.junit.platform.launcher.LauncherDiscoveryRequest;
1516
import org.junit.platform.launcher.TestExecutionListener;
@@ -18,11 +19,11 @@
1819
/**
1920
* @since 1.10
2021
*/
21-
class DelegatingInternalLauncher<T extends InternalLauncher> implements InternalLauncher {
22+
class DelegatingLauncher<T extends Launcher> implements Launcher {
2223

2324
protected T delegate;
2425

25-
DelegatingInternalLauncher(T delegate) {
26+
DelegatingLauncher(T delegate) {
2627
this.delegate = delegate;
2728
}
2829

@@ -51,13 +52,4 @@ public void execute(TestPlan testPlan, TestExecutionListener... listeners) {
5152
delegate.execute(testPlan, listeners);
5253
}
5354

54-
@Override
55-
public ListenerRegistry<TestExecutionListener> getTestExecutionListenerRegistry() {
56-
return delegate.getTestExecutionListenerRegistry();
57-
}
58-
59-
@Override
60-
public ListenerRegistry<LauncherDiscoveryListener> getLauncherDiscoveryListenerRegistry() {
61-
return delegate.getLauncherDiscoveryListenerRegistry();
62-
}
6355
}
Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@
1010

1111
package org.junit.platform.launcher.core;
1212

13+
import static java.util.function.Function.identity;
14+
1315
import java.util.List;
1416
import java.util.Optional;
17+
import java.util.function.Supplier;
1518

19+
import org.junit.platform.launcher.Launcher;
1620
import org.junit.platform.launcher.LauncherDiscoveryRequest;
1721
import org.junit.platform.launcher.LauncherInterceptor;
1822
import org.junit.platform.launcher.TestExecutionListener;
@@ -21,15 +25,15 @@
2125
/**
2226
* @since 1.10
2327
*/
24-
class InterceptingInternalLauncher extends DelegatingCloseableInternalLauncher<InternalLauncher> {
28+
class InterceptingClosableLauncher extends DelegatingCloseableLauncher<Launcher> {
2529

26-
static CloseableInternalLauncher decorate(InternalLauncher launcher, List<LauncherInterceptor> interceptors) {
27-
return composite(interceptors) //
28-
.map(combinedInterceptor -> (CloseableInternalLauncher) new InterceptingInternalLauncher(launcher,
29-
combinedInterceptor)) //
30-
.orElse(new DelegatingCloseableInternalLauncher<>(launcher, () -> {
31-
// do nothing
32-
}));
30+
static CloseableLauncher decorate(Supplier<Launcher> launcherSupplier, List<LauncherInterceptor> interceptors) {
31+
Optional<LauncherInterceptor> combinedInterceptor = composite(interceptors);
32+
Launcher launcher = combinedInterceptor.map(it -> it.intercept(launcherSupplier::get)).orElseGet(
33+
launcherSupplier);
34+
return combinedInterceptor //
35+
.map(it -> (CloseableLauncher) new InterceptingClosableLauncher(launcher, it)) //
36+
.orElse(new DelegatingCloseableLauncher<>(launcher, identity()));
3337
}
3438

3539
private static Optional<LauncherInterceptor> composite(List<LauncherInterceptor> interceptors) {
@@ -58,8 +62,11 @@ public <T> T intercept(Invocation<T> invocation) {
5862

5963
private final LauncherInterceptor interceptor;
6064

61-
private InterceptingInternalLauncher(InternalLauncher delegate, LauncherInterceptor interceptor) {
62-
super(delegate, interceptor::close);
65+
private InterceptingClosableLauncher(Launcher delegate, LauncherInterceptor interceptor) {
66+
super(delegate, it -> {
67+
interceptor.close();
68+
return it;
69+
});
6370
this.interceptor = interceptor;
6471
}
6572

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,10 @@ public static LauncherSession openSession() throws PreconditionViolationExceptio
9898
*/
9999
@API(status = EXPERIMENTAL, since = "1.8")
100100
public static LauncherSession openSession(LauncherConfig config) throws PreconditionViolationException {
101+
Preconditions.notNull(config, "LauncherConfig must not be null");
101102
LauncherConfigurationParameters configurationParameters = LauncherConfigurationParameters.builder().build();
102-
return new DefaultLauncherSession(createDefaultLauncher(config, configurationParameters),
103-
createLauncherSessionListener(config), collectLauncherInterceptors(configurationParameters));
103+
return new DefaultLauncherSession(() -> createDefaultLauncher(config, configurationParameters),
104+
collectLauncherInterceptors(configurationParameters), createLauncherSessionListener(config));
104105
}
105106

106107
/**
@@ -127,15 +128,14 @@ public static Launcher create() throws PreconditionViolationException {
127128
*/
128129
@API(status = EXPERIMENTAL, since = "1.3")
129130
public static Launcher create(LauncherConfig config) throws PreconditionViolationException {
131+
Preconditions.notNull(config, "LauncherConfig must not be null");
130132
LauncherConfigurationParameters configurationParameters = LauncherConfigurationParameters.builder().build();
131-
return new SessionPerRequestLauncher(createDefaultLauncher(config, configurationParameters),
133+
return new SessionPerRequestLauncher(() -> createDefaultLauncher(config, configurationParameters),
132134
createLauncherSessionListener(config), () -> collectLauncherInterceptors(configurationParameters));
133135
}
134136

135137
private static DefaultLauncher createDefaultLauncher(LauncherConfig config,
136138
LauncherConfigurationParameters configurationParameters) {
137-
Preconditions.notNull(config, "LauncherConfig must not be null");
138-
139139
Set<TestEngine> engines = collectTestEngines(config);
140140
List<PostDiscoveryFilter> filters = collectPostDiscoveryFilters(config);
141141

junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/InternalLauncher.java renamed to junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/LauncherListenerRegistry.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,10 @@
1010

1111
package org.junit.platform.launcher.core;
1212

13-
import org.junit.platform.launcher.Launcher;
1413
import org.junit.platform.launcher.LauncherDiscoveryListener;
1514
import org.junit.platform.launcher.TestExecutionListener;
1615

17-
/**
18-
* @since 1.8
19-
*/
20-
interface InternalLauncher extends Launcher {
21-
22-
ListenerRegistry<TestExecutionListener> getTestExecutionListenerRegistry();
23-
24-
ListenerRegistry<LauncherDiscoveryListener> getLauncherDiscoveryListenerRegistry();
16+
class LauncherListenerRegistry {
17+
final ListenerRegistry<LauncherDiscoveryListener> launcherDiscoveryListeners = ListenerRegistry.forLauncherDiscoveryListeners();
18+
final ListenerRegistry<TestExecutionListener> testExecutionListeners = ListenerRegistry.forTestExecutionListeners();
2519
}

0 commit comments

Comments
 (0)