|
12 | 12 |
|
13 | 13 | import static org.apiguardian.api.API.Status.INTERNAL; |
14 | 14 | import static org.junit.platform.engine.TestExecutionResult.successful; |
15 | | -import static org.junit.vintage.engine.Constants.PARALLEL_EXECUTION_ENABLED; |
16 | | -import static org.junit.vintage.engine.Constants.PARALLEL_POOL_SIZE; |
17 | 15 | import static org.junit.vintage.engine.descriptor.VintageTestDescriptor.ENGINE_ID; |
18 | 16 |
|
19 | | -import java.util.ArrayList; |
20 | | -import java.util.Iterator; |
21 | | -import java.util.List; |
22 | 17 | import java.util.Optional; |
23 | | -import java.util.concurrent.CompletableFuture; |
24 | | -import java.util.concurrent.ExecutionException; |
25 | | -import java.util.concurrent.ExecutorService; |
26 | | -import java.util.concurrent.Executors; |
27 | | -import java.util.concurrent.TimeUnit; |
28 | 18 |
|
29 | 19 | import org.apiguardian.api.API; |
30 | | -import org.junit.platform.commons.logging.Logger; |
31 | | -import org.junit.platform.commons.logging.LoggerFactory; |
32 | | -import org.junit.platform.commons.util.ExceptionUtils; |
33 | 20 | import org.junit.platform.engine.EngineDiscoveryRequest; |
34 | 21 | import org.junit.platform.engine.EngineExecutionListener; |
35 | 22 | import org.junit.platform.engine.ExecutionRequest; |
36 | 23 | import org.junit.platform.engine.TestDescriptor; |
37 | 24 | import org.junit.platform.engine.TestEngine; |
38 | 25 | import org.junit.platform.engine.UniqueId; |
39 | | -import org.junit.vintage.engine.descriptor.RunnerTestDescriptor; |
40 | 26 | import org.junit.vintage.engine.descriptor.VintageEngineDescriptor; |
41 | 27 | import org.junit.vintage.engine.discovery.VintageDiscoverer; |
42 | | -import org.junit.vintage.engine.execution.RunnerExecutor; |
| 28 | +import org.junit.vintage.engine.execution.VintageExecutor; |
43 | 29 |
|
44 | 30 | /** |
45 | 31 | * The JUnit Vintage {@link TestEngine}. |
|
49 | 35 | @API(status = INTERNAL, since = "4.12") |
50 | 36 | public final class VintageTestEngine implements TestEngine { |
51 | 37 |
|
52 | | - private static final Logger logger = LoggerFactory.getLogger(VintageTestEngine.class); |
53 | | - |
54 | | - private static final int DEFAULT_THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors(); |
55 | | - private static final int SHUTDOWN_TIMEOUT_SECONDS = 30; |
56 | | - |
57 | 38 | @Override |
58 | 39 | public String getId() { |
59 | 40 | return ENGINE_ID; |
@@ -86,96 +67,7 @@ public void execute(ExecutionRequest request) { |
86 | 67 | EngineExecutionListener engineExecutionListener = request.getEngineExecutionListener(); |
87 | 68 | VintageEngineDescriptor engineDescriptor = (VintageEngineDescriptor) request.getRootTestDescriptor(); |
88 | 69 | engineExecutionListener.executionStarted(engineDescriptor); |
89 | | - executeAllChildren(engineDescriptor, engineExecutionListener, request); |
| 70 | + new VintageExecutor(engineDescriptor, engineExecutionListener, request).executeAllChildren(); |
90 | 71 | engineExecutionListener.executionFinished(engineDescriptor, successful()); |
91 | 72 | } |
92 | | - |
93 | | - private void executeAllChildren(VintageEngineDescriptor engineDescriptor, |
94 | | - EngineExecutionListener engineExecutionListener, ExecutionRequest request) { |
95 | | - boolean parallelExecutionEnabled = getParallelExecutionEnabled(request); |
96 | | - |
97 | | - if (parallelExecutionEnabled) { |
98 | | - if (executeInParallel(engineDescriptor, engineExecutionListener, request)) { |
99 | | - Thread.currentThread().interrupt(); |
100 | | - } |
101 | | - } |
102 | | - else { |
103 | | - executeSequentially(engineDescriptor, engineExecutionListener); |
104 | | - } |
105 | | - } |
106 | | - |
107 | | - private boolean executeInParallel(VintageEngineDescriptor engineDescriptor, |
108 | | - EngineExecutionListener engineExecutionListener, ExecutionRequest request) { |
109 | | - ExecutorService executorService = Executors.newFixedThreadPool(getThreadPoolSize(request)); |
110 | | - RunnerExecutor runnerExecutor = new RunnerExecutor(engineExecutionListener); |
111 | | - |
112 | | - List<CompletableFuture<Void>> futures = new ArrayList<>(); |
113 | | - for (Iterator<TestDescriptor> iterator = engineDescriptor.getModifiableChildren().iterator(); iterator.hasNext();) { |
114 | | - TestDescriptor descriptor = iterator.next(); |
115 | | - CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { |
116 | | - runnerExecutor.execute((RunnerTestDescriptor) descriptor); |
117 | | - }, executorService); |
118 | | - |
119 | | - futures.add(future); |
120 | | - iterator.remove(); |
121 | | - } |
122 | | - |
123 | | - CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0])); |
124 | | - boolean wasInterrupted = false; |
125 | | - try { |
126 | | - allOf.get(); |
127 | | - } |
128 | | - catch (InterruptedException e) { |
129 | | - logger.warn(e, () -> "Interruption while waiting for parallel test execution to finish"); |
130 | | - wasInterrupted = true; |
131 | | - } |
132 | | - catch (ExecutionException e) { |
133 | | - throw ExceptionUtils.throwAsUncheckedException(e.getCause()); |
134 | | - } |
135 | | - finally { |
136 | | - shutdownExecutorService(executorService); |
137 | | - } |
138 | | - return wasInterrupted; |
139 | | - } |
140 | | - |
141 | | - private void shutdownExecutorService(ExecutorService executorService) { |
142 | | - try { |
143 | | - executorService.shutdown(); |
144 | | - if (!executorService.awaitTermination(SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { |
145 | | - logger.warn(() -> "Executor service did not terminate within the specified timeout"); |
146 | | - executorService.shutdownNow(); |
147 | | - } |
148 | | - } |
149 | | - catch (InterruptedException e) { |
150 | | - logger.warn(e, () -> "Interruption while waiting for executor service to shut down"); |
151 | | - Thread.currentThread().interrupt(); |
152 | | - } |
153 | | - } |
154 | | - |
155 | | - private void executeSequentially(VintageEngineDescriptor engineDescriptor, |
156 | | - EngineExecutionListener engineExecutionListener) { |
157 | | - RunnerExecutor runnerExecutor = new RunnerExecutor(engineExecutionListener); |
158 | | - for (Iterator<TestDescriptor> iterator = engineDescriptor.getModifiableChildren().iterator(); iterator.hasNext();) { |
159 | | - runnerExecutor.execute((RunnerTestDescriptor) iterator.next()); |
160 | | - iterator.remove(); |
161 | | - } |
162 | | - } |
163 | | - |
164 | | - private boolean getParallelExecutionEnabled(ExecutionRequest request) { |
165 | | - return request.getConfigurationParameters().getBoolean(PARALLEL_EXECUTION_ENABLED).orElse(false); |
166 | | - } |
167 | | - |
168 | | - private int getThreadPoolSize(ExecutionRequest request) { |
169 | | - Optional<String> poolSize = request.getConfigurationParameters().get(PARALLEL_POOL_SIZE); |
170 | | - if (poolSize.isPresent()) { |
171 | | - try { |
172 | | - return Integer.parseInt(poolSize.get()); |
173 | | - } |
174 | | - catch (NumberFormatException e) { |
175 | | - logger.warn(() -> "Invalid value for parallel pool size: " + poolSize.get()); |
176 | | - } |
177 | | - } |
178 | | - return DEFAULT_THREAD_POOL_SIZE; |
179 | | - } |
180 | | - |
181 | 73 | } |
0 commit comments