From 55184c0afb4d23afe31b864ffacaf6d8fef39fd7 Mon Sep 17 00:00:00 2001 From: Emond Papegaaij Date: Fri, 10 Sep 2021 22:19:41 +0200 Subject: [PATCH] [SUREFIRE-1935] Use JUnit Platform 1.8 API to start Launcher via LauncherSession --- .../junitplatform/JUnitPlatformProvider.java | 64 +++++++++++++++---- .../surefire/junitplatform/LazyLauncher.java | 26 +++++++- 2 files changed, 75 insertions(+), 15 deletions(-) diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java index c8df55be6a..12db34cc0c 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java @@ -25,10 +25,10 @@ import static java.util.Optional.of; import static java.util.logging.Level.WARNING; import static java.util.stream.Collectors.toList; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_GROUPS_PROP; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.INCLUDE_JUNIT5_ENGINES_PROP; import static org.apache.maven.surefire.api.booter.ProviderParameterNames.EXCLUDE_JUNIT5_ENGINES_PROP; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.INCLUDE_JUNIT5_ENGINES_PROP; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_GROUPS_PROP; import static org.apache.maven.surefire.api.report.ConsoleOutputCapture.startCapture; import static org.apache.maven.surefire.api.util.TestsToRun.fromClass; import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank; @@ -58,6 +58,7 @@ import org.apache.maven.surefire.api.testset.TestListResolver; import org.apache.maven.surefire.api.testset.TestSetFailedException; import org.apache.maven.surefire.api.util.ScanResult; +import org.apache.maven.surefire.api.util.SurefireReflectionException; import org.apache.maven.surefire.api.util.TestsToRun; import org.apache.maven.surefire.shared.utils.StringUtils; import org.junit.platform.engine.DiscoverySelector; @@ -104,7 +105,14 @@ public JUnitPlatformProvider( ProviderParameters parameters ) @Override public Iterable> getSuites() { - return scanClasspath(); + try + { + return scanClasspath(); + } + finally + { + closeLauncher(); + } } @Override @@ -153,22 +161,37 @@ private TestsToRun scanClasspath() private void invokeAllTests( TestsToRun testsToRun, RunListener runListener ) { RunListenerAdapter adapter = new RunListenerAdapter( runListener ); - execute( testsToRun, adapter ); + try + { + execute( testsToRun, adapter ); + } + finally + { + closeLauncher(); + } // Rerun failing tests if requested int count = parameters.getTestRequest().getRerunFailingTestsCount(); if ( count > 0 && adapter.hasFailingTests() ) { for ( int i = 0; i < count; i++ ) { - // Replace the "discoveryRequest" so that it only specifies the failing tests - LauncherDiscoveryRequest discoveryRequest = buildLauncherDiscoveryRequestForRerunFailures( adapter ); - // Reset adapter's recorded failures and invoke the failed tests again - adapter.reset(); - launcher.execute( discoveryRequest, adapter ); - // If no tests fail in the rerun, we're done - if ( !adapter.hasFailingTests() ) + try { - break; + // Replace the "discoveryRequest" so that it only specifies the failing tests + LauncherDiscoveryRequest discoveryRequest = + buildLauncherDiscoveryRequestForRerunFailures( adapter ); + // Reset adapter's recorded failures and invoke the failed tests again + adapter.reset(); + launcher.execute( discoveryRequest, adapter ); + // If no tests fail in the rerun, we're done + if ( !adapter.hasFailingTests() ) + { + break; + } + } + finally + { + closeLauncher(); } } } @@ -202,6 +225,21 @@ private void execute( TestsToRun testsToRun, RunListenerAdapter adapter ) } ); } } + + private void closeLauncher() + { + if ( launcher instanceof AutoCloseable ) + { + try + { + ( (AutoCloseable) launcher ).close(); + } + catch ( Exception e ) + { + throw new SurefireReflectionException( e ); + } + } + } private LauncherDiscoveryRequest buildLauncherDiscoveryRequestForRerunFailures( RunListenerAdapter adapter ) { diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LazyLauncher.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LazyLauncher.java index 45c9c4913f..6a1a3b3b38 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LazyLauncher.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LazyLauncher.java @@ -19,6 +19,7 @@ * under the License. */ +import org.apache.maven.surefire.api.util.ReflectionUtils; import org.junit.platform.launcher.Launcher; import org.junit.platform.launcher.LauncherDiscoveryRequest; import org.junit.platform.launcher.TestExecutionListener; @@ -29,8 +30,9 @@ * Launcher proxy which delays the most possible the initialization of the real JUnit * Launcher in order to avoid stream/stdout corruption due to early logging. */ -class LazyLauncher implements Launcher +class LazyLauncher implements Launcher, AutoCloseable { + private AutoCloseable launcherSession; private Launcher launcher; @@ -57,8 +59,28 @@ private Launcher launcher() { if ( launcher == null ) { - launcher = LauncherFactory.create(); + try + { + Class sessionClass = Class.forName( "org.junit.platform.launcher.LauncherSession" ); + launcherSession = ReflectionUtils.invokeGetter( LauncherFactory.class, null, "openSession" ); + launcher = ReflectionUtils.invokeGetter( sessionClass, launcherSession, "getLauncher" ); + } + catch ( ClassNotFoundException e ) + { + launcher = LauncherFactory.create(); + } } return launcher; } + + @Override + public void close() throws Exception + { + if ( launcherSession != null ) + { + launcherSession.close(); + launcherSession = null; + } + launcher = null; + } }