This is an automated email from the ASF dual-hosted git repository.

olamy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git


The following commit(s) were added to refs/heads/master by this push:
     new bfa3ccace Create a single LauncherSession for invocations of 
JUnitPlatformProvider (#863)
bfa3ccace is described below

commit bfa3ccace3623802a1927d16b0cd2a09d7ca2f77
Author: Marc Philipp <[email protected]>
AuthorDate: Fri Jul 4 00:36:43 2025 +0000

    Create a single LauncherSession for invocations of JUnitPlatformProvider 
(#863)
    
    Prior to this commit, `JUnitPlatformProvider` created multiple
    `LauncherSessions` for some executions, for example when `forkTestSet`
    was `null` or when rerunning failed tests. This caused registered
    `LauncherSessionListeners` registered via `ServiceLoader` on the JUnit
    Platform to be called multiple times. As they are intended to set up and
    tear down resources, this had the potential of unnecessarily slowing
    down test execution.
---
 .../junitplatform/JUnitPlatformProvider.java       |  68 ++++------
 .../junitplatform/LauncherSessionAdapter.java      |  33 +++++
 .../junitplatform/LauncherSessionFactory.java      |  83 ++++++++++++
 .../maven/surefire/junitplatform/LazyLauncher.java |  85 ------------
 .../ConcreteLauncherSessionAdapter.java            |  50 +++++++
 .../junitplatform/JUnitPlatformProviderTest.java   | 145 +++++++++++----------
 6 files changed, 270 insertions(+), 194 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 416c38a38..70e0cac92 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
@@ -37,7 +37,6 @@
 import org.apache.maven.surefire.api.suite.RunResult;
 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;
@@ -80,29 +79,27 @@ public class JUnitPlatformProvider extends AbstractProvider 
{
 
     private final ProviderParameters parameters;
 
-    private final Launcher launcher;
+    private final LauncherSessionFactory launcherSessionFactory;
 
     private final Filter<?>[] filters;
 
     private final Map<String, String> configurationParameters;
 
     public JUnitPlatformProvider(ProviderParameters parameters) {
-        this(parameters, new LazyLauncher());
+        this(parameters, LauncherSessionFactory.DEFAULT);
     }
 
-    JUnitPlatformProvider(ProviderParameters parameters, Launcher launcher) {
+    JUnitPlatformProvider(ProviderParameters parameters, 
LauncherSessionFactory launcherSessionFactory) {
         this.parameters = parameters;
-        this.launcher = launcher;
+        this.launcherSessionFactory = launcherSessionFactory;
         filters = newFilters();
         configurationParameters = newConfigurationParameters();
     }
 
     @Override
     public Iterable<Class<?>> getSuites() {
-        try {
-            return scanClasspath();
-        } finally {
-            closeLauncher();
+        try (LauncherSessionAdapter launcherSession = 
launcherSessionFactory.openSession()) {
+            return scanClasspath(launcherSession.getLauncher());
         }
     }
 
@@ -110,18 +107,19 @@ public Iterable<Class<?>> getSuites() {
     public RunResult invoke(Object forkTestSet) throws TestSetFailedException, 
ReporterException {
         ReporterFactory reporterFactory = parameters.getReporterFactory();
         final RunResult runResult;
-        try {
+        try (LauncherSessionAdapter launcherSession = 
launcherSessionFactory.openSession()) {
             RunListenerAdapter adapter = new 
RunListenerAdapter(reporterFactory.createTestReportListener());
             adapter.setRunMode(NORMAL_RUN);
 
             startCapture(adapter);
             setupJunitLogger();
+            Launcher launcher = launcherSession.getLauncher();
             if (forkTestSet instanceof TestsToRun) {
-                invokeAllTests((TestsToRun) forkTestSet, adapter);
+                invokeAllTests(launcher, (TestsToRun) forkTestSet, adapter);
             } else if (forkTestSet instanceof Class) {
-                invokeAllTests(fromClass((Class<?>) forkTestSet), adapter);
+                invokeAllTests(launcher, fromClass((Class<?>) forkTestSet), 
adapter);
             } else if (forkTestSet == null) {
-                invokeAllTests(scanClasspath(), adapter);
+                invokeAllTests(launcher, scanClasspath(launcher), adapter);
             } else {
                 throw new IllegalArgumentException("Unexpected value of 
forkTestSet: " + forkTestSet);
             }
@@ -138,42 +136,36 @@ private static void setupJunitLogger() {
         }
     }
 
-    private TestsToRun scanClasspath() {
+    private TestsToRun scanClasspath(Launcher launcher) {
         TestPlanScannerFilter filter = new TestPlanScannerFilter(launcher, 
filters);
         ScanResult scanResult = parameters.getScanResult();
         TestsToRun scannedClasses = scanResult.applyFilter(filter, 
parameters.getTestClassLoader());
         return 
parameters.getRunOrderCalculator().orderTestClasses(scannedClasses);
     }
 
-    private void invokeAllTests(TestsToRun testsToRun, RunListenerAdapter 
adapter) {
-        try {
-            execute(testsToRun, adapter);
-        } finally {
-            closeLauncher();
-        }
+    private void invokeAllTests(Launcher launcher, TestsToRun testsToRun, 
RunListenerAdapter adapter) {
+
+        execute(launcher, testsToRun, adapter);
+
         // Rerun failing tests if requested
         int count = parameters.getTestRequest().getRerunFailingTestsCount();
         if (count > 0 && adapter.hasFailingTests()) {
             adapter.setRunMode(RERUN_TEST_AFTER_FAILURE);
             for (int i = 0; i < count; i++) {
-                try {
-                    // 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();
+                // 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;
                 }
             }
         }
     }
 
-    private void execute(TestsToRun testsToRun, RunListenerAdapter adapter) {
+    private void execute(Launcher launcher, TestsToRun testsToRun, 
RunListenerAdapter adapter) {
         // parameters.getProviderProperties().get(CONFIGURATION_PARAMETERS)
         // add this LegacyXmlReportGeneratingListener ?
         //            adapter,
@@ -203,16 +195,6 @@ 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) {
         LauncherDiscoveryRequestBuilder builder =
                 
request().filters(filters).configurationParameters(configurationParameters);
diff --git 
a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LauncherSessionAdapter.java
 
b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LauncherSessionAdapter.java
new file mode 100644
index 000000000..e8e37c3a9
--- /dev/null
+++ 
b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LauncherSessionAdapter.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.surefire.junitplatform;
+
+import org.junit.platform.launcher.Launcher;
+
+/**
+ * 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.
+ */
+interface LauncherSessionAdapter extends AutoCloseable {
+
+    Launcher getLauncher();
+
+    @Override
+    void close();
+}
diff --git 
a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LauncherSessionFactory.java
 
b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LauncherSessionFactory.java
new file mode 100644
index 000000000..fccc078de
--- /dev/null
+++ 
b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LauncherSessionFactory.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.surefire.junitplatform;
+
+import org.apache.maven.surefire.api.util.ReflectionUtils;
+import org.apache.maven.surefire.api.util.SurefireReflectionException;
+import org.junit.platform.launcher.Launcher;
+import org.junit.platform.launcher.core.LauncherFactory;
+
+interface LauncherSessionFactory {
+
+    LauncherSessionFactory DEFAULT = () -> {
+        try {
+            Class<?> sessionClass = 
Class.forName("org.junit.platform.launcher.LauncherSession");
+            AutoCloseable launcherSession = 
ReflectionUtils.invokeGetter(LauncherFactory.class, null, "openSession");
+            return new SupportedLauncherSessionAdapter(sessionClass, 
launcherSession);
+        } catch (ClassNotFoundException e) {
+            return new LegacyLauncherSessionAdapter(LauncherFactory.create());
+        }
+    };
+
+    LauncherSessionAdapter openSession();
+
+    class SupportedLauncherSessionAdapter implements LauncherSessionAdapter {
+
+        private final Class<?> sessionClass;
+        private final AutoCloseable launcherSession;
+
+        SupportedLauncherSessionAdapter(Class<?> sessionClass, AutoCloseable 
launcherSession) {
+            this.sessionClass = sessionClass;
+            this.launcherSession = launcherSession;
+        }
+
+        @Override
+        public Launcher getLauncher() {
+            return ReflectionUtils.invokeGetter(sessionClass, launcherSession, 
"getLauncher");
+        }
+
+        @Override
+        public void close() {
+            try {
+                launcherSession.close();
+            } catch (Exception e) {
+                throw new SurefireReflectionException(e);
+            }
+        }
+    }
+
+    class LegacyLauncherSessionAdapter implements LauncherSessionAdapter {
+
+        private final Launcher launcher;
+
+        LegacyLauncherSessionAdapter(Launcher launcher) {
+            this.launcher = launcher;
+        }
+
+        @Override
+        public Launcher getLauncher() {
+            return launcher;
+        }
+
+        @Override
+        public void close() {
+            // do nothing
+        }
+    }
+}
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
deleted file mode 100644
index 6d4b00068..000000000
--- 
a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LazyLauncher.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.surefire.junitplatform;
-
-import org.apache.maven.surefire.api.util.ReflectionUtils;
-import org.junit.platform.launcher.Launcher;
-import org.junit.platform.launcher.LauncherDiscoveryListener;
-import org.junit.platform.launcher.LauncherDiscoveryRequest;
-import org.junit.platform.launcher.TestExecutionListener;
-import org.junit.platform.launcher.TestPlan;
-import org.junit.platform.launcher.core.LauncherFactory;
-
-/**
- * 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, AutoCloseable {
-    private AutoCloseable launcherSession;
-
-    private Launcher launcher;
-
-    @Override
-    public void 
registerLauncherDiscoveryListeners(LauncherDiscoveryListener... listeners) {
-        launcher().registerLauncherDiscoveryListeners(listeners);
-    }
-
-    @Override
-    public void registerTestExecutionListeners(TestExecutionListener... 
testExecutionListeners) {
-        launcher().registerTestExecutionListeners(testExecutionListeners);
-    }
-
-    @Override
-    public TestPlan discover(LauncherDiscoveryRequest 
launcherDiscoveryRequest) {
-        return launcher().discover(launcherDiscoveryRequest);
-    }
-
-    @Override
-    public void execute(
-            LauncherDiscoveryRequest launcherDiscoveryRequest, 
TestExecutionListener... testExecutionListeners) {
-        launcher().execute(launcherDiscoveryRequest, testExecutionListeners);
-    }
-
-    @Override
-    public void execute(TestPlan testPlan, TestExecutionListener... listeners) 
{
-        launcher().execute(testPlan, listeners);
-    }
-
-    private Launcher launcher() {
-        if (launcher == null) {
-            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;
-    }
-}
diff --git 
a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/ConcreteLauncherSessionAdapter.java
 
b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/ConcreteLauncherSessionAdapter.java
new file mode 100644
index 000000000..7ebe3d015
--- /dev/null
+++ 
b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/ConcreteLauncherSessionAdapter.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.surefire.junitplatform;
+
+import org.junit.platform.launcher.Launcher;
+import org.junit.platform.launcher.LauncherSession;
+import org.junit.platform.launcher.TestExecutionListener;
+import org.junit.platform.launcher.core.LauncherConfig;
+import org.junit.platform.launcher.core.LauncherFactory;
+
+class ConcreteLauncherSessionAdapter implements LauncherSessionAdapter {
+
+    private final LauncherSession launcherSession;
+
+    public static LauncherSessionFactory 
createLauncherSessionWithListeners(TestExecutionListener... listeners) {
+        LauncherConfig launcherConfig =
+                
LauncherConfig.builder().addTestExecutionListeners(listeners).build();
+        return () -> new 
ConcreteLauncherSessionAdapter(LauncherFactory.openSession(launcherConfig));
+    }
+
+    ConcreteLauncherSessionAdapter(LauncherSession launcherSession) {
+        this.launcherSession = launcherSession;
+    }
+
+    @Override
+    public Launcher getLauncher() {
+        return launcherSession.getLauncher();
+    }
+
+    @Override
+    public void close() {
+        launcherSession.close();
+    }
+}
diff --git 
a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java
 
b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java
index 4b28ab18c..bde1c35c5 100644
--- 
a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java
+++ 
b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java
@@ -49,9 +49,11 @@
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.platform.launcher.EngineFilter;
-import org.junit.platform.launcher.Launcher;
+import org.junit.platform.launcher.LauncherSession;
+import org.junit.platform.launcher.TestExecutionListener;
 import org.junit.platform.launcher.TestIdentifier;
 import org.junit.platform.launcher.TestPlan;
+import org.junit.platform.launcher.core.LauncherConfig;
 import org.junit.platform.launcher.core.LauncherFactory;
 import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
 import org.junit.platform.launcher.listeners.TestExecutionSummary;
@@ -67,6 +69,7 @@
 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.RunMode.NORMAL_RUN;
+import static 
org.apache.maven.surefire.junitplatform.ConcreteLauncherSessionAdapter.createLauncherSessionWithListeners;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -80,6 +83,7 @@
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -94,16 +98,16 @@
 public class JUnitPlatformProviderTest {
     @Test
     public void shouldFailClassOnBeforeAll() throws Exception {
-        Launcher launcher = LauncherFactory.create();
-        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParametersMock(), launcher);
         TestReportListener<TestOutputReportEntry> listener = 
mock(TestReportListener.class);
 
-        ArgumentCaptor<ReportEntry> testCaptor = 
ArgumentCaptor.forClass(ReportEntry.class);
-        ArgumentCaptor<TestSetReportEntry> testSetCaptor = 
ArgumentCaptor.forClass(TestSetReportEntry.class);
-
         RunListenerAdapter adapter = new RunListenerAdapter(listener);
         adapter.setRunMode(NORMAL_RUN);
-        launcher.registerTestExecutionListeners(adapter);
+
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(providerParametersMock(), 
createLauncherSessionWithListeners(adapter));
+
+        ArgumentCaptor<ReportEntry> testCaptor = 
ArgumentCaptor.forClass(ReportEntry.class);
+        ArgumentCaptor<TestSetReportEntry> testSetCaptor = 
ArgumentCaptor.forClass(TestSetReportEntry.class);
 
         TestsToRun testsToRun = 
newTestsToRun(FailingBeforeAllJupiterTest.class);
         invokeProvider(provider, testsToRun);
@@ -134,16 +138,16 @@ public void shouldFailClassOnBeforeAll() throws Exception 
{
 
     @Test
     public void shouldErrorClassOnBeforeAll() throws Exception {
-        Launcher launcher = LauncherFactory.create();
-        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParametersMock(), launcher);
         TestReportListener<TestOutputReportEntry> listener = 
mock(TestReportListener.class);
 
-        ArgumentCaptor<ReportEntry> testCaptor = 
ArgumentCaptor.forClass(ReportEntry.class);
-        ArgumentCaptor<TestSetReportEntry> testSetCaptor = 
ArgumentCaptor.forClass(TestSetReportEntry.class);
-
         RunListenerAdapter adapter = new RunListenerAdapter(listener);
         adapter.setRunMode(NORMAL_RUN);
-        launcher.registerTestExecutionListeners(adapter);
+
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(providerParametersMock(), 
createLauncherSessionWithListeners(adapter));
+
+        ArgumentCaptor<ReportEntry> testCaptor = 
ArgumentCaptor.forClass(ReportEntry.class);
+        ArgumentCaptor<TestSetReportEntry> testSetCaptor = 
ArgumentCaptor.forClass(TestSetReportEntry.class);
 
         TestsToRun testsToRun = 
newTestsToRun(FailingWithErrorBeforeAllJupiterTest.class);
         invokeProvider(provider, testsToRun);
@@ -176,8 +180,14 @@ public void shouldErrorClassOnBeforeAll() throws Exception 
{
     @Test
     public void getSuitesReturnsScannedClasses() {
         ProviderParameters providerParameters = 
providerParametersMock(TestClass1.class, TestClass2.class);
-        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParameters);
+        List<LauncherSession> createdSessions = new ArrayList<>();
+        LauncherSessionFactory launcherSessionFactory = 
spyingLauncherSessionFactory(createdSessions);
+
+        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParameters, launcherSessionFactory);
+
         assertThat(provider.getSuites()).containsOnly(TestClass1.class, 
TestClass2.class);
+        assertThat(createdSessions).hasSize(1);
+        verify(createdSessions.get(0)).close();
     }
 
     @Test
@@ -190,11 +200,10 @@ public void invokeThrowsForWrongForkTestSet() {
 
     @Test
     public void allGivenTestsToRunAreInvoked() throws Exception {
-        Launcher launcher = LauncherFactory.create();
-        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParametersMock(), launcher);
-
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
-        launcher.registerTestExecutionListeners(executionListener);
+
+        JUnitPlatformProvider provider = new JUnitPlatformProvider(
+                providerParametersMock(), 
createLauncherSessionWithListeners(executionListener));
 
         TestsToRun testsToRun = newTestsToRun(TestClass1.class, 
TestClass2.class);
         invokeProvider(provider, testsToRun);
@@ -211,11 +220,10 @@ public void allGivenTestsToRunAreInvoked() throws 
Exception {
 
     @Test
     public void singleTestClassIsInvoked() throws Exception {
-        Launcher launcher = LauncherFactory.create();
-        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParametersMock(), launcher);
-
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
-        launcher.registerTestExecutionListeners(executionListener);
+
+        JUnitPlatformProvider provider = new JUnitPlatformProvider(
+                providerParametersMock(), 
createLauncherSessionWithListeners(executionListener));
 
         invokeProvider(provider, TestClass1.class);
 
@@ -231,11 +239,10 @@ public void singleTestClassIsInvoked() throws Exception {
 
     @Test
     public void singleTestClassIsInvokedLazily() throws Exception {
-        Launcher launcher = LauncherFactory.create();
-        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParametersMock(), launcher);
-
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
-        launcher.registerTestExecutionListeners(executionListener);
+
+        JUnitPlatformProvider provider = new JUnitPlatformProvider(
+                providerParametersMock(), 
createLauncherSessionWithListeners(executionListener));
 
         invokeProvider(provider, newTestsToRunLazily(TestClass1.class));
 
@@ -251,15 +258,14 @@ public void singleTestClassIsInvokedLazily() throws 
Exception {
 
     @Test
     public void failingTestCaseAfterRerun() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         ProviderParameters parameters = providerParametersMock();
         // Mock the rerun variable
         
when(parameters.getTestRequest().getRerunFailingTestsCount()).thenReturn(1);
 
-        JUnitPlatformProvider provider = new JUnitPlatformProvider(parameters, 
launcher);
-
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
-        launcher.registerTestExecutionListeners(executionListener);
+
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(parameters, 
createLauncherSessionWithListeners(executionListener));
 
         invokeProvider(provider, TestClass2.class);
 
@@ -285,14 +291,14 @@ public void failingTestCaseAfterRerun() throws Exception {
 
     @Test
     public void rerunStillFailing() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         ProviderParameters parameters = providerParametersMock();
         // Mock the rerun variable
         
when(parameters.getTestRequest().getRerunFailingTestsCount()).thenReturn(2);
 
-        JUnitPlatformProvider provider = new JUnitPlatformProvider(parameters, 
launcher);
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
-        launcher.registerTestExecutionListeners(executionListener);
+
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(parameters, 
createLauncherSessionWithListeners(executionListener));
 
         // 3 unit tests:
         // - fail always
@@ -353,7 +359,6 @@ public void rerunStillFailing() throws Exception {
 
     @Test
     public void rerunWithSuccess() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         ProviderParameters parameters = providerParametersMock();
         // Mock the rerun variable
         
when(parameters.getTestRequest().getRerunFailingTestsCount()).thenReturn(2);
@@ -361,9 +366,10 @@ public void rerunWithSuccess() throws Exception {
                 .thenReturn(singletonMap(
                         JUnitPlatformProvider.CONFIGURATION_PARAMETERS, 
"forkCount = 1\nreuseForks = true"));
 
-        JUnitPlatformProvider provider = new JUnitPlatformProvider(parameters, 
launcher);
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
-        launcher.registerTestExecutionListeners(executionListener);
+
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(parameters, 
createLauncherSessionWithListeners(executionListener));
 
         invokeProvider(provider, TestClass5.class);
 
@@ -389,16 +395,15 @@ public void rerunWithSuccess() throws Exception {
 
     @Test
     public void runDisplayNameTest() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         ProviderParameters parameters = providerParametersMock();
-        JUnitPlatformProvider provider = new JUnitPlatformProvider(parameters, 
launcher);
 
         TestReportListener<TestOutputReportEntry> listener = 
mock(TestReportListener.class);
         ArgumentCaptor<ReportEntry> entryCaptor = 
ArgumentCaptor.forClass(ReportEntry.class);
         RunListenerAdapter adapter = new RunListenerAdapter(listener);
         adapter.setRunMode(NORMAL_RUN);
 
-        launcher.registerTestExecutionListeners(adapter);
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(parameters, 
createLauncherSessionWithListeners(adapter));
 
         invokeProvider(provider, DisplayNameTest.class);
 
@@ -415,16 +420,15 @@ public void runDisplayNameTest() throws Exception {
 
     @Test
     public void runNestingTest() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         ProviderParameters parameters = providerParametersMock();
-        JUnitPlatformProvider provider = new JUnitPlatformProvider(parameters, 
launcher);
 
         TestReportListener<TestOutputReportEntry> listener = 
mock(TestReportListener.class);
         ArgumentCaptor<ReportEntry> entryCaptor = 
ArgumentCaptor.forClass(ReportEntry.class);
         RunListenerAdapter adapter = new RunListenerAdapter(listener);
         adapter.setRunMode(NORMAL_RUN);
 
-        launcher.registerTestExecutionListeners(adapter);
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(parameters, 
createLauncherSessionWithListeners(adapter));
 
         invokeProvider(provider, NestingTest.class);
 
@@ -450,11 +454,8 @@ public void runNestingTest() throws Exception {
 
     @Test
     public void detectSkippedParameterized() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         ProviderParameters parameters = providerParametersMock();
 
-        JUnitPlatformProvider provider = new JUnitPlatformProvider(parameters, 
launcher);
-
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
 
         TestReportListener<TestOutputReportEntry> listener = 
mock(TestReportListener.class);
@@ -462,7 +463,8 @@ public void detectSkippedParameterized() throws Exception {
         RunListenerAdapter adapter = new RunListenerAdapter(listener);
         adapter.setRunMode(NORMAL_RUN);
 
-        launcher.registerTestExecutionListeners(executionListener, adapter);
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(parameters, 
createLauncherSessionWithListeners(executionListener, adapter));
 
         invokeProvider(provider, DisabledParameterizedTest.class);
 
@@ -493,11 +495,8 @@ public void detectSkippedParameterized() throws Exception {
 
     @Test
     public void detectErroredParameterized() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         ProviderParameters parameters = providerParametersMock();
 
-        JUnitPlatformProvider provider = new JUnitPlatformProvider(parameters, 
launcher);
-
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
 
         TestReportListener<TestOutputReportEntry> listener = 
mock(TestReportListener.class);
@@ -505,7 +504,8 @@ public void detectErroredParameterized() throws Exception {
         RunListenerAdapter adapter = new RunListenerAdapter(listener);
         adapter.setRunMode(NORMAL_RUN);
 
-        launcher.registerTestExecutionListeners(executionListener, adapter);
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(parameters, 
createLauncherSessionWithListeners(executionListener, adapter));
 
         invokeProvider(provider, TestClass8.class);
 
@@ -530,11 +530,8 @@ public void detectErroredParameterized() throws Exception {
 
     @Test
     public void detectFailedParameterized() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         ProviderParameters parameters = providerParametersMock();
 
-        JUnitPlatformProvider provider = new JUnitPlatformProvider(parameters, 
launcher);
-
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
 
         TestReportListener<TestOutputReportEntry> listener = 
mock(TestReportListener.class);
@@ -542,7 +539,8 @@ public void detectFailedParameterized() throws Exception {
         RunListenerAdapter adapter = new RunListenerAdapter(listener);
         adapter.setRunMode(NORMAL_RUN);
 
-        launcher.registerTestExecutionListeners(executionListener, adapter);
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(parameters, 
createLauncherSessionWithListeners(executionListener, adapter));
 
         invokeProvider(provider, TestClass9.class);
 
@@ -567,7 +565,6 @@ public void detectFailedParameterized() throws Exception {
 
     @Test
     public void rerunParameterized() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         ProviderParameters parameters = providerParametersMock();
         // Mock the rerun variable
         
when(parameters.getTestRequest().getRerunFailingTestsCount()).thenReturn(2);
@@ -575,8 +572,6 @@ public void rerunParameterized() throws Exception {
                 .thenReturn(singletonMap(
                         JUnitPlatformProvider.CONFIGURATION_PARAMETERS, 
"forkCount = 1\nreuseForks = true"));
 
-        JUnitPlatformProvider provider = new JUnitPlatformProvider(parameters, 
launcher);
-
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
 
         TestReportListener<TestOutputReportEntry> listener = 
mock(TestReportListener.class);
@@ -584,7 +579,8 @@ public void rerunParameterized() throws Exception {
         RunListenerAdapter adapter = new RunListenerAdapter(listener);
         adapter.setRunMode(NORMAL_RUN);
 
-        launcher.registerTestExecutionListeners(executionListener, adapter);
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(parameters, 
createLauncherSessionWithListeners(executionListener, adapter));
 
         invokeProvider(provider, TestClass7.class);
 
@@ -652,11 +648,11 @@ public void rerunParameterized() throws Exception {
     public void allDiscoveredTestsAreInvokedForNullArgument() throws Exception 
{
         TestReportListener<TestOutputReportEntry> runListener = 
runListenerMock();
         ProviderParameters providerParameters = 
providerParametersMock(runListener, TestClass1.class, TestClass2.class);
-        Launcher launcher = LauncherFactory.create();
-        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParameters, launcher);
 
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
-        launcher.registerTestExecutionListeners(executionListener);
+
+        JUnitPlatformProvider provider =
+                new JUnitPlatformProvider(providerParameters, 
createLauncherSessionWithListeners(executionListener));
 
         invokeProvider(provider, null);
 
@@ -694,9 +690,9 @@ public void allDiscoveredTestsAreInvokedForNullArgument() 
throws Exception {
 
     @Test
     public void outputIsCaptured() throws Exception {
-        Launcher launcher = LauncherFactory.create();
         TestReportListener<TestOutputReportEntry> runListener = 
runListenerMock();
-        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParametersMock(runListener), launcher);
+
+        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParametersMock(runListener));
 
         invokeProvider(provider, VerboseTestClass.class);
 
@@ -1008,11 +1004,14 @@ private static void testExecutionOfMatchingTestMethods(
             Class<?> testClass, String pattern, String... expectedTestNames) 
throws Exception {
         TestListResolver testListResolver = new TestListResolver(pattern);
         ProviderParameters providerParameters = 
providerParametersMock(testListResolver, testClass);
-        Launcher launcher = LauncherFactory.create();
-        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParameters, launcher);
 
         TestPlanSummaryListener executionListener = new 
TestPlanSummaryListener();
-        launcher.registerTestExecutionListeners(executionListener);
+
+        List<LauncherSession> createdSessions = new ArrayList<>();
+        LauncherSessionFactory launcherSessionFactory =
+                spyingLauncherSessionFactory(createdSessions, 
executionListener);
+
+        JUnitPlatformProvider provider = new 
JUnitPlatformProvider(providerParameters, launcherSessionFactory);
 
         invokeProvider(provider, null);
 
@@ -1024,6 +1023,9 @@ private static void testExecutionOfMatchingTestMethods(
         assertEquals(expectedCount, summary.getFailures().size());
 
         
assertThat(failedTestDisplayNames(summary)).contains(expectedTestNames);
+
+        assertThat(createdSessions).hasSize(1);
+        verify(createdSessions.get(0)).close();
     }
 
     private static ProviderParameters providerParametersMock(Class<?>... 
testClasses) {
@@ -1128,6 +1130,17 @@ private static void invokeProvider(JUnitPlatformProvider 
provider, Object forkTe
         }
     }
 
+    private static LauncherSessionFactory spyingLauncherSessionFactory(
+            List<LauncherSession> createdSessions, TestExecutionListener... 
listeners) {
+        LauncherConfig launcherConfig =
+                
LauncherConfig.builder().addTestExecutionListeners(listeners).build();
+        return () -> {
+            LauncherSession session = 
spy(LauncherFactory.openSession(launcherConfig));
+            createdSessions.add(session);
+            return new ConcreteLauncherSessionAdapter(session);
+        };
+    }
+
     static class TestClass1 {
 
         static final int TESTS_FOUND = 4;


Reply via email to