Skip to content

Commit

Permalink
Introduce 'provideForNestedClass' method.
Browse files Browse the repository at this point in the history
Issue: #2677
  • Loading branch information
Vladimir Dmitrienko committed Jul 22, 2024
1 parent b703172 commit 194832d
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,35 @@
// Which 'status' and 'since' values should I use?
@API(status = STABLE, since = "?")
public interface ExclusiveResourcesProvider {
default Set<ExclusiveResource> provideForClass(Class<?> testClass) {
default Set<Resource> provideForClass(Class<?> testClass) {
return Collections.emptySet();
}

default Set<ExclusiveResource> provideForMethod(Method testMethod) {
default Set<Resource> provideForNestedClass(Class<?> testClass) {
return Collections.emptySet();
}

final class ExclusiveResource {
default Set<Resource> provideForMethod(Class<?> testClass, Method testMethod) {
return Collections.emptySet();
}

final class Resource {

private final String key;

private final ResourceAccessMode accessMode;

public ExclusiveResource(String key, ResourceAccessMode accessMode) {
public Resource(String key, ResourceAccessMode accessMode) {
this.key = key;
this.accessMode = accessMode;
}

public static ExclusiveResource readLockOf(String key) {
return new ExclusiveResource(key, ResourceAccessMode.READ);
public static Resource readLockOf(String key) {
return new Resource(key, ResourceAccessMode.READ);
}

public static ExclusiveResource readWriteLockOf(String key) {
return new ExclusiveResource(key, ResourceAccessMode.READ_WRITE);
public static Resource readWriteLockOf(String key) {
return new Resource(key, ResourceAccessMode.READ_WRITE);
}

public String getKey() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
@API(status = STABLE, since = "?")
public final class MethodNameBasedExclusiveResourcesProvider implements ExclusiveResourcesProvider {

private static final ExclusiveResource LOCK = ExclusiveResource.readWriteLockOf("method_lock");
private static final Resource LOCK = Resource.readWriteLockOf("method_lock");

public MethodNameBasedExclusiveResourcesProvider() {
}

@Override
public Set<ExclusiveResource> provideForMethod(Method testMethod) {
public Set<Resource> provideForMethod(Class<?> unused, Method testMethod) {
if (testMethod.getName().contains("give_me_lock")) {
return Collections.singleton(LOCK);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,13 @@ public void setDefaultChildExecutionMode(ExecutionMode defaultChildExecutionMode
@Override
public Set<ExclusiveResource> getExclusiveResources() {
// @formatter:off
Set<ExclusiveResource> resourcesFromAnnotation = getExclusiveResourcesFromAnnotation(getTestClass());
Set<ExclusiveResource> resourcesFromProvider = getExclusiveResourcesFromProvider(
getTestClass(),
provider -> provider.provideForClass(getTestClass())
);

return Stream.concat(resourcesFromAnnotation.stream(), resourcesFromProvider.stream()).collect(toSet());
return Stream.concat(
getExclusiveResourcesFromAnnotation(getTestClass()),
getExclusiveResourcesFromProvider(
getTestClass(),
provider -> provider.provideForClass(getTestClass())
)
).collect(toSet());
// @formatter:on
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@

package org.junit.jupiter.engine.descriptor;

import static java.util.Collections.emptySet;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toSet;
import static org.apiguardian.api.API.Status.INTERNAL;
import static org.junit.jupiter.engine.descriptor.DisplayNameUtils.determineDisplayName;
import static org.junit.platform.commons.util.AnnotationUtils.findAnnotation;
Expand Down Expand Up @@ -187,26 +185,24 @@ public static ExecutionMode toExecutionMode(org.junit.jupiter.api.parallel.Execu
throw new JUnitException("Unknown ExecutionMode: " + mode);
}

Set<ExclusiveResource> getExclusiveResourcesFromAnnotation(AnnotatedElement element) {
Stream<ExclusiveResource> getExclusiveResourcesFromAnnotation(AnnotatedElement element) {
// @formatter:off
return findRepeatableAnnotations(element, ResourceLock.class).stream()
.map(resource -> new ExclusiveResource(resource.value(), toLockMode(resource.mode())))
.collect(toSet());
.map(resource -> new ExclusiveResource(resource.value(), toLockMode(resource.mode())));
// @formatter:on
}

@SuppressWarnings("Convert2MethodRef")
Set<ExclusiveResource> getExclusiveResourcesFromProvider(Class<?> testClass,
Function<ExclusiveResourcesProvider, Set<ExclusiveResourcesProvider.ExclusiveResource>> providerToResources) {
Stream<ExclusiveResource> getExclusiveResourcesFromProvider(Class<?> testClass,
Function<ExclusiveResourcesProvider, Set<ExclusiveResourcesProvider.Resource>> providerToResources) {
// @formatter:off
return findAnnotation(testClass, ExclusiveResources.class)
.map(annotation -> Stream.of(annotation.value())
.map(providerClass -> ReflectionUtils.newInstance(providerClass))
.map(providerToResources)
.flatMap(Collection::stream)
.map(resource -> new ExclusiveResource(resource.getKey(), toLockMode(resource.getAccessMode())))
.collect(toSet()))
.orElse(emptySet());
.map(annotation -> Stream.of(annotation.value()))
.orElseGet(Stream::empty)
.map(providerClass -> ReflectionUtils.newInstance(providerClass))
.map(providerToResources)
.flatMap(Collection::stream)
.map(resource -> new ExclusiveResource(resource.getKey(), toLockMode(resource.getAccessMode())));
// @formatter:on
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ public final Set<TestTag> getTags() {
@Override
public Set<ExclusiveResource> getExclusiveResources() {
// @formatter:off
Set<ExclusiveResource> resourcesFromAnnotation = getExclusiveResourcesFromAnnotation(getTestMethod());
Set<ExclusiveResource> resourcesFromProvider = getExclusiveResourcesFromProvider(
getTestClass(),
provider -> provider.provideForMethod(getTestMethod())
);

return Stream.concat(resourcesFromAnnotation.stream(), resourcesFromProvider.stream()).collect(toSet());
return Stream.concat(
getExclusiveResourcesFromAnnotation(getTestMethod()),
getExclusiveResourcesFromProvider(
getTestClass(),
provider -> provider.provideForMethod(getTestClass(), getTestMethod())
)
).collect(toSet());
// @formatter:on
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package org.junit.jupiter.engine.descriptor;

import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toSet;
import static org.apiguardian.api.API.Status.INTERNAL;
import static org.junit.jupiter.engine.descriptor.DisplayNameUtils.createDisplayNameSupplierForNestedClass;

Expand All @@ -19,6 +20,7 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

import org.apiguardian.api.API;
import org.junit.jupiter.api.extension.ExtensionContext;
Expand All @@ -30,6 +32,7 @@
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.TestTag;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.engine.support.hierarchical.ExclusiveResource;
import org.junit.platform.engine.support.hierarchical.ThrowableCollector;

/**
Expand Down Expand Up @@ -87,4 +90,17 @@ protected TestInstances instantiateTestClass(JupiterEngineExecutionContext paren
return instantiateTestClass(Optional.of(outerInstances), registry, extensionContext);
}

@Override
public Set<ExclusiveResource> getExclusiveResources() {
// @formatter:off
return Stream.concat(
getExclusiveResourcesFromAnnotation(getTestClass()),
getExclusiveResourcesFromProvider(
getTestClass(),
provider -> provider.provideForNestedClass(getTestClass())
)
).collect(toSet());
// @formatter:on
}

}

0 comments on commit 194832d

Please sign in to comment.