in maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java [311:364]
private RunResult runSuitesForkOnceMultiple(SurefireProperties effectiveSystemProps, int forkCount)
throws SurefireBooterForkException {
ThreadPoolExecutor executor =
new ThreadPoolExecutor(forkCount, forkCount, 60L, SECONDS, new ArrayBlockingQueue<>(forkCount));
executor.setThreadFactory(FORKED_JVM_DAEMON_THREAD_FACTORY);
Queue<String> tests = new ConcurrentLinkedQueue<>();
for (Class<?> clazz : getSuitesIterator()) {
tests.add(clazz.getName());
}
Queue<TestProvidingInputStream> forks = new ConcurrentLinkedQueue<>();
for (int forkNum = 0, total = min(forkCount, tests.size()); forkNum < total; forkNum++) {
forks.add(new TestProvidingInputStream(tests));
}
Thread shutdown = createShutdownHookThread(forks, providerConfiguration.getShutdown());
addShutDownHook(shutdown);
ScheduledFuture<?> ping = triggerPingTimerForShutdown(forks);
try {
int failFastCount = providerConfiguration.getSkipAfterFailureCount();
AtomicInteger notifyForksToSkipTestsNow = new AtomicInteger(failFastCount);
Collection<Future<RunResult>> results = forks.stream()
.filter(fork -> !forkConfiguration.getPluginPlatform().isShutdown())
.map(fork -> (Callable<RunResult>) () -> {
int forkNumber = drawNumber();
DefaultReporterFactory reporter =
new DefaultReporterFactory(startupReportConfiguration, log, forkNumber);
defaultReporterFactories.add(reporter);
ForkClient client = new ForkClient(reporter, fork, forkNumber);
client.setStopOnNextTestListener(() ->
runIfZeroCountDown(() -> notifyStreamsToSkipTests(forks), notifyForksToSkipTestsNow));
Map<String, String> providerProperties = providerConfiguration.getProviderProperties();
PropertiesWrapper keyValues = new PropertiesWrapper(providerProperties);
ForkNodeFactory node = forkConfiguration.getForkNodeFactory();
try {
return fork(null, keyValues, client, effectiveSystemProps, forkNumber, fork, node, true);
} finally {
returnNumber(forkNumber);
}
})
.map(executor::submit)
.collect(toList());
return awaitResultsDone(results, executor);
} finally {
removeShutdownHook(shutdown);
ping.cancel(true);
closeExecutor(executor);
}
}