1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.surefire.junitplatform;
20
21 import java.lang.reflect.Method;
22
23 import org.apache.maven.surefire.api.util.ReflectionUtils;
24 import org.junit.platform.launcher.Launcher;
25 import org.junit.platform.launcher.LauncherDiscoveryRequest;
26 import org.junit.platform.launcher.TestExecutionListener;
27 import org.junit.platform.launcher.TestPlan;
28
29 import static java.util.Objects.requireNonNull;
30 import static org.apache.maven.surefire.junitplatform.CancellationTokenAdapter.CANCELLATION_TOKEN_CLASS;
31
32 final class LauncherAdapter {
33
34 static final Class<?> LAUNCHER_EXECUTION_REQUEST_CLASS = loadLauncherExecutionRequestClass();
35 static final Method EXECUTE_METHOD_WITH_LAUNCHER_EXECUTION_REQUEST_PARAMETER =
36 findExecuteMethodWithLauncherExecutionRequestParameter();
37
38 private final Launcher delegate;
39 private final CancellationTokenAdapter cancellationToken;
40
41 LauncherAdapter(Launcher delegate, CancellationTokenAdapter cancellationToken) {
42 this.delegate = delegate;
43 this.cancellationToken = cancellationToken;
44 }
45
46 TestPlan discover(LauncherDiscoveryRequest discoveryRequest) {
47 return delegate.discover(discoveryRequest);
48 }
49
50 void execute(LauncherDiscoveryRequest discoveryRequest, TestExecutionListener... listeners) {
51 if (cancellationToken == null) {
52 executeWithoutCancellationToken(discoveryRequest, listeners);
53 } else {
54 executeWithCancellationToken(discoveryRequest, listeners);
55 }
56 }
57
58 void executeWithoutCancellationToken(
59 LauncherDiscoveryRequest discoveryRequest, TestExecutionListener... listeners) {
60 delegate.execute(discoveryRequest, listeners);
61 }
62
63 private void executeWithCancellationToken(
64 LauncherDiscoveryRequest discoveryRequest, TestExecutionListener... listeners) {
65
66 Method executeMethod = requireNonNull(EXECUTE_METHOD_WITH_LAUNCHER_EXECUTION_REQUEST_PARAMETER);
67 Object executionRequest = createExecutionRequest(discoveryRequest, listeners);
68 ReflectionUtils.invokeMethodWithArray(delegate, executeMethod, executionRequest);
69 }
70
71 private static Method findExecuteMethodWithLauncherExecutionRequestParameter() {
72 if (LAUNCHER_EXECUTION_REQUEST_CLASS == null) {
73 return null;
74 }
75 return ReflectionUtils.getMethod(Launcher.class, "execute", LAUNCHER_EXECUTION_REQUEST_CLASS);
76 }
77
78 private static Class<?> loadLauncherExecutionRequestClass() {
79 return ReflectionUtils.tryLoadClass(
80 Launcher.class.getClassLoader(), "org.junit.platform.launcher.LauncherExecutionRequest");
81 }
82
83 private Object createExecutionRequest(
84 LauncherDiscoveryRequest discoveryRequest, TestExecutionListener[] listeners) {
85
86 Object builder = createLauncherExecutionRequestBuilder(discoveryRequest);
87 ReflectionUtils.invokeSetter(builder, "listeners", TestExecutionListener[].class, listeners);
88 ReflectionUtils.invokeSetter(
89 builder, "cancellationToken", CANCELLATION_TOKEN_CLASS, cancellationToken.getDelegate());
90 return ReflectionUtils.invokeGetter(builder, "build");
91 }
92
93 private static Object createLauncherExecutionRequestBuilder(LauncherDiscoveryRequest discoveryRequest) {
94 ClassLoader classLoader = discoveryRequest.getClass().getClassLoader();
95 Class<?> builderClass = ReflectionUtils.loadClass(
96 classLoader, "org.junit.platform.launcher.core.LauncherExecutionRequestBuilder");
97 Class<?>[] parameterTypes = {LauncherDiscoveryRequest.class};
98 Object[] parameters = {discoveryRequest};
99 return ReflectionUtils.invokeStaticMethod(builderClass, "request", parameterTypes, parameters);
100 }
101 }