Skip to content

Commit 1ae597c

Browse files
committed
Check for JUnit 5 and 6 conflicts with junit-jupiter-engine and not with
junit-platform-engine Fixes: #2045
1 parent 2b81907 commit 1ae597c

File tree

2 files changed

+79
-20
lines changed

2 files changed

+79
-20
lines changed

ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/JUnitLaunchValidationOperation.java

Lines changed: 77 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,35 @@
1313
*******************************************************************************/
1414
package org.eclipse.pde.internal.launching;
1515

16+
import java.util.ArrayList;
1617
import java.util.HashMap;
1718
import java.util.LinkedHashMap;
19+
import java.util.List;
1820
import java.util.Map;
1921
import java.util.Set;
20-
import java.util.stream.Collectors;
2122

2223
import org.eclipse.core.runtime.CoreException;
2324
import org.eclipse.core.runtime.IProgressMonitor;
2425
import org.eclipse.core.runtime.Status;
2526
import org.eclipse.debug.core.ILaunchConfiguration;
27+
import org.eclipse.jdt.internal.junit.buildpath.BuildPathSupport;
2628
import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
2729
import org.eclipse.osgi.service.resolver.BundleDescription;
30+
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
2831
import org.eclipse.osgi.util.NLS;
2932
import org.eclipse.pde.core.plugin.IPluginModelBase;
3033
import org.eclipse.pde.internal.launching.launcher.LaunchValidationOperation;
31-
import org.osgi.framework.Version;
3234

3335
public class JUnitLaunchValidationOperation extends LaunchValidationOperation {
3436

35-
private static final Set<String> JUNIT_PLATFORM_ENGINE_BUNLDES = Set.of(new String[] { //
36-
"junit-platform-engine", //$NON-NLS-1$
37-
"org.junit.platform.engine", //$NON-NLS-1$
38-
});
37+
private record JunitDependency(String fromBundle, String toBundle, int majorVersion) {
38+
}
39+
40+
private static final String JUNIT_BUNDLE_PREFIX_ORBIT = "org.junit"; //$NON-NLS-1$
41+
private static final String JUNIT_BUNDLE_PREFIX = "junit"; //$NON-NLS-1$
42+
43+
private static final Map<String, String> JUNIT_BUNDLE_NAMES = junitBundleNames();
44+
private static final Map<String, String> JUNIT_PACKAGE_TO_BUNDLE = junitPackageToBundle();
3945

4046
private final Map<Object, Object[]> fErrors = new HashMap<>(2);
4147

@@ -58,17 +64,56 @@ private void checkJunitVersion(ILaunchConfiguration configuration, Set<IPluginMo
5864
if (testKind.isNull()) {
5965
return;
6066
}
61-
Set<Version> junitPlatformBundlesVersions = junitPlatformBundleVersions(models);
6267
String testKindId = testKind.getId();
6368
switch (testKindId) {
6469
case TestKindRegistry.JUNIT3_TEST_KIND_ID, TestKindRegistry.JUNIT4_TEST_KIND_ID -> {
6570
} // nothing to check
6671
case TestKindRegistry.JUNIT5_TEST_KIND_ID -> {
67-
// JUnit 5 platform bundles have version range [1.0,2.0)
68-
junitPlatformBundlesVersions.stream().map(Version::getMajor).filter(i -> i.intValue() != 1).findFirst().ifPresent(otherVersion -> {
69-
String message = NLS.bind(PDEMessages.JUnitLaunchConfiguration_error_JUnitLaunchAndRuntimeMissmatch, 5, otherVersion);
72+
List<JunitDependency> junitDependencies = new ArrayList<>();
73+
for (IPluginModelBase model : models) {
74+
BundleDescription description = model.getBundleDescription();
75+
String symbolicName = description.getSymbolicName();
76+
// JUnit bundles depends on JUnit bundles, so don't report that
77+
if (symbolicName.startsWith(JUNIT_BUNDLE_PREFIX) || symbolicName.startsWith(JUNIT_BUNDLE_PREFIX_ORBIT)) {
78+
continue;
79+
}
80+
BundleDescription[] requires = description.getResolvedRequires();
81+
for (BundleDescription require : requires) {
82+
String junitBundleName = JUNIT_BUNDLE_NAMES.get(require.getSymbolicName());
83+
if (junitBundleName != null) {
84+
junitDependencies.add(new JunitDependency(symbolicName, junitBundleName, require.getVersion().getMajor()));
85+
}
86+
}
87+
ExportPackageDescription[] resolvedImports = description.getResolvedImports();
88+
for (ExportPackageDescription resolvedImport : resolvedImports) {
89+
String junitBundleName = JUNIT_PACKAGE_TO_BUNDLE.get(resolvedImport.getName());
90+
if (junitBundleName != null) {
91+
junitDependencies.add(new JunitDependency(symbolicName, junitBundleName, resolvedImport.getVersion().getMajor()));
92+
}
93+
}
94+
}
95+
JunitDependency junitJupiterEngine5 = null;
96+
JunitDependency junitPlatformEngine6 = null;
97+
for (JunitDependency dependency : junitDependencies) {
98+
if (dependency.majorVersion == 6 && (BuildPathSupport.JUNIT_JUPITER_API.equals(dependency.toBundle) || BuildPathSupport.JUNIT_JUPITER_ENGINE.equals(dependency.toBundle))) {
99+
String message = NLS.bind(PDEMessages.JUnitLaunchConfiguration_error_JUnitLaunchAndRuntimeMissmatch, 5, 6, dependency.fromBundle, dependency.toBundle);
100+
addError(message);
101+
}
102+
if (dependency.majorVersion == 5 && BuildPathSupport.JUNIT_JUPITER_ENGINE.equals(dependency.toBundle)) {
103+
junitJupiterEngine5 = dependency;
104+
}
105+
if (dependency.majorVersion == 6 && BuildPathSupport.JUNIT_PLATFORM_ENGINE.equals(dependency.toBundle)) {
106+
junitPlatformEngine6 = dependency;
107+
}
108+
}
109+
/*
110+
* Depending on junit-platform-engine 6.x causes problems only if junit-jupiter-engine 5.x is also depended on directly.
111+
* The dependency from junit-jupiter-api 5.x to junit-jupiter-engine 5.x doesn't interfere here.
112+
*/
113+
if (junitJupiterEngine5 != null && junitPlatformEngine6 != null) {
114+
String message = NLS.bind(PDEMessages.JUnitLaunchConfiguration_error_JUnitLaunchAndRuntimeMissmatch, 5, 6, junitPlatformEngine6.fromBundle, junitPlatformEngine6.toBundle);
70115
addError(message);
71-
});
116+
}
72117
}
73118
default -> throw new CoreException(Status.error("Unsupported test kind: " + testKindId)); //$NON-NLS-1$
74119
}
@@ -78,6 +123,27 @@ private void addError(String message) {
78123
fErrors.put(message.replaceAll("\\R", " "), null); //$NON-NLS-1$//$NON-NLS-2$
79124
}
80125

126+
@SuppressWarnings("restriction")
127+
private static Map<String, String> junitBundleNames() {
128+
Map<String, String> map = new HashMap<>();
129+
map.put("org.junit.jupiter.api", BuildPathSupport.JUNIT_JUPITER_API); //$NON-NLS-1$
130+
map.put("org.junit.jupiter.engine", BuildPathSupport.JUNIT_JUPITER_ENGINE); //$NON-NLS-1$
131+
map.put("org.junit.platofrm.engine", BuildPathSupport.JUNIT_PLATFORM_ENGINE); //$NON-NLS-1$
132+
map.put(BuildPathSupport.JUNIT_JUPITER_API, BuildPathSupport.JUNIT_JUPITER_API);
133+
map.put(BuildPathSupport.JUNIT_JUPITER_ENGINE, BuildPathSupport.JUNIT_JUPITER_ENGINE);
134+
map.put(BuildPathSupport.JUNIT_PLATFORM_ENGINE, BuildPathSupport.JUNIT_PLATFORM_ENGINE);
135+
return map;
136+
}
137+
138+
@SuppressWarnings("restriction")
139+
private static Map<String, String> junitPackageToBundle() {
140+
Map<String, String> map = new HashMap<>();
141+
map.put("org.junit.jupiter.api", BuildPathSupport.JUNIT_JUPITER_API); //$NON-NLS-1$
142+
map.put("org.junit.jupiter.engine", BuildPathSupport.JUNIT_JUPITER_ENGINE); //$NON-NLS-1$
143+
map.put("org.junit.platofrm.engine", BuildPathSupport.JUNIT_PLATFORM_ENGINE); //$NON-NLS-1$
144+
return map;
145+
}
146+
81147
@Override
82148
public boolean hasErrors() {
83149
return !fErrors.isEmpty();
@@ -89,10 +155,4 @@ public Map<Object, Object[]> getInput() {
89155
map.putAll(fErrors);
90156
return map;
91157
}
92-
93-
private static Set<Version> junitPlatformBundleVersions(Set<IPluginModelBase> models) {
94-
return models.stream().map(IPluginModelBase::getBundleDescription) //
95-
.filter(d -> JUNIT_PLATFORM_ENGINE_BUNLDES.contains(d.getSymbolicName())) //
96-
.map(BundleDescription::getVersion).collect(Collectors.toSet());
97-
}
98158
}

ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/pderesources.properties

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@ JUnitLaunchConfiguration_error_JUnitLaunchAndRuntimeMissmatch = Launch targets J
2929
Therefore this launch is expected to fail.\n\
3030
\n\
3131
Either update the launch configuration to target JUnit {1},\n\
32-
or restrict the versions of JUnit Jupiter and JUnit Platform\n\
33-
by specifying corresponding version bounds\n\
34-
in your test-project to match only JUnit {0}.
32+
or restrict the version bounds of {3}\n\
33+
in bundle {2} to match only JUnit {0}.
3534

3635
OSGiLaunchConfiguration_cannotFindLaunchConfiguration=Cannot find the {0} OSGi framework.
3736
OSGiLaunchConfiguration_selected=selected

0 commit comments

Comments
 (0)