Skip to content

Commit d834468

Browse files
committed
Implement fail-fast behavior for JUnit Platform provider
1 parent 12d4155 commit d834468

File tree

23 files changed

+531
-154
lines changed

23 files changed

+531
-154
lines changed

maven-surefire-plugin/src/site/apt/examples/skip-after-failure.apt.vm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ Skipping Tests After the Nth Failure or Error
4141

4242
Prerequisite
4343

44-
Use ${project.artifactId} 2.19 or higher, JUnit 4.0 or higher, or
45-
TestNG 5.10 or higher.
44+
Use ${project.artifactId} 2.19 or higher, JUnit 4.0 or higher, TestNG 5.10 or
45+
higher, or JUnit Platform 6.0 or higher.
4646

4747
If version of TestNG is lower than 5.10 while the parameter
4848
<<<skipAfterFailureCount>>> is set, the plugin fails with error:
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,24 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.maven.surefire.testng.utils;
20-
21-
import org.apache.maven.surefire.api.report.RunListener;
19+
package org.apache.maven.surefire.api.report;
2220

2321
/**
2422
* Covers configuration parameter {@code skipAfterFailureCount}.
2523
*
2624
* @author <a href="mailto:[email protected]">Tibor Digana (tibor17)</a>
2725
* @since 2.19
2826
*/
27+
@FunctionalInterface
2928
public interface Stoppable {
29+
30+
/**
31+
* Null object for use when fail-fast behavior is disabled.
32+
*/
33+
Stoppable NOOP = () -> {
34+
// do nothing
35+
};
36+
3037
/**
3138
* Delegates this call to {@link RunListener#testExecutionSkippedByUser()}.
3239
*/

surefire-its/src/test/java/org/apache/maven/surefire/its/AbstractFailFastIT.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,14 @@ static Map<String, String> props(int forkCount, int skipAfterFailureCount, boole
110110
@Test
111111
public void test() throws Exception {
112112
String cls = useProcessPipes ? LEGACY_FORK_NODE : SUREFIRE_FORK_NODE;
113-
prepare(description, profile, properties)
113+
OutputValidator validator = prepare(description, profile, properties);
114+
validator
114115
.assertTestSuiteResults(total, errors, failures, skipped)
115116
.assertThatLogLine(containsString("Found implementation of fork node factory: " + cls), equalTo(1));
117+
performExtraChecks(validator);
118+
}
119+
120+
protected void performExtraChecks(OutputValidator validator) throws Exception {
121+
// may be overriden in subclasses
116122
}
117123
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.surefire.its;
20+
21+
import java.util.Arrays;
22+
import java.util.Map;
23+
24+
import org.apache.maven.surefire.its.fixture.OutputValidator;
25+
import org.junit.Test;
26+
import org.junit.runners.Parameterized.Parameters;
27+
28+
import static java.lang.Integer.parseInt;
29+
import static org.apache.maven.surefire.its.fixture.HelperAssertions.assumeJavaVersion;
30+
import static org.hamcrest.Matchers.containsString;
31+
import static org.hamcrest.Matchers.equalTo;
32+
33+
public class FailFastJUnitPlatformIT extends AbstractFailFastIT {
34+
35+
@Parameters(name = "{0}")
36+
public static Iterable<Object[]> data() {
37+
// description profile forkCount,
38+
// | | | fail-fast-count,
39+
// | | | | reuseForks
40+
// | | | | | total
41+
// | | | | | | failures
42+
// | | | | | | | errors
43+
// | | | | | | | | skipped
44+
// | | | | | | | | | pipes
45+
return Arrays.asList( // | | | | | | | | |
46+
new Object[] {"oneFork-ff1", null, props(1, 1, true), 5, 0, 1, 4, true},
47+
new Object[] {"oneFork-ff2", null, props(1, 2, true), 5, 0, 2, 3, true},
48+
new Object[] {"twoForks-ff1", null, props(2, 1, true), 5, 0, 2, 3, true},
49+
new Object[] {"twoForks-ff2", null, props(2, 2, true), 5, 0, 2, 2, true},
50+
new Object[] {"oneFork-ff3", null, props(1, 3, true), 5, 0, 2, 0, true},
51+
new Object[] {"twoForks-ff3", null, props(2, 3, true), 5, 0, 2, 0, true},
52+
new Object[] {
53+
"unsupported-version", null, withUnsupportedJUnitVersion(props(2, 1, true)), 5, 0, 2, 0, true
54+
});
55+
}
56+
57+
private static Map<String, String> withUnsupportedJUnitVersion(Map<String, String> props) {
58+
props.put("junit.version", "5.13.3");
59+
return props;
60+
}
61+
62+
@Override
63+
protected String withProvider() {
64+
return "junit-platform";
65+
}
66+
67+
@Override
68+
@Test
69+
public void test() throws Exception {
70+
if (!"unsupported-version".equals(description)) {
71+
// JUnit 6.0.0 requires Java 17+
72+
assumeJavaVersion(17);
73+
}
74+
super.test();
75+
}
76+
77+
@Override
78+
protected void performExtraChecks(OutputValidator validator) throws Exception {
79+
if ("unsupported-version".equals(description)) {
80+
int forkCount = parseInt(properties.get("forkCount"));
81+
validator.assertThatLogLine(
82+
containsString("An attempt was made to cancel the current test run"), equalTo(forkCount));
83+
}
84+
}
85+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one
4+
~ or more contributor license agreements. See the NOTICE file
5+
~ distributed with this work for additional information
6+
~ regarding copyright ownership. The ASF licenses this file
7+
~ to you under the Apache License, Version 2.0 (the
8+
~ "License"); you may not use this file except in compliance
9+
~ with the License. You may obtain a copy of the License at
10+
~
11+
~ http://www.apache.org/licenses/LICENSE-2.0
12+
~
13+
~ Unless required by applicable law or agreed to in writing,
14+
~ software distributed under the License is distributed on an
15+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
~ KIND, either express or implied. See the License for the
17+
~ specific language governing permissions and limitations
18+
~ under the License.
19+
-->
20+
21+
<project xmlns="http://maven.apache.org/POM/4.0.0"
22+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
23+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
24+
<modelVersion>4.0.0</modelVersion>
25+
26+
<groupId>org.apache.maven.plugins.surefire</groupId>
27+
<artifactId>fail-fast-junit-platform</artifactId>
28+
<version>1.0</version>
29+
30+
<properties>
31+
<maven.compiler.release>${java.specification.version}</maven.compiler.release>
32+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
33+
<junit.version>6.0.0-M2</junit.version>
34+
</properties>
35+
36+
<dependencies>
37+
<dependency>
38+
<groupId>org.junit.jupiter</groupId>
39+
<artifactId>junit-jupiter-api</artifactId>
40+
<version>${junit.version}</version>
41+
<scope>test</scope>
42+
</dependency>
43+
</dependencies>
44+
<build>
45+
<plugins>
46+
<plugin>
47+
<groupId>org.apache.maven.plugins</groupId>
48+
<artifactId>maven-surefire-plugin</artifactId>
49+
<version>${surefire.version}</version>
50+
<configuration>
51+
<runOrder>alphabetical</runOrder>
52+
</configuration>
53+
</plugin>
54+
<plugin>
55+
<groupId>org.apache.maven.plugins</groupId>
56+
<artifactId>maven-compiler-plugin</artifactId>
57+
<version>3.14.0</version>
58+
</plugin>
59+
</plugins>
60+
</build>
61+
62+
</project>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package pkg;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
6+
7+
class ATest {
8+
@Test
9+
void test() throws Exception {
10+
MILLISECONDS.sleep(1_000);
11+
throw new RuntimeException();
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package pkg;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
6+
7+
class BTest {
8+
@Test
9+
void test() throws Exception {
10+
MILLISECONDS.sleep(2_000);
11+
throw new RuntimeException();
12+
}
13+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package pkg;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
6+
7+
class CTest {
8+
@Test
9+
void test() throws Exception {
10+
MILLISECONDS.sleep(2_000);
11+
}
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package pkg;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
6+
7+
class DTest {
8+
@Test
9+
void test() {
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package pkg;
2+
3+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
class ETest {
8+
@Test
9+
void test() {
10+
}
11+
}

0 commit comments

Comments
 (0)