Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add possibility to register launcher-discovery listeners via SPI #2457

Closed

Conversation

filiphr
Copy link
Contributor

@filiphr filiphr commented Oct 21, 2020

LauncherDiscoveryListeners can now be registered via Java's ServiceLoader
mechanism in addition to those
passed as part of each LauncherDiscoveryRequest and the default one.

Overview

The idea of this PR is to enable registering LauncherDiscoveryListener through an SPI. I am creating this PR in order to hear the opinion of the JUnit Team. Is something like this acceptable for you? If it is I am going to add add the documentation and finish whatever needs to be finished from your feedback.


I hereby agree to the terms of the JUnit Contributor License Agreement.


Definition of Done

`LauncherDiscoveryListeners` can now be registered via Java's `ServiceLoader`
mechanism in addition to those
passed as part of each `LauncherDiscoveryRequest` and the default one.
@filiphr filiphr force-pushed the launcher-discovery-auto-detection branch from 5a8c228 to 68b2244 Compare October 21, 2020 18:55
@codecov
Copy link

codecov bot commented Oct 21, 2020

Codecov Report

Merging #2457 (95b2cad) into main (a8d08e0) will increase coverage by 0.02%.
The diff coverage is 100.00%.

Impacted file tree graph

@@             Coverage Diff              @@
##               main    #2457      +/-   ##
============================================
+ Coverage     90.39%   90.41%   +0.02%     
- Complexity     4572     4584      +12     
============================================
  Files           399      400       +1     
  Lines         11292    11324      +32     
  Branches        909      910       +1     
============================================
+ Hits          10207    10239      +32     
  Misses          808      808              
  Partials        277      277              
Impacted Files Coverage Δ Complexity Δ
.../junit/platform/launcher/core/DefaultLauncher.java 96.87% <100.00%> (+0.10%) 11.00 <1.00> (+1.00)
.../platform/launcher/core/DefaultLauncherConfig.java 100.00% <100.00%> (ø) 8.00 <1.00> (+1.00)
...orm/launcher/core/EngineDiscoveryOrchestrator.java 100.00% <100.00%> (ø) 25.00 <3.00> (+2.00)
...g/junit/platform/launcher/core/LauncherConfig.java 100.00% <100.00%> (ø) 1.00 <0.00> (ø)
...launcher/core/LauncherDiscoveryRequestBuilder.java 100.00% <100.00%> (ø) 19.00 <0.00> (ø)
.../junit/platform/launcher/core/LauncherFactory.java 100.00% <100.00%> (ø) 12.00 <2.00> (+5.00)
...erviceLoaderLauncherDiscoveryListenerRegistry.java 100.00% <100.00%> (ø) 4.00 <4.00> (?)
...g/junit/platform/testkit/engine/EngineTestKit.java 75.34% <100.00%> (ø) 17.00 <1.00> (ø)
...junit/platform/launcher/TestExecutionListener.java 85.71% <0.00%> (-14.29%) 6.00% <0.00%> (-1.00%)
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a8d08e0...95b2cad. Read the comment docs.

@marcphilipp
Copy link
Member

Tentatively slated for 5.8 M1 solely for the purpose of team discussion.

@filiphr
Copy link
Contributor Author

filiphr commented Oct 24, 2020

Just FYI doing something like this allows to have an SPI change the current thread context classloader and actually can help with #201 and #806. I needed to use a different classloader for loading the classes that are discovered and adding my own classloader before the discovery is started is one way to achieve this.

I am sure that this is not the only use case for this, and the use case I have does not really fit this, I am sure that there are other more suitable use cases for this.

Comment on lines 274 to 294
if (discoveryListeners.contains(defaultDiscoveryListener)) {
if (discoveryListeners.contains(defaultDiscoveryListener) && serviceLoaderListeners.isEmpty()) {
return LauncherDiscoveryListeners.composite(discoveryListeners);
}
List<LauncherDiscoveryListener> allDiscoveryListeners = new ArrayList<>(discoveryListeners);
allDiscoveryListeners.add(defaultDiscoveryListener);
allDiscoveryListeners.addAll(serviceLoaderListeners);
if (!allDiscoveryListeners.contains(defaultDiscoveryListener)) {
allDiscoveryListeners.add(defaultDiscoveryListener);
}
return LauncherDiscoveryListeners.composite(allDiscoveryListeners);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this optimization is necessary. Let's get rid of the first if.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure no problem, I was not entirely sure about this part as well, it didn't feel quite right anyways. I'll make a small optimisation so that the list is created with a correct size at least (to avoid resizes)

@filiphr filiphr force-pushed the launcher-discovery-auto-detection branch from 73349b8 to 0973542 Compare October 26, 2020 21:25
@marcphilipp marcphilipp self-requested a review October 27, 2020 07:07
@Frontrider
Copy link

So this would let us stuff like changing the class path for the tests?

@filiphr
Copy link
Contributor Author

filiphr commented Oct 28, 2020

I want to be really clear that the goal of this PR is not to fix the issues that need different classpath for the tests. I don't want the JUnit team to reject this PR solely on the fact of allowing users to change the classloader.

However, it indeed allows implementors of this interface to change the current thread context classloader in LauncherDiscoveryListener#LauncherDiscoveryListener. This only works when the discovery selectors are created without the class already loaded, i.e. only with the class name. JUnit Jupiter the uses this constructor to load the class for the tests.

Copy link
Member

@marcphilipp marcphilipp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Could you please add this to the user guide and release notes as well?

@filiphr
Copy link
Contributor Author

filiphr commented Oct 28, 2020

Looks good! Could you please add this to the user guide and release notes as well?

Thanks. I just pushed the update to the user guide and release notes.

One thing that I just remembered. What would you like the default flag to be set to. Currently discovering LauncherDiscoveryListener(s) is an opt-in. Users have to explicitly enable it via junit.platform.discovery.listener.autodetection.enabled

@marcphilipp
Copy link
Member

Team decision: Let's include this feature in 5.8.

Whether discovery listeners are picked up via ServiceLoader is now
configurable via `LauncherConfig` for consistency with all other APIs
potentially loaded that way. Moreover, discovery listeners are now
registered via ServiceLoader by default.
Copy link
Member

@marcphilipp marcphilipp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@filiphr I took the liberty of reworking a few parts based on your implementation. I hope you don't mind!

@filiphr
Copy link
Contributor Author

filiphr commented Dec 21, 2020

Really appreciated @marcphilipp. Thanks for the work on it.

One small comment though, I think that you missed a @since 1.8 on the isLauncherDiscoveryListenerAutoRegistrationEnabled() in the LauncherConfig. I saw that you added some missing @since 1.7 and wanted to let you know.

@marcphilipp marcphilipp force-pushed the launcher-discovery-auto-detection branch from 994d405 to 95b2cad Compare December 21, 2020 16:09
@marcphilipp
Copy link
Member

I merged this manuaally in 8b71ee6 to resolve the merge conflict. I'm glad this is now in place. Thanks for the contribution and patience, @filiphr! 👍

@filiphr
Copy link
Contributor Author

filiphr commented Dec 21, 2020

That's great news @marcphilipp. Looking forward in using this and finalising the migration to JUnit 5 in the MapStruct project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants