Skip to content

Commit e0822fe

Browse files
trancexpressHannesWell
authored andcommitted
Check for mixed JUnit 5 and JUnit 6 launch type and required bundles
This changes ensures an error dialog is shown, if a user runs a JUnit 5 launch with required JUnit 6 bundles. Fixes: #2045
1 parent 9f7c60d commit e0822fe

File tree

5 files changed

+114
-0
lines changed

5 files changed

+114
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Simeon Andreev and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Simeon Andreev - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.pde.internal.launching;
15+
16+
import java.util.HashMap;
17+
import java.util.LinkedHashMap;
18+
import java.util.Map;
19+
import java.util.Set;
20+
import java.util.stream.Collectors;
21+
22+
import org.eclipse.core.runtime.CoreException;
23+
import org.eclipse.core.runtime.IProgressMonitor;
24+
import org.eclipse.core.runtime.Status;
25+
import org.eclipse.debug.core.ILaunchConfiguration;
26+
import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
27+
import org.eclipse.osgi.service.resolver.BundleDescription;
28+
import org.eclipse.osgi.util.NLS;
29+
import org.eclipse.pde.core.plugin.IPluginModelBase;
30+
import org.eclipse.pde.internal.launching.launcher.LaunchValidationOperation;
31+
import org.osgi.framework.Version;
32+
33+
public class JUnitLaunchValidationOperation extends LaunchValidationOperation {
34+
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+
});
39+
40+
private final Map<Object, Object[]> fErrors = new HashMap<>(2);
41+
42+
public JUnitLaunchValidationOperation(ILaunchConfiguration configuration, Set<IPluginModelBase> models) {
43+
super(configuration, models, null);
44+
}
45+
46+
@Override
47+
public void run(IProgressMonitor monitor) throws CoreException {
48+
try {
49+
checkJunitVersion(fLaunchConfiguration, fModels);
50+
} catch (CoreException e) {
51+
PDELaunchingPlugin.log(e);
52+
}
53+
}
54+
55+
@SuppressWarnings("restriction")
56+
private void checkJunitVersion(ILaunchConfiguration configuration, Set<IPluginModelBase> models) throws CoreException {
57+
org.eclipse.jdt.internal.junit.launcher.ITestKind testKind = org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants.getTestRunnerKind(configuration);
58+
if (testKind.isNull()) {
59+
return;
60+
}
61+
Set<Version> junitPlatformBundlesVersions = junitPlatformBundleVersions(models);
62+
String testKindId = testKind.getId();
63+
switch (testKindId) {
64+
case TestKindRegistry.JUNIT3_TEST_KIND_ID, TestKindRegistry.JUNIT4_TEST_KIND_ID -> {
65+
} // nothing to check
66+
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);
70+
addError(message);
71+
});
72+
}
73+
default -> throw new CoreException(Status.error("Unsupported test kind: " + testKindId)); //$NON-NLS-1$
74+
}
75+
}
76+
77+
private void addError(String message) {
78+
fErrors.put(message.replaceAll("\\R", " "), null); //$NON-NLS-1$//$NON-NLS-2$
79+
}
80+
81+
@Override
82+
public boolean hasErrors() {
83+
return !fErrors.isEmpty();
84+
}
85+
86+
@Override
87+
public Map<Object, Object[]> getInput() {
88+
Map<Object, Object[]> map = new LinkedHashMap<>();
89+
map.putAll(fErrors);
90+
return map;
91+
}
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+
}
98+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class PDEMessages extends NLS {
3636
public static String WorkbenchLauncherConfigurationDelegate_noStartup;
3737
public static String JUnitLaunchConfiguration_error_notaplugin;
3838
public static String JUnitLaunchConfiguration_error_missingPlugin;
39+
public static String JUnitLaunchConfiguration_error_JUnitLaunchAndRuntimeMissmatch;
3940

4041
public static String OSGiLaunchConfiguration_cannotFindLaunchConfiguration;
4142
public static String OSGiLaunchConfiguration_selected;

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ WorkbenchLauncherConfigurationDelegate_jrePathNotFound = The installation path t
2525
WorkbenchLauncherConfigurationDelegate_noStartup = Launching failed. Bootstrap code cannot be found.
2626
JUnitLaunchConfiguration_error_notaplugin = Could not launch the JUnit plug-in tests because project ''{0}'' is not a plug-in project.
2727
JUnitLaunchConfiguration_error_missingPlugin = Required plug-in ''{0}'' could not be found.
28+
JUnitLaunchConfiguration_error_JUnitLaunchAndRuntimeMissmatch = Launch targets JUnit {0} but contains JUnit {1} bundles.\n\
29+
Therefore this launch is expected to fail.\n\
30+
\n\
31+
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}.
2835

2936
OSGiLaunchConfiguration_cannotFindLaunchConfiguration=Cannot find the {0} OSGi framework.
3037
OSGiLaunchConfiguration_selected=selected

ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import org.eclipse.pde.internal.core.util.VersionUtil;
7272
import org.eclipse.pde.internal.launching.IPDEConstants;
7373
import org.eclipse.pde.internal.launching.JUnitLaunchRequirements;
74+
import org.eclipse.pde.internal.launching.JUnitLaunchValidationOperation;
7475
import org.eclipse.pde.internal.launching.PDELaunchingPlugin;
7576
import org.eclipse.pde.internal.launching.PDEMessages;
7677
import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper;
@@ -518,6 +519,9 @@ protected void preLaunchCheck(ILaunchConfiguration configuration, ILaunch launch
518519
fAllBundles = fModels.keySet().stream().collect(Collectors.groupingBy(m -> m.getPluginBase().getId(), LinkedHashMap::new, Collectors.toCollection(ArrayList::new)));
519520
launchMode = launch.getLaunchMode();
520521

522+
JUnitLaunchValidationOperation junitValidation = new JUnitLaunchValidationOperation(configuration, fModels.keySet());
523+
LaunchPluginValidator.runValidationOperation(junitValidation, monitor);
524+
521525
// implicitly add the plug-ins required for JUnit testing if necessary
522526
JUnitLaunchRequirements.addRequiredJunitRuntimePlugins(configuration, fAllBundles, fModels);
523527

ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchConfigurationDelegate.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import org.eclipse.pde.internal.core.util.CoreUtility;
8787
import org.eclipse.pde.internal.launching.IPDEConstants;
8888
import org.eclipse.pde.internal.launching.JUnitLaunchRequirements;
89+
import org.eclipse.pde.internal.launching.JUnitLaunchValidationOperation;
8990
import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper;
9091
import org.eclipse.pde.internal.launching.launcher.EclipsePluginValidationOperation;
9192
import org.eclipse.pde.internal.launching.launcher.LaunchArgumentsHelper;
@@ -359,6 +360,9 @@ protected void preLaunchCheck(ILaunchConfiguration configuration, ILaunch launch
359360
fAllBundles = fModels.keySet().stream().collect(Collectors.groupingBy(m -> m.getPluginBase().getId(),
360361
LinkedHashMap::new, Collectors.toCollection(ArrayList::new)));
361362

363+
JUnitLaunchValidationOperation junitValidation = new JUnitLaunchValidationOperation(configuration, fModels.keySet());
364+
LaunchPluginValidator.runValidationOperation(junitValidation, monitor);
365+
362366
// implicitly add the plug-ins required for JUnit testing if necessary
363367
JUnitLaunchRequirements.addRequiredJunitRuntimePlugins(configuration, fAllBundles, fModels);
364368

0 commit comments

Comments
 (0)