-
-
Notifications
You must be signed in to change notification settings - Fork 305
Description
The latest version of junit-platform-engine has changed its internal discovery algorithm, and in doing so exposed a bug in the JUnit Platform tester.
The bug relates to the following code:
Lines 520 to 533 in 362f0ae
| @Override | |
| public <T extends DiscoverySelector> List<T> getSelectorsByType(Class<T> selectorType) { | |
| info(() -> "Getting selectors from sub-request for: " + selectorType); | |
| if (selectorType.equals(ClassSelector.class) || selectorType.equals(MethodSelector.class)) { | |
| return selectors.stream() | |
| .filter(selectorType::isInstance) | |
| .map(selectorType::cast) | |
| .collect(toList()); | |
| } | |
| if (selectorType.equals(BundleSelector.class)) { | |
| return new ArrayList<>(); | |
| } | |
| return request.getSelectorsByType(selectorType); | |
| } |
The aim of this method is to resolve any raw ClassSelector or MethodSelector selectors (ie, those specified using Strings for the class names) into the versions that have fully loaded Class instances. This allows it to take care of the OSGi aspects of the classloading (which plain JUnit Platform is not adequately aware of), and it also turns a BundleSelector (which only BundleEngine understands) into ClassSelectors that can be understood by the sub-engines.
Under the older version of JUnit Platform, calls to EngineDiscoveryRequest.getSelectorsByType() were always made using the individual concrete subclasses ClassSelector and MethodSelector. So the code path would go via L524 and return our fully-resolved version of the selectors rather than the original selector instance (which may include a String version).
Under the new version, it first calls getSelectorsByType() with the interface DiscoverySelector.class:
This causes it to bypass L524 of BundleSelectorResolver and instead delegate to the original request.
In the common use case (running all tests in one or more bundles), the original request will typically comprise one or more BundleSelectors and nothing else. So these BundleSelectors will be returned. These are in turn passed on to the sub-engine for discovery, but the sub-engine, not understanding what a BundleSelector is, will simply ignore them. Thus, it doesn't discover any tests (hence the behaviour @bjhargrave discovered in eclipse-osgi-technology/osgi-test#70).
The fix:
- Instead of
selectorType.equals(), in L523, we should use something likeselectorType.isAssignableFrom(). - Always delegate to the original request, filter the result to remove
BundleSelectors,ClassSelectors andMethodSelector, and add the pre-resolved versions ofClassSelector/MethodSelectorinstances to the return value if appropriate.
Unfortunately this bug makes junit-platform tester 5.0.0 unusable with JUnit 5.6. I'll look at a fix, and perhaps we can consider cherrypicking it into a 5.0.1 release or something like that.