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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduced @ResourceLock(target = SELF | CHILDREN) #3220

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

anatolyD
Copy link

@anatolyD anatolyD commented Apr 1, 2023

Defaults to SELF to preserve existing behavior.
Using CHILDREN has the same effect as declaring @ResourceLock on every @test method of a test class.

Issue: #3102

Overview

Introduced @ResourceLock(target = SELF | CHILDREN) where the target defaults to SELF to preserve existing behavior. Using CHILDREN has the same effect as declaring @ResourceLock on every @Test method of a test class.

I've added a couple of integration tests to verify it works, plus one for NodeWalker. Happy to hear the feedback. 馃槃


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


Definition of Done

Defaults to SELF to preserve existing behavior.
Using CHILDREN has the same effect as declaring @ResourceLock on every @test method of a test class.

Issue: junit-team#3102
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.

Sorry for the delay! This looks very useful. 馃檪

import org.apiguardian.api.API;

/**
* Indicates the target of a {@link ResourceLock}.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Indicates the target of a {@link ResourceLock}.
* Indicates the target of a {@link ResourceLock}.

@@ -40,6 +40,9 @@
* <p>Since JUnit Jupiter 5.4, this annotation is {@linkplain Inherited inherited}
* within class hierarchies.
*
* <p>Since JUnit Jupiter 5.10, this annotation can be used to specify the target
* of the lock with {@link ResourceLockTarget}.
*
Copy link
Member

Choose a reason for hiding this comment

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

What happens if a class has a @ResourceLock annotation with target CHILDREN and a method has one for the same resource? Does the one from the method override the one from the class? This should be documented here.

* @param lockScope the lock scope to use to synchronize access to the
* resource; never {@code null}
*/
public ExclusiveResource(String key, LockMode lockMode, LockScope lockScope) {
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 should be a Platform concept. Instead, Jupiter should return ExclusiveResource instances from the children TestDescriptors if their parent declares a @ResourceLock with target of CHILDREN.

Copy link
Author

Choose a reason for hiding this comment

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

sounds good, no need to bother Platform with those details :) I drafted how it may look in https://github.com/junit-team/junit5/pull/3220/files#diff-63a01db8dd78b02e05c3888eb786c656af0cd3dc8263c816530003f2d7069daeR188

Set<ExclusiveResource> resources = mapResourceLocksForTarget(getResourceLocks(), ResourceLockTarget.SELF);

Optional<TestDescriptor> nextParent = getParent();
while (nextParent.isPresent()) {
Copy link
Member

Choose a reason for hiding this comment

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

IIUC @ResourceLock(target = CHILDREN) should only cause them to be applied to direct children.

Choose a reason for hiding this comment

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

IIUC @ResourceLock(target = CHILDREN) should only cause them to be applied to direct children.

Is there any reason for this? Is it harmful in someway for it to not be just direct children? e.g. in our project our tests inherit from base classes scattered throughout our packages and those base classes tend to inherit from a single source parent. If I have a resource that I want read locked for everything (main server component for example) it makes more sense to me to have the lock specified in one place instead of having to remember to add it to all the base classes

Copy link
Member

Choose a reason for hiding this comment

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

@Squibbles This is unrelated to inheritance in class hierarchies. The @ResourceLock annotation is inherited to subclasses already. However, the way resource locks are applied is that if a node acquires a lock, its children already hold it while being executed. Therefore it doesn't make sense to recursively declare it for all descendants.

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.

I think we also need to think about the case where @ResourceLock(target = CHILDREN) is applied to methods. I think for @Test this should cause a failure. For test templates such as @ParameterizedTest and @RepeatedTest the invocations should get the ExclusiveResource (might already work with the code in this PR but we're missing a test). For @TestFactory methods, the direct DynamicNodeTestDescriptor children should get the ExclusiveResource.

@marcphilipp
Copy link
Member

@anatolyD Do you have time to continue working on this PR or should someone from the JUnit team take over?

@anatolyD
Copy link
Author

@anatolyD Do you have time to continue working on this PR or should someone from the JUnit team take over?

Hey, yes I would love to continue, but if time is a pressuring matter you may want to take it over. I plan to get to it within a week or two

@marcphilipp
Copy link
Member

marcphilipp commented Jun 7, 2023

I don't think it's urgent, so that's fine. 馃憤

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

Successfully merging this pull request may close these issues.

Add a way to inherit ResourceLocks that allows for more parallel execution of tests
3 participants