From 7542d4683862f0603f3c3aeabb5d545b736a3828 Mon Sep 17 00:00:00 2001 From: KOSEUNGBIN Date: Sun, 23 Nov 2025 18:33:07 +0900 Subject: [PATCH 1/3] Allow @ResourceLock on @ClassTemplate classes Fixes #5155 Signed-off-by: raccoonback --- ...ClassTemplateInvocationTestDescriptor.java | 8 ++++++++ .../engine/ClassTemplateInvocationTests.java | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassTemplateInvocationTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassTemplateInvocationTestDescriptor.java index 9d3037b6059b..afa3e639daac 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassTemplateInvocationTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassTemplateInvocationTestDescriptor.java @@ -10,6 +10,7 @@ package org.junit.jupiter.engine.descriptor; +import static java.util.Collections.emptySet; import static java.util.Objects.requireNonNull; import static org.apiguardian.api.API.Status.INTERNAL; import static org.junit.jupiter.engine.descriptor.CallbackSupport.invokeAfterCallbacks; @@ -36,6 +37,7 @@ import org.junit.jupiter.engine.extension.MutableExtensionRegistry; import org.junit.platform.engine.TestSource; import org.junit.platform.engine.UniqueId; +import org.junit.platform.engine.support.hierarchical.ExclusiveResource; import org.junit.platform.engine.support.hierarchical.ThrowableCollector; /** @@ -112,6 +114,12 @@ public Function> getResou // --- Node ---------------------------------------------------------------- + @Override + public Set getExclusiveResources() { + // Resources are already collected and returned by the enclosing ClassTemplateTestDescriptor + return emptySet(); + } + @Override public JupiterEngineExecutionContext prepare(JupiterEngineExecutionContext context) { MutableExtensionRegistry registry = context.getExtensionRegistry(); diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java index 8be2bab63816..50c6e8ab3d6c 100644 --- a/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java +++ b/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java @@ -79,6 +79,7 @@ import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.parallel.ResourceLock; import org.junit.jupiter.engine.descriptor.ClassTemplateInvocationTestDescriptor; import org.junit.jupiter.engine.descriptor.ClassTemplateTestDescriptor; import org.junit.jupiter.engine.descriptor.ClassTestDescriptor; @@ -1004,6 +1005,14 @@ void ignoresComposedAnnotations() { assertThat(engineDescriptor.getDescendants()).isEmpty(); } + @Test + void classTemplateWithResourceLockExecutesSuccessfully() { + var results = executeTestsForClass(ClassTemplateWithResourceLockTestCase.class); + + results.testEvents().assertStatistics(stats -> stats.started(2).succeeded(2)); + results.containerEvents().assertStatistics(stats -> stats.started(4).succeeded(4)); + } + // ------------------------------------------------------------------- private static Stream allReportEntryValues(EngineExecutionResults results) { @@ -1567,4 +1576,15 @@ void test() { } } + @SuppressWarnings("JUnitMalformedDeclaration") + @ClassTemplate + @ExtendWith(TwoInvocationsClassTemplateInvocationContextProvider.class) + @ResourceLock("test-resource") + static class ClassTemplateWithResourceLockTestCase { + @Test + void test() { + // This test verifies that @ResourceLock works with @ClassTemplate (issue #5155) + } + } + } From ea7cfc883b23d115dd83e9c6e4afa754ff9966b2 Mon Sep 17 00:00:00 2001 From: KOSEUNGBIN Date: Mon, 1 Dec 2025 09:34:15 +0900 Subject: [PATCH 2/3] Add test for @ResourceLock exclusive resource collection Signed-off-by: raccoonback --- .../jupiter/engine/ClassTemplateInvocationTests.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java index 50c6e8ab3d6c..c0f04016515c 100644 --- a/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java +++ b/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java @@ -96,6 +96,7 @@ import org.junit.platform.engine.UniqueId; import org.junit.platform.engine.discovery.DiscoverySelectors; import org.junit.platform.engine.reporting.ReportEntry; +import org.junit.platform.engine.support.hierarchical.ExclusiveResource; import org.junit.platform.testkit.engine.EngineExecutionResults; import org.opentest4j.AssertionFailedError; import org.opentest4j.TestAbortedException; @@ -1005,6 +1006,16 @@ void ignoresComposedAnnotations() { assertThat(engineDescriptor.getDescendants()).isEmpty(); } + @Test + void classTemplateWithResourceLockCollectsExclusiveResources() { + var results = discoverTestsForClass(ClassTemplateWithResourceLockTestCase.class); + var classTemplateDescriptor = (ClassTemplateTestDescriptor) getOnlyElement( + results.getEngineDescriptor().getChildren()); + + assertThat(classTemplateDescriptor.getExclusiveResources()).extracting( + ExclusiveResource::getKey).containsExactly("test-resource"); + } + @Test void classTemplateWithResourceLockExecutesSuccessfully() { var results = executeTestsForClass(ClassTemplateWithResourceLockTestCase.class); From 52b6a09a505cb3c236944ad5088b17138b27f5cf Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sun, 7 Dec 2025 14:24:34 +0100 Subject: [PATCH 3/3] Add entry to release notes --- .../src/docs/asciidoc/release-notes/release-notes-6.0.2.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.2.adoc b/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.2.adoc index a0ba07732b62..382420cc04bc 100644 --- a/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.2.adoc +++ b/documentation/src/docs/asciidoc/release-notes/release-notes-6.0.2.adoc @@ -35,7 +35,8 @@ repository on GitHub. [[release-notes-6.0.2-junit-jupiter-bug-fixes]] ==== Bug Fixes -* ❓ +* Allow using `@ResourceLock` on classes annotated with `@ClassTemplate` (or + `@ParameterizedClass`). [[release-notes-6.0.2-junit-jupiter-deprecations-and-breaking-changes]] ==== Deprecations and Breaking Changes