From 5b42e8583573b5a4351d5e729b5840a96bb1e283 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 10 Aug 2017 12:03:44 +0200 Subject: [PATCH] detect junit 5 based on custom classloader with engines (IDEA-168685) --- .../JavaTestFrameworkRunnableState.java | 5 ++ .../execution/TestClassCollector.java | 35 ++++---- .../execution/junit/JUnitConfiguration.java | 30 ------- .../execution/junit/TestClassFilter.java | 3 - .../intellij/execution/junit/TestObject.java | 83 +++++++++++++++---- .../intellij/execution/junit/TestPackage.java | 5 +- .../ui/properties/JUnitConsoleProperties.java | 3 - .../execution/junit/JUnit5EngineDetector.java | 40 --------- .../rt/execution/junit/JUnitStarter.java | 2 +- 9 files changed, 98 insertions(+), 108 deletions(-) delete mode 100644 plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnit5EngineDetector.java diff --git a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java index 011d3243a7e2..3f9b20770324 100644 --- a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java +++ b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java @@ -123,12 +123,17 @@ public abstract class JavaTestFrameworkRunnableState>> predicateProducer) { Module module = configuration.getConfigurationModule().getModule(); - List urls = new ArrayList<>(); - - PathsList pathsList = ReadAction.compute(() -> (module == null || configuration.getTestSearchScope() == TestSearchScope.WHOLE_PROJECT ? OrderEnumerator.orderEntries(configuration.getProject()) : OrderEnumerator.orderEntries(module)) - .runtimeOnly().recursively().getPathsList()); //include jdk to avoid NoClassDefFoundError for classes inside tools.jar - for (VirtualFile file : pathsList.getVirtualFiles()) { - try { - urls.add(VfsUtilCore.virtualToIoFile(file).toURI().toURL()); - } - catch (MalformedURLException ignored) { - LOG.info(ignored); - } - } - + ClassLoader classLoader = createUsersClassLoader(configuration); Set classes = new HashSet<>(); - UrlClassLoader classLoader = UrlClassLoader.build().allowLock().useCache().urls(urls).get(); try { String packagePath = packageName.replace('.', '/'); Enumeration resources = classLoader.getResources(packagePath); @@ -118,6 +105,26 @@ public class TestClassCollector { return ArrayUtil.toStringArray(classes); } + public static ClassLoader createUsersClassLoader(JavaTestConfigurationBase configuration) { + Module module = configuration.getConfigurationModule().getModule(); + List urls = new ArrayList<>(); + + PathsList pathsList = ReadAction + .compute(() -> (module == null || configuration.getTestSearchScope() == TestSearchScope.WHOLE_PROJECT ? OrderEnumerator + .orderEntries(configuration.getProject()) : OrderEnumerator.orderEntries(module)) + .runtimeOnly().recursively().getPathsList()); //include jdk to avoid NoClassDefFoundError for classes inside tools.jar + for (VirtualFile file : pathsList.getVirtualFiles()) { + try { + urls.add(VfsUtilCore.virtualToIoFile(file).toURI().toURL()); + } + catch (MalformedURLException ignored) { + LOG.info(ignored); + } + } + + return UrlClassLoader.build().allowLock().useCache().urls(urls).get(); + } + @Nullable public static Path getRootPath(Module module, final boolean chooseSingleModule) { if (chooseSingleModule) { diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java index 19fc5d863c7d..3dc769a68f83 100644 --- a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java +++ b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java @@ -42,11 +42,9 @@ import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.ClassUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.listeners.RefactoringElementListener; -import com.intellij.rt.execution.junit.JUnitStarter; import com.intellij.rt.execution.junit.RepeatCount; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -523,34 +521,6 @@ public class JUnitConfiguration extends JavaTestConfigurationBase { return "j"; } - public String getPreferredRunner(final GlobalSearchScope globalSearchScope) { - Data data = getPersistentData(); - Project project = getProject(); - boolean isMethodConfiguration = TEST_METHOD.equals(data.TEST_OBJECT); - boolean isClassConfiguration = TEST_CLASS.equals(data.TEST_OBJECT); - final PsiClass psiClass = isMethodConfiguration || isClassConfiguration - ? JavaExecutionUtil.findMainClass(project, data.getMainClassName(), globalSearchScope) : null; - if (psiClass != null) { - if (JUnitUtil.isJUnit5TestClass(psiClass, false)) { - return JUnitStarter.JUNIT5_PARAMETER; - } - - if (isClassConfiguration || JUnitUtil.isJUnit4TestClass(psiClass)) { - return JUnitStarter.JUNIT4_PARAMETER; - } - - final String methodName = data.getMethodName(); - final PsiMethod[] methods = psiClass.findMethodsByName(methodName, true); - for (PsiMethod method : methods) { - if (JUnitUtil.isTestAnnotated(method)) { - return JUnitStarter.JUNIT4_PARAMETER; - } - } - return JUnitStarter.JUNIT3_PARAMETER; - } - return JUnitUtil.isJUnit5(globalSearchScope, project) ? JUnitStarter.JUNIT5_PARAMETER : null; - } - public static class Data implements Cloneable { public String PACKAGE_NAME; public String MAIN_CLASS_NAME; diff --git a/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java b/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java index 9fd035e68540..5fe46af26235 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestClassFilter.java @@ -82,9 +82,6 @@ public class TestClassFilter implements ClassFilter.ClassFilterWithScope { if (sourceScope == null) throw new JUnitUtil.NoJUnitException(); final JUnitUtil.NoJUnitException[] ex = new JUnitUtil.NoJUnitException[1]; final PsiClass testCase = ReadAction.compute(() -> { - if (TestObject.isJUnit5(module, sourceScope, sourceScope.getProject())) { - return null; - } try { return module == null ? JUnitUtil.getTestCaseClass(sourceScope) : JUnitUtil.getTestCaseClass(module); } diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index fdace57fba90..b65564cf6a1d 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -32,7 +32,6 @@ import com.intellij.execution.testframework.TestSearchScope; import com.intellij.execution.util.JavaParametersUtil; import com.intellij.execution.util.ProgramParametersUtil; import com.intellij.junit4.JUnit4IdeaTestRunner; -import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; @@ -167,9 +166,8 @@ public abstract class TestObject extends JavaTestFrameworkRunnableState 0; } - public static boolean isJUnit5(@Nullable Module module, @Nullable SourceScope sourceScope, Project project) { - return JUnitUtil.isJUnit5(getScopeForJUnit(module, sourceScope, project), project); - } - - private static GlobalSearchScope getScopeForJUnit(@Nullable Module module, @Nullable SourceScope sourceScope, Project project) { - return module != null ? GlobalSearchScope.moduleRuntimeScope(module, true) - : sourceScope != null ? sourceScope.getLibrariesScope() : GlobalSearchScope.allScope(project); + private static GlobalSearchScope getScopeForJUnit(@Nullable Module module, Project project) { + return module != null ? GlobalSearchScope.moduleRuntimeScope(module, true) : GlobalSearchScope.allScope(project); } public static GlobalSearchScope getScopeForJUnit(JUnitConfiguration configuration) { return getScopeForJUnit(configuration.getConfigurationModule().getModule(), - configuration.getTestSearchScope().getSourceScope(configuration), configuration.getProject() ); } @@ -246,6 +238,11 @@ public abstract class TestObject extends JavaTestFrameworkRunnableState isJUnit5(getConfiguration().getConfigurationModule().getModule(), - sourceScope, - getConfiguration().getProject()))) { + && !JUnitStarter.JUNIT5_PARAMETER.equals(getRunner())) { final PsiPackage aPackage = JavaPsiFacade.getInstance(getConfiguration().getProject()).findPackage(packageName); if (aPackage != null) { final TestSearchScope scope = getScope(); @@ -377,4 +372,62 @@ public abstract class TestObject extends JavaTestFrameworkRunnableState serviceLoader = ServiceLoader.load(Class.forName("org.junit.platform.engine.TestEngine", false, loader), loader); + for (Object engine : serviceLoader) { + String engineClassName = engine.getClass().getName(); + if (!"org.junit.jupiter.engine.JupiterTestEngine".equals(engineClassName) && + !"org.junit.vintage.engine.VintageTestEngine".equals(engineClassName)) { + return true; + } + } + return false; + } + catch (Throwable e) { + return false; + } + } } diff --git a/plugins/junit/src/com/intellij/execution/junit/TestPackage.java b/plugins/junit/src/com/intellij/execution/junit/TestPackage.java index c5879d1a712b..27413740204a 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestPackage.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestPackage.java @@ -36,6 +36,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PackageScope; import com.intellij.psi.util.ClassUtil; import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.rt.execution.junit.JUnitStarter; import gnu.trove.THashSet; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; @@ -73,7 +74,7 @@ public class TestPackage extends TestObject { myClasses.clear(); final SourceScope sourceScope = getSourceScope(); final Module module = getConfiguration().getConfigurationModule().getModule(); - if (sourceScope != null && !ReadAction.compute(() -> isJUnit5(module, sourceScope, myProject))) { + if (sourceScope != null && !JUnitStarter.JUNIT5_PARAMETER.equals(getRunner())) { DumbService instance = DumbService.getInstance(myProject); try { instance.setAlternativeResolveEnabled(true); @@ -139,7 +140,7 @@ public class TestPackage extends TestObject { final JUnitConfiguration.Data data = getConfiguration().getPersistentData(); final Project project = getConfiguration().getProject(); final SourceScope sourceScope = data.getScope().getSourceScope(getConfiguration()); - if (sourceScope == null || !isJUnit5(getConfiguration().getConfigurationModule().getModule(), sourceScope, project)) { //check for junit 5 + if (sourceScope == null || !JUnitStarter.JUNIT5_PARAMETER.equals(getRunner())) { //check for junit 5 JUnitUtil.checkTestCase(sourceScope, project); } createTempFiles(javaParameters); diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java b/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java index d2f5d85aec63..a5f1bb411fe0 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java @@ -17,7 +17,6 @@ package com.intellij.execution.junit2.ui.properties; import com.intellij.execution.Executor; import com.intellij.execution.junit.JUnitConfiguration; -import com.intellij.execution.junit.TestObject; import com.intellij.execution.junit2.ui.actions.RerunFailedTestsAction; import com.intellij.execution.testframework.JavaAwareTestConsoleProperties; import com.intellij.execution.testframework.JavaTestLocator; @@ -28,7 +27,6 @@ import com.intellij.execution.testframework.sm.runner.SMTestLocator; import com.intellij.execution.ui.ConsoleView; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.rt.execution.junit.JUnitStarter; import com.intellij.rt.execution.junit.RepeatCount; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -40,7 +38,6 @@ public class JUnitConsoleProperties extends JavaAwareTestConsoleProperties