mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
detect junit 5 based on custom classloader with engines (IDEA-168685)
This commit is contained in:
@@ -123,12 +123,17 @@ public abstract class JavaTestFrameworkRunnableState<T extends
|
||||
return module != null;
|
||||
}
|
||||
|
||||
protected boolean isIdBasedTestTree() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ExecutionResult execute(@NotNull Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
|
||||
final RunnerSettings runnerSettings = getRunnerSettings();
|
||||
|
||||
final SMTRunnerConsoleProperties testConsoleProperties = getConfiguration().createTestConsoleProperties(executor);
|
||||
testConsoleProperties.setIdBasedTestTree(isIdBasedTestTree());
|
||||
testConsoleProperties.setIfUndefined(TestConsoleProperties.HIDE_PASSED_TESTS, false);
|
||||
|
||||
final BaseTestsOutputConsoleView consoleView = SMTestRunnerConnectionUtil.createConsole(getFrameworkName(), testConsoleProperties);
|
||||
|
||||
@@ -50,21 +50,8 @@ public class TestClassCollector {
|
||||
JavaTestConfigurationBase configuration,
|
||||
Function<ClassLoader, Predicate<Class<?>>> predicateProducer) {
|
||||
Module module = configuration.getConfigurationModule().getModule();
|
||||
List<URL> 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<String> classes = new HashSet<>();
|
||||
UrlClassLoader classLoader = UrlClassLoader.build().allowLock().useCache().urls(urls).get();
|
||||
try {
|
||||
String packagePath = packageName.replace('.', '/');
|
||||
Enumeration<URL> 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<URL> 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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<JUnitCon
|
||||
}
|
||||
|
||||
final Project project = getConfiguration().getProject();
|
||||
final SourceScope sourceScope = getSourceScope();
|
||||
GlobalSearchScope globalSearchScope = getScopeForJUnit(getConfiguration().getConfigurationModule().getModule(), sourceScope, project);
|
||||
String preferredRunner = getConfiguration().getPreferredRunner(globalSearchScope);
|
||||
GlobalSearchScope globalSearchScope = getScopeForJUnit(getConfiguration().getConfigurationModule().getModule(), project);
|
||||
String preferredRunner = getRunner();
|
||||
if (JUnitStarter.JUNIT5_PARAMETER.equals(preferredRunner)) {
|
||||
final PathsList classPath = javaParameters.getClassPath();
|
||||
File lib = new File(PathUtil.getJarPathForClass(MultipleFailuresError.class)).getParentFile();
|
||||
@@ -210,18 +208,12 @@ public abstract class TestObject extends JavaTestFrameworkRunnableState<JUnitCon
|
||||
return aPackage != null && aPackage.getDirectories(globalSearchScope).length > 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<JUnitCon
|
||||
return processHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIdBasedTestTree() {
|
||||
return JUnitStarter.JUNIT5_PARAMETER.equals(getRunner());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getForkMode() {
|
||||
@@ -270,9 +267,7 @@ public abstract class TestObject extends JavaTestFrameworkRunnableState<JUnitCon
|
||||
final SourceScope sourceScope = getSourceScope();
|
||||
Project project = getConfiguration().getProject();
|
||||
if (sourceScope != null && packageName != null
|
||||
&& !ReadAction.compute(() -> 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<JUnitCon
|
||||
parameters.getProgramParametersList().add(ForkedDebuggerHelper.DEBUG_SOCKET + getForkSocket().getLocalPort());
|
||||
}
|
||||
}
|
||||
|
||||
private String myRunner;
|
||||
|
||||
protected String getRunner() {
|
||||
if (myRunner == null) {
|
||||
myRunner = getRunnerInner();
|
||||
}
|
||||
return myRunner;
|
||||
}
|
||||
|
||||
private String getRunnerInner() {
|
||||
final GlobalSearchScope globalSearchScope = getScopeForJUnit(myConfiguration);
|
||||
JUnitConfiguration.Data data = myConfiguration.getPersistentData();
|
||||
Project project = myConfiguration.getProject();
|
||||
boolean isMethodConfiguration = JUnitConfiguration.TEST_METHOD.equals(data.TEST_OBJECT);
|
||||
boolean isClassConfiguration = JUnitConfiguration.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) || isCustomJUnit5() ? JUnitStarter.JUNIT5_PARAMETER : null;
|
||||
}
|
||||
|
||||
private boolean isCustomJUnit5() {
|
||||
if (JavaPsiFacade.getInstance(myConfiguration.getProject()).findPackage("org.junit.platform") == null) return false;
|
||||
|
||||
ClassLoader loader = TestClassCollector.createUsersClassLoader(myConfiguration);
|
||||
try {
|
||||
ServiceLoader<?> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
-3
@@ -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<JUnit
|
||||
|
||||
public JUnitConsoleProperties(@NotNull JUnitConfiguration configuration, Executor executor) {
|
||||
super("JUnit", configuration, executor);
|
||||
setIdBasedTestTree(JUnitStarter.JUNIT5_PARAMETER.equals(configuration.getPreferredRunner(TestObject.getScopeForJUnit(configuration))));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed 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 com.intellij.rt.execution.junit;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
public class JUnit5EngineDetector {
|
||||
|
||||
public static boolean hasCustomEngine() {
|
||||
try {
|
||||
Iterator iterator = ServiceLoader.load(Class.forName("org.junit.platform.engine.TestEngine")).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Object engine = iterator.next();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,7 +178,7 @@ public class JUnitStarter {
|
||||
public static boolean isJUnit5Preferred() {
|
||||
final String useJUnit5 = System.getProperty(JUNIT5_KEY);
|
||||
if (useJUnit5 == null) {
|
||||
return JUnit5EngineDetector.hasCustomEngine();
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
final Boolean boolValue = Boolean.valueOf(useJUnit5);
|
||||
|
||||
Reference in New Issue
Block a user