From 6bf2a85f78cb34abb132d94be9671e11ee9276ee Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Mon, 8 Jan 2024 21:31:50 +0100 Subject: [PATCH] Provide a session test framework for JUnit 5 A first draft for realizing session tests with JUnit 5. It uses an extension that intercepts test methods calls to start a separate Eclipse session in which the tests are executed. The results are evaluated in the intercepted method execution in way they were evaluated for existing JUnit-3-based session tests. Functionality is demonstrated in a manually executed sample session test as well as by application to the session test in the runtime tests project. Since JUnit 5 test suites are not yet supported, the project is adapted to execute tests without suites. In order to get the session test running with Tycho, an adaptation of the test application provided via PDE is necessary, because a faulty class loader is currently used for the test engines during remote execution. --- .../META-INF/MANIFEST.MF | 17 +- .../harness/session/SessionShouldError.java | 27 ++ .../harness/session/SessionTestExtension.java | 350 ++++++++++++++++++ .../session/samples/SampleSessionTests.java | 82 ++++ .../ConfigurationSessionTestSuite.java | 11 + .../META-INF/MANIFEST.MF | 5 +- .../preferences/AllPreferenceTests.java | 12 +- .../runtime/AllInternalRuntimeTests.java | 8 +- .../core/tests/runtime/AllRuntimeTests.java | 8 +- .../tests/runtime/AutomatedRuntimeTests.java | 8 +- .../core/tests/runtime/jobs/AllJobTests.java | 14 +- .../core/tests/runtime/jobs/Bug_412138.java | 48 ++- 12 files changed, 544 insertions(+), 46 deletions(-) create mode 100644 runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/SessionShouldError.java create mode 100644 runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/SessionTestExtension.java create mode 100644 runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/samples/SampleSessionTests.java diff --git a/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF index 90638e7726c..e9bcb833182 100644 --- a/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF @@ -5,13 +5,21 @@ Bundle-SymbolicName: org.eclipse.core.tests.harness;singleton:=true Bundle-Version: 3.15.300.qualifier Bundle-Vendor: Eclipse.org Export-Package: org.eclipse.core.tests.harness;version="2.0", + org.eclipse.core.tests.harness.session, org.eclipse.core.tests.session;version="2.0" Require-Bundle: org.junit, org.eclipse.test.performance, org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.jdt.junit.runtime, org.eclipse.jdt.junit4.runtime, - org.eclipse.pde.junit.runtime + org.eclipse.jdt.junit5.runtime, + org.eclipse.pde.junit.runtime, + junit-platform-launcher, + junit-platform-engine, + junit-jupiter-engine, + junit-vintage-engine, + junit-platform-suite-commons, + junit-platform-suite-engine Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Import-Package: javax.xml.parsers, @@ -19,8 +27,13 @@ Import-Package: javax.xml.parsers, org.apiguardian.api, org.assertj.core.api, org.junit.jupiter.api, - org.junit.platform.suite.api, + org.junit.jupiter.api.condition, + org.junit.jupiter.api.extension, + org.junit.jupiter.migrationsupport, + org.junit.jupiter.params, org.junit.platform.commons, + org.junit.platform.runner, + org.junit.platform.suite.api, org.opentest4j, org.w3c.dom, org.xml.sax diff --git a/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/SessionShouldError.java b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/SessionShouldError.java new file mode 100644 index 00000000000..a4960c0327e --- /dev/null +++ b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/SessionShouldError.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2023 Vector Informatik GmbH and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.core.tests.harness.session; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates that a session of a test case is expected to terminate with a + * failure or error. To be used in combination with a + * {@link SessionTestExtension}. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface SessionShouldError { + // Marker annotation +} diff --git a/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/SessionTestExtension.java b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/SessionTestExtension.java new file mode 100644 index 00000000000..8d2d4f1944a --- /dev/null +++ b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/SessionTestExtension.java @@ -0,0 +1,350 @@ +/******************************************************************************* + * Copyright (c) 2023 Vector Informatik GmbH and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.core.tests.harness.session; + +import static org.eclipse.core.tests.harness.TestHarnessPlugin.PI_HARNESS; +import static org.eclipse.core.tests.harness.TestHarnessPlugin.log; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.reflect.Method; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Objects; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.AssertionFailedException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.tests.session.RemoteAssertionFailedError; +import org.eclipse.core.tests.session.RemoteTestException; +import org.eclipse.core.tests.session.Setup; +import org.eclipse.core.tests.session.SetupManager; +import org.eclipse.core.tests.session.SetupManager.SetupException; +import org.eclipse.core.tests.session.TestDescriptor; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.InvocationInterceptor; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; + +/** + */ +public class SessionTestExtension implements InvocationInterceptor { + public static final String CORE_TEST_APPLICATION = "org.eclipse.pde.junit.runtime.coretestapplication"; //$NON-NLS-1$ + /** + * Is set to true during remote execution to ensure that the JUnit 5 executor + * does not recursively make a remote call for executing the test + */ + private static final String REMOTE_EXECUTION_INDICATION_SYSTEM_PROPERY = "org.eclipse.core.tests.session.isRemoteExecution"; //$NON-NLS-1$ + + private final String pluginId; + private final String applicationId; + private final Setup setup; + + private SessionTestExtension(String pluginId, String applicationId) { + this.pluginId = pluginId; + this.applicationId = applicationId; + try { + this.setup = SetupManager.getInstance().getDefaultSetup(); + setup.setSystemProperty("org.eclipse.update.reconcile", "false"); + } catch (SetupException e) { + throw new IllegalStateException("unable to create setup", e); + } + + } + + public static SessionTestExtensionBuilder forPlugin(String pluginId) { + return new SessionTestExtensionBuilder(pluginId); + } + + public static class SessionTestExtensionBuilder { + private final String storedPluginId; + private String storedApplicationId = CORE_TEST_APPLICATION; + + private SessionTestExtensionBuilder(String pluginId) { + Objects.requireNonNull(pluginId); + this.storedPluginId = pluginId; + } + + public SessionTestExtensionBuilder withApplicationId(String applicationId) { + storedApplicationId = applicationId; + return this; + } + + public SessionTestExtension create() { + return new SessionTestExtension(storedPluginId, storedApplicationId); + } + } + + @Override + public void interceptTestMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, + ExtensionContext extensionContext) throws Throwable { + boolean isRemoteExecution = System.getProperty(REMOTE_EXECUTION_INDICATION_SYSTEM_PROPERY, "").equals(Boolean.toString(true)); + if (isRemoteExecution) { + invocation.proceed(); + return; + } + String testClass = extensionContext.getTestClass().get().getName(); + String testMethod = extensionContext.getTestMethod().get().getName(); + + boolean shouldFail = extensionContext.getTestMethod().get().getAnnotation(SessionShouldError.class) != null; + invocation.skip(); + executeRemotely(testClass, testMethod, shouldFail); + } + + private void executeRemotely(String testClass, String testMethod, boolean shouldFail) throws Throwable { + Setup localSetup = createSingleTestSetup(testClass, testMethod); + localSetup.setSystemProperty(REMOTE_EXECUTION_INDICATION_SYSTEM_PROPERY, Boolean.toString(true)); + + TestDescriptor descriptor = new TestDescriptor(testClass, testMethod); + ResultCollector collector = new ResultCollector(getTestId(testClass, testMethod)); + localSetup.setEclipseArgument("port", Integer.toString(collector.getPort())); + new Thread(collector, "Test result collector").start(); + IStatus status = launch(localSetup); + collector.shutdown(); + if (!shouldFail) { + if (!status.isOK()) { + log(status); + throw new CoreException(status); + } + if (!collector.didTestFinish()) { + throw new Exception("session test did not run: " + descriptor); + } + if (!collector.wasTestSuccessful()) { + throw collector.getError(); + } + } else { + if (status.isOK() && collector.wasTestSuccessful()) { + throw new AssertionFailedException("test should fail but did not: " + descriptor); + } + } + } + + private static String getTestId(String testClass, String testMethod) { + return testMethod + "(" + testClass + ")"; + } + + private Setup createSingleTestSetup(String testClassName, String testMethodName) { + Setup localSetup = (Setup) setup.clone(); + localSetup.setEclipseArgument(Setup.APPLICATION, applicationId); +// localSetup.setEclipseArgument("runasjunit5", ""); + localSetup.setEclipseArgument("loaderpluginname", "org.eclipse.core.tests.harness"); + localSetup.setEclipseArgument("testloaderclass", "org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader"); + localSetup.setEclipseArgument("testpluginname", pluginId); + localSetup.setEclipseArgument("test", testClassName + ":" + testMethodName); + return localSetup; + } + + /** + * Runs the setup. Returns a status object indicating the outcome of the + * operation. + * + * @return a status object indicating the outcome + */ + private static IStatus launch(Setup setup) { + Assert.isNotNull(setup.getEclipseArgument(Setup.APPLICATION), "test application is not defined"); + Assert.isNotNull(setup.getEclipseArgument("testpluginname"), "test plug-in id not defined"); + Assert.isTrue(setup.getEclipseArgument("classname") != null ^ setup.getEclipseArgument("test") != null, + "either a test suite or a test case must be provided"); + // to prevent changes in the protocol from breaking us, + // force the version we know we can work with + setup.setEclipseArgument("version", "4"); + IStatus outcome = Status.OK_STATUS; + try { + int returnCode = setup.run(); + if (returnCode == 23) { + // asked to restart; for now just do this once. + // Note that 23 is our magic return code indicating that a restart is required. + // This can happen for tests that update framework extensions which requires a + // restart. + returnCode = setup.run(); + } + if (returnCode != 0) { + outcome = new Status(IStatus.WARNING, Platform.PI_RUNTIME, returnCode, + "Process returned non-zero code: " + returnCode + "\n\tCommand: " + setup, null); + } + } catch (Exception e) { + outcome = new Status(IStatus.ERROR, Platform.PI_RUNTIME, -1, "Error running process\n\tCommand: " + setup, + e); + } + return outcome; + } + + /** + * Partly taken from + * {@code org.eclipse.core.tests.session.SessionTestRunner#ResultCollector}. + */ + static class ResultCollector implements Runnable { + private final String testId; + private final ServerSocket serverSocket; + + private volatile boolean shouldRun = true; + private volatile boolean executionFinished; + + private static enum STATE { + SUCCESS, FAILURE, ERROR; + } + private STATE state = STATE.SUCCESS; + private StringBuilder stackBuilder; + + private String stackTrace; + private boolean testFinished; + private Throwable error; + + ResultCollector(String testId) throws IOException { + this.serverSocket = new ServerSocket(0); + this.testId = testId; + } + + int getPort() { + return serverSocket.getLocalPort(); + } + + boolean didTestFinish() { + return testFinished; + } + + boolean wasTestSuccessful() { + return testFinished && error == null; + } + + Throwable getError() { + return error; + } + + @Override + public void run() { + // someone asked us to stop before we could do anything + if (!shouldRun) { + return; + } + try (Socket s = serverSocket.accept(); + BufferedReader messageReader = new BufferedReader( + new InputStreamReader(s.getInputStream(), "UTF-8"))) { + // main loop + while (true) { + synchronized (this) { + processAvailableMessages(messageReader); + if (!shouldRun) { + return; + } + this.wait(150); + } + } + } catch (InterruptedException e) { + // not expected + } catch (IOException e) { + if (!shouldRun) { + // we have been finished without ever getting any connections + // no need to throw exception + return; + } + log(new Status(IStatus.WARNING, PI_HARNESS, IStatus.ERROR, "Error", e)); + } finally { + executionFinished = true; + synchronized (this) { + notifyAll(); + } + } + } + + /* + * Politely asks the collector thread to stop and wait until it is finished. + */ + void shutdown() { + // ask the collector to stop + synchronized (this) { + if (executionFinished) { + return; + } + shouldRun = false; + try { + serverSocket.close(); + } catch (IOException e) { + log(new Status(IStatus.ERROR, PI_HARNESS, IStatus.ERROR, "Error", e)); + } + notifyAll(); + } + // wait until the collector is done + synchronized (this) { + while (!executionFinished) { + try { + wait(100); + } catch (InterruptedException e) { + // we don't care + } + } + } + } + + private void processAvailableMessages(BufferedReader messageReader) throws IOException { + while (messageReader.ready()) { + String message = messageReader.readLine(); + processMessage(message); + } + } + + private void processMessage(String message) { + if (message.startsWith("%TESTS")) { + String receivedTestId = parseTestId(message); + if (!testId.equals(receivedTestId)) { + throw new IllegalStateException("unknown test id: " + receivedTestId + message); + } + return; + } else if (message.startsWith("%TESTE")) { + switch (state) { + case FAILURE: + error = new RemoteAssertionFailedError("", stackTrace); + break; + case ERROR: + error = new RemoteTestException("", stackTrace); + } + testFinished = true; + } else if (message.startsWith("%ERROR")) { + state = STATE.ERROR; + } else if (message.startsWith("%FAILED")) { + state = STATE.FAILURE; + } else if (message.startsWith("%TRACES")) { + // just create the string buffer that will hold all the frames of the stack + // trace + stackBuilder = new StringBuilder(); + } else if (message.startsWith("%TRACEE")) { + // stack trace fully read - fill the slot in the result object and reset the + // string buffer + stackTrace = stackBuilder.toString(); + stackBuilder = null; + } else if (message.startsWith("%")) { + // ignore any other messages + } else if (stackBuilder != null) { + // build the stack trace line by line + stackBuilder.append(message); + stackBuilder.append(System.lineSeparator()); + } + } + + private String parseTestId(String message) { + if (message.isEmpty() || message.charAt(0) != '%') { + return null; + } + int firstComma = message.indexOf(','); + if (firstComma == -1) { + return null; + } + int secondComma = message.indexOf(',', firstComma + 1); + if (secondComma == -1) { + secondComma = message.length(); + } + return message.substring(firstComma + 1, secondComma); + } + + } +} diff --git a/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/samples/SampleSessionTests.java b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/samples/SampleSessionTests.java new file mode 100644 index 00000000000..7c978877bf5 --- /dev/null +++ b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/samples/SampleSessionTests.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2023 Vector Informatik GmbH and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.core.tests.harness.session.samples; + +import static org.eclipse.core.tests.harness.TestHarnessPlugin.PI_HARNESS; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import org.eclipse.core.tests.harness.session.SessionShouldError; +import org.eclipse.core.tests.harness.session.SessionTestExtension; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +/** + * Examples demonstrating the behavior of session tests using the JUnit 5 + * platform. When executed, the {@code Successful} tests will succeed, while the + * {@code Failing} ones will fail. + */ +public class SampleSessionTests { + @RegisterExtension + static SessionTestExtension sessionTestExtension = SessionTestExtension.forPlugin(PI_HARNESS).create(); + + @Nested + public class Successful { + @Test + public void asIntended() { + assertEquals(1, 1); + } + + @Test + @SessionShouldError + public void withExpectedFailure() { + fail("fail"); + } + + @Test + @SessionShouldError + public void withExpectedError_viaException() { + throw new RuntimeException("error"); + } + + @Test + @SessionShouldError + public void withExpectedError_viaExit() { + System.exit(1); + } + } + + @Nested + public class Failing { + @Test + @SessionShouldError + public void unexpectedlySuccessful() { + assertEquals(1, 1); + } + + @Test + public void withFailure() { + fail("fail"); + } + + @Test + public void withError_viaException() { + throw new RuntimeException("error"); + } + + @Test + public void withError_viaExit() { + System.exit(1); + } + } + +} diff --git a/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/session/ConfigurationSessionTestSuite.java b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/session/ConfigurationSessionTestSuite.java index 1f1ab78844a..3e610c84988 100644 --- a/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/session/ConfigurationSessionTestSuite.java +++ b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/session/ConfigurationSessionTestSuite.java @@ -74,6 +74,7 @@ public ConfigurationSessionTestSuite(String pluginId, String name) { super(pluginId, name); } + @SuppressWarnings("deprecation") public void addMinimalBundleSet() { // Just use any class from the bundles we want to add as minimal bundle set @@ -91,6 +92,7 @@ public void addMinimalBundleSet() { addBundle(org.eclipse.jdt.internal.junit.runner.ITestLoader.class); // org.eclipse.jdt.junit.runtime addBundle(org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.class); // org.eclipse.jdt.junit4.runtime + addBundle(org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.class); // org.eclipse.jdt.junit5.runtime addBundle(org.eclipse.pde.internal.junit.runtime.CoreTestApplication.class); // org.eclipse.pde.junit.runtime addBundle(net.bytebuddy.ByteBuddy.class); // net.bytebuddy for org.assertj.core.api @@ -120,8 +122,17 @@ public void addMinimalBundleSet() { addBundle(org.junit.Test.class); // org.junit addBundle(org.junit.jupiter.api.Test.class); // junit-jupiter-api + addBundle(org.junit.jupiter.engine.JupiterTestEngine.class); // junit-jupiter-engine + addBundle(org.junit.jupiter.migrationsupport.EnableJUnit4MigrationSupport.class); // junit-jupiter-migrationsupport + addBundle(org.junit.jupiter.params.ParameterizedTest.class); // junit-jupiter-params + addBundle(org.junit.vintage.engine.VintageTestEngine.class); // junit-vintage-engine addBundle(org.junit.platform.commons.JUnitException.class); // junit-platform-commons + addBundle(org.junit.platform.engine.TestEngine.class); // junit-platform-engine + addBundle(org.junit.platform.launcher.Launcher.class); // junit-platform-launcher + addBundle(org.junit.platform.runner.JUnitPlatform.class); // junit-platform-runner addBundle(org.junit.platform.suite.api.Suite.class); // junit-platform-suite-api + addBundle(org.junit.platform.suite.commons.SuiteLauncherDiscoveryRequestBuilder.class); // junit-platform-suite-commons + addBundle(org.junit.platform.suite.engine.SuiteTestEngine.class); // junit-platform-suite-engine addBundle(org.apiguardian.api.API.class); // org.apiguardian.api addBundle(org.opentest4j.AssertionFailedError.class); // org.opentest4j } diff --git a/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF index e3c5bef1f60..fd1d1ca5f25 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF @@ -14,7 +14,10 @@ Require-Bundle: org.junit, org.eclipse.test.performance;resolution:=optional, org.eclipse.core.runtime;bundle-version="3.29.0", org.eclipse.core.tests.harness;bundle-version="3.11.0" -Import-Package: org.assertj.core.api +Import-Package: org.assertj.core.api, + org.junit.jupiter.api, + org.junit.jupiter.api.extension, + org.junit.platform.suite.api Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Plugin-Class: org.eclipse.core.tests.runtime.RuntimeTestsPlugin diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/preferences/AllPreferenceTests.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/preferences/AllPreferenceTests.java index ae00fe2d2f4..0c687b73313 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/preferences/AllPreferenceTests.java +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/preferences/AllPreferenceTests.java @@ -13,12 +13,14 @@ *******************************************************************************/ package org.eclipse.core.tests.internal.preferences; -import org.eclipse.core.tests.runtime.*; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import org.eclipse.core.tests.runtime.PreferenceExportTest; +import org.eclipse.core.tests.runtime.PreferenceForwarderTest; +import org.eclipse.core.tests.runtime.PreferencesTest; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; -@RunWith(Suite.class) -@Suite.SuiteClasses({ EclipsePreferencesTest.class, PreferencesServiceTest.class, IScopeContextTest.class, +@Suite +@SelectClasses({ EclipsePreferencesTest.class, PreferencesServiceTest.class, IScopeContextTest.class, TestBug388004.class, TestBug380859.class, PreferenceExportTest.class, PreferenceForwarderTest.class, PreferencesTest.class }) @SuppressWarnings("deprecation") diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java index c332ba49f56..852e7a5bf73 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java @@ -13,10 +13,10 @@ *******************************************************************************/ package org.eclipse.core.tests.internal.runtime; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; -@RunWith(Suite.class) -@Suite.SuiteClasses({ LogSerializationTest.class, PlatformURLLocalTest.class, PlatformURLSessionTest.class }) +@Suite +@SelectClasses({ LogSerializationTest.class, PlatformURLLocalTest.class, PlatformURLSessionTest.class }) public class AllInternalRuntimeTests { } diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/AllRuntimeTests.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/AllRuntimeTests.java index 412acbc93f3..236e5f71a84 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/AllRuntimeTests.java +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/AllRuntimeTests.java @@ -13,11 +13,11 @@ *******************************************************************************/ package org.eclipse.core.tests.runtime; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; -@RunWith(Suite.class) -@Suite.SuiteClasses({ PlatformTest.class }) +@Suite +@SelectClasses({ PlatformTest.class }) public class AllRuntimeTests { } diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/AutomatedRuntimeTests.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/AutomatedRuntimeTests.java index ec72a718c6d..d803fa43a24 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/AutomatedRuntimeTests.java +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/AutomatedRuntimeTests.java @@ -16,15 +16,15 @@ import org.eclipse.core.tests.internal.preferences.AllPreferenceTests; import org.eclipse.core.tests.internal.runtime.AllInternalRuntimeTests; import org.eclipse.core.tests.runtime.jobs.AllJobTests; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Runs the sniff tests for the build. All tests listed here should be * automated. */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ +@Suite +@SelectClasses({ AllInternalRuntimeTests.class, AllRuntimeTests.class, diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/AllJobTests.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/AllJobTests.java index c3611e9a48f..19c92734a24 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/AllJobTests.java +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/AllJobTests.java @@ -14,25 +14,25 @@ *******************************************************************************/ package org.eclipse.core.tests.runtime.jobs; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Runs all job tests */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ +@SelectClasses({ YieldTest.class, IJobManagerTest.class, JobGroupTest.class, JobQueueTest.class, OrderedLockTest.class, BeginEndRuleTest.class, JobTest.class, DeadlockDetectionTest.class, Bug_129551.class, Bug_211799.class, Bug_307282.class, Bug_307391.class, MultiRuleTest.class, Bug_311756.class, Bug_311863.class, Bug_316839.class, - Bug_320329.class, Bug_478634.class, Bug_550738.class, Bug_574883.class, Bug_412138.class, - Bug_574883Join.class, GithubBug_193.class, - WorkerPoolTest.class, + Bug_320329.class, Bug_478634.class, Bug_550738.class, Bug_574883.class, + Bug_412138.class, + Bug_574883Join.class, GithubBug_193.class, WorkerPoolTest.class, /* * Intentional the LAST TEST in the list to testNoTimeoutOccured() in the other * tests: */ JobEventTest.class }) +@Suite public class AllJobTests { } diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_412138.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_412138.java index 38f7e5ca829..c5dcbdb144a 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_412138.java +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_412138.java @@ -13,33 +13,42 @@ *******************************************************************************/ package org.eclipse.core.tests.runtime.jobs; -import java.io.*; +import static org.eclipse.core.tests.runtime.RuntimeTestsPlugin.PI_RUNTIME_TESTS; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.util.concurrent.atomic.AtomicIntegerArray; -import junit.framework.*; -import org.eclipse.core.runtime.*; +import junit.framework.AssertionFailedError; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.tests.harness.FileSystemHelper; import org.eclipse.core.tests.harness.TestBarrier2; -import org.eclipse.core.tests.runtime.RuntimeTestsPlugin; -import org.eclipse.core.tests.session.SessionTestSuite; +import org.eclipse.core.tests.harness.session.SessionShouldError; +import org.eclipse.core.tests.harness.session.SessionTestExtension; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.RegisterExtension; /** * Test for bug 412138. */ -public class Bug_412138 extends TestCase { - private static final String FILE_NAME = FileSystemHelper.getTempDir().append(Bug_412138.class.getName()).toOSString(); - - public static Test suite() { - SessionTestSuite suite = new SessionTestSuite(RuntimeTestsPlugin.PI_RUNTIME_TESTS, Bug_412138.class.getName()); - suite.addCrashTest(new Bug_412138("testRunScenario")); - suite.addTest(new Bug_412138("testVerifyResult")); - return suite; - } +@TestMethodOrder(MethodOrderer.MethodName.class) +public class Bug_412138 { + @RegisterExtension + static SessionTestExtension sessionTestExtension = SessionTestExtension.forPlugin(PI_RUNTIME_TESTS).create(); - public Bug_412138(String name) { - super(name); - } + private static final String FILE_NAME = FileSystemHelper.getTempDir().append(Bug_412138.class.getName()).toOSString(); + @Test + @SessionShouldError public void testRunScenario() throws InterruptedException { // delete the file so that we don't report previous results new File(FILE_NAME).delete(); @@ -59,7 +68,7 @@ protected IStatus run(IProgressMonitor monitor) { return Status.OK_STATUS; } } catch (InterruptedException e) { - return new Status(IStatus.ERROR, RuntimeTestsPlugin.PI_RUNTIME_TESTS, e.getMessage(), e); + return new Status(IStatus.ERROR, PI_RUNTIME_TESTS, e.getMessage(), e); } } }; @@ -72,7 +81,7 @@ protected IStatus run(IProgressMonitor monitor) { status.set(0, TestBarrier2.STATUS_DONE); return Status.OK_STATUS; } catch (InterruptedException e) { - return new Status(IStatus.ERROR, RuntimeTestsPlugin.PI_RUNTIME_TESTS, e.getMessage(), e); + return new Status(IStatus.ERROR, PI_RUNTIME_TESTS, e.getMessage(), e); } } }; @@ -104,6 +113,7 @@ protected IStatus run(IProgressMonitor monitor) { } } + @Test public void testVerifyResult() throws IOException, ClassNotFoundException { File file = new File(FILE_NAME); // if the file does not exist, there was no deadlock so the whole test pass