Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

junit5: Add support for --test_runner_fail_fast #221

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.engine.Constants;
import org.junit.platform.engine.DiscoverySelector;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.Launcher;
Expand All @@ -44,10 +45,11 @@ public boolean run(String testClassName) {

try (BazelJUnitOutputListener bazelJUnitXml = new BazelJUnitOutputListener(xmlOut)) {
CommandLineSummary summary = new CommandLineSummary();
FailFastExtension failFastExtension = new FailFastExtension();

LauncherConfig config =
LauncherConfig.builder()
.addTestExecutionListeners(bazelJUnitXml, summary)
.addTestExecutionListeners(bazelJUnitXml, summary, failFastExtension)
.addPostDiscoveryFilters(TestSharding.makeShardFilter())
.build();

Expand All @@ -74,7 +76,9 @@ public boolean run(String testClassName) {
LauncherDiscoveryRequestBuilder.request()
.selectors(classSelectors)
.configurationParameter(LauncherConstants.CAPTURE_STDERR_PROPERTY_NAME, "true")
.configurationParameter(LauncherConstants.CAPTURE_STDOUT_PROPERTY_NAME, "true");
.configurationParameter(LauncherConstants.CAPTURE_STDOUT_PROPERTY_NAME, "true")
.configurationParameter(
Constants.EXTENSIONS_AUTODETECTION_ENABLED_PROPERTY_NAME, "true");

String filter = System.getenv("TESTBRIDGE_TEST_ONLY");
request.filters(new PatternFilter(filter));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,18 @@ java_library(
"--release",
"8",
],
resource_strip_prefix = package_name(),
resources = ["META-INF/services/org.junit.jupiter.api.extension.Extension"],
deps = [
":system-exit-toggle",
# The only dependencies here are those required to run
# a junit5 test. We try not to pollute the classpath, so
# be very careful when adding new deps here.
#
# junit-jupiter-api is only a compilation dependency and not listed in JUNIT5_DEPS. This is
illicitonion marked this conversation as resolved.
Show resolved Hide resolved
# fine as it is a transitive dependency of junit-jupiter-engine and will thus be available
# at runtime.
artifact("org.junit.jupiter:junit-jupiter-api"),
artifact("org.junit.jupiter:junit-jupiter-engine"),
artifact("org.junit.platform:junit-platform-commons"),
artifact("org.junit.platform:junit-platform-engine"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.github.bazel_contrib.contrib_rules_jvm.junit5;

import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.TestExecutionResult.Status;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;

public class FailFastExtension implements ExecutionCondition, TestExecutionListener {
/**
* This environment variable is set to 1 if Bazel is run with --test_runner_fail_fast, indicating
* that the test runner should exit as soon as possible after the first failure. {@see
* https://github.com/bazelbuild/bazel/commit/957554037ced26dc1860b9c23445a8ccc44f697e}
*/
private static final boolean SHOULD_FAIL_FAST =
"1".equals(System.getenv("TESTBRIDGE_TEST_RUNNER_FAIL_FAST"));

private static final AtomicBoolean SOME_TEST_FAILED = new AtomicBoolean();

@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) {
if (!SHOULD_FAIL_FAST) {
return ConditionEvaluationResult.enabled(
"Running test since --test_runner_fail_fast is not enabled");
}
if (SOME_TEST_FAILED.get()) {
return ConditionEvaluationResult.disabled(
"Skipping test since --test_runner_fail_fast is enabled and another test has failed");
} else {
return ConditionEvaluationResult.enabled("Running test since no other test has failed yet");
}
}

@Override
public void executionFinished(
TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
if (SHOULD_FAIL_FAST && testExecutionResult.getStatus().equals(Status.FAILED)) {
SOME_TEST_FAILED.set(true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ private static SystemExitToggle getSystemExitToggle() {
}

private static void detectJUnit5Classes() {
checkClass(
"org.junit.jupiter.api.extension.ExecutionCondition",
"org.junit.jupiter:junit-jupiter-api");
checkClass(
"org.junit.jupiter.engine.JupiterTestEngine", "org.junit.jupiter:junit-jupiter-engine");
checkClass(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.github.bazel_contrib.contrib_rules_jvm.junit5.FailFastExtension
Loading