You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2025/06/25 21:17:39 UTC
(lucene) branch main updated: Correct tests.seed to be reported on failures (#14848)
This is an automated email from the ASF dual-hosted git repository.
dweiss pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git
The following commit(s) were added to refs/heads/main by this push:
new 4b47fb1a311 Correct tests.seed to be reported on failures (#14848)
4b47fb1a311 is described below
commit 4b47fb1a3113d22bca6cd8c1664529ef2d7f4877
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Wed Jun 25 23:17:33 2025 +0200
Correct tests.seed to be reported on failures (#14848)
---
.../lucene.java.show-failed-tests-at-end.gradle | 31 ++++++++++++++++++----
.../lucene.java.tests-and-randomization.gradle | 8 ++++++
.../lucene/gradle/ErrorReportingTestListener.java | 16 ++++++++---
3 files changed, 46 insertions(+), 9 deletions(-)
diff --git a/build-tools/build-infra/src/main/groovy/lucene.java.show-failed-tests-at-end.gradle b/build-tools/build-infra/src/main/groovy/lucene.java.show-failed-tests-at-end.gradle
index 5c76ca592ac..9e3fcbd3fc0 100644
--- a/build-tools/build-infra/src/main/groovy/lucene.java.show-failed-tests-at-end.gradle
+++ b/build-tools/build-infra/src/main/groovy/lucene.java.show-failed-tests-at-end.gradle
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+import java.util.regex.Pattern
import org.apache.lucene.gradle.ErrorReportingTestListener
// Display all failed tests at the end of the build.
@@ -33,11 +34,28 @@ allprojects {
afterTest { desc, result ->
if (result.resultType == TestResult.ResultType.FAILURE) {
+ // check if it's a constructor or a before/after class hook that failed.
+ def qTestName
+ if (desc.name == "classMethod") {
+ qTestName = desc.className
+ } else {
+ qTestName = "${desc.className}.${desc.name}"
+ }
+
+ def randomizationParameters = ""
+ def p = Pattern.compile(/.+ (?<params>[{].*[}])$/)
+ def matcher = p.matcher(qTestName)
+ if (matcher.matches()) {
+ randomizationParameters = matcher.group("params")
+ qTestName = qTestName.replace(randomizationParameters, "").trim()
+ }
+
failedTests << [
- "name" : "${desc.className}.${desc.name}",
+ "name" : qTestName,
+ "randomizationParameters": randomizationParameters,
"project" : "${test.project.path}",
"output" : file("${testOutputsDir}/${ErrorReportingTestListener.getOutputLogName(desc.parent)}"),
- "reproduce": "gradlew ${project.path}:test --tests \"${desc.className}.${desc.name}\" ${reproLine}"
+ "reproduce": "gradlew ${project.path}:test --tests \"${qTestName}\" ${reproLine}"
]
}
}
@@ -62,11 +80,14 @@ gradle.buildFinished { result ->
.sort { a, b -> b.project.compareTo(a.project) }
.collect { e ->
String.format(Locale.ROOT,
- " - %s (%s)\n Test output: %s\n Reproduce with: %s\n",
- e.name, e.project, e.output, e.reproduce)
+ " - %s (%s)%s\n Test output: %s\n Reproduce with: %s\n",
+ e.name, e.project,
+ e.containsKey("randomizationParameters") &&
+ !e.randomizationParameters.isBlank() ? "\n Context parameters: ${e.randomizationParameters}" : "",
+ e.output, e.reproduce)
}
.join("\n")
- logger.error("\nERROR: The following test(s) have failed:\n${formatted}")
+ logger.error("\nERROR: The following {} failed:\n\n{}", failedTests.size() == 1 ? "test has" : "tests have", formatted)
}
}
diff --git a/build-tools/build-infra/src/main/groovy/lucene.java.tests-and-randomization.gradle b/build-tools/build-infra/src/main/groovy/lucene.java.tests-and-randomization.gradle
index 670a1591407..cfddde2db78 100644
--- a/build-tools/build-infra/src/main/groovy/lucene.java.tests-and-randomization.gradle
+++ b/build-tools/build-infra/src/main/groovy/lucene.java.tests-and-randomization.gradle
@@ -20,6 +20,7 @@ import org.apache.tools.ant.types.Commandline
import org.gradle.api.tasks.testing.logging.*
import com.carrotsearch.randomizedtesting.generators.RandomPicks
import org.apache.lucene.gradle.ErrorReportingTestListener
+import com.carrotsearch.gradle.buildinfra.buildoptions.BuildOptionsExtension
def loggingConfigFile = rootProject.layout.projectDirectory.file("gradle/testing/logging.properties")
def verboseModeHookInstalled = false
@@ -82,6 +83,13 @@ Provider<Integer> upperJavaFeatureVersionOption = buildOptions.addIntOption(
"tests.upperJavaFeatureVersion", "Min JDK feature version to configure the Panama Vectorization provider")
// Test reiteration, filtering and component randomization options.
+
+// Propagate root seed so that it is visible and reported as an option in subprojects.
+if (project != project.rootProject) {
+ buildOptions.addOption("tests.seed", "The \"root\" randomization seed for options and test parameters.",
+ rootProject.getExtensions().getByType(BuildOptionsExtension).getOption("tests.seed").asStringProvider())
+}
+
buildOptions.addIntOption("tests.iters", "Duplicate (re-run) each test case N times.")
optionsInheritedAsProperties += ["tests.iters"]
diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/ErrorReportingTestListener.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/ErrorReportingTestListener.java
index a58038ff710..a6dc738a645 100644
--- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/ErrorReportingTestListener.java
+++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/ErrorReportingTestListener.java
@@ -173,11 +173,19 @@ public class ErrorReportingTestListener implements TestOutputListener, TestListe
})
.filter(
option -> {
+ // if the option is not present, ignore it in repro line.
+ if (!option.isPresent()) {
+ return false;
+ }
+
// we only care about options that have non-default values or options
- // where values are computed are runtime (possibly randomized).
- return option.isPresent()
- && (option.getSource() == BuildOptionValueSource.COMPUTED_VALUE
- || !option.isEqualToDefaultValue());
+ // where values are computed at runtime (possibly randomized).
+ if (option.getSource() == BuildOptionValueSource.COMPUTED_VALUE) {
+ return true;
+ }
+
+ // filter out all non-computed options with default values.
+ return !option.isEqualToDefaultValue();
})
.map(
option -> {