Skip to content

Commit b66c8ab

Browse files
trancexpressHannesWellmerks
committed
Consider bundle versions when adding JUnit to launch
and remove unnecessary separate attempts to add junit-launcher and jupiter.engine bundles to the runtime, intending to support @RunWith(JUnitPlatform.class), because these bundles always are already added to a runtime. This change adjusts JUnitLaunchConfigurationDelegate, to consider bundle versions when adding required JUnit bundles. E.g. when adding JUnit bundles for a JUnit 5 test, JUnit 5 versions are added. This avoids conflicts when both JUnit 5 and JUnit 6 bundles are in the platform, since they share symbolic names. Furthermore handle multiple versions of a bundle when searching them in the host. Fixes: #2006 Co-authored-by: Hannes Wellmann <[email protected]> Co-authored-by: Ed Merks <[email protected]>
1 parent f588de6 commit b66c8ab

File tree

1 file changed

+38
-35
lines changed

1 file changed

+38
-35
lines changed

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

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515

1616
import java.util.ArrayList;
1717
import java.util.Collection;
18-
import java.util.Collections;
1918
import java.util.Comparator;
20-
import java.util.HashSet;
2119
import java.util.LinkedHashSet;
2220
import java.util.List;
2321
import java.util.Map;
22+
import java.util.Optional;
2423
import java.util.Set;
25-
import java.util.stream.Collectors;
24+
import java.util.function.Function;
25+
import java.util.stream.Stream;
2626

2727
import org.eclipse.core.runtime.CoreException;
2828
import org.eclipse.core.runtime.Status;
@@ -34,69 +34,72 @@
3434
import org.eclipse.pde.internal.core.DependencyManager;
3535
import org.eclipse.pde.internal.core.PDECore;
3636
import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper;
37+
import org.osgi.framework.wiring.BundleRevision;
3738

3839
public class JUnitLaunchRequirements {
3940

4041
public static final String JUNIT4_JDT_RUNTIME_PLUGIN = "org.eclipse.jdt.junit4.runtime"; //$NON-NLS-1$
4142
public static final String JUNIT5_JDT_RUNTIME_PLUGIN = "org.eclipse.jdt.junit5.runtime"; //$NON-NLS-1$
43+
private static final Comparator<IPluginModelBase> VERSION = Comparator.comparing(p -> p.getBundleDescription().getVersion());
4244

4345
public static void addRequiredJunitRuntimePlugins(ILaunchConfiguration configuration, Map<String, List<IPluginModelBase>> allBundles, Map<IPluginModelBase, String> allModels) throws CoreException {
44-
Set<String> requiredPlugins = new LinkedHashSet<>(getRequiredJunitRuntimeEclipsePlugins(configuration));
45-
46-
if (allBundles.containsKey("junit-platform-runner")) { //$NON-NLS-1$
47-
// add launcher and jupiter.engine to support @RunWith(JUnitPlatform.class)
48-
requiredPlugins.add("junit-platform-launcher"); //$NON-NLS-1$
49-
requiredPlugins.add("junit-jupiter-engine"); //$NON-NLS-1$
50-
}
51-
52-
Set<BundleDescription> addedRequirements = new HashSet<>();
53-
addAbsentRequirements(requiredPlugins, addedRequirements, allBundles, allModels);
54-
55-
Set<BundleDescription> requirementsOfRequirements = DependencyManager.findRequirementsClosure(addedRequirements);
56-
Set<String> rorIds = requirementsOfRequirements.stream().map(BundleDescription::getSymbolicName).collect(Collectors.toSet());
57-
addAbsentRequirements(rorIds, null, allBundles, allModels);
46+
Collection<String> runtimePlugins = getRequiredJunitRuntimeEclipsePlugins(configuration);
47+
Set<BundleDescription> addedRuntimeBundles = addAbsentRequirements(runtimePlugins, allBundles, allModels);
48+
Set<BundleDescription> runtimeRequirements = DependencyManager.findRequirementsClosure(addedRuntimeBundles);
49+
addAbsentRequirements(runtimeRequirements, allBundles, allModels);
5850
}
5951

6052
@SuppressWarnings("restriction")
6153
public static Collection<String> getRequiredJunitRuntimeEclipsePlugins(ILaunchConfiguration configuration) {
6254
org.eclipse.jdt.internal.junit.launcher.ITestKind testKind = org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants.getTestRunnerKind(configuration);
6355
if (testKind.isNull()) {
64-
return Collections.emptyList();
56+
return List.of();
6557
}
6658
List<String> plugins = new ArrayList<>();
6759
plugins.add("org.eclipse.pde.junit.runtime"); //$NON-NLS-1$
68-
69-
if (org.eclipse.jdt.internal.junit.launcher.TestKindRegistry.JUNIT4_TEST_KIND_ID.equals(testKind.getId())) {
70-
plugins.add("org.eclipse.jdt.junit4.runtime"); //$NON-NLS-1$
71-
} else if (org.eclipse.jdt.internal.junit.launcher.TestKindRegistry.JUNIT5_TEST_KIND_ID.equals(testKind.getId())) {
72-
plugins.add("org.eclipse.jdt.junit5.runtime"); //$NON-NLS-1$
60+
switch (testKind.getId()) {
61+
case org.eclipse.jdt.internal.junit.launcher.TestKindRegistry.JUNIT3_TEST_KIND_ID -> {
62+
} // Nothing to add for JUnit-3
63+
case org.eclipse.jdt.internal.junit.launcher.TestKindRegistry.JUNIT4_TEST_KIND_ID -> plugins.add(JUNIT4_JDT_RUNTIME_PLUGIN);
64+
case org.eclipse.jdt.internal.junit.launcher.TestKindRegistry.JUNIT5_TEST_KIND_ID -> plugins.add(JUNIT5_JDT_RUNTIME_PLUGIN);
65+
default -> throw new IllegalArgumentException("Unsupported junit test kind: " + testKind.getId()); //$NON-NLS-1$
7366
}
7467
return plugins;
7568
}
7669

77-
private static void addAbsentRequirements(Collection<String> requirements, Set<BundleDescription> addedRequirements, Map<String, List<IPluginModelBase>> allBundles, Map<IPluginModelBase, String> allModels) throws CoreException {
70+
private static Set<BundleDescription> addAbsentRequirements(Collection<String> requirements, Map<String, List<IPluginModelBase>> allBundles, Map<IPluginModelBase, String> allModels) throws CoreException {
71+
Set<BundleDescription> addedRequirements = new LinkedHashSet<>();
7872
for (String id : requirements) {
7973
List<IPluginModelBase> models = allBundles.computeIfAbsent(id, k -> new ArrayList<>());
80-
if (models.stream().noneMatch(m -> m.getBundleDescription().isResolved())) {
81-
IPluginModelBase model = findRequiredPluginInTargetOrHost(id);
74+
if (models.stream().noneMatch(p -> p.getBundleDescription().isResolved())) {
75+
IPluginModelBase model = findRequiredPluginInTargetOrHost(PluginRegistry.findModel(id), plugins -> plugins.max(VERSION), id);
76+
models.add(model);
77+
BundleLauncherHelper.addDefaultStartingBundle(allModels, model);
78+
addedRequirements.add(model.getBundleDescription());
79+
}
80+
}
81+
return addedRequirements;
82+
}
83+
84+
private static void addAbsentRequirements(Set<BundleDescription> requirements, Map<String, List<IPluginModelBase>> allBundles, Map<IPluginModelBase, String> allModels) throws CoreException {
85+
for (BundleRevision bundle : requirements) {
86+
String id = bundle.getSymbolicName();
87+
List<IPluginModelBase> models = allBundles.computeIfAbsent(id, k -> new ArrayList<>());
88+
if (models.stream().map(IPluginModelBase::getBundleDescription).noneMatch(b -> b.isResolved() && b.getVersion().equals(bundle.getVersion()))) {
89+
IPluginModelBase model = findRequiredPluginInTargetOrHost(PluginRegistry.findModel(bundle), plgs -> plgs.filter(p -> p.getBundleDescription() == bundle).findFirst(), id);
8290
models.add(model);
8391
BundleLauncherHelper.addDefaultStartingBundle(allModels, model);
84-
if (addedRequirements != null) {
85-
addedRequirements.add(model.getBundleDescription());
86-
}
8792
}
8893
}
8994
}
9095

91-
private static IPluginModelBase findRequiredPluginInTargetOrHost(String id) throws CoreException {
92-
IPluginModelBase model = PluginRegistry.findModel(id);
96+
private static IPluginModelBase findRequiredPluginInTargetOrHost(IPluginModelBase model, Function<Stream<IPluginModelBase>, Optional<IPluginModelBase>> pluginSelector, String id) throws CoreException {
9397
if (model == null || !model.getBundleDescription().isResolved()) {
9498
// prefer bundle from host over unresolved bundle from target
95-
model = PDECore.getDefault().findPluginInHost(id).max(Comparator.comparing(p -> p.getBundleDescription().getVersion())).orElse(null);
96-
}
97-
if (model == null) {
98-
throw new CoreException(Status.error(NLS.bind(PDEMessages.JUnitLaunchConfiguration_error_missingPlugin, id)));
99+
model = pluginSelector.apply(PDECore.getDefault().findPluginInHost(id)) //
100+
.orElseThrow(() -> new CoreException(Status.error(NLS.bind(PDEMessages.JUnitLaunchConfiguration_error_missingPlugin, id))));
99101
}
100102
return model;
101103
}
104+
102105
}

0 commit comments

Comments
 (0)