From 194832d3307dfe89fb87e5d20df8dadf69189aa1 Mon Sep 17 00:00:00 2001 From: Vladimir Dmitrienko Date: Mon, 22 Jul 2024 17:30:36 +0200 Subject: [PATCH] Introduce 'provideForNestedClass' method. Issue: #2677 --- .../parallel/ExclusiveResourcesProvider.java | 20 +++++++++------- ...odNameBasedExclusiveResourcesProvider.java | 4 ++-- .../descriptor/ClassBasedTestDescriptor.java | 14 +++++------ .../descriptor/JupiterTestDescriptor.java | 24 ++++++++----------- .../descriptor/MethodBasedTestDescriptor.java | 14 +++++------ .../descriptor/NestedClassTestDescriptor.java | 16 +++++++++++++ 6 files changed, 54 insertions(+), 38 deletions(-) diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/parallel/ExclusiveResourcesProvider.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/parallel/ExclusiveResourcesProvider.java index 6a3fd2c4e71f..66f3926757a2 100644 --- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/parallel/ExclusiveResourcesProvider.java +++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/parallel/ExclusiveResourcesProvider.java @@ -21,31 +21,35 @@ // Which 'status' and 'since' values should I use? @API(status = STABLE, since = "?") public interface ExclusiveResourcesProvider { - default Set provideForClass(Class testClass) { + default Set provideForClass(Class testClass) { return Collections.emptySet(); } - default Set provideForMethod(Method testMethod) { + default Set provideForNestedClass(Class testClass) { return Collections.emptySet(); } - final class ExclusiveResource { + default Set 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() { diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/parallel/MethodNameBasedExclusiveResourcesProvider.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/parallel/MethodNameBasedExclusiveResourcesProvider.java index bdfce5fe6bb0..04b946bf4afc 100644 --- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/parallel/MethodNameBasedExclusiveResourcesProvider.java +++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/parallel/MethodNameBasedExclusiveResourcesProvider.java @@ -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 provideForMethod(Method testMethod) { + public Set provideForMethod(Class unused, Method testMethod) { if (testMethod.getName().contains("give_me_lock")) { return Collections.singleton(LOCK); } diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java index 52e6a89db5e8..1cf8286511cc 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java @@ -145,13 +145,13 @@ public void setDefaultChildExecutionMode(ExecutionMode defaultChildExecutionMode @Override public Set getExclusiveResources() { // @formatter:off - Set resourcesFromAnnotation = getExclusiveResourcesFromAnnotation(getTestClass()); - Set 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 } diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/JupiterTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/JupiterTestDescriptor.java index 48968421e24b..d69cf6c94cdc 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/JupiterTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/JupiterTestDescriptor.java @@ -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; @@ -187,26 +185,24 @@ public static ExecutionMode toExecutionMode(org.junit.jupiter.api.parallel.Execu throw new JUnitException("Unknown ExecutionMode: " + mode); } - Set getExclusiveResourcesFromAnnotation(AnnotatedElement element) { + Stream 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 getExclusiveResourcesFromProvider(Class testClass, - Function> providerToResources) { + Stream getExclusiveResourcesFromProvider(Class testClass, + Function> 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 } diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/MethodBasedTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/MethodBasedTestDescriptor.java index 1fb7744a3c79..85e3dc0f7c8c 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/MethodBasedTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/MethodBasedTestDescriptor.java @@ -84,13 +84,13 @@ public final Set getTags() { @Override public Set getExclusiveResources() { // @formatter:off - Set resourcesFromAnnotation = getExclusiveResourcesFromAnnotation(getTestMethod()); - Set 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 } diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/NestedClassTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/NestedClassTestDescriptor.java index 84ce0645b7d3..9878793d7fb8 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/NestedClassTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/NestedClassTestDescriptor.java @@ -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; @@ -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; @@ -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; /** @@ -87,4 +90,17 @@ protected TestInstances instantiateTestClass(JupiterEngineExecutionContext paren return instantiateTestClass(Optional.of(outerInstances), registry, extensionContext); } + @Override + public Set getExclusiveResources() { + // @formatter:off + return Stream.concat( + getExclusiveResourcesFromAnnotation(getTestClass()), + getExclusiveResourcesFromProvider( + getTestClass(), + provider -> provider.provideForNestedClass(getTestClass()) + ) + ).collect(toSet()); + // @formatter:on + } + }