-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Support scanning for classpath resources #3705
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
Support scanning for classpath resources #3705
Conversation
junit-platform-commons/src/main/java/org/junit/platform/commons/util/ResourceFileVisitor.java
Outdated
Show resolved
Hide resolved
junit-platform-commons/src/main/java/org/junit/platform/commons/support/Resource.java
Show resolved
Hide resolved
junit-platform-commons/src/main/java9/org/junit/platform/commons/util/ModuleUtils.java
Outdated
Show resolved
Hide resolved
platform-tests/src/test/java/org/junit/platform/commons/util/ClasspathScannerTests.java
Show resolved
Hide resolved
junit-platform-commons/src/main/java/org/junit/platform/commons/util/ClasspathFilters.java
Show resolved
Hide resolved
As a follow up for junit-team#3630 and junit-team#3705 this adds a `addResourceContainerSelectorResolver()` method to `EngineDiscoveryRequestResolver.Builder` analogous to `addClassContainerSelectorResolver()`. Points of note: * As classpath resources can be selected from packages, the package filter should also be applied. To make this possible the base path of a resource is rewritten to a package name prior to being filtered. * The `ClasspathResourceSelector` now has a `getClasspathResource` method. This method will lazily try to load the resource if not was not already provided when discovering resources in a container. * `selectClasspathResource(Resource)` was added to short circuit the need to resolve resources twice. And to make it possible to use this method as part of the public API, `ReflectionSupport.tryToLoadResource` was also added.
Thanks for the PR, @mpkorstanje! 👍 We'll try to find some time to properly review it in the coming weeks (months?). |
Cheers! No problem. |
That's my bad (again). Rebasing should fix it. |
Cheers! Might be good to document the switches for coverage and predictive test selection in the |
Done in c8beae0. Do you think that's clear enough? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I briefly discussed this PR with the team. We think restricting the resources to remove "duplicates" is too limiting. Instead, a filter that checks that Resource.getUri()
equals ClassLoader.getResource
could be used with a default implementation provided as a static method in ResourceFilter
. WDYT?
Yes. Though I now seem to have some problems generating the coverage report at all now. I'll have to look into this later.
Seems reasonable. I'll have a look at the plumbing. |
@mpkorstanje Do you have time to continue working on this? We'd like to include it in the 5.11 RC1 which is ~3 weeks from now. |
I've pushed the plumbing changes. I'm mostly stuck on #3718. I think there are some subtleties that could maybe propagate backwards into this PR. But I suppose we can keep evolving the API as needed. So we can consider this done. |
Agreed. Let's finish this one and then focus on #3718. I can also take a more active role there if you don't have the time. |
That would be appreciated! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mpkorstanje Do you think it would make sense to add a Predicate<Resource>
as a constant that allows filtering out duplicates?
Predicate<Resource> DEFAULT_RESOURCE = resource -> {
try {
URL defaultResourceUrl = ClassLoaderUtils.getDefaultClassLoader().getResource(resource.getName());
return defaultResourceUrl != null && resource.getUri().equals(defaultResourceUrl.toURI());
}
catch (URISyntaxException e) {
throw new JUnitException("Failed to convert URL of resource to URI", e);
}
};
Not in this iteration I'd think. You're about to go down the same rabbit hole I spend a week in. 😉 A predicate would not work. It would not remove duplicates, but rather remove all shadowed resources. Instead you would need a function that transform a resources into a "canonical" version of the resource. Then you can de-duplicate the canonical resources. In #3718 I wrote a few functions to just that, a good starting point would be the You could probably cherry pick those in. |
Thanks for writing that up! I'll reply on the other PR.
Isn't that what you were after? Wouldn't it only allow canonical resources to pass the predicate? |
That depends. When discovering a class in classpath root a, we currently load a class from classpath root b, if b shadows a. Do we want the same behaviour for resources? If so we need a function, if not, then a predicate will do. |
I see what you mean now... 🤔 I'm pondering whether it makes sense to include this PR in 5.11 without #3718 and, if so, when we would ship the latter. WDYT? |
I think it would make sense to ship this PR as it would unlock #3628. That was the original motivation for splitting these PRs. |
@mpkorstanje Thanks for all your hard work! 👍 |
As a follow up for #3630 and #3705 this adds a `addResourceContainerSelectorResolver()` method to `EngineDiscoveryRequestResolver.Builder` analogous to `addClassContainerSelectorResolver()`. Points of note: * As classpath resources can be selected from packages, the package filter should also be applied. To make this possible the base path of a resource is rewritten to a package name prior to being filtered. * The `ClasspathResourceSelector` now has a `getClasspathResources` method. This method will lazily try to load the resources if not already provided when discovering resources in a container. * `selectClasspathResource(Resource)` was added to short circuit the need to resolve resources twice. And to make it possible to use this method as part of the public API, `ReflectionSupport.tryToLoadResource` was also added. --------- Co-authored-by: Marc Philipp <[email protected]>
Overview
Adds several new methods to
ReflectionSupport
to find or stream resource objects in the classpath root, package, and modules.A resource is represented as:
Fixes: #3630
I hereby agree to the terms of the JUnit Contributor License Agreement.
Definition of Done
@API
annotations