Skip to content

Commit f6cfa55

Browse files
committed
Add declarative JRE gating for JUnit 4 tests
Introduces @EnabledForJreRange plus a small JreConditionRule so JUnit 4 tests can declare a JRE feature-version range at the method level, mirroring the semantics of JUnit Jupiter's EnabledForJreRange. The rule reads the annotation from the test description and throws AssumptionViolatedException when the current JRE is outside the range, so Surefire reports out-of-range methods as skipped. Migrates VirtualThreadHelperTest off imperative Assume.assumeTrue / Assume.assumeFalse calls: Java 21+ cases use @EnabledForJreRange(min=21), the UnsupportedOperationException cases use @EnabledForJreRange(max=20).
1 parent d4a9e67 commit f6cfa55

3 files changed

Lines changed: 99 additions & 18 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.openejb.junit.jre;
18+
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
/**
25+
* Enables a JUnit 4 test method only when the running JRE feature version falls in
26+
* {@code [min, max]}. Mirrors {@code org.junit.jupiter.api.condition.EnabledForJreRange}
27+
* for codebases that cannot depend on JUnit Jupiter. Tests outside the range are skipped
28+
* via {@code Assume} semantics (surefire reports them as skipped).
29+
*
30+
* <p>Must be combined with {@link JreConditionRule} as a {@code @Rule}.
31+
*/
32+
@Retention(RetentionPolicy.RUNTIME)
33+
@Target(ElementType.METHOD)
34+
public @interface EnabledForJreRange {
35+
int min() default 0;
36+
int max() default Integer.MAX_VALUE;
37+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.openejb.junit.jre;
18+
19+
import org.junit.AssumptionViolatedException;
20+
import org.junit.rules.TestRule;
21+
import org.junit.runner.Description;
22+
import org.junit.runners.model.Statement;
23+
24+
/**
25+
* JUnit 4 rule that skips a test method when the running JRE feature version is
26+
* outside the range declared by {@link EnabledForJreRange} on the method. Skipping is
27+
* implemented by throwing {@link AssumptionViolatedException}, matching surefire's
28+
* "skipped" category.
29+
*/
30+
public final class JreConditionRule implements TestRule {
31+
32+
@Override
33+
public Statement apply(final Statement base, final Description description) {
34+
final EnabledForJreRange range = description.getAnnotation(EnabledForJreRange.class);
35+
if (range == null) {
36+
return base;
37+
}
38+
39+
final int current = Runtime.version().feature();
40+
if (current < range.min() || current > range.max()) {
41+
return new Statement() {
42+
@Override
43+
public void evaluate() {
44+
throw new AssumptionViolatedException(
45+
"Requires Java " + range.min() + ".." + range.max()
46+
+ ", running on " + current);
47+
}
48+
};
49+
}
50+
return base;
51+
}
52+
}

container/openejb-core/src/test/java/org/apache/openejb/threads/impl/VirtualThreadHelperTest.java

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
*/
1717
package org.apache.openejb.threads.impl;
1818

19-
import org.junit.Assume;
19+
import org.apache.openejb.junit.jre.EnabledForJreRange;
20+
import org.apache.openejb.junit.jre.JreConditionRule;
21+
import org.junit.Rule;
2022
import org.junit.Test;
2123

2224
import java.util.concurrent.CountDownLatch;
@@ -31,18 +33,12 @@
3133

3234
public class VirtualThreadHelperTest {
3335

34-
@Test
35-
public void isSupportedReturnsConsistentValue() {
36-
// Just verify it doesn't throw — result depends on JVM version
37-
final boolean supported = VirtualThreadHelper.isSupported();
38-
// On Java 21+ should be true, on 17 false
39-
assertNotNull("isSupported should return a value", Boolean.valueOf(supported));
40-
}
36+
@Rule
37+
public final JreConditionRule jreCondition = new JreConditionRule();
4138

4239
@Test
40+
@EnabledForJreRange(min = 21)
4341
public void newVirtualThreadCreatesThread() {
44-
Assume.assumeTrue("Virtual threads require Java 21+", VirtualThreadHelper.isSupported());
45-
4642
final CountDownLatch latch = new CountDownLatch(1);
4743
final Thread thread = VirtualThreadHelper.newVirtualThread("test-vt-", 1, latch::countDown);
4844

@@ -59,9 +55,8 @@ public void newVirtualThreadCreatesThread() {
5955
}
6056

6157
@Test
58+
@EnabledForJreRange(min = 21)
6259
public void newVirtualThreadFactoryCreatesThreads() {
63-
Assume.assumeTrue("Virtual threads require Java 21+", VirtualThreadHelper.isSupported());
64-
6560
final ThreadFactory factory = VirtualThreadHelper.newVirtualThreadFactory("test-vtf-");
6661
assertNotNull(factory);
6762

@@ -79,9 +74,8 @@ public void newVirtualThreadFactoryCreatesThreads() {
7974
}
8075

8176
@Test
77+
@EnabledForJreRange(min = 21)
8278
public void newVirtualThreadPerTaskExecutorWorks() {
83-
Assume.assumeTrue("Virtual threads require Java 21+", VirtualThreadHelper.isSupported());
84-
8579
final ThreadFactory factory = VirtualThreadHelper.newVirtualThreadFactory("test-vtpe-");
8680
final ExecutorService executor = VirtualThreadHelper.newVirtualThreadPerTaskExecutor(factory);
8781
assertNotNull(executor);
@@ -102,16 +96,14 @@ public void newVirtualThreadPerTaskExecutorWorks() {
10296
}
10397

10498
@Test(expected = UnsupportedOperationException.class)
99+
@EnabledForJreRange(max = 20)
105100
public void newVirtualThreadThrowsOnUnsupported() {
106-
Assume.assumeFalse("Only run on Java < 21", VirtualThreadHelper.isSupported());
107-
108101
VirtualThreadHelper.newVirtualThread("test-", 1, () -> {});
109102
}
110103

111104
@Test(expected = UnsupportedOperationException.class)
105+
@EnabledForJreRange(max = 20)
112106
public void newVirtualThreadFactoryThrowsOnUnsupported() {
113-
Assume.assumeFalse("Only run on Java < 21", VirtualThreadHelper.isSupported());
114-
115107
VirtualThreadHelper.newVirtualThreadFactory("test-");
116108
}
117109
}

0 commit comments

Comments
 (0)