From 49d48003d25f3473109c12d52ba692b78f934e7a Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sun, 12 Apr 2026 21:02:26 +0200 Subject: [PATCH 01/68] Check if jupiter can be used/ is available. --- gradle/libs.versions.toml | 14 +++--- .../lucene/search/join/TestJupiter.java | 45 +++++++++++++++++++ lucene/test-framework/build.gradle | 3 ++ .../test-framework/src/java/module-info.java | 2 + 4 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fd9bd8d9bdc9..f741338eee64 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -34,6 +34,7 @@ jmh = "1.37" jts = "1.20.0" # unit tests junit = "4.13.2" +junit5 = "6.0.3" # @keep Minimum gradle version to run the build minGradle = "9.4.1" # @keep This is the minimum required Java version. @@ -50,6 +51,7 @@ opennlp = "2.5.8" procfork = "1.0.6" # unit tests randomizedtesting = "2.8.4" +randomizedtesting-jupiter = "0.2.0" # spatial-extras/ support s2-geometry = "1.0.0" # spatial-extras/ support @@ -83,8 +85,9 @@ jmh-annprocess = { module = "org.openjdk.jmh:jmh-generator-annprocess", version. jmh-core = { module = "org.openjdk.jmh:jmh-core", version.ref = "jmh" } jts = { module = "org.locationtech.jts:jts-core", version.ref = "jts" } junit = { module = "junit:junit", version.ref = "junit" } -junitplatform-launcher = "org.junit.platform:junit-platform-launcher:6.0.3" -junitplatform-vintage = "org.junit.vintage:junit-vintage-engine:6.0.3" +junitplatform-launcher = {module = "org.junit.platform:junit-platform-launcher", version.ref = "junit5" } +junitplatform-vintage = {module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" } +junitplatform-jupiter = {module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit5" } morfologik-polish = { module = "org.carrot2:morfologik-polish", version.ref = "morfologik" } morfologik-stemming = { module = "org.carrot2:morfologik-stemming", version.ref = "morfologik" } morfologik-ukrainian = { module = "ua.net.nlp:morfologik-ukrainian-search", version.ref = "morfologik-ukrainian" } @@ -92,17 +95,12 @@ nekohtml = { module = "net.sourceforge.nekohtml:nekohtml", version.ref = "nekoht opennlp-tools = { module = "org.apache.opennlp:opennlp-tools", version.ref = "opennlp" } procfork = { module = "com.carrotsearch:procfork", version.ref = "procfork" } randomizedtesting-runner = { module = "com.carrotsearch.randomizedtesting:randomizedtesting-runner", version.ref = "randomizedtesting" } +randomizedtesting-jupiter = { module = "com.carrotsearch.randomizedtesting:randomizedtesting-jupiter", version.ref = "randomizedtesting-jupiter" } s2-geometry = { module = "io.sgr:s2-geometry-library-java", version.ref = "s2-geometry" } spatial4j = { module = "org.locationtech.spatial4j:spatial4j", version.ref = "spatial4j" } xerces = { module = "xerces:xercesImpl", version.ref = "xerces" } zstd = { module = "com.github.luben:zstd-jni", version.ref = "zstd" } -[bundles] -junitplatform = [ - "junitplatform-launcher", - "junitplatform-vintage", -] - [plugins] benmanes-versions = "com.github.ben-manes.versions:0.53.0" carrotsearch-buildopts = "com.carrotsearch.gradle.opts:0.2.1" diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java new file mode 100644 index 000000000000..9de3744e9b86 --- /dev/null +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.search.join; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import com.carrotsearch.randomizedtesting.jupiter.Randomized; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.StringField; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.NoMergePolicy; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.MatchNoDocsQuery; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.store.Directory; +import org.apache.lucene.tests.index.RandomIndexWriter; +import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.TestUtil; +import org.junit.jupiter.api.Test; + +@Randomized +public class TestJupiter { + @Test + public void testNoParent(Random random) throws IOException { + System.out.println("Foo."); + } +} diff --git a/lucene/test-framework/build.gradle b/lucene/test-framework/build.gradle index 36687e87b833..bb6cde3bddda 100644 --- a/lucene/test-framework/build.gradle +++ b/lucene/test-framework/build.gradle @@ -30,6 +30,9 @@ dependencies { }) moduleApi deps.hamcrest + moduleApi(deps.randomizedtesting.jupiter) + moduleApi(deps.junitplatform.jupiter) + moduleImplementation project(':lucene:codecs') } diff --git a/lucene/test-framework/src/java/module-info.java b/lucene/test-framework/src/java/module-info.java index 277533540485..ba14aaf7474e 100644 --- a/lucene/test-framework/src/java/module-info.java +++ b/lucene/test-framework/src/java/module-info.java @@ -22,6 +22,8 @@ requires org.apache.lucene.codecs; requires transitive junit; requires transitive randomizedtesting.runner; + requires transitive com.carrotsearch.randomizedtesting; + requires transitive org.junit.jupiter.api; requires org.hamcrest; // Open certain packages for junit because it scans methods via reflection. From 940417039447e213b588cd0a15019294c3bb6517 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sun, 12 Apr 2026 21:41:10 +0200 Subject: [PATCH 02/68] Modular configurations don't play well with module descriptors that gradle/ junit uses. --- lucene/test-framework/build.gradle | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lucene/test-framework/build.gradle b/lucene/test-framework/build.gradle index bb6cde3bddda..5b1165f3ede8 100644 --- a/lucene/test-framework/build.gradle +++ b/lucene/test-framework/build.gradle @@ -19,6 +19,14 @@ import org.apache.lucene.gradle.plugins.misc.QuietExec description = 'Framework for testing Lucene-based applications' +configurations { + foo { + attributes { + attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_API)) + } + } +} + dependencies { moduleApi project(':lucene:core') @@ -30,6 +38,7 @@ dependencies { }) moduleApi deps.hamcrest + foo("org.junit.platform:junit-platform-engine:6.0.3") moduleApi(deps.randomizedtesting.jupiter) moduleApi(deps.junitplatform.jupiter) From 1892f252e5035013ea0169a882f6c5acd5fd0365 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sun, 12 Apr 2026 22:16:30 +0200 Subject: [PATCH 03/68] Fix modular classpath extension by adding gradle variants for runtime and compilation, respectively. --- .../gradle/plugins/java/ModularPathsExtension.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ModularPathsExtension.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ModularPathsExtension.java index 0aee7689be75..63e05467d8c2 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ModularPathsExtension.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ModularPathsExtension.java @@ -30,6 +30,7 @@ import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ConfigurationContainer; import org.gradle.api.attributes.LibraryElements; +import org.gradle.api.attributes.Usage; import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileSystemLocation; import org.gradle.api.provider.Provider; @@ -117,12 +118,13 @@ public ModularPathsExtension(Project project, SourceSet sourceSet) { // We have to ensure configurations are using assembled resources and classes (jar variant) as a // single module can't be expanded into multiple folders. + var objects = project.getObjects(); Consumer ensureJarVariant = (Configuration c) -> c.getAttributes() .attribute( LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, - project.getObjects().named(LibraryElements.class, LibraryElements.JAR)); + objects.named(LibraryElements.class, LibraryElements.JAR)); // Set up compilation/runtime classpath configurations to prefer JAR variant as well. ensureJarVariant.accept( @@ -156,6 +158,13 @@ public ModularPathsExtension(Project project, SourceSet sourceSet) { this.runtimeModulePathConfiguration = createResolvableModuleConfiguration.apply(sourceSet.getRuntimeClasspathConfigurationName()); this.runtimeModulePathConfiguration.extendsFrom(moduleRuntimeOnly, moduleImplementation); + + compileModulePathConfiguration + .getAttributes() + .attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.class, Usage.JAVA_API)); + runtimeModulePathConfiguration + .getAttributes() + .attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.class, Usage.JAVA_RUNTIME)); } /** From 16be4ffb07a705219495983b81fedc5d7be5b275 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sun, 12 Apr 2026 22:17:07 +0200 Subject: [PATCH 04/68] Tidy, assertion to verify jupiter works. --- gradle/libs.versions.toml | 8 ++++---- .../apache/lucene/search/join/TestJupiter.java | 18 ++---------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f741338eee64..c5bbd1a7183d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -85,17 +85,17 @@ jmh-annprocess = { module = "org.openjdk.jmh:jmh-generator-annprocess", version. jmh-core = { module = "org.openjdk.jmh:jmh-core", version.ref = "jmh" } jts = { module = "org.locationtech.jts:jts-core", version.ref = "jts" } junit = { module = "junit:junit", version.ref = "junit" } -junitplatform-launcher = {module = "org.junit.platform:junit-platform-launcher", version.ref = "junit5" } -junitplatform-vintage = {module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" } -junitplatform-jupiter = {module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit5" } +junitplatform-jupiter = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit5" } +junitplatform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit5" } +junitplatform-vintage = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" } morfologik-polish = { module = "org.carrot2:morfologik-polish", version.ref = "morfologik" } morfologik-stemming = { module = "org.carrot2:morfologik-stemming", version.ref = "morfologik" } morfologik-ukrainian = { module = "ua.net.nlp:morfologik-ukrainian-search", version.ref = "morfologik-ukrainian" } nekohtml = { module = "net.sourceforge.nekohtml:nekohtml", version.ref = "nekohtml" } opennlp-tools = { module = "org.apache.opennlp:opennlp-tools", version.ref = "opennlp" } procfork = { module = "com.carrotsearch:procfork", version.ref = "procfork" } -randomizedtesting-runner = { module = "com.carrotsearch.randomizedtesting:randomizedtesting-runner", version.ref = "randomizedtesting" } randomizedtesting-jupiter = { module = "com.carrotsearch.randomizedtesting:randomizedtesting-jupiter", version.ref = "randomizedtesting-jupiter" } +randomizedtesting-runner = { module = "com.carrotsearch.randomizedtesting:randomizedtesting-runner", version.ref = "randomizedtesting" } s2-geometry = { module = "io.sgr:s2-geometry-library-java", version.ref = "s2-geometry" } spatial4j = { module = "org.locationtech.spatial4j:spatial4j", version.ref = "spatial4j" } xerces = { module = "xerces:xercesImpl", version.ref = "xerces" } diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java index 9de3744e9b86..a57c4388c9d5 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java @@ -16,24 +16,9 @@ */ package org.apache.lucene.search.join; +import com.carrotsearch.randomizedtesting.jupiter.Randomized; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.Random; -import com.carrotsearch.randomizedtesting.jupiter.Randomized; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.StringField; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.index.NoMergePolicy; -import org.apache.lucene.index.Term; -import org.apache.lucene.search.MatchNoDocsQuery; -import org.apache.lucene.search.TermQuery; -import org.apache.lucene.store.Directory; -import org.apache.lucene.tests.index.RandomIndexWriter; -import org.apache.lucene.tests.util.LuceneTestCase; -import org.apache.lucene.tests.util.TestUtil; import org.junit.jupiter.api.Test; @Randomized @@ -41,5 +26,6 @@ public class TestJupiter { @Test public void testNoParent(Random random) throws IOException { System.out.println("Foo."); + assert false; } } From deaa10680d5cb4d80850d45dcf0d317cc0846c4f Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Mon, 13 Apr 2026 10:48:15 +0200 Subject: [PATCH 05/68] Add api/runtime Usage attribute to modular configurations. --- .../gradle/plugins/java/ModularPathsExtension.java | 14 +++++++++++++- lucene/CHANGES.txt | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ModularPathsExtension.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ModularPathsExtension.java index 0aee7689be75..630c5d09ba08 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ModularPathsExtension.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ModularPathsExtension.java @@ -30,6 +30,7 @@ import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ConfigurationContainer; import org.gradle.api.attributes.LibraryElements; +import org.gradle.api.attributes.Usage; import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileSystemLocation; import org.gradle.api.provider.Provider; @@ -117,12 +118,13 @@ public ModularPathsExtension(Project project, SourceSet sourceSet) { // We have to ensure configurations are using assembled resources and classes (jar variant) as a // single module can't be expanded into multiple folders. + var objects = project.getObjects(); Consumer ensureJarVariant = (Configuration c) -> c.getAttributes() .attribute( LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, - project.getObjects().named(LibraryElements.class, LibraryElements.JAR)); + objects.named(LibraryElements.class, LibraryElements.JAR)); // Set up compilation/runtime classpath configurations to prefer JAR variant as well. ensureJarVariant.accept( @@ -156,6 +158,13 @@ public ModularPathsExtension(Project project, SourceSet sourceSet) { this.runtimeModulePathConfiguration = createResolvableModuleConfiguration.apply(sourceSet.getRuntimeClasspathConfigurationName()); this.runtimeModulePathConfiguration.extendsFrom(moduleRuntimeOnly, moduleImplementation); + + compileModulePathConfiguration + .getAttributes() + .attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.class, Usage.JAVA_API)); + runtimeModulePathConfiguration + .getAttributes() + .attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.class, Usage.JAVA_RUNTIME)); } /** @@ -236,6 +245,9 @@ public Iterable asArguments() { return List.of(); } + // we use custom module path assembly. This unfortunately causes + // the module-path to be emitted twice in compiler arguments; + // see gradle bug https://github.com/gradle/gradle/issues/19492. List extraArgs = new ArrayList<>(); extraArgs.add("--module-path"); extraArgs.add(joinPaths(modulePath)); diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 90db96c0d553..0eab5495c637 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -200,6 +200,8 @@ Build paths in cache keys, improving cache hit rates across different project locations. (Gasper Kojek) +* Add api/runtime Usage attribute to modular configurations. (Dawid Weiss) + Other --------------------- From d1cb9e358fbca96fb211b820a1aa4cee89ed4f61 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Mon, 13 Apr 2026 13:48:09 +0200 Subject: [PATCH 06/68] Bump gradle opts to 0.2.2 (fixes dynamic opt values changing when read multiple times). --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c5bbd1a7183d..927c86b6555c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -103,7 +103,7 @@ zstd = { module = "com.github.luben:zstd-jni", version.ref = "zstd" } [plugins] benmanes-versions = "com.github.ben-manes.versions:0.53.0" -carrotsearch-buildopts = "com.carrotsearch.gradle.opts:0.2.1" +carrotsearch-buildopts = "com.carrotsearch.gradle.opts:0.2.2" carrotsearch-dependencychecks = "com.carrotsearch.gradle.dependencychecks:0.2.1" errorprone = "net.ltgt.errorprone:5.1.0" forbiddenapis = "de.thetaphi.forbiddenapis:3.10" From 528421899f70c64ff90760beac59ed1df88d550f Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Mon, 13 Apr 2026 14:02:43 +0200 Subject: [PATCH 07/68] Correct message when tests fail. --- .../lucene/gradle/plugins/java/ShowFailedTestsAtEndPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ShowFailedTestsAtEndPlugin.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ShowFailedTestsAtEndPlugin.java index a44e56bcad3d..ebb044d2339c 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ShowFailedTestsAtEndPlugin.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ShowFailedTestsAtEndPlugin.java @@ -202,7 +202,7 @@ public void close() { LOGGER.error( "\nERROR: {} {} failed{}:\n\n{}", failedTests.size(), - failedTests.size() == 1 ? "test has" : failedTests.size() + " tests have", + failedTests.size() == 1 ? "test has" : "tests have", failedTests.size() > limit ? " (top " + limit + " shown)" : "", formatted); } From fafae38038b017907b372b89a4ebecf25442ffe1 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Tue, 14 Apr 2026 11:55:42 +0200 Subject: [PATCH 08/68] Cleanups and back-compat modifications. --- .../lucene/search/join/TestJupiter.java | 12 +- .../lucene/tests/util/LuceneTestCase2.java | 155 ++++++++++++++++++ 2 files changed, 161 insertions(+), 6 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java index a57c4388c9d5..4508b385921c 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java @@ -16,16 +16,16 @@ */ package org.apache.lucene.search.join; -import com.carrotsearch.randomizedtesting.jupiter.Randomized; -import java.io.IOException; import java.util.Random; +import java.util.concurrent.TimeUnit; +import org.apache.lucene.tests.util.LuceneTestCase2; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; -@Randomized -public class TestJupiter { +@Timeout(value = 3, unit = TimeUnit.SECONDS) +public class TestJupiter extends LuceneTestCase2 { @Test - public void testNoParent(Random random) throws IOException { + public void testNoParent(Random random) throws Exception { System.out.println("Foo."); - assert false; } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java new file mode 100644 index 000000000000..dcc7bdae6cf5 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.tests.util; + +import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; +import com.carrotsearch.randomizedtesting.jupiter.Randomized; +import com.carrotsearch.randomizedtesting.jupiter.SystemThreadFilter; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.lucene.util.Constants; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.platform.commons.support.AnnotationSupport; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ModifierSupport; +import org.junit.platform.commons.support.ReflectionSupport; + +/// Base class for all Lucene unit tests (JUnit5/ Jupiter variant). +/// +/// ## Class and instance setup +/// +/// The preferred way to specify class (suite-level) setup/cleanup is to use static methods +/// annotated with [org.junit.jupiter.api.BeforeAll] and [org.junit.jupiter.api.AfterAll]. +/// **Do not use static initializers (including complex final field initializers).** +/// +/// For instance-level setup, use [BeforeEach] and +/// [AfterEach] annotated methods. +/// +/// ## Specifying test cases +/// +/// Any method of specifying JUnit jupiter tests will work. The most common way would therefore be: +/// ```java +/// @Test +/// public void testMethod(Random random) {} +/// ``` +/// +/// Note the (optional) [Random] argument - this is automatically populated for each test. +/// +/// ## Randomized execution and test facilities +/// +/// [LuceneTestCase2] uses the [Randomized] extension to support component randomization. +/// A [Random] can be automatically injected in the test (or any junit5 callback) as a parameter. +/// Tests should be fully reproducible for the same initial seed +/// (assuming no race conditions between threads +/// etc.). The initial seed for a test case is reported in many ways: +/// +/// - logged from the gradle build, +/// - inserted as a synthetic stack frame in any exceptions. +/// +/* +// TODO: port these. +- reproduce info listener, failuremarker? @Listeners({RunListenerPrintReproduceInfo.class, FailureMarker.class}) +- test sysout rule +@TestRuleLimitSysouts.Limit( + bytes = TestRuleLimitSysouts.DEFAULT_LIMIT, + hardLimit = TestRuleLimitSysouts.DEFAULT_HARD_LIMIT) + */ +@Randomized +@DetectThreadLeaks(scope = DetectThreadLeaks.Scope.SUITE) +@DetectThreadLeaks.LingerTime(millis = 20_000) +@DetectThreadLeaks.ExcludeThreads({SystemThreadFilter.class, LuceneTestCase2.IsSystemThread.class}) +@Timeout(value = 2, unit = TimeUnit.HOURS) +@Execution(value = ExecutionMode.SAME_THREAD, reason = "backward compatibility.") +public abstract class LuceneTestCase2 { + /** + * This predicate should return {@code true} for threads that should be ignored in {@linkplain + * DetectThreadLeaks thread leak detection}. + */ + public static class IsSystemThread implements Predicate { + static final boolean isJ9; + + static { + isJ9 = Constants.JAVA_VENDOR.startsWith("IBM"); + } + + @Override + public boolean test(Thread t) { + var threadName = t.getName(); + switch (threadName) { + case "ClassCache Reaper": // LUCENE-6518 + case "junit-jupiter-timeout-watcher": // junit5/jupiter timeouts. + case "JNA Cleaner": // JNA cleaner thread (system). + return true; + } + + if (isJ9 + && Stream.of(t.getStackTrace()) + .anyMatch(frame -> frame.getClassName().equals("java.util.Timer$TimerImpl"))) { + return true; + } + + return false; + } + } + + // + // Deprecated or removed methods (LuceneTestCase) and other backward-compatibility + // infrastructure. + // + + /** + * Unfortunately there is no easy way to implement custom test providers in jupiter so we just + * enforce annotations on {@code test*} methods (so that they're not silently ignored). + * + *

A dynamic test factory would almost work but dynamic tests skip all the + * before-after hooks so they're not a direct substitute. + */ + @Test + public void allTestMethodsAreAnnotated() { + var testMethodsWithoutAnnotations = + ReflectionSupport.findMethods( + getClass(), + m -> { + return m.getName().startsWith("test") + && !ModifierSupport.isStatic(m) + && !AnnotationSupport.isAnnotated(m, Test.class); + }, + HierarchyTraversalMode.BOTTOM_UP); + + if (!testMethodsWithoutAnnotations.isEmpty()) { + throw new AssertionError( + "test* methods must be annotated with @Test in junit5/jupiter, the following are not: " + + testMethodsWithoutAnnotations.stream() + .map(m -> "\n - " + m.getDeclaringClass().getName() + "#" + m.getName()) + .collect(Collectors.joining())); + } + } + + /** Use jupiter's {@link BeforeEach} instead. */ + protected final void setUp() throws Exception {} + + /** Use jupiter's {@link AfterEach} instead. */ + protected final void tearDown() throws Exception {} +} From 346fc2b8d9c560da1af6a8aa8e009ff4c28712b4 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Tue, 14 Apr 2026 19:07:59 +0200 Subject: [PATCH 09/68] Some progress but mostly hitting issues with random context access and other infrastructure used from within LuceneTestCase's facilities. --- .../lucene/search/join/TestJupiter.java | 42 ++- .../lucene/index/memory/TestMemoryIndex.java | 84 +++--- .../TestMemoryIndexAgainstDirectory.java | 259 ++++++++++-------- .../index/memory/TestSlicedIntBlockPool.java | 32 ++- .../lucene/tests/analysis/MockTokenizer.java | 5 +- .../tests/util/GlobalStaticRandomAccess.java | 71 +++++ .../lucene/tests/util/LuceneTestCase.java | 16 +- .../lucene/tests/util/LuceneTestCase2.java | 24 +- 8 files changed, 360 insertions(+), 173 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStaticRandomAccess.java diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java index 4508b385921c..e1378836adea 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java @@ -16,16 +16,50 @@ */ package org.apache.lucene.search.join; +import java.util.Objects; import java.util.Random; import java.util.concurrent.TimeUnit; +import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.tests.util.LuceneTestCase2; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; @Timeout(value = 3, unit = TimeUnit.SECONDS) -public class TestJupiter extends LuceneTestCase2 { - @Test - public void testNoParent(Random random) throws Exception { - System.out.println("Foo."); +public class TestJupiter { + @Nested + class T1 extends LuceneTestCase2 { + @Test + public void t1() throws Exception { + Random r1 = LuceneTestCase.random(); + Random r2 = LuceneTestCase.random(); + Assertions.assertSame(r1, r2); + System.out.println("R: " + Objects.hashCode(r1) + " " + r1.nextLong()); + } + + @Test + public void t2() throws Exception { + { + Random r1 = LuceneTestCase.random(); + System.out.println("R: " + Objects.hashCode(r1) + " " + r1.nextLong()); + } + var t = + new Thread( + () -> { + Random r1 = LuceneTestCase.random(); + Random r2 = LuceneTestCase.random(); + Assertions.assertSame(r1, r2); + System.out.println("R: " + Objects.hashCode(r1) + " " + r1.nextLong()); + }); + t.start(); + t.join(); + } + } + + @Nested + public class T2 extends LuceneTestCase2 { + @Test + public void testNoParent(Random random) throws Exception {} } } diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java index 1a98699bb7b4..41446f9fdb84 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java @@ -18,6 +18,7 @@ import static org.hamcrest.core.StringContains.containsString; +import com.carrotsearch.randomizedtesting.jupiter.generators.RandomBytes; import java.io.IOException; import java.io.Reader; import java.nio.charset.StandardCharsets; @@ -26,6 +27,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Random; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.LongStream; @@ -91,26 +93,24 @@ import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.analysis.MockPayloadAnalyzer; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCase2; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRef; import org.hamcrest.MatcherAssert; -import org.junit.Before; -import org.junit.Test; - -public class TestMemoryIndex extends LuceneTestCase { +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +public class TestMemoryIndex extends LuceneTestCase2 { private MockAnalyzer analyzer; - @Before - public void setup() { - analyzer = new MockAnalyzer(random()); + @BeforeEach + public void setup(Random random) { + analyzer = new MockAnalyzer(random); analyzer.setEnableChecks(false); // MemoryIndex can close a TokenStream on init error } @Test public void testFreezeAPI() { - MemoryIndex mi = new MemoryIndex(); mi.addField("f1", "some text", analyzer); @@ -143,6 +143,7 @@ public void testFreezeAPI() { mi.setSimilarity(new ClassicSimilarity()); } + @Test public void testSeekByTermOrd() throws IOException { MemoryIndex mi = new MemoryIndex(); mi.addField("field", "some terms be here", analyzer); @@ -154,6 +155,7 @@ public void testSeekByTermOrd() throws IOException { TestUtil.checkReader(reader); } + @Test public void testFieldsOnlyReturnsIndexedFields() throws IOException { Document doc = new Document(); @@ -167,6 +169,7 @@ public void testFieldsOnlyReturnsIndexedFields() throws IOException { assertEquals(reader.termVectors().get(0).size(), 1); } + @Test public void testReaderConsistency() throws IOException { Analyzer analyzer = new MockPayloadAnalyzer(); @@ -267,6 +270,7 @@ public void testBuildFromDocument() { assertEquals(0.0f, mi.search(new PhraseQuery("field1", "text", "some")), 0); } + @Test public void testDocValues() throws Exception { Document doc = new Document(); doc.add(new NumericDocValuesField("numeric", 29L)); @@ -321,6 +325,7 @@ public void testDocValues() throws Exception { assertEquals(DocIdSetIterator.NO_MORE_DOCS, sortedDocValues.nextDoc()); } + @Test public void testDocValues_resetIterator() throws Exception { Document doc = new Document(); @@ -361,6 +366,7 @@ public void testDocValues_resetIterator() throws Exception { } } + @Test public void testInvalidDocValuesUsage() throws Exception { Document doc = new Document(); doc.add(new NumericDocValuesField("field", 29L)); @@ -407,6 +413,7 @@ public void testInvalidDocValuesUsage() throws Exception { } } + @Test public void testDocValuesDoNotAffectBoostPositionsOrOffset() throws Exception { Document doc = new Document(); doc.add(new BinaryDocValuesField("text", new BytesRef("quick brown fox"))); @@ -444,10 +451,10 @@ public void testDocValuesDoNotAffectBoostPositionsOrOffset() throws Exception { assertEquals("quick brown fox", binaryDocValues.binaryValue().utf8ToString()); } - public void testBigBinaryDocValues() throws Exception { + @Test + public void testBigBinaryDocValues(Random random) throws Exception { Document doc = new Document(); - byte[] bytes = new byte[33 * 1024]; - random().nextBytes(bytes); + byte[] bytes = RandomBytes.randomBytesOfLength(random, 33 * 1024); doc.add(new BinaryDocValuesField("binary", new BytesRef(bytes))); MemoryIndex mi = MemoryIndex.fromDocument(doc, analyzer, true, true); LeafReader leafReader = mi.createSearcher().getIndexReader().leaves().get(0).reader(); @@ -456,10 +463,10 @@ public void testBigBinaryDocValues() throws Exception { assertArrayEquals(bytes, binaryDocValues.binaryValue().bytes); } - public void testBigSortedDocValues() throws Exception { + @Test + public void testBigSortedDocValues(Random random) throws Exception { Document doc = new Document(); - byte[] bytes = new byte[33 * 1024]; - random().nextBytes(bytes); + byte[] bytes = RandomBytes.randomBytesOfLength(random, 33 * 1024); doc.add(new SortedDocValuesField("binary", new BytesRef(bytes))); MemoryIndex mi = MemoryIndex.fromDocument(doc, analyzer, true, true); LeafReader leafReader = mi.createSearcher().getIndexReader().leaves().get(0).reader(); @@ -468,6 +475,7 @@ public void testBigSortedDocValues() throws Exception { assertArrayEquals(bytes, sortedDocValues.lookupOrd(0).bytes); } + @Test public void testPointValues() throws Exception { List> fieldFunctions = Arrays.asList( @@ -535,6 +543,7 @@ public void testPointValues() throws Exception { } } + @Test public void testMissingPoints() throws IOException { Document doc = new Document(); doc.add(new StoredField("field", 42)); @@ -552,6 +561,7 @@ public void testMissingPoints() throws IOException { .getPointValues("some_missing_field")); } + @Test public void testPointValuesDoNotAffectPositionsOrOffset() throws Exception { MemoryIndex mi = new MemoryIndex(true, true); mi.addField(new TextField("text", "quick brown fox", Field.Store.NO), analyzer); @@ -599,6 +609,7 @@ public void testPointValuesDoNotAffectPositionsOrOffset() throws Exception { BinaryPoint.newExactQuery("text", "jumps".getBytes(StandardCharsets.UTF_8)))); } + @Test public void test2DPoints() throws Exception { Document doc = new Document(); doc.add(new IntPoint("ints", 0, -100)); @@ -632,6 +643,7 @@ public void test2DPoints() throws Exception { "doubles", new double[] {10D, 10D}, new double[] {30D, 30D}))); } + @Test public void testMultiValuedPointsSortedCorrectly() throws Exception { Document doc = new Document(); doc.add(new IntPoint("ints", 3)); @@ -656,6 +668,7 @@ public void testMultiValuedPointsSortedCorrectly() throws Exception { assertEquals(1, s.count(DoublePoint.newSetQuery("doubles", 2))); } + @Test public void testIndexingPointsAndDocValues() throws Exception { FieldType type = new FieldType(); type.setDimensions(1, 4); @@ -676,6 +689,7 @@ public void testIndexingPointsAndDocValues() throws Exception { assertEquals("term", dvs.binaryValue().utf8ToString()); } + @Test public void testToStringDebug() { MemoryIndex mi = new MemoryIndex(true, true); Analyzer analyzer = new MockPayloadAnalyzer(); @@ -702,7 +716,8 @@ public void testToStringDebug() { mi.toStringDebug()); } - public void testStoredFields() throws IOException { + @Test + public void testStoredFields(Random random) throws IOException { List fields = new ArrayList<>(); fields.add(new StoredField("float", 1.5f)); fields.add(new StoredField("multifloat", 2.5f)); @@ -725,7 +740,7 @@ public void testStoredFields() throws IOException { fields.add(new StoredField("multibinary", "bbar".getBytes(StandardCharsets.UTF_8))); fields.add(new StoredField("multibinary", "bbaz".getBytes(StandardCharsets.UTF_8))); - Collections.shuffle(fields, random()); + Collections.shuffle(fields, random); Document doc = new Document(); for (IndexableField f : fields) { doc.add(f); @@ -751,6 +766,7 @@ public void testStoredFields() throws IOException { d, "multibinary", new BytesRef[] {new BytesRef("bbar"), new BytesRef("bbaz")}); } + @Test public void testKnnFloatVectorOnlyOneVectorAllowed() throws IOException { Document doc = new Document(); doc.add(new KnnFloatVectorField("knnFloatA", new float[] {1.0f, 2.0f})); @@ -760,14 +776,15 @@ public void testKnnFloatVectorOnlyOneVectorAllowed() throws IOException { () -> MemoryIndex.fromDocument(doc, new StandardAnalyzer())); } - public void testKnnFloatVectors() throws IOException { + @Test + public void testKnnFloatVectors(Random random) throws IOException { List fields = new ArrayList<>(); fields.add(new KnnFloatVectorField("knnFloatA", new float[] {1.0f, 2.0f})); fields.add(new KnnFloatVectorField("knnFloatB", new float[] {3.0f, 4.0f, 5.0f, 6.0f})); fields.add( new KnnFloatVectorField( "knnFloatC", new float[] {7.0f, 8.0f, 9.0f}, VectorSimilarityFunction.DOT_PRODUCT)); - Collections.shuffle(fields, random()); + Collections.shuffle(fields, random); Document doc = new Document(); for (IndexableField f : fields) { doc.add(f); @@ -778,9 +795,10 @@ public void testKnnFloatVectors() throws IOException { assertFloatVectorValue(mi, "knnFloatB", new float[] {3.0f, 4.0f, 5.0f, 6.0f}); assertFloatVectorValue(mi, "knnFloatC", new float[] {7.0f, 8.0f, 9.0f}); - assertFloatVectorScore(mi, "knnFloatA", new float[] {1.0f, 1.0f}, 0.5f); - assertFloatVectorScore(mi, "knnFloatB", new float[] {3.0f, 3.0f, 3.0f, 3.0f}, 0.06666667f); - assertFloatVectorScore(mi, "knnFloatC", new float[] {7.0f, 7.0f, 7.0f}, 84.5f); + assertFloatVectorScore(random, mi, "knnFloatA", new float[] {1.0f, 1.0f}, 0.5f); + assertFloatVectorScore( + random, mi, "knnFloatB", new float[] {3.0f, 3.0f, 3.0f, 3.0f}, 0.06666667f); + assertFloatVectorScore(random, mi, "knnFloatC", new float[] {7.0f, 7.0f, 7.0f}, 84.5f); assertNull( mi.createSearcher() @@ -803,6 +821,7 @@ public void testKnnFloatVectors() throws IOException { assertEquals(0, docs.totalHits.value()); } + @Test public void testKnnByteVectorOnlyOneVectorAllowed() throws IOException { Document doc = new Document(); doc.add(new KnnByteVectorField("knnByteA", new byte[] {1, 2})); @@ -812,14 +831,15 @@ public void testKnnByteVectorOnlyOneVectorAllowed() throws IOException { () -> MemoryIndex.fromDocument(doc, new StandardAnalyzer())); } - public void testKnnByteVectors() throws IOException { + @Test + public void testKnnByteVectors(Random random) throws IOException { List fields = new ArrayList<>(); fields.add(new KnnByteVectorField("knnByteA", new byte[] {1, 2})); fields.add(new KnnByteVectorField("knnByteB", new byte[] {3, 4, 5, 6})); fields.add( new KnnByteVectorField( "knnByteC", new byte[] {7, 8, 9}, VectorSimilarityFunction.DOT_PRODUCT)); - Collections.shuffle(fields, random()); + Collections.shuffle(fields, random); Document doc = new Document(); for (IndexableField f : fields) { doc.add(f); @@ -830,9 +850,9 @@ public void testKnnByteVectors() throws IOException { assertByteVectorValue(mi, "knnByteB", new byte[] {3, 4, 5, 6}); assertByteVectorValue(mi, "knnByteC", new byte[] {7, 8, 9}); - assertByteVectorScore(mi, "knnByteA", new byte[] {1, 1}, 0.5f); - assertByteVectorScore(mi, "knnByteB", new byte[] {3, 3, 3, 3}, 0.06666667f); - assertByteVectorScore(mi, "knnByteC", new byte[] {7, 7, 7}, 0.501709f); + assertByteVectorScore(random, mi, "knnByteA", new byte[] {1, 1}, 0.5f); + assertByteVectorScore(random, mi, "knnByteB", new byte[] {3, 3, 3, 3}, 0.06666667f); + assertByteVectorScore(random, mi, "knnByteC", new byte[] {7, 7, 7}, 0.501709f); assertNull( mi.createSearcher() @@ -871,7 +891,7 @@ private static void assertFloatVectorValue(MemoryIndex mi, String fieldName, flo } private static void assertFloatVectorScore( - MemoryIndex mi, String fieldName, float[] queryVector, float expectedScore) + Random random, MemoryIndex mi, String fieldName, float[] queryVector, float expectedScore) throws IOException { FloatVectorValues fvv = mi.createSearcher() @@ -881,7 +901,7 @@ private static void assertFloatVectorScore( .reader() .getFloatVectorValues(fieldName); assertNotNull(fvv); - if (random().nextBoolean()) { + if (random.nextBoolean()) { fvv.iterator().nextDoc(); } VectorScorer scorer = fvv.scorer(queryVector); @@ -907,7 +927,7 @@ private static void assertByteVectorValue(MemoryIndex mi, String fieldName, byte } private static void assertByteVectorScore( - MemoryIndex mi, String fieldName, byte[] queryVector, float expectedScore) + Random random, MemoryIndex mi, String fieldName, byte[] queryVector, float expectedScore) throws IOException { ByteVectorValues bvv = mi.createSearcher() @@ -917,7 +937,7 @@ private static void assertByteVectorScore( .reader() .getByteVectorValues(fieldName); assertNotNull(bvv); - if (random().nextBoolean()) { + if (random.nextBoolean()) { bvv.iterator().nextDoc(); } VectorScorer scorer = bvv.scorer(queryVector); @@ -979,6 +999,7 @@ private static boolean arrayBinaryContains(BytesRef[] array, BytesRef value) { return false; } + @Test public void testIntegerNumericDocValue() throws IOException { // MemoryIndex used to fail when doc values are enabled and numericValue() returns an Integer // such as with IntField. @@ -1069,6 +1090,7 @@ public InvertableType invertableType() { } } + @Test public void testKeywordWithoutTokenStream() throws IOException { List legalFieldTypes = new ArrayList<>(); { diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java index f57a7d978fcd..e2593bb2cce5 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java @@ -16,14 +16,21 @@ */ package org.apache.lucene.index.memory; +import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.RANDOM_MULTIPLIER; +import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.TEST_NIGHTLY; +import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newDirectory; +import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newIndexWriterConfig; +import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newSearcher; +import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newTextField; + import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Random; import java.util.Set; import java.util.function.Supplier; import org.apache.lucene.analysis.Analyzer; @@ -78,53 +85,64 @@ import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.ByteBuffersDirectory; import org.apache.lucene.store.Directory; -import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.apache.lucene.tests.analysis.CannedTokenStream; import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.analysis.MockTokenFilter; import org.apache.lucene.tests.analysis.MockTokenizer; import org.apache.lucene.tests.analysis.Token; import org.apache.lucene.tests.util.LineFileDocs; +import org.apache.lucene.tests.util.LuceneTestCase2; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; /** - * Verifies that Lucene MemoryIndex and RAM-resident Directory have the same behaviour, returning - * the same results for queries on some randomish indexes. + * Verifies that Lucene MemoryIndex and RAM-resident Directory have the same behavior, returning the + * same results for queries on some randomish indexes. */ -public class TestMemoryIndexAgainstDirectory extends BaseTokenStreamTestCase { - private final Set queries = new HashSet<>(); +public class TestMemoryIndexAgainstDirectory extends LuceneTestCase2 { + private static Set queries = new HashSet<>(); - @Override - public void setUp() throws Exception { - super.setUp(); + @BeforeAll + public static void prepare() throws Exception { queries.addAll(readQueries("testqueries.txt")); queries.addAll(readQueries("testqueries2.txt")); } + @AfterAll + public static void cleanup() throws Exception { + queries = null; + } + /** read a set of queries from a resource file */ - private Set readQueries(String resource) throws IOException { + private static Set readQueries(String resource) throws IOException { Set queries = new HashSet<>(); - InputStream stream = getClass().getResourceAsStream(resource); - BufferedReader reader = - new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)); - String line; - while ((line = reader.readLine()) != null) { - line = line.trim(); - if (line.length() > 0 && !line.startsWith("#") && !line.startsWith("//")) { - queries.add(line); + try (var reader = + new BufferedReader( + new InputStreamReader( + TestMemoryIndexAgainstDirectory.class.getResourceAsStream(resource), + StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (!line.isEmpty() && !line.startsWith("#") && !line.startsWith("//")) { + queries.add(line); + } } + return queries; } - return queries; } /** runs random tests, up to ITERATIONS times. */ - public void testRandomQueries() throws Exception { - MemoryIndex index = randomMemoryIndex(); + @Test + public void testRandomQueries(Random random) throws Exception { + MemoryIndex index = randomMemoryIndex(random); int iterations = TEST_NIGHTLY ? 100 * RANDOM_MULTIPLIER : 10 * RANDOM_MULTIPLIER; for (int i = 0; i < iterations; i++) { - assertAgainstDirectory(index); + assertAgainstDirectory(random, index); } } @@ -132,27 +150,27 @@ public void testRandomQueries() throws Exception { * Build a randomish document for both Directory and MemoryIndex, and run all the queries against * it. */ - public void assertAgainstDirectory(MemoryIndex memory) throws Exception { + public void assertAgainstDirectory(Random random, MemoryIndex memory) throws Exception { memory.reset(); StringBuilder fooField = new StringBuilder(); StringBuilder termField = new StringBuilder(); // add up to 250 terms to field "foo" - final int numFooTerms = random().nextInt(250 * RANDOM_MULTIPLIER); + final int numFooTerms = random.nextInt(250 * RANDOM_MULTIPLIER); for (int i = 0; i < numFooTerms; i++) { fooField.append(" "); - fooField.append(randomTerm()); + fooField.append(randomTerm(random)); } // add up to 250 terms to field "term" - final int numTermTerms = random().nextInt(250 * RANDOM_MULTIPLIER); + final int numTermTerms = random.nextInt(250 * RANDOM_MULTIPLIER); for (int i = 0; i < numTermTerms; i++) { termField.append(" "); - termField.append(randomTerm()); + termField.append(randomTerm(random)); } Directory dir = new ByteBuffersDirectory(); - Analyzer analyzer = randomAnalyzer(); + Analyzer analyzer = randomAnalyzer(random); IndexWriter writer = new IndexWriter( dir, @@ -172,13 +190,13 @@ public void assertAgainstDirectory(MemoryIndex memory) throws Exception { LeafReader reader = (LeafReader) memory.createSearcher().getIndexReader(); TestUtil.checkReader(reader); DirectoryReader competitor = DirectoryReader.open(dir); - duellReaders(competitor, reader); + duelReaders(competitor, reader); IOUtils.close(reader, competitor); assertAllQueries(memory, dir, analyzer); dir.close(); } - private void duellReaders(CompositeReader other, LeafReader memIndexReader) throws IOException { + private void duelReaders(CompositeReader other, LeafReader memIndexReader) throws IOException { Fields memFields = memIndexReader.termVectors().get(0); for (String field : FieldInfos.getIndexedFields(other)) { Terms memTerms = memFields.terms(field); @@ -215,9 +233,9 @@ private void duellReaders(CompositeReader other, LeafReader memIndexReader) thro assertEquals(iwDocsAndPos.freq(), memDocsAndPos.freq()); for (int i = 0; i < iwDocsAndPos.freq(); i++) { assertEquals( - "term: " + iwTermsIter.term().utf8ToString(), iwDocsAndPos.nextPosition(), - memDocsAndPos.nextPosition()); + memDocsAndPos.nextPosition(), + "term: " + iwTermsIter.term().utf8ToString()); if (offsets) { assertEquals(iwDocsAndPos.startOffset(), memDocsAndPos.startOffset()); assertEquals(iwDocsAndPos.endOffset(), memDocsAndPos.endOffset()); @@ -254,19 +272,19 @@ public void assertAllQueries(MemoryIndex memory, Directory directory, Analyzer a for (String query : queries) { TopDocs ramDocs = ram.search(qp.parse(query), 1); TopDocs memDocs = mem.search(qp.parse(query), 1); - assertEquals(query, ramDocs.totalHits.value(), memDocs.totalHits.value()); + assertEquals(ramDocs.totalHits.value(), memDocs.totalHits.value(), query); } reader.close(); } /** Return a random analyzer (Simple, Stop, Standard) to analyze the terms. */ - private Analyzer randomAnalyzer() { - switch (random().nextInt(4)) { + private Analyzer randomAnalyzer(Random random) { + switch (random.nextInt(4)) { case 0: - return new MockAnalyzer(random(), MockTokenizer.SIMPLE, true); + return new MockAnalyzer(random, MockTokenizer.SIMPLE, true); case 1: return new MockAnalyzer( - random(), MockTokenizer.SIMPLE, true, MockTokenFilter.ENGLISH_STOPSET); + random, MockTokenizer.SIMPLE, true, MockTokenFilter.ENGLISH_STOPSET); case 2: return new Analyzer() { @Override @@ -276,7 +294,7 @@ protected TokenStreamComponents createComponents(String fieldName) { } }; default: - return new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false); + return new MockAnalyzer(random, MockTokenizer.WHITESPACE, false); } } @@ -335,25 +353,26 @@ public boolean incrementToken() throws IOException { * half of the time, returns a random term from TEST_TERMS. the other half of the time, returns a * random unicode string. */ - private String randomTerm() { - if (random().nextBoolean()) { + private String randomTerm(Random random) { + if (random.nextBoolean()) { // return a random TEST_TERM - return TEST_TERMS[random().nextInt(TEST_TERMS.length)]; + return TEST_TERMS[random.nextInt(TEST_TERMS.length)]; } else { // return a random unicode term - return TestUtil.randomUnicodeString(random()); + return TestUtil.randomUnicodeString(random); } } - public void testDocsEnumStart() throws Exception { - Analyzer analyzer = new MockAnalyzer(random()); + @Test + public void testDocsEnumStart(Random random) throws Exception { + Analyzer analyzer = new MockAnalyzer(random); MemoryIndex memory = - new MemoryIndex(random().nextBoolean(), false, random().nextInt(50) * 1024 * 1024); + new MemoryIndex(random.nextBoolean(), false, random.nextInt(50) * 1024 * 1024); memory.addField("foo", "bar", analyzer); LeafReader reader = (LeafReader) memory.createSearcher().getIndexReader(); TestUtil.checkReader(reader); PostingsEnum disi = - TestUtil.docs(random(), reader, "foo", new BytesRef("bar"), null, PostingsEnum.NONE); + TestUtil.docs(random, reader, "foo", new BytesRef("bar"), null, PostingsEnum.NONE); int docid = disi.docID(); assertEquals(-1, docid); assertTrue(disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS); @@ -368,15 +387,16 @@ public void testDocsEnumStart() throws Exception { reader.close(); } - private MemoryIndex randomMemoryIndex() { + private MemoryIndex randomMemoryIndex(Random random) { return new MemoryIndex( - random().nextBoolean(), random().nextBoolean(), random().nextInt(50) * 1024 * 1024); + random.nextBoolean(), random.nextBoolean(), random.nextInt(50) * 1024 * 1024); } - public void testDocsAndPositionsEnumStart() throws Exception { - Analyzer analyzer = new MockAnalyzer(random()); - int numIters = atLeast(3); - MemoryIndex memory = new MemoryIndex(true, false, random().nextInt(50) * 1024 * 1024); + @Test + public void testDocsAndPositionsEnumStart(Random random) throws Exception { + Analyzer analyzer = new MockAnalyzer(random); + int numIters = atLeast(random, 3); + MemoryIndex memory = new MemoryIndex(true, false, random.nextInt(50) * 1024 * 1024); for (int i = 0; i < numIters; i++) { // check reuse memory.addField("foo", "bar", analyzer); LeafReader reader = (LeafReader) memory.createSearcher().getIndexReader(); @@ -403,12 +423,13 @@ public void testDocsAndPositionsEnumStart() throws Exception { } // LUCENE-3831 - public void testNullPointerException() throws IOException { + @Test + public void testNullPointerException(Random random) throws IOException { RegexpQuery regex = new RegexpQuery(new Term("field", "worl.")); SpanQuery wrappedquery = new SpanMultiTermQueryWrapper<>(regex); - MemoryIndex mindex = randomMemoryIndex(); - mindex.addField("field", new MockAnalyzer(random()).tokenStream("field", "hello there")); + MemoryIndex mindex = randomMemoryIndex(random); + mindex.addField("field", new MockAnalyzer(random).tokenStream("field", "hello there")); // This throws an NPE assertEquals(0, mindex.search(wrappedquery), 0.00001f); @@ -416,21 +437,23 @@ public void testNullPointerException() throws IOException { } // LUCENE-3831 - public void testPassesIfWrapped() throws IOException { + @Test + public void testPassesIfWrapped(Random random) throws IOException { RegexpQuery regex = new RegexpQuery(new Term("field", "worl.")); SpanQuery wrappedquery = new SpanOrQuery(new SpanMultiTermQueryWrapper<>(regex)); - MemoryIndex mindex = randomMemoryIndex(); - mindex.addField("field", new MockAnalyzer(random()).tokenStream("field", "hello there")); + MemoryIndex mindex = randomMemoryIndex(random); + mindex.addField("field", new MockAnalyzer(random).tokenStream("field", "hello there")); // This passes though assertEquals(0, mindex.search(wrappedquery), 0.00001f); TestUtil.checkReader(mindex.createSearcher().getIndexReader()); } - public void testSameFieldAddedMultipleTimes() throws IOException { - MemoryIndex mindex = randomMemoryIndex(); - MockAnalyzer mockAnalyzer = new MockAnalyzer(random()); + @Test + public void testSameFieldAddedMultipleTimes(Random random) throws IOException { + MemoryIndex mindex = randomMemoryIndex(random); + MockAnalyzer mockAnalyzer = new MockAnalyzer(random); mindex.addField("field", "the quick brown fox", mockAnalyzer); mindex.addField("field", "jumps over the", mockAnalyzer); LeafReader reader = (LeafReader) mindex.createSearcher().getIndexReader(); @@ -439,19 +462,20 @@ public void testSameFieldAddedMultipleTimes() throws IOException { PhraseQuery query = new PhraseQuery("field", "fox", "jumps"); assertTrue(mindex.search(query) > 0.1); mindex.reset(); - mockAnalyzer.setPositionIncrementGap(1 + random().nextInt(10)); + mockAnalyzer.setPositionIncrementGap(1 + random.nextInt(10)); mindex.addField("field", "the quick brown fox", mockAnalyzer); mindex.addField("field", "jumps over the", mockAnalyzer); assertEquals(0, mindex.search(query), 0.00001f); query = new PhraseQuery(10, "field", "fox", "jumps"); assertTrue( - "posGap" + mockAnalyzer.getPositionIncrementGap("field"), mindex.search(query) > 0.0001); + mindex.search(query) > 0.0001, "posGap" + mockAnalyzer.getPositionIncrementGap("field")); TestUtil.checkReader(mindex.createSearcher().getIndexReader()); } - public void testNonExistentField() throws IOException { - MemoryIndex mindex = randomMemoryIndex(); - MockAnalyzer mockAnalyzer = new MockAnalyzer(random()); + @Test + public void testNonExistentField(Random random) throws IOException { + MemoryIndex mindex = randomMemoryIndex(random); + MockAnalyzer mockAnalyzer = new MockAnalyzer(random); mindex.addField("field", "the quick brown fox", mockAnalyzer); LeafReader reader = (LeafReader) mindex.createSearcher().getIndexReader(); TestUtil.checkReader(reader); @@ -462,50 +486,51 @@ public void testNonExistentField() throws IOException { assertNull(reader.terms("not-in-index")); } - public void testDocValuesMemoryIndexVsNormalIndex() throws Exception { + @Test + public void testDocValuesMemoryIndexVsNormalIndex(Random random) throws Exception { Document doc = new Document(); - long randomLong = random().nextLong(); + long randomLong = random.nextLong(); doc.add(new NumericDocValuesField("numeric", randomLong)); - int numValues = atLeast(5); + int numValues = atLeast(random, 5); for (int i = 0; i < numValues; i++) { - randomLong = random().nextLong(); + randomLong = random.nextLong(); doc.add(new SortedNumericDocValuesField("sorted_numeric", randomLong)); - if (random().nextBoolean()) { + if (random.nextBoolean()) { // randomly duplicate field/value doc.add(new SortedNumericDocValuesField("sorted_numeric", randomLong)); } } - BytesRef randomTerm = new BytesRef(randomTerm()); + BytesRef randomTerm = new BytesRef(randomTerm(random)); doc.add(new BinaryDocValuesField("binary", randomTerm)); - if (random().nextBoolean()) { + if (random.nextBoolean()) { doc.add(new StringField("binary", randomTerm, Field.Store.NO)); } - randomTerm = new BytesRef(randomTerm()); + randomTerm = new BytesRef(randomTerm(random)); doc.add(new SortedDocValuesField("sorted", randomTerm)); - if (random().nextBoolean()) { + if (random.nextBoolean()) { doc.add(new StringField("sorted", randomTerm, Field.Store.NO)); } - numValues = atLeast(5); + numValues = atLeast(random, 5); for (int i = 0; i < numValues; i++) { - randomTerm = new BytesRef(randomTerm()); + randomTerm = new BytesRef(randomTerm(random)); doc.add(new SortedSetDocValuesField("sorted_set", randomTerm)); - if (random().nextBoolean()) { + if (random.nextBoolean()) { // randomly duplicate field/value doc.add(new SortedSetDocValuesField("sorted_set", randomTerm)); } - if (random().nextBoolean()) { + if (random.nextBoolean()) { // randomly just add a normal string field doc.add(new StringField("sorted_set", randomTerm, Field.Store.NO)); } } - MockAnalyzer mockAnalyzer = new MockAnalyzer(random()); + MockAnalyzer mockAnalyzer = new MockAnalyzer(random); MemoryIndex memoryIndex = MemoryIndex.fromDocument(doc, mockAnalyzer); IndexReader indexReader = memoryIndex.createSearcher().getIndexReader(); LeafReader leafReader = indexReader.leaves().get(0).reader(); Directory dir = newDirectory(); - IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), mockAnalyzer)); + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random, mockAnalyzer)); writer.addDocument(doc); writer.close(); IndexReader controlIndexReader = DirectoryReader.open(dir); @@ -562,9 +587,10 @@ public void testDocValuesMemoryIndexVsNormalIndex() throws Exception { dir.close(); } - public void testNormsWithDocValues() throws Exception { + @Test + public void testNormsWithDocValues(Random random) throws Exception { MemoryIndex mi = new MemoryIndex(true, true); - MockAnalyzer mockAnalyzer = new MockAnalyzer(random()); + MockAnalyzer mockAnalyzer = new MockAnalyzer(random); mi.addField(new BinaryDocValuesField("text", new BytesRef("quick brown fox")), mockAnalyzer); mi.addField(new TextField("text", "quick brown fox", Field.Store.NO), mockAnalyzer); @@ -575,7 +601,7 @@ public void testNormsWithDocValues() throws Exception { Field field = new TextField("text", "quick brown fox", Field.Store.NO); doc.add(field); Directory dir = newDirectory(); - IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), mockAnalyzer)); + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random, mockAnalyzer)); writer.addDocument(doc); writer.close(); @@ -592,13 +618,14 @@ public void testNormsWithDocValues() throws Exception { dir.close(); } - public void testPointValuesMemoryIndexVsNormalIndex() throws Exception { - int size = atLeast(12); + @Test + public void testPointValuesMemoryIndexVsNormalIndex(Random random) throws Exception { + int size = atLeast(random, 12); List randomValues = new ArrayList<>(); Document doc = new Document(); - for (Integer randomInteger : random().ints(size).toArray()) { + for (Integer randomInteger : random.ints(size).toArray()) { doc.add(new IntPoint("int", randomInteger)); randomValues.add(randomInteger); doc.add(new LongPoint("long", randomInteger)); @@ -606,18 +633,18 @@ public void testPointValuesMemoryIndexVsNormalIndex() throws Exception { doc.add(new DoublePoint("double", randomInteger)); } - MockAnalyzer mockAnalyzer = new MockAnalyzer(random()); + MockAnalyzer mockAnalyzer = new MockAnalyzer(random); MemoryIndex memoryIndex = MemoryIndex.fromDocument(doc, mockAnalyzer); IndexSearcher memoryIndexSearcher = memoryIndex.createSearcher(); - Directory dir = newDirectory(); - IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), mockAnalyzer)); + Directory dir = newDirectory(random); + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random, mockAnalyzer)); writer.addDocument(doc); writer.close(); IndexReader controlIndexReader = DirectoryReader.open(dir); IndexSearcher controlIndexSearcher = new IndexSearcher(controlIndexReader); - Supplier valueSupplier = () -> randomValues.get(random().nextInt(randomValues.size())); + Supplier valueSupplier = () -> randomValues.get(random.nextInt(randomValues.size())); Query[] queries = new Query[] { IntPoint.newExactQuery("int", valueSupplier.get()), @@ -642,21 +669,22 @@ public void testPointValuesMemoryIndexVsNormalIndex() throws Exception { dir.close(); } - public void testDuellMemIndex() throws IOException { - LineFileDocs lineFileDocs = new LineFileDocs(random()); - int numDocs = atLeast(10); - MemoryIndex memory = randomMemoryIndex(); + @Test + public void testDuelMemIndex(Random random) throws IOException { + LineFileDocs lineFileDocs = new LineFileDocs(random); + int numDocs = atLeast(random, 10); + MemoryIndex memory = randomMemoryIndex(random); for (int i = 0; i < numDocs; i++) { - Directory dir = newDirectory(); - MockAnalyzer mockAnalyzer = new MockAnalyzer(random()); - mockAnalyzer.setMaxTokenLength(TestUtil.nextInt(random(), 1, IndexWriter.MAX_TERM_LENGTH)); - IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), mockAnalyzer)); + Directory dir = newDirectory(random); + MockAnalyzer mockAnalyzer = new MockAnalyzer(random); + mockAnalyzer.setMaxTokenLength(TestUtil.nextInt(random, 1, IndexWriter.MAX_TERM_LENGTH)); + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random, mockAnalyzer)); Document nextDoc = lineFileDocs.nextDoc(); Document doc = new Document(); for (IndexableField field : nextDoc.getFields()) { if (field.fieldType().indexOptions() != IndexOptions.NONE) { doc.add(field); - if (random().nextInt(3) == 0) { + if (random.nextInt(3) == 0) { doc.add(field); // randomly add the same field twice } } @@ -670,7 +698,7 @@ public void testDuellMemIndex() throws IOException { DirectoryReader competitor = DirectoryReader.open(dir); LeafReader memIndexReader = (LeafReader) memory.createSearcher().getIndexReader(); TestUtil.checkReader(memIndexReader); - duellReaders(competitor, memIndexReader); + duelReaders(competitor, memIndexReader); IOUtils.close(competitor, memIndexReader); memory.reset(); dir.close(); @@ -679,6 +707,7 @@ public void testDuellMemIndex() throws IOException { } // LUCENE-4880 + @Test public void testEmptyString() throws IOException { MemoryIndex memory = new MemoryIndex(); memory.addField("foo", new CannedTokenStream(new Token("", 0, 5))); @@ -688,12 +717,12 @@ public void testEmptyString() throws IOException { TestUtil.checkReader(searcher.getIndexReader()); } - public void testDuelMemoryIndexCoreDirectoryWithArrayField() throws Exception { - + @Test + public void testDuelMemoryIndexCoreDirectoryWithArrayField(Random random) throws Exception { final String field_name = "text"; - MockAnalyzer mockAnalyzer = new MockAnalyzer(random()); - if (random().nextBoolean()) { - mockAnalyzer.setOffsetGap(random().nextInt(100)); + MockAnalyzer mockAnalyzer = new MockAnalyzer(random); + if (random.nextBoolean()) { + mockAnalyzer.setOffsetGap(random.nextInt(100)); } // index into a random directory FieldType type = new FieldType(TextField.TYPE_STORED); @@ -708,7 +737,7 @@ public void testDuelMemoryIndexCoreDirectoryWithArrayField() throws Exception { doc.add(new Field(field_name, "foo bar foo bar foo", type)); Directory dir = newDirectory(); - IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), mockAnalyzer)); + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random, mockAnalyzer)); writer.updateDocument(new Term("id", "1"), doc); writer.commit(); writer.close(); @@ -759,21 +788,21 @@ protected void compareTermVectors(Terms terms, Terms memTerms, String field_name String failDesc = " (field:" + field_name + " term:" + currentTerm + ")"; int memPos = memDocsPosEnum.nextPosition(); int pos = docsPosEnum.nextPosition(); - assertEquals("Position test failed" + failDesc, pos, memPos); + assertEquals(pos, memPos, "Position test failed" + failDesc); assertEquals( - "Start offset test failed" + failDesc, docsPosEnum.startOffset(), - memDocsPosEnum.startOffset()); + memDocsPosEnum.startOffset(), + "Start offset test failed" + failDesc); assertEquals( - "End offset test failed" + failDesc, docsPosEnum.endOffset(), - memDocsPosEnum.endOffset()); + memDocsPosEnum.endOffset(), + "End offset test failed" + failDesc); assertEquals( - "Missing payload test failed" + failDesc, docsPosEnum.getPayload(), - memDocsPosEnum.getPayload()); + memDocsPosEnum.getPayload(), + "Missing payload test failed" + failDesc); } } - assertNull("Still some tokens not processed", memTermEnum.next()); + assertNull(memTermEnum.next(), "Still some tokens not processed"); } } diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java index d8e7c420fea6..a852702fa687 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java @@ -18,12 +18,15 @@ import java.util.ArrayList; import java.util.List; -import org.apache.lucene.tests.util.LuceneTestCase; +import java.util.Random; +import org.apache.lucene.tests.util.LuceneTestCase2; import org.apache.lucene.util.Counter; import org.apache.lucene.util.IntBlockPool; +import org.junit.jupiter.api.Test; -public class TestSlicedIntBlockPool extends LuceneTestCase { - public void testSingleWriterReader() { +public class TestSlicedIntBlockPool extends LuceneTestCase2 { + @Test + public void testSingleWriterReader(Random random) { Counter bytesUsed = Counter.newCounter(); MemoryIndex.SlicedIntBlockPool slicedIntBlockPool = new MemoryIndex.SlicedIntBlockPool(new ByteTrackingAllocator(bytesUsed)); @@ -32,7 +35,7 @@ public void testSingleWriterReader() { MemoryIndex.SlicedIntBlockPool.SliceWriter writer = new MemoryIndex.SlicedIntBlockPool.SliceWriter(slicedIntBlockPool); int start = writer.startNewSlice(); - int num = atLeast(100); + int num = atLeast(random, 100); for (int i = 0; i < num; i++) { writer.writeInt(i); } @@ -45,7 +48,7 @@ public void testSingleWriterReader() { assertEquals(i, reader.readInt()); } assertTrue(reader.endOfSlice()); - if (random().nextBoolean()) { + if (random.nextBoolean()) { slicedIntBlockPool.reset(true, false); assertEquals(0, bytesUsed.get()); } else { @@ -55,24 +58,25 @@ public void testSingleWriterReader() { } } - public void testMultipleWriterReader() { + @Test + public void testMultipleWriterReader(Random random) { Counter bytesUsed = Counter.newCounter(); MemoryIndex.SlicedIntBlockPool slicedIntBlockPool = new MemoryIndex.SlicedIntBlockPool(new ByteTrackingAllocator(bytesUsed)); for (int j = 0; j < 2; j++) { List holders = new ArrayList<>(); - int num = atLeast(4); + int num = atLeast(random, 4); for (int i = 0; i < num; i++) { - holders.add(new StartEndAndValues(random().nextInt(1000))); + holders.add(new StartEndAndValues(random.nextInt(1000))); } MemoryIndex.SlicedIntBlockPool.SliceWriter writer = new MemoryIndex.SlicedIntBlockPool.SliceWriter(slicedIntBlockPool); MemoryIndex.SlicedIntBlockPool.SliceReader reader = new MemoryIndex.SlicedIntBlockPool.SliceReader(slicedIntBlockPool); - int numValuesToWrite = atLeast(10000); + int numValuesToWrite = atLeast(random, 10000); for (int i = 0; i < numValuesToWrite; i++) { - StartEndAndValues values = holders.get(random().nextInt(holders.size())); + StartEndAndValues values = holders.get(random.nextInt(holders.size())); if (values.valueCount == 0) { values.start = writer.startNewSlice(); } else { @@ -80,17 +84,17 @@ public void testMultipleWriterReader() { } writer.writeInt(values.nextValue()); values.end = writer.getCurrentOffset(); - if (random().nextInt(5) == 0) { + if (random.nextInt(5) == 0) { // pick one and reader the ints - assertReader(reader, holders.get(random().nextInt(holders.size()))); + assertReader(reader, holders.get(random.nextInt(holders.size()))); } } while (!holders.isEmpty()) { - StartEndAndValues values = holders.remove(random().nextInt(holders.size())); + StartEndAndValues values = holders.remove(random.nextInt(holders.size())); assertReader(reader, values); } - if (random().nextBoolean()) { + if (random.nextBoolean()) { slicedIntBlockPool.reset(true, false); assertEquals(0, bytesUsed.get()); } else { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/analysis/MockTokenizer.java b/lucene/test-framework/src/java/org/apache/lucene/tests/analysis/MockTokenizer.java index c5e5bddf0952..aef160c7fb40 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/analysis/MockTokenizer.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/analysis/MockTokenizer.java @@ -16,13 +16,13 @@ */ package org.apache.lucene.tests.analysis; -import com.carrotsearch.randomizedtesting.RandomizedContext; import java.io.IOException; import java.nio.CharBuffer; import java.util.Random; import org.apache.lucene.analysis.Tokenizer; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; +import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.AttributeFactory; import org.apache.lucene.util.automaton.CharacterRunAutomaton; import org.apache.lucene.util.automaton.Operations; @@ -105,7 +105,7 @@ private enum State { private boolean enableChecks = true; // evil: but we don't change the behavior with this random, we only switch up how we read - private final Random random = new Random(RandomizedContext.current().getRandom().nextLong()); + private final Random random; public MockTokenizer( AttributeFactory factory, @@ -117,6 +117,7 @@ public MockTokenizer( this.lowerCase = lowerCase; this.state = 0; this.maxTokenLength = maxTokenLength; + this.random = new Random(LuceneTestCase.random().nextLong()); } public MockTokenizer(CharacterRunAutomaton runAutomaton, boolean lowerCase, int maxTokenLength) { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStaticRandomAccess.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStaticRandomAccess.java new file mode 100644 index 000000000000..e26cadd5f290 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStaticRandomAccess.java @@ -0,0 +1,71 @@ +package org.apache.lucene.tests.util; + +import java.io.Closeable; +import java.util.Objects; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import org.apache.lucene.util.IOUtils; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +public final class GlobalStaticRandomAccess + implements BeforeEachCallback, AfterEachCallback, BeforeAllCallback, AfterAllCallback { + private ConcurrentHashMap perThreadRandoms; + private Supplier previousSupplier; + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + if (perThreadRandoms != null) { + throw new RuntimeException( + "Expected perThreadRandoms to be null (single-threaded, sequential test execution)."); + } + perThreadRandoms = new ConcurrentHashMap<>(); + + // This trick is needed to get the Supplier injected by a parameter resolved + // of the randomized testing framework. + @SuppressWarnings("unchecked") + Supplier rnd = + (Supplier) + Objects.requireNonNull( + context + .getExecutableInvoker() + .invoke(getClass().getMethod("beforeAll0", Supplier.class), this)); + + previousSupplier = + LuceneTestCase.replaceRandomSupplier( + () -> perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get())); + } + + public Supplier beforeAll0(Supplier rnd) { + return rnd; + } + + @Override + public void beforeEach(ExtensionContext context) throws Exception { + // TODO: push test context? + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + // TODO: push test context? + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + try { + LuceneTestCase.replaceRandomSupplier(previousSupplier); + IOUtils.close( + perThreadRandoms.values().stream() + .filter(rnd1 -> rnd1 instanceof Closeable) + .map(rnd1 -> (Closeable) rnd1) + .toList()); + } finally { + perThreadRandoms = null; + previousSupplier = null; + } + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index e9dbfd823142..4c25575c9986 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -18,7 +18,6 @@ package org.apache.lucene.tests.util; import static com.carrotsearch.randomizedtesting.RandomizedTest.frequently; -import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean; import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean; import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsInt; import static org.apache.lucene.search.DocIdSetIterator.NO_MORE_DOCS; @@ -83,6 +82,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.TimeZone; @@ -725,7 +725,13 @@ static void setLiveIWCFlushMode(LiveIWCFlushMode flushMode) { liveIWCFlushMode = flushMode; } - private static final Supplier randomSupplier; + private static volatile AtomicReference> randomSupplier = + new AtomicReference<>(); + + /** Internal use only; replace the current {@link #randomSupplier}. */ + static Supplier replaceRandomSupplier(Supplier rndSupplier) { + return randomSupplier.getAndSet(rndSupplier); + } /** A counter of calls to {@link #random()} if {@link #SYSPROP_RANDOM_MAXACQUIRES} is defined. */ @SuppressWarnings("NonFinalStaticField") @@ -753,7 +759,7 @@ static void setLiveIWCFlushMode(LiveIWCFlushMode flushMode) { }; } - randomSupplier = supplier; + replaceRandomSupplier(supplier); } // ----------------------------------------------------------------- @@ -813,7 +819,7 @@ public void restoreIndexWriterMaxDocs() { * multiple invocations are present. See {@link #nonAssertingRandom(Random)}. */ public static Random random() { - return randomSupplier.get(); + return Objects.requireNonNull(randomSupplier.get()).get(); } /** @@ -1964,7 +1970,7 @@ public static IndexSearcher newSearcher(IndexReader r, boolean maybeWrap) { */ public static IndexSearcher newSearcher( IndexReader r, boolean maybeWrap, boolean wrapWithAssertions) { - return newSearcher(r, maybeWrap, wrapWithAssertions, randomBoolean()); + return newSearcher(r, maybeWrap, wrapWithAssertions, random().nextBoolean()); } /** diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java index dcc7bdae6cf5..19cce60539e6 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java @@ -20,15 +20,18 @@ import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; import com.carrotsearch.randomizedtesting.jupiter.Randomized; import com.carrotsearch.randomizedtesting.jupiter.SystemThreadFilter; +import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.lucene.util.Constants; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; import org.junit.platform.commons.support.AnnotationSupport; @@ -71,6 +74,7 @@ /* // TODO: port these. - reproduce info listener, failuremarker? @Listeners({RunListenerPrintReproduceInfo.class, FailureMarker.class}) +- predictable test ordering - test sysout rule @TestRuleLimitSysouts.Limit( bytes = TestRuleLimitSysouts.DEFAULT_LIMIT, @@ -81,8 +85,11 @@ @DetectThreadLeaks.LingerTime(millis = 20_000) @DetectThreadLeaks.ExcludeThreads({SystemThreadFilter.class, LuceneTestCase2.IsSystemThread.class}) @Timeout(value = 2, unit = TimeUnit.HOURS) -@Execution(value = ExecutionMode.SAME_THREAD, reason = "backward compatibility.") -public abstract class LuceneTestCase2 { +@Execution( + value = ExecutionMode.SAME_THREAD, + reason = "single-threaded for backward compatibility.") +@ExtendWith({GlobalStaticRandomAccess.class}) +public abstract class LuceneTestCase2 extends Assertions { /** * This predicate should return {@code true} for threads that should be ignored in {@linkplain * DetectThreadLeaks thread leak detection}. @@ -114,6 +121,14 @@ public boolean test(Thread t) { } } + // + // Custom assertion methods. + // + + public static int atLeast(Random random, int i) { + return LuceneTestCase.atLeast(random, i); + } + // // Deprecated or removed methods (LuceneTestCase) and other backward-compatibility // infrastructure. @@ -152,4 +167,9 @@ protected final void setUp() throws Exception {} /** Use jupiter's {@link AfterEach} instead. */ protected final void tearDown() throws Exception {} + + public static T expectThrows( + Class expectedType, LuceneTestCase.ThrowingRunnable runnable) { + return LuceneTestCase.expectThrows(expectedType, runnable); + } } From dd89ef64395b601872906f376d1832db20272683 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 16 Apr 2026 10:47:18 +0200 Subject: [PATCH 10/68] Pull up a base class for junit4/junit5, some renames. --- .../lucene/search/join/TestJupiter.java | 8 +- .../lucene/index/memory/TestMemoryIndex.java | 4 +- .../TestMemoryIndexAgainstDirectory.java | 28 +++--- .../index/memory/TestSlicedIntBlockPool.java | 4 +- .../lucene/tests/util/GlobalStateSupport.java | 92 +++++++++++++++++++ .../tests/util/GlobalStaticRandomAccess.java | 71 -------------- .../lucene/tests/util/LuceneTestCase.java | 43 +-------- ...tCase2.java => LuceneTestCaseJupiter.java} | 23 ++++- .../tests/util/LuceneTestCaseParent.java | 56 +++++++++++ 9 files changed, 189 insertions(+), 140 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java delete mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStaticRandomAccess.java rename lucene/test-framework/src/java/org/apache/lucene/tests/util/{LuceneTestCase2.java => LuceneTestCaseJupiter.java} (90%) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java index e1378836adea..bc0db043905c 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java @@ -20,7 +20,7 @@ import java.util.Random; import java.util.concurrent.TimeUnit; import org.apache.lucene.tests.util.LuceneTestCase; -import org.apache.lucene.tests.util.LuceneTestCase2; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -29,13 +29,13 @@ @Timeout(value = 3, unit = TimeUnit.SECONDS) public class TestJupiter { @Nested - class T1 extends LuceneTestCase2 { + class T1 extends LuceneTestCaseJupiter { @Test public void t1() throws Exception { Random r1 = LuceneTestCase.random(); Random r2 = LuceneTestCase.random(); Assertions.assertSame(r1, r2); - System.out.println("R: " + Objects.hashCode(r1) + " " + r1.nextLong()); + System.out.println("R: " + random().nextLong()); } @Test @@ -58,7 +58,7 @@ public void t2() throws Exception { } @Nested - public class T2 extends LuceneTestCase2 { + public class T2 extends LuceneTestCaseJupiter { @Test public void testNoParent(Random random) throws Exception {} } diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java index 41446f9fdb84..2c194c03c4e0 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java @@ -93,14 +93,14 @@ import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.analysis.MockPayloadAnalyzer; -import org.apache.lucene.tests.util.LuceneTestCase2; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRef; import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class TestMemoryIndex extends LuceneTestCase2 { +public class TestMemoryIndex extends LuceneTestCaseJupiter { private MockAnalyzer analyzer; @BeforeEach diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java index e2593bb2cce5..606d99adb92f 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java @@ -91,7 +91,7 @@ import org.apache.lucene.tests.analysis.MockTokenizer; import org.apache.lucene.tests.analysis.Token; import org.apache.lucene.tests.util.LineFileDocs; -import org.apache.lucene.tests.util.LuceneTestCase2; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; @@ -103,7 +103,7 @@ * Verifies that Lucene MemoryIndex and RAM-resident Directory have the same behavior, returning the * same results for queries on some randomish indexes. */ -public class TestMemoryIndexAgainstDirectory extends LuceneTestCase2 { +public class TestMemoryIndexAgainstDirectory extends LuceneTestCaseJupiter { private static Set queries = new HashSet<>(); @BeforeAll @@ -233,9 +233,9 @@ private void duelReaders(CompositeReader other, LeafReader memIndexReader) throw assertEquals(iwDocsAndPos.freq(), memDocsAndPos.freq()); for (int i = 0; i < iwDocsAndPos.freq(); i++) { assertEquals( + "term: " + iwTermsIter.term().utf8ToString(), iwDocsAndPos.nextPosition(), - memDocsAndPos.nextPosition(), - "term: " + iwTermsIter.term().utf8ToString()); + memDocsAndPos.nextPosition()); if (offsets) { assertEquals(iwDocsAndPos.startOffset(), memDocsAndPos.startOffset()); assertEquals(iwDocsAndPos.endOffset(), memDocsAndPos.endOffset()); @@ -272,7 +272,7 @@ public void assertAllQueries(MemoryIndex memory, Directory directory, Analyzer a for (String query : queries) { TopDocs ramDocs = ram.search(qp.parse(query), 1); TopDocs memDocs = mem.search(qp.parse(query), 1); - assertEquals(ramDocs.totalHits.value(), memDocs.totalHits.value(), query); + assertEquals(query, ramDocs.totalHits.value(), memDocs.totalHits.value()); } reader.close(); } @@ -468,7 +468,7 @@ public void testSameFieldAddedMultipleTimes(Random random) throws IOException { assertEquals(0, mindex.search(query), 0.00001f); query = new PhraseQuery(10, "field", "fox", "jumps"); assertTrue( - mindex.search(query) > 0.0001, "posGap" + mockAnalyzer.getPositionIncrementGap("field")); + "posGap" + mockAnalyzer.getPositionIncrementGap("field"), mindex.search(query) > 0.0001); TestUtil.checkReader(mindex.createSearcher().getIndexReader()); } @@ -788,21 +788,21 @@ protected void compareTermVectors(Terms terms, Terms memTerms, String field_name String failDesc = " (field:" + field_name + " term:" + currentTerm + ")"; int memPos = memDocsPosEnum.nextPosition(); int pos = docsPosEnum.nextPosition(); - assertEquals(pos, memPos, "Position test failed" + failDesc); + assertEquals("Position test failed" + failDesc, pos, memPos); assertEquals( + "Start offset test failed" + failDesc, docsPosEnum.startOffset(), - memDocsPosEnum.startOffset(), - "Start offset test failed" + failDesc); + memDocsPosEnum.startOffset()); assertEquals( + "End offset test failed" + failDesc, docsPosEnum.endOffset(), - memDocsPosEnum.endOffset(), - "End offset test failed" + failDesc); + memDocsPosEnum.endOffset()); assertEquals( + "Missing payload test failed" + failDesc, docsPosEnum.getPayload(), - memDocsPosEnum.getPayload(), - "Missing payload test failed" + failDesc); + memDocsPosEnum.getPayload()); } } - assertNull(memTermEnum.next(), "Still some tokens not processed"); + assertNull("Still some tokens not processed", memTermEnum.next()); } } diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java index a852702fa687..9d78be89bf76 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java @@ -19,12 +19,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -import org.apache.lucene.tests.util.LuceneTestCase2; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; import org.apache.lucene.util.Counter; import org.apache.lucene.util.IntBlockPool; import org.junit.jupiter.api.Test; -public class TestSlicedIntBlockPool extends LuceneTestCase2 { +public class TestSlicedIntBlockPool extends LuceneTestCaseJupiter { @Test public void testSingleWriterReader(Random random) { Counter bytesUsed = Counter.newCounter(); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java new file mode 100644 index 000000000000..e673d8c24589 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java @@ -0,0 +1,92 @@ +package org.apache.lucene.tests.util; + +import java.io.Closeable; +import java.util.Objects; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import org.apache.lucene.util.IOUtils; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExecutableInvoker; +import org.junit.jupiter.api.extension.ExtensionContext; + +/** + * Simulate global state for backward compatibility with static methods from {@link LuceneTestCase} + * that are used all over the place. + */ +public final class GlobalStateSupport implements BeforeAllCallback, AfterAllCallback { + private final ExtensionContext.Namespace NS = + ExtensionContext.Namespace.create(getClass().getName()); + + private static final class State { + private ConcurrentHashMap perThreadRandoms; + private Supplier previousSupplier; + + void reset() { + perThreadRandoms = null; + previousSupplier = null; + } + + void initialize() { + if (perThreadRandoms != null) { + throw new RuntimeException( + "Expected perThreadRandoms to be null (single-threaded, sequential test execution)."); + } + perThreadRandoms = new ConcurrentHashMap<>(); + } + } + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + State state = getState(context); + state.initialize(); + + Supplier rnd = getRandomSupplier(context.getExecutableInvoker()); + + var perThreadRandoms = state.perThreadRandoms; + state.previousSupplier = + LuceneTestCaseParent.replaceRandomSupplier( + () -> perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get())); + } + + // This trick is needed to get the Supplier injected by a parameter resolved + // of the randomized testing framework. + private Supplier getRandomSupplier(ExecutableInvoker executableInvoker) throws Exception { + var hack = + new Object() { + public Supplier captureParameter(Supplier rnd) { + return rnd; + } + }; + + @SuppressWarnings("unchecked") + Supplier rnd = + (Supplier) + Objects.requireNonNull( + executableInvoker.invoke( + hack.getClass().getMethod("captureParameter", Supplier.class), hack)); + return rnd; + } + + private State getState(ExtensionContext context) { + return context + .getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS) + .computeIfAbsent(State.class); + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + var state = getState(context); + try { + LuceneTestCaseParent.replaceRandomSupplier(state.previousSupplier); + IOUtils.close( + state.perThreadRandoms.values().stream() + .filter(rnd1 -> rnd1 instanceof Closeable) + .map(rnd1 -> (Closeable) rnd1) + .toList()); + } finally { + state.reset(); + } + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStaticRandomAccess.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStaticRandomAccess.java deleted file mode 100644 index e26cadd5f290..000000000000 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStaticRandomAccess.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.apache.lucene.tests.util; - -import java.io.Closeable; -import java.util.Objects; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; -import org.apache.lucene.util.IOUtils; -import org.junit.jupiter.api.extension.AfterAllCallback; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeAllCallback; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; - -public final class GlobalStaticRandomAccess - implements BeforeEachCallback, AfterEachCallback, BeforeAllCallback, AfterAllCallback { - private ConcurrentHashMap perThreadRandoms; - private Supplier previousSupplier; - - @Override - public void beforeAll(ExtensionContext context) throws Exception { - if (perThreadRandoms != null) { - throw new RuntimeException( - "Expected perThreadRandoms to be null (single-threaded, sequential test execution)."); - } - perThreadRandoms = new ConcurrentHashMap<>(); - - // This trick is needed to get the Supplier injected by a parameter resolved - // of the randomized testing framework. - @SuppressWarnings("unchecked") - Supplier rnd = - (Supplier) - Objects.requireNonNull( - context - .getExecutableInvoker() - .invoke(getClass().getMethod("beforeAll0", Supplier.class), this)); - - previousSupplier = - LuceneTestCase.replaceRandomSupplier( - () -> perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get())); - } - - public Supplier beforeAll0(Supplier rnd) { - return rnd; - } - - @Override - public void beforeEach(ExtensionContext context) throws Exception { - // TODO: push test context? - } - - @Override - public void afterEach(ExtensionContext context) throws Exception { - // TODO: push test context? - } - - @Override - public void afterAll(ExtensionContext context) throws Exception { - try { - LuceneTestCase.replaceRandomSupplier(previousSupplier); - IOUtils.close( - perThreadRandoms.values().stream() - .filter(rnd1 -> rnd1 instanceof Closeable) - .map(rnd1 -> (Closeable) rnd1) - .toList()); - } finally { - perThreadRandoms = null; - previousSupplier = null; - } - } -} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 2571eaa1f226..11490d1edd07 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -29,7 +29,6 @@ import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedRunner; import com.carrotsearch.randomizedtesting.RandomizedTest; -import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom; import com.carrotsearch.randomizedtesting.annotations.Listeners; import com.carrotsearch.randomizedtesting.annotations.SeedDecorators; import com.carrotsearch.randomizedtesting.annotations.TestGroup; @@ -82,7 +81,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.TimeZone; @@ -207,7 +205,6 @@ import org.hamcrest.MatcherAssert; import org.junit.After; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; @@ -276,7 +273,7 @@ @TestRuleLimitSysouts.Limit( bytes = TestRuleLimitSysouts.DEFAULT_LIMIT, hardLimit = TestRuleLimitSysouts.DEFAULT_HARD_LIMIT) -public abstract class LuceneTestCase extends Assert { +public abstract non-sealed class LuceneTestCase extends LuceneTestCaseParent { // -------------------------------------------------------------------- // Test groups, system properties and other annotations modifying tests @@ -725,14 +722,6 @@ static void setLiveIWCFlushMode(LiveIWCFlushMode flushMode) { liveIWCFlushMode = flushMode; } - private static volatile AtomicReference> randomSupplier = - new AtomicReference<>(); - - /** Internal use only; replace the current {@link #randomSupplier}. */ - static Supplier replaceRandomSupplier(Supplier rndSupplier) { - return randomSupplier.getAndSet(rndSupplier); - } - /** A counter of calls to {@link #random()} if {@link #SYSPROP_RANDOM_MAXACQUIRES} is defined. */ @SuppressWarnings("NonFinalStaticField") private static AtomicLong randomCalls = new AtomicLong(); @@ -803,36 +792,6 @@ public void restoreIndexWriterMaxDocs() { // Test facilities and facades for subclasses. // ----------------------------------------------------------------- - /** - * Access to the current {@link RandomizedContext}'s Random instance. It is safe to use this - * method from multiple threads, etc., but it should be called while within a runner's scope (so - * no static initializers). The returned {@link Random} instance will be different when - * this method is called inside a {@link BeforeClass} hook (static suite scope) and within {@link - * Before}/ {@link After} hooks or test methods. - * - *

The returned instance must not be shared with other threads or cross a single scope's - * boundary. For example, a {@link Random} acquired within a test method shouldn't be reused for - * another test case. - * - *

There is an overhead connected with getting the {@link Random} for a particular context and - * thread. It is better to use a non-asserting {@link Random} instance locally if tight loops with - * multiple invocations are present. See {@link #nonAssertingRandom(Random)}. - */ - public static Random random() { - return Objects.requireNonNull(randomSupplier.get()).get(); - } - - /** - * Returns a Random instance based on the current state of another Random. The returned instance - * should be faster for thousands of consecutive calls because it doesn't assert that it isn't - * shared between threads or used within the correct {@link RandomizedContext}. - * - *

Use this method for local tight loops that generate a lot of random data. - */ - public static Random nonAssertingRandom(Random rnd) { - return new Xoroshiro128PlusRandom(rnd.nextLong()); - } - /** * Registers a {@link Closeable} resource that should be closed after the test completes. * diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java similarity index 90% rename from lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java rename to lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 19cce60539e6..e31981eb95b6 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase2.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -27,7 +27,6 @@ import java.util.stream.Stream; import org.apache.lucene.util.Constants; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; @@ -62,7 +61,7 @@ /// /// ## Randomized execution and test facilities /// -/// [LuceneTestCase2] uses the [Randomized] extension to support component randomization. +/// [LuceneTestCaseJupiter] uses the [Randomized] extension to support component randomization. /// A [Random] can be automatically injected in the test (or any junit5 callback) as a parameter. /// Tests should be fully reproducible for the same initial seed /// (assuming no race conditions between threads @@ -83,13 +82,16 @@ @Randomized @DetectThreadLeaks(scope = DetectThreadLeaks.Scope.SUITE) @DetectThreadLeaks.LingerTime(millis = 20_000) -@DetectThreadLeaks.ExcludeThreads({SystemThreadFilter.class, LuceneTestCase2.IsSystemThread.class}) +@DetectThreadLeaks.ExcludeThreads({ + SystemThreadFilter.class, + LuceneTestCaseJupiter.IsSystemThread.class +}) @Timeout(value = 2, unit = TimeUnit.HOURS) @Execution( value = ExecutionMode.SAME_THREAD, reason = "single-threaded for backward compatibility.") -@ExtendWith({GlobalStaticRandomAccess.class}) -public abstract class LuceneTestCase2 extends Assertions { +@ExtendWith({GlobalStateSupport.class}) +public abstract non-sealed class LuceneTestCaseJupiter extends LuceneTestCaseParent { /** * This predicate should return {@code true} for threads that should be ignored in {@linkplain * DetectThreadLeaks thread leak detection}. @@ -134,6 +136,17 @@ public static int atLeast(Random random, int i) { // infrastructure. // + /** + * Whenever possible, you should use an injected {@link Random} or {@link + * java.util.function.Supplier} parameter on junit5 test methods. + * + *

Global static methods make running test suites in parallel impossible. + */ + @Deprecated + public static Random random() { + return LuceneTestCaseParent.random(); + } + /** * Unfortunately there is no easy way to implement custom test providers in jupiter so we just * enforce annotations on {@code test*} methods (so that they're not silently ignored). diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java new file mode 100644 index 000000000000..8cfe115bc1c7 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -0,0 +1,56 @@ +package org.apache.lucene.tests.util; + +import com.carrotsearch.randomizedtesting.RandomizedContext; +import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom; +import java.util.Objects; +import java.util.Random; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; + +/** + * Private parent class for junit4 ({@link LuceneTestCase} and junit5 ({@link + * LuceneTestCaseJupiter}). + */ +abstract sealed class LuceneTestCaseParent extends Assert + permits LuceneTestCase, LuceneTestCaseJupiter { + private static volatile AtomicReference> randomSupplier = + new AtomicReference<>(); + + static Supplier replaceRandomSupplier(Supplier rndSupplier) { + return randomSupplier.getAndSet(rndSupplier); + } + + /** + * Access to the current {@link RandomizedContext}'s Random instance. It is safe to use this + * method from multiple threads, etc., but it should be called while within a runner's scope (so + * no static initializers). The returned {@link Random} instance will be different when + * this method is called inside a {@link BeforeClass} hook (static suite scope) and within {@link + * Before}/ {@link After} hooks or test methods. + * + *

The returned instance must not be shared with other threads or cross a single scope's + * boundary. For example, a {@link Random} acquired within a test method shouldn't be reused for + * another test case. + * + *

There is an overhead connected with getting the {@link Random} for a particular context and + * thread. It is better to use a non-asserting {@link Random} instance locally if tight loops with + * multiple invocations are present. See {@link #nonAssertingRandom(Random)}. + */ + public static Random random() { + return Objects.requireNonNull(randomSupplier.get()).get(); + } + + /** + * Returns a Random instance based on the current state of another Random. The returned instance + * should be faster for thousands of consecutive calls because it doesn't assert that it isn't + * shared between threads or used within the correct {@link RandomizedContext}. + * + *

Use this method for local tight loops that generate a lot of random data. + */ + public static Random nonAssertingRandom(Random rnd) { + return new Xoroshiro128PlusRandom(rnd.nextLong()); + } +} From ca951d0cc6f62debb0bee28b70d0dde796f0a67f Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 16 Apr 2026 12:04:34 +0200 Subject: [PATCH 11/68] Passing tests. --- .../lucene/search/join/TestJupiter.java | 10 + .../licenses/apiguardian-api-1.1.2.jar.sha1 | 1 + .../licenses/apiguardian-api-LICENSE-ASL.txt | 202 +++ lucene/licenses/apiguardian-api-NOTICE.txt | 0 lucene/licenses/jspecify-1.0.0.jar.sha1 | 1 + lucene/licenses/jspecify-LICENSE-ASL.txt | 202 +++ lucene/licenses/jspecify-NOTICE.txt | 0 lucene/licenses/junit-jupiter-6.0.3.jar.sha1 | 1 + .../licenses/junit-jupiter-api-6.0.3.jar.sha1 | 1 + .../junit-jupiter-engine-6.0.3.jar.sha1 | 1 + .../junit-jupiter-params-6.0.3.jar.sha1 | 1 + .../randomizedtesting-jupiter-0.2.0.jar.sha1 | 1 + .../randomizedtesting-jupiter-LICENSE-ASL.txt | 202 +++ .../randomizedtesting-jupiter-NOTICE.txt | 0 .../test-framework/src/java/module-info.java | 3 + .../lucene/tests/util/GlobalStateSupport.java | 106 +- .../lucene/tests/util/LuceneTestCase.java | 63 +- .../tests/util/LuceneTestCaseJupiter.java | 4 +- .../tests/util/LuceneTestCaseParent.java | 47 +- .../util/TestRuleSetupAndRestoreClassEnv.java | 22 +- .../apache/lucene/tests/util/TestUtil.java | 3 +- versions.lock | 1177 ++++++++++++++++- 22 files changed, 1945 insertions(+), 103 deletions(-) create mode 100644 lucene/licenses/apiguardian-api-1.1.2.jar.sha1 create mode 100644 lucene/licenses/apiguardian-api-LICENSE-ASL.txt create mode 100644 lucene/licenses/apiguardian-api-NOTICE.txt create mode 100644 lucene/licenses/jspecify-1.0.0.jar.sha1 create mode 100644 lucene/licenses/jspecify-LICENSE-ASL.txt create mode 100644 lucene/licenses/jspecify-NOTICE.txt create mode 100644 lucene/licenses/junit-jupiter-6.0.3.jar.sha1 create mode 100644 lucene/licenses/junit-jupiter-api-6.0.3.jar.sha1 create mode 100644 lucene/licenses/junit-jupiter-engine-6.0.3.jar.sha1 create mode 100644 lucene/licenses/junit-jupiter-params-6.0.3.jar.sha1 create mode 100644 lucene/licenses/randomizedtesting-jupiter-0.2.0.jar.sha1 create mode 100644 lucene/licenses/randomizedtesting-jupiter-LICENSE-ASL.txt create mode 100644 lucene/licenses/randomizedtesting-jupiter-NOTICE.txt diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java index bc0db043905c..5cd8d1b41f2c 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java @@ -16,6 +16,8 @@ */ package org.apache.lucene.search.join; +import java.io.Closeable; +import java.io.IOException; import java.util.Objects; import java.util.Random; import java.util.concurrent.TimeUnit; @@ -32,6 +34,14 @@ public class TestJupiter { class T1 extends LuceneTestCaseJupiter { @Test public void t1() throws Exception { + closeAfterSuite( + new Closeable() { + @Override + public void close() throws IOException { + System.out.println("Closed."); + } + }); + Random r1 = LuceneTestCase.random(); Random r2 = LuceneTestCase.random(); Assertions.assertSame(r1, r2); diff --git a/lucene/licenses/apiguardian-api-1.1.2.jar.sha1 b/lucene/licenses/apiguardian-api-1.1.2.jar.sha1 new file mode 100644 index 000000000000..4fb58e602aa8 --- /dev/null +++ b/lucene/licenses/apiguardian-api-1.1.2.jar.sha1 @@ -0,0 +1 @@ +a231e0d844d2721b0fa1b238006d15c6ded6842a diff --git a/lucene/licenses/apiguardian-api-LICENSE-ASL.txt b/lucene/licenses/apiguardian-api-LICENSE-ASL.txt new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/lucene/licenses/apiguardian-api-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/lucene/licenses/apiguardian-api-NOTICE.txt b/lucene/licenses/apiguardian-api-NOTICE.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lucene/licenses/jspecify-1.0.0.jar.sha1 b/lucene/licenses/jspecify-1.0.0.jar.sha1 new file mode 100644 index 000000000000..6a8a9a9d37c7 --- /dev/null +++ b/lucene/licenses/jspecify-1.0.0.jar.sha1 @@ -0,0 +1 @@ +7425a601c1c7ec76645a78d22b8c6a627edee507 diff --git a/lucene/licenses/jspecify-LICENSE-ASL.txt b/lucene/licenses/jspecify-LICENSE-ASL.txt new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/lucene/licenses/jspecify-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/lucene/licenses/jspecify-NOTICE.txt b/lucene/licenses/jspecify-NOTICE.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lucene/licenses/junit-jupiter-6.0.3.jar.sha1 b/lucene/licenses/junit-jupiter-6.0.3.jar.sha1 new file mode 100644 index 000000000000..78a08a02fd46 --- /dev/null +++ b/lucene/licenses/junit-jupiter-6.0.3.jar.sha1 @@ -0,0 +1 @@ +da72f4bc0feccbca639b901ace26e3a62512ebec diff --git a/lucene/licenses/junit-jupiter-api-6.0.3.jar.sha1 b/lucene/licenses/junit-jupiter-api-6.0.3.jar.sha1 new file mode 100644 index 000000000000..21ea8d898975 --- /dev/null +++ b/lucene/licenses/junit-jupiter-api-6.0.3.jar.sha1 @@ -0,0 +1 @@ +2e6cfb62db85350179f0408ed5270f7cdf8cefda diff --git a/lucene/licenses/junit-jupiter-engine-6.0.3.jar.sha1 b/lucene/licenses/junit-jupiter-engine-6.0.3.jar.sha1 new file mode 100644 index 000000000000..59ac4203c558 --- /dev/null +++ b/lucene/licenses/junit-jupiter-engine-6.0.3.jar.sha1 @@ -0,0 +1 @@ +e26f7e17d06cfc85ba7643b5ad00c87d5f2084dd diff --git a/lucene/licenses/junit-jupiter-params-6.0.3.jar.sha1 b/lucene/licenses/junit-jupiter-params-6.0.3.jar.sha1 new file mode 100644 index 000000000000..8497dc9f8b73 --- /dev/null +++ b/lucene/licenses/junit-jupiter-params-6.0.3.jar.sha1 @@ -0,0 +1 @@ +6cd3efadd171a3ddd70413868a9c3af988a45907 diff --git a/lucene/licenses/randomizedtesting-jupiter-0.2.0.jar.sha1 b/lucene/licenses/randomizedtesting-jupiter-0.2.0.jar.sha1 new file mode 100644 index 000000000000..3923da66ac1b --- /dev/null +++ b/lucene/licenses/randomizedtesting-jupiter-0.2.0.jar.sha1 @@ -0,0 +1 @@ +b205d971bdbba960f6aa7b177f7dae2602112568 diff --git a/lucene/licenses/randomizedtesting-jupiter-LICENSE-ASL.txt b/lucene/licenses/randomizedtesting-jupiter-LICENSE-ASL.txt new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/lucene/licenses/randomizedtesting-jupiter-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/lucene/licenses/randomizedtesting-jupiter-NOTICE.txt b/lucene/licenses/randomizedtesting-jupiter-NOTICE.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/lucene/test-framework/src/java/module-info.java b/lucene/test-framework/src/java/module-info.java index ba14aaf7474e..17bb6a3ca45f 100644 --- a/lucene/test-framework/src/java/module-info.java +++ b/lucene/test-framework/src/java/module-info.java @@ -25,10 +25,13 @@ requires transitive com.carrotsearch.randomizedtesting; requires transitive org.junit.jupiter.api; requires org.hamcrest; + requires java.sql; // Open certain packages for junit because it scans methods via reflection. opens org.apache.lucene.tests.index to junit; + opens org.apache.lucene.tests.util to + org.junit.platform.commons; exports org.apache.lucene.tests.analysis.standard; exports org.apache.lucene.tests.analysis; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java index e673d8c24589..e991ee4393ec 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java @@ -1,12 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.apache.lucene.tests.util; import java.io.Closeable; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; +import java.util.stream.Stream; import org.apache.lucene.util.IOUtils; import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.ExecutableInvoker; import org.junit.jupiter.api.extension.ExtensionContext; @@ -15,17 +36,25 @@ * Simulate global state for backward compatibility with static methods from {@link LuceneTestCase} * that are used all over the place. */ -public final class GlobalStateSupport implements BeforeAllCallback, AfterAllCallback { +public final class GlobalStateSupport + implements BeforeAllCallback, AfterAllCallback, AfterEachCallback { private final ExtensionContext.Namespace NS = ExtensionContext.Namespace.create(getClass().getName()); private static final class State { + private TestRuleSetupAndRestoreClassEnv prevClassEnvRule; + private ConcurrentHashMap perThreadRandoms; private Supplier previousSupplier; + private final List closeAfterTest = new ArrayList<>(); + private final List closeAfterSuite = new ArrayList<>(); + void reset() { perThreadRandoms = null; previousSupplier = null; + closeAfterTest.clear(); + closeAfterSuite.clear(); } void initialize() { @@ -42,12 +71,71 @@ public void beforeAll(ExtensionContext context) throws Exception { State state = getState(context); state.initialize(); + if (LuceneTestCase.VERBOSE) { + // touch LuceneTestCase to trigger static initializers. + // TODO: perhaps we should run the entire rule chain instead... + } + Supplier rnd = getRandomSupplier(context.getExecutableInvoker()); var perThreadRandoms = state.perThreadRandoms; state.previousSupplier = LuceneTestCaseParent.replaceRandomSupplier( () -> perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get())); + + LuceneTestCaseParent.closeAfter.set( + new LuceneTestCaseParent.CloseAfterHook() { + @Override + public T closeAfterTest(T resource) { + synchronized (state) { + state.closeAfterTest.add(resource); + } + return resource; + } + + @Override + public T closeAfterSuite(T resource) { + synchronized (state) { + state.closeAfterSuite.add(resource); + } + return resource; + } + }); + + state.prevClassEnvRule = LuceneTestCase.classEnvRule; + var targetClass = context.getRequiredTestClass(); + LuceneTestCase.classEnvRule = new TestRuleSetupAndRestoreClassEnv(rnd, () -> targetClass); + LuceneTestCase.classEnvRule.before(); + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + var state = getState(context); + List toClose; + synchronized (state) { + toClose = List.copyOf(state.closeAfterTest); + } + IOUtils.close(toClose); + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + var state = getState(context); + var rule = LuceneTestCaseParent.classEnvRule; + try { + LuceneTestCaseParent.replaceRandomSupplier(state.previousSupplier); + LuceneTestCaseParent.classEnvRule = state.prevClassEnvRule; + IOUtils.close( + Stream.concat( + state.closeAfterSuite.stream(), + state.perThreadRandoms.values().stream() + .filter(rnd1 -> rnd1 instanceof Closeable) + .map(rnd1 -> (Closeable) rnd1)) + .toList()); + } finally { + rule.after(); + state.reset(); + } } // This trick is needed to get the Supplier injected by a parameter resolved @@ -55,6 +143,7 @@ public void beforeAll(ExtensionContext context) throws Exception { private Supplier getRandomSupplier(ExecutableInvoker executableInvoker) throws Exception { var hack = new Object() { + @SuppressWarnings("unused") public Supplier captureParameter(Supplier rnd) { return rnd; } @@ -74,19 +163,4 @@ private State getState(ExtensionContext context) { .getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS) .computeIfAbsent(State.class); } - - @Override - public void afterAll(ExtensionContext context) throws Exception { - var state = getState(context); - try { - LuceneTestCaseParent.replaceRandomSupplier(state.previousSupplier); - IOUtils.close( - state.perThreadRandoms.values().stream() - .filter(rnd1 -> rnd1 instanceof Closeable) - .map(rnd1 -> (Closeable) rnd1) - .toList()); - } finally { - state.reset(); - } - } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 11490d1edd07..02c839286932 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -48,6 +48,7 @@ import com.carrotsearch.randomizedtesting.generators.RandomPicks; import com.carrotsearch.randomizedtesting.rules.NoClassHooksShadowingRule; import com.carrotsearch.randomizedtesting.rules.NoInstanceHooksOverridesRule; +import com.carrotsearch.randomizedtesting.rules.TestRuleAdapter; import java.io.Closeable; import java.io.FileNotFoundException; import java.io.IOException; @@ -297,16 +298,10 @@ public abstract non-sealed class LuceneTestCase extends LuceneTestCaseParent { /** * If specified, limits the number of method calls to each individual instance returned by {@link * #random()}. - * - * @see #randomSupplier */ public static final String SYSPROP_RANDOM_MAXCALLS = "tests.random.maxcalls"; - /** - * If specified, limits the number of calls {@link #random()} itself. - * - * @see #randomSupplier - */ + /** If specified, limits the number of calls {@link #random()} itself. */ public static final String SYSPROP_RANDOM_MAXACQUIRES = "tests.random.maxacquires"; /** Annotation for tests that should only be run during nightly builds. */ @@ -575,9 +570,6 @@ public boolean shouldCache(Query query) throws IOException { /** Stores the currently class under test. */ private static final TestRuleStoreClassName classNameRule; - /** Class environment setup rule. */ - static final TestRuleSetupAndRestoreClassEnv classEnvRule; - /** Suite failure marker (any error in the test or suite scope). */ @SuppressWarnings("NonFinalStaticField") protected static TestRuleMarkFailure suiteFailureMarker; @@ -656,7 +648,32 @@ public static TestRuleIgnoreAfterMaxFailures replaceMaxFailureRule( "org.apache.lucene", Pattern.compile("(.+\\.)(Test)([^.]+)"))) .around(new TestRuleAssertionsRequired()) .around(new TestRuleLimitSysouts(suiteFailureMarker)) - .around(tempFilesCleanupRule = new TestRuleTemporaryFilesCleanup(suiteFailureMarker)); + .around(tempFilesCleanupRule = new TestRuleTemporaryFilesCleanup(suiteFailureMarker)) + .around( + new TestRuleAdapter() { + @Override + protected void before() throws Throwable { + LuceneTestCaseParent.closeAfter.set( + new CloseAfterHook() { + @Override + public T closeAfterTest(T resource) { + return RandomizedContext.current() + .closeAtEnd(resource, LifecycleScope.TEST); + } + + @Override + public T closeAfterSuite(T resource) { + return RandomizedContext.current() + .closeAtEnd(resource, LifecycleScope.SUITE); + } + }); + } + + @Override + protected void afterAlways(List errors) throws Throwable { + LuceneTestCaseParent.closeAfter.set(null); + } + }); classRules = r.around(new NoClassHooksShadowingRule()) .around( @@ -677,7 +694,11 @@ protected boolean verify(Method key) { // We reset the default locale and timezone; these properties change as a // side-effect "user.language", "user.timezone")) - .around(classEnvRule = new TestRuleSetupAndRestoreClassEnv()); + .around( + classEnvRule = + new TestRuleSetupAndRestoreClassEnv( + () -> RandomizedContext.current().getRandom(), + () -> RandomizedContext.current().getTargetClass())); } // ----------------------------------------------------------------- @@ -792,24 +813,6 @@ public void restoreIndexWriterMaxDocs() { // Test facilities and facades for subclasses. // ----------------------------------------------------------------- - /** - * Registers a {@link Closeable} resource that should be closed after the test completes. - * - * @return resource (for call chaining). - */ - public T closeAfterTest(T resource) { - return RandomizedContext.current().closeAtEnd(resource, LifecycleScope.TEST); - } - - /** - * Registers a {@link Closeable} resource that should be closed after the suite completes. - * - * @return resource (for call chaining). - */ - public static T closeAfterSuite(T resource) { - return RandomizedContext.current().closeAtEnd(resource, LifecycleScope.SUITE); - } - /** Return the current class being tested. */ public static Class getTestClass() { return classNameRule.getTestClass(); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index e31981eb95b6..7c552b672f3e 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -137,8 +137,8 @@ public static int atLeast(Random random, int i) { // /** - * Whenever possible, you should use an injected {@link Random} or {@link - * java.util.function.Supplier} parameter on junit5 test methods. + * Whenever possible, you should use an injected {@link Random} or {@code Supplier} + * parameter on junit5 test methods. * *

Global static methods make running test suites in parallel impossible. */ diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index 8cfe115bc1c7..ea88ed4a33f0 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -1,7 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.lucene.tests.util; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom; +import java.io.Closeable; import java.util.Objects; import java.util.Random; import java.util.concurrent.atomic.AtomicReference; @@ -15,8 +32,10 @@ * Private parent class for junit4 ({@link LuceneTestCase} and junit5 ({@link * LuceneTestCaseJupiter}). */ -abstract sealed class LuceneTestCaseParent extends Assert +public abstract sealed class LuceneTestCaseParent extends Assert permits LuceneTestCase, LuceneTestCaseJupiter { + static TestRuleSetupAndRestoreClassEnv classEnvRule; + private static volatile AtomicReference> randomSupplier = new AtomicReference<>(); @@ -53,4 +72,30 @@ public static Random random() { public static Random nonAssertingRandom(Random rnd) { return new Xoroshiro128PlusRandom(rnd.nextLong()); } + + interface CloseAfterHook { + T closeAfterTest(T resource); + + T closeAfterSuite(T resource); + } + + static volatile AtomicReference closeAfter = new AtomicReference<>(); + + /** + * Registers a {@link Closeable} resource that should be closed after the test completes. + * + * @return resource (for call chaining). + */ + public T closeAfterTest(T resource) { + return closeAfter.get().closeAfterTest(resource); + } + + /** + * Registers a {@link Closeable} resource that should be closed after the suite completes. + * + * @return resource (for call chaining). + */ + public static T closeAfterSuite(T resource) { + return closeAfter.get().closeAfterSuite(resource); + } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreClassEnv.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreClassEnv.java index f5ab9b3a1737..433fc425b01e 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreClassEnv.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreClassEnv.java @@ -23,11 +23,9 @@ import static org.apache.lucene.tests.util.LuceneTestCase.VERBOSE; import static org.apache.lucene.tests.util.LuceneTestCase.assumeFalse; import static org.apache.lucene.tests.util.LuceneTestCase.localeForLanguageTag; -import static org.apache.lucene.tests.util.LuceneTestCase.random; import static org.apache.lucene.tests.util.LuceneTestCase.randomLocale; import static org.apache.lucene.tests.util.LuceneTestCase.randomTimeZone; -import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.generators.RandomPicks; import java.io.PrintStream; import java.util.Arrays; @@ -35,6 +33,7 @@ import java.util.Locale; import java.util.Random; import java.util.TimeZone; +import java.util.function.Supplier; import org.apache.lucene.codecs.Codec; import org.apache.lucene.codecs.DocValuesFormat; import org.apache.lucene.codecs.PostingsFormat; @@ -58,6 +57,9 @@ /** Setup and restore suite-level environment (fine grained junk that doesn't fit anywhere else). */ final class TestRuleSetupAndRestoreClassEnv extends AbstractBeforeAfterRule { + private final Supplier randomSupplier; + private final Supplier> targetClassSupplier; + private Codec savedCodec; private Locale savedLocale; private TimeZone savedTimeZone; @@ -76,6 +78,12 @@ final class TestRuleSetupAndRestoreClassEnv extends AbstractBeforeAfterRule { */ HashSet avoidCodecs; + TestRuleSetupAndRestoreClassEnv( + Supplier randomSupplier, Supplier> targetClassSupplier) { + this.randomSupplier = randomSupplier; + this.targetClassSupplier = targetClassSupplier; + } + static class ThreadNameFixingPrintStreamInfoStream extends PrintStreamInfoStream { public ThreadNameFixingPrintStreamInfoStream(PrintStream out) { super(out); @@ -112,7 +120,7 @@ protected void before() throws Exception { } savedInfoStream = InfoStream.getDefault(); - final Random random = RandomizedContext.current().getRandom(); + final Random random = randomSupplier.get(); final boolean v = random.nextBoolean(); if (INFOSTREAM) { InfoStream.setDefault(new ThreadNameFixingPrintStreamInfoStream(System.out)); @@ -120,7 +128,7 @@ protected void before() throws Exception { InfoStream.setDefault(new NullInfoStream()); } - Class targetClass = RandomizedContext.current().getTargetClass(); + Class targetClass = targetClassSupplier.get(); avoidCodecs = new HashSet<>(); if (targetClass.isAnnotationPresent(SuppressCodecs.class)) { SuppressCodecs a = targetClass.getAnnotation(SuppressCodecs.class); @@ -211,10 +219,10 @@ public String toString() { Locale.setDefault(locale); savedTimeZone = TimeZone.getDefault(); - TimeZone randomTimeZone = randomTimeZone(random()); + TimeZone randomTimeZone = randomTimeZone(random); timeZone = testTimeZone.equals("random") ? randomTimeZone : TimeZone.getTimeZone(testTimeZone); TimeZone.setDefault(timeZone); - similarity = new AssertingSimilarity(new RandomSimilarity(random())); + similarity = new AssertingSimilarity(new RandomSimilarity(random)); // Check codec restrictions once at class level. try { @@ -233,7 +241,7 @@ public String toString() { // This way the assertMemory in DocumentsWriterFlushControl sometimes runs (when we always flush // by RAM). LiveIWCFlushMode flushMode; - switch (random().nextInt(3)) { + switch (random.nextInt(3)) { case 0: flushMode = LiveIWCFlushMode.BY_RAM; break; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestUtil.java index 9f900b6d68f8..122817a39223 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestUtil.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestUtil.java @@ -27,7 +27,6 @@ import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.Matchers.not; -import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.generators.RandomNumbers; import com.carrotsearch.randomizedtesting.generators.RandomPicks; import java.io.BufferedInputStream; @@ -326,7 +325,7 @@ public static CheckIndex.Status checkIndex( checker.setFailFast(failFast); checker.setInfoStream(new PrintStream(output, false, UTF_8), false); if (concurrent) { - checker.setThreadCount(RandomizedTest.randomIntBetween(2, 5)); + checker.setThreadCount(RandomNumbers.randomIntBetween(LuceneTestCase.random(), 2, 5)); } else { checker.setThreadCount(1); } diff --git a/versions.lock b/versions.lock index 63e85841507a..6c55ccbeb062 100644 --- a/versions.lock +++ b/versions.lock @@ -2,6 +2,7 @@ "comment" : "An inventory of resolved dependency versions. Do not edit this file directly.", "configurationGroups" : { "main_dependencies" : { + "com.carrotsearch.randomizedtesting:randomizedtesting-jupiter:0.2.0" : "fa9ef26b,refs=4", "com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.8.4" : "fa9ef26b,refs=4", "com.ibm.icu:icu4j:78.3" : "47ea4550,refs=6", "commons-codec:commons-codec:1.21.0" : "e6288df0,refs=6", @@ -15,17 +16,28 @@ "org.apache.commons:commons-lang3:3.18.0" : "5ce8cdc6,refs=2", "org.apache.commons:commons-math3:3.6.1" : "85a1e4c6,refs=2", "org.apache.opennlp:opennlp-tools:2.5.8" : "2f760bab,refs=4", + "org.apiguardian:apiguardian-api:1.1.2" : "bd5e3ce4,refs=2", "org.carrot2:morfologik-fsa:2.1.9" : "79af844b,refs=4", "org.carrot2:morfologik-polish:2.1.9" : "fe494320,refs=3", "org.carrot2:morfologik-stemming:2.1.9" : "79af844b,refs=4", "org.hamcrest:hamcrest:3.0" : "fa9ef26b,refs=4", + "org.jspecify:jspecify:1.0.0" : "bd5e3ce4,refs=2", + "org.junit.jupiter:junit-jupiter:6.0.3" : "fa9ef26b,refs=4", + "org.junit.jupiter:junit-jupiter-api:6.0.3" : "fa9ef26b,refs=4", + "org.junit.jupiter:junit-jupiter-engine:6.0.3" : "fa9ef26b,refs=4", + "org.junit.jupiter:junit-jupiter-params:6.0.3" : "fa9ef26b,refs=4", + "org.junit.platform:junit-platform-commons:6.0.3" : "fa9ef26b,refs=4", + "org.junit.platform:junit-platform-engine:6.0.3" : "fa9ef26b,refs=4", + "org.junit:junit-bom:6.0.3" : "fa9ef26b,refs=4", "org.locationtech.spatial4j:spatial4j:0.8" : "cbc357ab,refs=4", "org.openjdk.jmh:jmh-core:1.37" : "85a1e4c6,refs=2", + "org.opentest4j:opentest4j:1.3.0" : "fa9ef26b,refs=4", "org.slf4j:slf4j-api:2.0.17" : "2f760bab,refs=4", "ua.net.nlp:morfologik-ukrainian-search:4.9.1" : "fe494320,refs=3", "xerces:xercesImpl:2.12.2" : "5ce8cdc6,refs=2" }, "test_dependencies" : { + "com.carrotsearch.randomizedtesting:randomizedtesting-jupiter:0.2.0" : "543b6dba,refs=74", "com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.8.4" : "129da9bf,refs=76", "com.carrotsearch:procfork:1.0.6" : "b7ba1646,refs=2", "com.github.ben-manes.caffeine:caffeine:3.0.5" : "90685606,refs=39", @@ -59,23 +71,28 @@ "org.apache.commons:commons-lang3:3.18.0" : "6f16ff86,refs=2", "org.apache.commons:commons-math3:3.6.1" : "152d9f78,refs=3", "org.apache.opennlp:opennlp-tools:2.5.8" : "b91715f0,refs=6", + "org.apiguardian:apiguardian-api:1.1.2" : "cab355bc,refs=37", "org.assertj:assertj-core:3.27.7" : "b7ba1646,refs=2", "org.carrot2:morfologik-fsa:2.1.9" : "e077a675,refs=8", "org.carrot2:morfologik-polish:2.1.9" : "cb00cecf,refs=5", "org.carrot2:morfologik-stemming:2.1.9" : "e077a675,refs=8", "org.checkerframework:checker-qual:3.19.0" : "90685606,refs=39", "org.hamcrest:hamcrest:3.0" : "129da9bf,refs=76", - "org.jspecify:jspecify:1.0.0" : "90685606,refs=39", - "org.junit.platform:junit-platform-commons:6.0.3" : "1ec8e4d2,refs=39", - "org.junit.platform:junit-platform-engine:6.0.3" : "1ec8e4d2,refs=39", + "org.jspecify:jspecify:1.0.0" : "8b117b59,refs=76", + "org.junit.jupiter:junit-jupiter:6.0.3" : "543b6dba,refs=74", + "org.junit.jupiter:junit-jupiter-api:6.0.3" : "543b6dba,refs=74", + "org.junit.jupiter:junit-jupiter-engine:6.0.3" : "543b6dba,refs=74", + "org.junit.jupiter:junit-jupiter-params:6.0.3" : "543b6dba,refs=74", + "org.junit.platform:junit-platform-commons:6.0.3" : "7b83bd93,refs=76", + "org.junit.platform:junit-platform-engine:6.0.3" : "7b83bd93,refs=76", "org.junit.platform:junit-platform-launcher:6.0.3" : "1ec8e4d2,refs=39", "org.junit.vintage:junit-vintage-engine:6.0.3" : "1ec8e4d2,refs=39", - "org.junit:junit-bom:6.0.3" : "1ec8e4d2,refs=39", + "org.junit:junit-bom:6.0.3" : "7b83bd93,refs=76", "org.locationtech.jts:jts-core:1.20.0" : "180518e6,refs=2", "org.locationtech.spatial4j:spatial4j:0.8" : "1d5a4b2b,refs=4", "org.openjdk.jmh:jmh-core:1.37" : "152d9f78,refs=3", "org.openjdk.jmh:jmh-generator-annprocess:1.37" : "ecaf1d73,refs=1", - "org.opentest4j:opentest4j:1.3.0" : "1ec8e4d2,refs=39", + "org.opentest4j:opentest4j:1.3.0" : "7b83bd93,refs=76", "org.pcollections:pcollections:4.0.1" : "90685606,refs=39", "org.slf4j:slf4j-api:2.0.17" : "b91715f0,refs=6", "ua.net.nlp:morfologik-ukrainian-search:4.9.1" : "cb00cecf,refs=5", @@ -633,74 +650,984 @@ "projectPath" : ":lucene:analysis:icu" } ], + "543b6dba" : [ + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:backward-codecs" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:backward-codecs" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:classification" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:classification" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:codecs" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:codecs" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:core" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:core" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:core.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:core.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:demo" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:demo" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:facet" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:facet" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:grouping" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:grouping" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:highlighter" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:highlighter" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:join" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:join" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:memory" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:memory" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:misc" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:misc" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:monitor" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:monitor" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:queries" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:queries" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:queryparser" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:queryparser" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:replicator" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:replicator" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:sandbox" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:sandbox" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial-extras" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:spatial-extras" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial-test-fixtures" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:spatial-test-fixtures" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial3d" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:spatial3d" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:suggest" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:suggest" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:common" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:common" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:icu" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:icu" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:kuromoji" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:kuromoji" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:morfologik" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:morfologik" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:morfologik.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:morfologik.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:nori" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:nori" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:opennlp" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:opennlp" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:phonetic" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:phonetic" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:smartcn" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:smartcn" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:stempel" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:stempel" + } + ], "5ce8cdc6" : [ { - "configuration" : "compileClasspath", - "projectPath" : ":lucene:benchmark" + "configuration" : "compileClasspath", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "runtimeClasspath", + "projectPath" : ":lucene:benchmark" + } + ], + "6f16ff86" : [ + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:benchmark" + } + ], + "6fbc4021" : [ + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:demo" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:queries" + } + ], + "79af844b" : [ + { + "configuration" : "compileClasspath", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "runtimeClasspath", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "compileClasspath", + "projectPath" : ":lucene:analysis:morfologik" + }, + { + "configuration" : "runtimeClasspath", + "projectPath" : ":lucene:analysis:morfologik" + } + ], + "7b83bd93" : [ + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":build-tools:missing-doclet" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:backward-codecs" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:backward-codecs" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:classification" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:classification" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:codecs" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:codecs" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:core" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:core" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:core.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:core.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:demo" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:demo" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:distribution.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:facet" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:facet" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:grouping" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:grouping" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:highlighter" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:highlighter" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:join" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:join" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:memory" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:memory" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:misc" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:misc" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:monitor" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:monitor" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:queries" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:queries" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:queryparser" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:queryparser" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:replicator" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:replicator" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:sandbox" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:sandbox" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial-extras" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:spatial-extras" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial-test-fixtures" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:spatial-test-fixtures" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial3d" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:spatial3d" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:suggest" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:suggest" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:common" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:common" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:icu" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:icu" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:kuromoji" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:kuromoji" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:morfologik" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:morfologik" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:morfologik.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:morfologik.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:nori" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:nori" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:opennlp" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:opennlp" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:phonetic" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:phonetic" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:smartcn" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:smartcn" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:stempel" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:stempel" + } + ], + "85a1e4c6" : [ + { + "configuration" : "compileClasspath", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "runtimeClasspath", + "projectPath" : ":lucene:benchmark-jmh" + } + ], + "8b117b59" : [ + { + "configuration" : "annotationProcessor", + "projectPath" : ":build-tools:missing-doclet" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis.tests" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:backward-codecs" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:backward-codecs" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:classification" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:classification" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:codecs" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:codecs" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:core" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:core" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:core.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:core.tests" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:demo" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:demo" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:distribution.tests" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:facet" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:facet" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:grouping" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:grouping" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:highlighter" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:highlighter" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:join" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:join" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:memory" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:memory" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:misc" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:misc" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:monitor" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:monitor" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:queries" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:queries" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:queryparser" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:queryparser" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:replicator" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:replicator" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:sandbox" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:sandbox" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:spatial-extras" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial-extras" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:spatial-test-fixtures" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial-test-fixtures" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:spatial3d" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial3d" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:suggest" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:suggest" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:test-framework" }, { - "configuration" : "runtimeClasspath", - "projectPath" : ":lucene:benchmark" - } - ], - "6f16ff86" : [ + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:common" + }, { "configuration" : "testCompileClasspath", - "projectPath" : ":lucene:benchmark" + "projectPath" : ":lucene:analysis:common" }, { - "configuration" : "testRuntimeClasspath", - "projectPath" : ":lucene:benchmark" - } - ], - "6fbc4021" : [ + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:icu" + }, { - "configuration" : "testRuntimeClasspath", - "projectPath" : ":lucene:benchmark-jmh" + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:icu" }, { - "configuration" : "testRuntimeClasspath", - "projectPath" : ":lucene:demo" + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:kuromoji" }, { "configuration" : "testCompileClasspath", - "projectPath" : ":lucene:expressions" + "projectPath" : ":lucene:analysis:kuromoji" }, { - "configuration" : "testRuntimeClasspath", - "projectPath" : ":lucene:expressions" + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:morfologik" }, { - "configuration" : "testRuntimeClasspath", - "projectPath" : ":lucene:queries" - } - ], - "79af844b" : [ + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:morfologik" + }, { - "configuration" : "compileClasspath", - "projectPath" : ":lucene:luke" + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:morfologik.tests" }, { - "configuration" : "runtimeClasspath", - "projectPath" : ":lucene:luke" + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:morfologik.tests" }, { - "configuration" : "compileClasspath", - "projectPath" : ":lucene:analysis:morfologik" + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:nori" }, { - "configuration" : "runtimeClasspath", - "projectPath" : ":lucene:analysis:morfologik" - } - ], - "85a1e4c6" : [ + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:nori" + }, { - "configuration" : "compileClasspath", - "projectPath" : ":lucene:benchmark-jmh" + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:opennlp" }, { - "configuration" : "runtimeClasspath", - "projectPath" : ":lucene:benchmark-jmh" + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:opennlp" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:phonetic" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:phonetic" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:smartcn" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:smartcn" + }, + { + "configuration" : "annotationProcessor", + "projectPath" : ":lucene:analysis:stempel" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:stempel" } ], "90685606" : [ @@ -931,6 +1858,166 @@ "projectPath" : ":lucene:analysis:opennlp" } ], + "bd5e3ce4" : [ + { + "configuration" : "compileClasspath", + "projectPath" : ":lucene:spatial-test-fixtures" + }, + { + "configuration" : "compileClasspath", + "projectPath" : ":lucene:test-framework" + } + ], + "cab355bc" : [ + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:backward-codecs" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:classification" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:codecs" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:core" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:core.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:demo" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:facet" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:grouping" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:highlighter" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:join" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:memory" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:misc" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:monitor" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:queries" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:queryparser" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:replicator" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:sandbox" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial-extras" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial-test-fixtures" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:spatial3d" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:suggest" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:common" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:icu" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:kuromoji" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:morfologik" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:morfologik.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:nori" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:opennlp" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:phonetic" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:smartcn" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:analysis:stempel" + } + ], "cb00cecf" : [ { "configuration" : "testRuntimeClasspath", From 754bce2cef14db43bffd1e4fc3b4ab2fae5766c9 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 17 Apr 2026 08:18:37 +0200 Subject: [PATCH 12/68] Remove debugging cruft. --- lucene/test-framework/build.gradle | 9 --------- lucene/test-framework/src/java/module-info.java | 1 - 2 files changed, 10 deletions(-) diff --git a/lucene/test-framework/build.gradle b/lucene/test-framework/build.gradle index 5b1165f3ede8..bb6cde3bddda 100644 --- a/lucene/test-framework/build.gradle +++ b/lucene/test-framework/build.gradle @@ -19,14 +19,6 @@ import org.apache.lucene.gradle.plugins.misc.QuietExec description = 'Framework for testing Lucene-based applications' -configurations { - foo { - attributes { - attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_API)) - } - } -} - dependencies { moduleApi project(':lucene:core') @@ -38,7 +30,6 @@ dependencies { }) moduleApi deps.hamcrest - foo("org.junit.platform:junit-platform-engine:6.0.3") moduleApi(deps.randomizedtesting.jupiter) moduleApi(deps.junitplatform.jupiter) diff --git a/lucene/test-framework/src/java/module-info.java b/lucene/test-framework/src/java/module-info.java index 17bb6a3ca45f..b841ae72c441 100644 --- a/lucene/test-framework/src/java/module-info.java +++ b/lucene/test-framework/src/java/module-info.java @@ -25,7 +25,6 @@ requires transitive com.carrotsearch.randomizedtesting; requires transitive org.junit.jupiter.api; requires org.hamcrest; - requires java.sql; // Open certain packages for junit because it scans methods via reflection. opens org.apache.lucene.tests.index to From 7892420b4947452af97b63b0c4469d8c68a3c735 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 17 Apr 2026 08:38:28 +0200 Subject: [PATCH 13/68] Removing direct access to randomized context, where possible.' --- .../lucene/index/TestClassloadingDeadlock.java | 2 +- .../memory/TestMemoryIndexAgainstDirectory.java | 2 +- .../spatial3d/tests/RandomGeo3dShapeGenerator.java | 3 ++- .../search/suggest/fst/TestBytesRefSorters.java | 3 +-- .../org/apache/lucene/tests/geo/GeoTestUtil.java | 4 ++-- .../org/apache/lucene/tests/geo/ShapeTestUtil.java | 3 +-- .../apache/lucene/tests/util/LuceneTestCase.java | 7 ++++++- .../tests/util/TestRuleTemporaryFilesCleanup.java | 13 +++++++++++-- 8 files changed, 25 insertions(+), 12 deletions(-) diff --git a/lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java b/lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java index 24c52c15d469..bf99db13b96e 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java @@ -50,7 +50,7 @@ import org.junit.runner.RunWith; /* WARNING: This test does *not* extend LuceneTestCase to prevent static class - * initialization when spawned as subprocess (and please let default codecs alive)! */ + * initialization when spawned as a subprocess (and please let default codecs alive)! */ @RunWith(RandomizedRunner.class) public class TestClassloadingDeadlock extends Assert { diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java index 606d99adb92f..cc35ddae6868 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java @@ -114,7 +114,7 @@ public static void prepare() throws Exception { @AfterAll public static void cleanup() throws Exception { - queries = null; + queries.clear(); } /** read a set of queries from a resource file */ diff --git a/lucene/spatial-test-fixtures/src/java/org/apache/lucene/spatial3d/tests/RandomGeo3dShapeGenerator.java b/lucene/spatial-test-fixtures/src/java/org/apache/lucene/spatial3d/tests/RandomGeo3dShapeGenerator.java index 2f963aa715d1..d5a0f5457463 100644 --- a/lucene/spatial-test-fixtures/src/java/org/apache/lucene/spatial3d/tests/RandomGeo3dShapeGenerator.java +++ b/lucene/spatial-test-fixtures/src/java/org/apache/lucene/spatial3d/tests/RandomGeo3dShapeGenerator.java @@ -42,6 +42,7 @@ import org.apache.lucene.spatial3d.geom.GeoPolygonFactory; import org.apache.lucene.spatial3d.geom.GeoShape; import org.apache.lucene.spatial3d.geom.PlanetModel; +import org.apache.lucene.tests.util.LuceneTestCase; /** * Class for generating random Geo3dShapes. They can be generated under given constraints which are @@ -83,7 +84,7 @@ private RandomGeo3dShapeGenerator() {} * @return Returns a private-use random forked from the current {@link RandomizedContext}. */ private static Random random() { - return new Random(RandomizedContext.current().getRandom().nextLong()); + return LuceneTestCase.nonAssertingRandom(LuceneTestCase.random()); } /** diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/TestBytesRefSorters.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/TestBytesRefSorters.java index 80a6351d5718..4a1939342877 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/TestBytesRefSorters.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/TestBytesRefSorters.java @@ -16,7 +16,6 @@ */ package org.apache.lucene.search.suggest.fst; -import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.generators.RandomBytes; import com.carrotsearch.randomizedtesting.generators.RandomNumbers; import java.io.IOException; @@ -86,7 +85,7 @@ private void check(BytesRefSorter sorter) throws Exception { } private void appendRandomSequences(BytesRefSorter sorter) throws IOException { - Random rnd = new Random(RandomizedContext.current().getRandom().nextLong()); + Random rnd = LuceneTestCase.nonAssertingRandom(LuceneTestCase.random()); for (int i = 0; i < RandomNumbers.randomIntBetween(rnd, 10, 100); i++) { sorter.add(new BytesRef(RandomBytes.randomBytesOfLengthBetween(rnd, 1, 256))); } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/geo/GeoTestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/tests/geo/GeoTestUtil.java index 0876795ee324..e697d6f67d99 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/geo/GeoTestUtil.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/geo/GeoTestUtil.java @@ -21,7 +21,6 @@ import static org.apache.lucene.geo.GeoUtils.MIN_LAT_INCL; import static org.apache.lucene.geo.GeoUtils.MIN_LON_INCL; -import com.carrotsearch.randomizedtesting.RandomizedContext; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; @@ -39,6 +38,7 @@ import org.apache.lucene.geo.Point; import org.apache.lucene.geo.Polygon; import org.apache.lucene.geo.Rectangle; +import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.SloppyMath; @@ -589,7 +589,7 @@ private static Polygon surpriseMePolygon() { /** Keep it simple, we don't need to take arbitrary Random for geo tests */ private static Random random() { - return RandomizedContext.current().getRandom(); + return LuceneTestCase.nonAssertingRandom(LuceneTestCase.random()); } /** diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/geo/ShapeTestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/tests/geo/ShapeTestUtil.java index de312b578342..29f5a83e73f7 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/geo/ShapeTestUtil.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/geo/ShapeTestUtil.java @@ -16,7 +16,6 @@ */ package org.apache.lucene.tests.geo; -import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.generators.BiasedNumbers; import java.util.ArrayList; import java.util.Random; @@ -243,7 +242,7 @@ public static float nextFloat(Random random) { /** Keep it simple, we don't need to take arbitrary Random for geo tests */ private static Random random() { - return RandomizedContext.current().getRandom(); + return LuceneTestCase.nonAssertingRandom(LuceneTestCase.random()); } /** Simple slow point in polygon check (for testing) */ diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 02c839286932..22800754fcb7 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -648,7 +648,12 @@ public static TestRuleIgnoreAfterMaxFailures replaceMaxFailureRule( "org.apache.lucene", Pattern.compile("(.+\\.)(Test)([^.]+)"))) .around(new TestRuleAssertionsRequired()) .around(new TestRuleLimitSysouts(suiteFailureMarker)) - .around(tempFilesCleanupRule = new TestRuleTemporaryFilesCleanup(suiteFailureMarker)) + .around( + tempFilesCleanupRule = + new TestRuleTemporaryFilesCleanup( + suiteFailureMarker, + LuceneTestCase::random, + () -> RandomizedContext.current().getTargetClass())) .around( new TestRuleAdapter() { @Override diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java index 8cd38b6bdc90..ed4018255535 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java @@ -33,6 +33,7 @@ import java.util.Locale; import java.util.Random; import java.util.Set; +import java.util.function.Supplier; import org.apache.lucene.tests.mockfile.DisableFsyncFS; import org.apache.lucene.tests.mockfile.ExtrasFS; import org.apache.lucene.tests.mockfile.HandleLimitFS; @@ -52,6 +53,9 @@ * @see LuceneTestCase#createTempFile() */ final class TestRuleTemporaryFilesCleanup extends TestRuleAdapter { + private final Supplier randomSupplier; + private final Supplier> targetClassSupplier; + /** Retry to create temporary file name this many times. */ private static final int TEMP_NAME_RETRY_THRESHOLD = 9999; @@ -74,8 +78,13 @@ final class TestRuleTemporaryFilesCleanup extends TestRuleAdapter { */ private static final List cleanupQueue = new ArrayList<>(); - public TestRuleTemporaryFilesCleanup(TestRuleMarkFailure failureMarker) { + public TestRuleTemporaryFilesCleanup( + TestRuleMarkFailure failureMarker, + Supplier randomSupplier, + Supplier> targetClassSupplier) { this.failureMarker = failureMarker; + this.randomSupplier = randomSupplier; + this.targetClassSupplier = targetClassSupplier; } /** Register temporary folder for removal after the suite completes. */ @@ -126,7 +135,7 @@ private FileSystem initializeFileSystem() { .getFileSystem(null); } - Random random = RandomizedContext.current().getRandom(); + Random random = randomSupplier.get(); // speed up tests by omitting actual fsync calls to the hardware most of the time. if (targetClass.isAnnotationPresent(SuppressFsync.class) || random.nextInt(100) > 0) { From 2a880cdb62074f4368c1e10db133dd603acc3b09 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 17 Apr 2026 13:32:16 +0200 Subject: [PATCH 14/68] Test group control via sys properties. --- .../lucene/search/join/TestJupiter.java | 1 + .../test-framework/src/java/module-info.java | 1 + .../lucene/tests/util/LuceneTestCase.java | 9 +++ .../apache/lucene/tests/util/TagState.java | 71 +++++++++++++++++++ .../util/TestRuleTemporaryFilesCleanup.java | 11 +-- 5 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java index 5cd8d1b41f2c..3fa2fa9d4497 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java @@ -31,6 +31,7 @@ @Timeout(value = 3, unit = TimeUnit.SECONDS) public class TestJupiter { @Nested + @LuceneTestCase.Nightly class T1 extends LuceneTestCaseJupiter { @Test public void t1() throws Exception { diff --git a/lucene/test-framework/src/java/module-info.java b/lucene/test-framework/src/java/module-info.java index b841ae72c441..54d06485e1eb 100644 --- a/lucene/test-framework/src/java/module-info.java +++ b/lucene/test-framework/src/java/module-info.java @@ -25,6 +25,7 @@ requires transitive com.carrotsearch.randomizedtesting; requires transitive org.junit.jupiter.api; requires org.hamcrest; + requires java.management; // Open certain packages for junit because it scans methods via reflection. opens org.apache.lucene.tests.index to diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 22800754fcb7..1037e7c78d70 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -211,6 +211,7 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.internal.AssumptionViolatedException; +import org.junit.jupiter.api.Tag; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.RunWith; @@ -309,6 +310,8 @@ public abstract non-sealed class LuceneTestCase extends LuceneTestCaseParent { @Inherited @Retention(RetentionPolicy.RUNTIME) @TestGroup(enabled = false, sysProperty = SYSPROP_NIGHTLY) + @Tag("nightly") + @TagState(enabled = false, sysProperty = SYSPROP_NIGHTLY) public @interface Nightly {} /** Annotation for tests that should only be run during weekly builds */ @@ -316,6 +319,8 @@ public abstract non-sealed class LuceneTestCase extends LuceneTestCaseParent { @Inherited @Retention(RetentionPolicy.RUNTIME) @TestGroup(enabled = false, sysProperty = SYSPROP_WEEKLY) + @Tag("weekly") + @TagState(enabled = false, sysProperty = SYSPROP_WEEKLY) public @interface Weekly {} /** Annotation for monster tests that require special setup (e.g. use tons of disk and RAM) */ @@ -323,6 +328,8 @@ public abstract non-sealed class LuceneTestCase extends LuceneTestCaseParent { @Inherited @Retention(RetentionPolicy.RUNTIME) @TestGroup(enabled = false, sysProperty = SYSPROP_MONSTER) + @Tag("monster") + @TagState(enabled = false, sysProperty = SYSPROP_MONSTER) public @interface Monster { String value(); } @@ -332,6 +339,8 @@ public abstract non-sealed class LuceneTestCase extends LuceneTestCaseParent { @Inherited @Retention(RetentionPolicy.RUNTIME) @TestGroup(enabled = false, sysProperty = SYSPROP_AWAITSFIX) + @Tag("awaitsfix") + @TagState(enabled = false, sysProperty = SYSPROP_AWAITSFIX) public @interface AwaitsFix { /** Point to JIRA entry. */ public String bugUrl(); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java new file mode 100644 index 000000000000..249ccf4d0f32 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.tests.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.platform.commons.support.AnnotationSupport; + +/** + * Control the state (enabled/ disabled) of a test tag meta-annotation: provides the default state + * and system property to control it. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +@ExtendWith(TagState.Condition.class) +public @interface TagState { + boolean enabled(); + + String sysProperty(); + + final class Condition implements ExecutionCondition { + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + var opt = context.getElement(); + if (opt.isPresent()) { + var element = opt.get(); + var stateAnn_ = AnnotationSupport.findAnnotation(element, TagState.class); + if (stateAnn_.isPresent()) { + var stateAnn = stateAnn_.get(); + var tagAnns = AnnotationSupport.findRepeatableAnnotations(element, Tag.class); + if (tagAnns.size() != 1) { + throw new RuntimeException("Expected exactly one @Tag meta-annotation on: " + element); + } + + String tag = tagAnns.getFirst().value(); + var enabled = + context + .getConfigurationParameter(stateAnn.sysProperty(), Boolean::parseBoolean) + .orElse(stateAnn.enabled()); + return enabled + ? ConditionEvaluationResult.enabled("@" + tag + " enabled") + : ConditionEvaluationResult.disabled( + "@" + tag + " disabled; use -D" + stateAnn.sysProperty() + "=true to enable."); + } + } + + return ConditionEvaluationResult.enabled("no @TestGroupTag found"); + } + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java index ed4018255535..bea895fbd0ab 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java @@ -236,8 +236,7 @@ protected void afterAlways(List errors) throws Throwable { Path getPerTestClassTempDir() { if (tempDirBase == null) { - RandomizedContext ctx = RandomizedContext.current(); - Class clazz = ctx.getTargetClass(); + Class clazz = targetClassSupplier.get(); String prefix = clazz.getName(); prefix = prefix.replaceFirst("^org.apache.lucene.", "lucene."); @@ -250,13 +249,7 @@ Path getPerTestClassTempDir() { "Failed to get a temporary name too many times, check your temp directory and consider manually cleaning it: " + javaTempDir.toAbsolutePath()); } - f = - javaTempDir.resolve( - prefix - + "_" - + ctx.getRunnerSeedAsString() - + "-" - + String.format(Locale.ENGLISH, "%03d", attempt)); + f = javaTempDir.resolve(prefix + "_" + String.format(Locale.ENGLISH, "%03d", attempt)); try { Files.createDirectory(f); success = true; From 581973acd96072aebc5c6e3befcb4928d4c49463 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Tue, 21 Apr 2026 09:34:25 +0200 Subject: [PATCH 15/68] Make lucene:memory tests pass. Hacky but shows the idea. --- .../lucene/tests/util/LuceneTestCase.java | 7 --- .../tests/util/LuceneTestCaseJupiter.java | 49 +++++++++++++++++++ .../tests/util/LuceneTestCaseParent.java | 6 +++ .../tests/util/TestRuleMarkFailure.java | 8 +-- .../util/TestRuleTemporaryFilesCleanup.java | 8 ++- 5 files changed, 63 insertions(+), 15 deletions(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 1037e7c78d70..5cee67db7a47 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -579,13 +579,6 @@ public boolean shouldCache(Query query) throws IOException { /** Stores the currently class under test. */ private static final TestRuleStoreClassName classNameRule; - /** Suite failure marker (any error in the test or suite scope). */ - @SuppressWarnings("NonFinalStaticField") - protected static TestRuleMarkFailure suiteFailureMarker; - - /** Temporary files cleanup rule. */ - private static final TestRuleTemporaryFilesCleanup tempFilesCleanupRule; - /** * Ignore tests after hitting a designated number of initial failures. This is truly a "static" * global singleton since it needs to span the lifetime of all test classes running inside this diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 7c552b672f3e..1472bc03064b 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -20,17 +20,27 @@ import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; import com.carrotsearch.randomizedtesting.jupiter.Randomized; import com.carrotsearch.randomizedtesting.jupiter.SystemThreadFilter; +import java.util.List; +import java.util.Objects; import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.lucene.util.Constants; +import org.jspecify.annotations.Nullable; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.extension.TestWatcher; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; import org.junit.platform.commons.support.AnnotationSupport; @@ -123,6 +133,45 @@ public boolean test(Thread t) { } } + static TestRuleTemporaryFilesCleanup tempFilesCleanupRule_; + static TestRuleMarkFailure failureMarker = new TestRuleMarkFailure(); + + @RegisterExtension + static Extension failureListener = + new TestWatcher() { + @Override + public void testAborted(ExtensionContext context, @Nullable Throwable cause) { + failureMarker.markFailed(); + } + + @Override + public void testFailed(ExtensionContext context, @Nullable Throwable cause) { + failureMarker.markFailed(); + } + }; + + @BeforeAll + public static void setupClass(TestInfo testInfo) throws Throwable { + var newRule = + new TestRuleTemporaryFilesCleanup( + failureMarker, + LuceneTestCaseJupiter::random, + () -> testInfo.getTestClass().orElseThrow()); + failureMarker.reset(); + newRule.before(); + + tempFilesCleanupRule_ = Objects.requireNonNull(tempFilesCleanupRule); + tempFilesCleanupRule = newRule; + } + + @AfterAll + public static void teardownClass() throws Throwable { + if (tempFilesCleanupRule != null) { + tempFilesCleanupRule.afterAlways(List.of()); + tempFilesCleanupRule = tempFilesCleanupRule_; + } + } + // // Custom assertion methods. // diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index ea88ed4a33f0..c38eae27a0bd 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -36,6 +36,12 @@ public abstract sealed class LuceneTestCaseParent extends Assert permits LuceneTestCase, LuceneTestCaseJupiter { static TestRuleSetupAndRestoreClassEnv classEnvRule; + /** Suite failure marker (any error in the test or suite scope). */ + @SuppressWarnings("NonFinalStaticField") + protected static TestRuleMarkFailure suiteFailureMarker; + + static TestRuleTemporaryFilesCleanup tempFilesCleanupRule; + private static volatile AtomicReference> randomSupplier = new AtomicReference<>(); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java index f825802729a0..127ce4afb2db 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java @@ -37,9 +37,7 @@ public Statement apply(final Statement s, Description d) { return new Statement() { @Override public void evaluate() throws Throwable { - // Clear status at start. - failures = false; - + reset(); try { s.evaluate(); } catch (Throwable t) { @@ -99,4 +97,8 @@ public boolean hadFailures() { public boolean wasSuccessful() { return !hadFailures(); } + + public void reset() { + failures = false; + } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java index bea895fbd0ab..f33103a018d0 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java @@ -16,7 +16,6 @@ */ package org.apache.lucene.tests.util; -import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.rules.TestRuleAdapter; import java.io.IOException; import java.net.URI; @@ -119,7 +118,7 @@ private boolean allowed(Set avoid, Class c } private FileSystem initializeFileSystem() { - Class targetClass = RandomizedContext.current().getTargetClass(); + Class targetClass = targetClassSupplier.get(); Set avoid = new HashSet<>(); if (targetClass.isAnnotationPresent(SuppressFileSystems.class)) { SuppressFileSystems a = targetClass.getAnnotation(SuppressFileSystems.class); @@ -206,14 +205,13 @@ protected void afterAlways(List errors) throws Throwable { } // Only check and throw an IOException on un-removable files if the test - // was successful. Otherwise just report the path of temporary files + // was successful. Otherwise, just report the path of temporary files // and leave them there. if (failureMarker.wasSuccessful()) { - try { IOUtils.rm(everything); } catch (IOException e) { - Class suiteClass = RandomizedContext.current().getTargetClass(); + Class suiteClass = targetClassSupplier.get(); if (suiteClass.isAnnotationPresent(SuppressTempFileChecks.class)) { System.err.println( "WARNING: Leftover undeleted temporary files (bugUrl: " From 6d1cf6f6546fd9e7fa7c066c53e424036b8b6abd Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Tue, 21 Apr 2026 20:29:02 +0200 Subject: [PATCH 16/68] Try to pull up a clear concept of test framework's infrastructure. --- .../TestMemoryIndexAgainstDirectory.java | 2 - .../lucene/tests/util/GlobalStateSupport.java | 39 +-- .../lucene/tests/util/LuceneTestCase.java | 233 ++++-------------- .../tests/util/LuceneTestCaseParent.java | 223 +++++++++++++++-- 4 files changed, 266 insertions(+), 231 deletions(-) diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java index cc35ddae6868..191394bd382f 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java @@ -16,8 +16,6 @@ */ package org.apache.lucene.index.memory; -import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.RANDOM_MULTIPLIER; -import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.TEST_NIGHTLY; import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newDirectory; import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newIndexWriterConfig; import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newSearcher; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java index e991ee4393ec..2ada4585e892 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java @@ -42,26 +42,26 @@ public final class GlobalStateSupport ExtensionContext.Namespace.create(getClass().getName()); private static final class State { - private TestRuleSetupAndRestoreClassEnv prevClassEnvRule; + private LuceneTestCaseParent.TestFrameworkInfra frameworkInfra; + private TestRuleSetupAndRestoreClassEnv prevClassEnvRule; private ConcurrentHashMap perThreadRandoms; - private Supplier previousSupplier; private final List closeAfterTest = new ArrayList<>(); private final List closeAfterSuite = new ArrayList<>(); void reset() { + frameworkInfra = null; perThreadRandoms = null; - previousSupplier = null; closeAfterTest.clear(); closeAfterSuite.clear(); } void initialize() { - if (perThreadRandoms != null) { - throw new RuntimeException( - "Expected perThreadRandoms to be null (single-threaded, sequential test execution)."); + if (frameworkInfra != null) { + throw new RuntimeException(); } + perThreadRandoms = new ConcurrentHashMap<>(); } } @@ -71,17 +71,21 @@ public void beforeAll(ExtensionContext context) throws Exception { State state = getState(context); state.initialize(); - if (LuceneTestCase.VERBOSE) { - // touch LuceneTestCase to trigger static initializers. - // TODO: perhaps we should run the entire rule chain instead... - } + // touch LuceneTestCase to trigger static initializers. + LuceneTestCase.ensureInitialized(); - Supplier rnd = getRandomSupplier(context.getExecutableInvoker()); + state.frameworkInfra = + new LuceneTestCaseParent.TestFrameworkInfra() { + final ConcurrentHashMap perThreadRandoms = state.perThreadRandoms; + final Supplier rnd = getRandomSupplier(context.getExecutableInvoker()); + + @Override + public Random threadRandom() { + return perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get()); + } + }; - var perThreadRandoms = state.perThreadRandoms; - state.previousSupplier = - LuceneTestCaseParent.replaceRandomSupplier( - () -> perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get())); + LuceneTestCaseParent.setTestFrameworkInfra(null, state.frameworkInfra); LuceneTestCaseParent.closeAfter.set( new LuceneTestCaseParent.CloseAfterHook() { @@ -104,7 +108,8 @@ public T closeAfterSuite(T resource) { state.prevClassEnvRule = LuceneTestCase.classEnvRule; var targetClass = context.getRequiredTestClass(); - LuceneTestCase.classEnvRule = new TestRuleSetupAndRestoreClassEnv(rnd, () -> targetClass); + LuceneTestCase.classEnvRule = + new TestRuleSetupAndRestoreClassEnv(state.frameworkInfra::threadRandom, () -> targetClass); LuceneTestCase.classEnvRule.before(); } @@ -123,7 +128,6 @@ public void afterAll(ExtensionContext context) throws Exception { var state = getState(context); var rule = LuceneTestCaseParent.classEnvRule; try { - LuceneTestCaseParent.replaceRandomSupplier(state.previousSupplier); LuceneTestCaseParent.classEnvRule = state.prevClassEnvRule; IOUtils.close( Stream.concat( @@ -134,6 +138,7 @@ public void afterAll(ExtensionContext context) throws Exception { .toList()); } finally { rule.after(); + LuceneTestCaseParent.setTestFrameworkInfra(state.frameworkInfra, null); state.reset(); } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 5cee67db7a47..b0056d0f544a 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -157,7 +157,6 @@ import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.LRUQueryCache; -import org.apache.lucene.search.Query; import org.apache.lucene.search.QueryCache; import org.apache.lucene.search.QueryCachingPolicy; import org.apache.lucene.store.ByteBuffersDirectory; @@ -188,14 +187,12 @@ import org.apache.lucene.tests.search.AssertingIndexSearcher; import org.apache.lucene.tests.store.BaseDirectoryWrapper; import org.apache.lucene.tests.store.MockDirectoryWrapper; -import org.apache.lucene.tests.store.MockDirectoryWrapper.Throttling; import org.apache.lucene.tests.store.RawDirectoryWrapper; import org.apache.lucene.tests.util.automaton.AutomatonTestUtil; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CommandLineUtil; import org.apache.lucene.util.IOUtils; -import org.apache.lucene.util.InfoStream; import org.apache.lucene.util.NamedThreadFactory; import org.apache.lucene.util.SuppressForbidden; import org.apache.lucene.util.automaton.Automaton; @@ -276,34 +273,7 @@ bytes = TestRuleLimitSysouts.DEFAULT_LIMIT, hardLimit = TestRuleLimitSysouts.DEFAULT_HARD_LIMIT) public abstract non-sealed class LuceneTestCase extends LuceneTestCaseParent { - - // -------------------------------------------------------------------- - // Test groups, system properties and other annotations modifying tests - // -------------------------------------------------------------------- - - public static final String SYSPROP_NIGHTLY = "tests.nightly"; - public static final String SYSPROP_WEEKLY = "tests.weekly"; - public static final String SYSPROP_MONSTER = "tests.monster"; - public static final String SYSPROP_AWAITSFIX = "tests.awaitsfix"; - - /** - * @see #ignoreAfterMaxFailures - */ - public static final String SYSPROP_MAXFAILURES = "tests.maxfailures"; - - /** - * @see #ignoreAfterMaxFailures - */ - public static final String SYSPROP_FAILFAST = "tests.failfast"; - - /** - * If specified, limits the number of method calls to each individual instance returned by {@link - * #random()}. - */ - public static final String SYSPROP_RANDOM_MAXCALLS = "tests.random.maxcalls"; - - /** If specified, limits the number of calls {@link #random()} itself. */ - public static final String SYSPROP_RANDOM_MAXACQUIRES = "tests.random.maxacquires"; + static final void ensureInitialized() {} /** Annotation for tests that should only be run during nightly builds. */ @Documented @@ -440,134 +410,6 @@ public abstract non-sealed class LuceneTestCase extends LuceneTestCaseParent { @Target(ElementType.TYPE) public @interface SuppressReproduceLine {} - // ----------------------------------------------------------------- - // Truly immutable fields and constants, initialized once and valid - // for all suites ever since. - // ----------------------------------------------------------------- - - /** - * True if and only if tests are run in verbose mode. If this flag is false tests are not expected - * to print any messages. Enforced with {@link TestRuleLimitSysouts}. - */ - public static final boolean VERBOSE = systemPropertyAsBoolean("tests.verbose", false); - - /** Enables or disables dumping of {@link InfoStream} messages. */ - public static final boolean INFOSTREAM = systemPropertyAsBoolean("tests.infostream", VERBOSE); - - /** - * True if {@code tests.asserts} is enabled (either explicitly via the build option or, if not - * present, by the default assertion status on this class). - */ - public static final boolean TEST_ASSERTS_ENABLED = - systemPropertyAsBoolean("tests.asserts", LuceneTestCase.class.desiredAssertionStatus()); - - /** - * The default (embedded resource) lines file. - * - * @see #TEST_LINE_DOCS_FILE - */ - public static final String DEFAULT_LINE_DOCS_FILE = "europarl.lines.txt.gz"; - - /** - * Random sample from enwiki used in tests. See {@code help/tests.txt}. gradle task downloading - * this data set: {@code gradlew getEnWikiRandomLines}. - */ - public static final String JENKINS_LARGE_LINE_DOCS_FILE = "enwiki.random.lines.txt"; - - /** Gets the codec to run tests with. */ - public static final String TEST_CODEC = System.getProperty("tests.codec", "random"); - - /** Gets the postingsFormat to run tests with. */ - public static final String TEST_POSTINGSFORMAT = - System.getProperty("tests.postingsformat", "random"); - - /** Gets the docValuesFormat to run tests with */ - public static final String TEST_DOCVALUESFORMAT = - System.getProperty("tests.docvaluesformat", "random"); - - /** Gets the directory to run tests with */ - public static final String TEST_DIRECTORY = System.getProperty("tests.directory", "random"); - - /** The line file used in tests (by {@link LineFileDocs}). */ - public static final String TEST_LINE_DOCS_FILE = - System.getProperty("tests.linedocsfile", DEFAULT_LINE_DOCS_FILE); - - /** Whether or not {@link Nightly} tests should run. */ - public static final boolean TEST_NIGHTLY = - systemPropertyAsBoolean( - SYSPROP_NIGHTLY, Nightly.class.getAnnotation(TestGroup.class).enabled()); - - /** Whether or not {@link Weekly} tests should run. */ - public static final boolean TEST_WEEKLY = - systemPropertyAsBoolean( - SYSPROP_WEEKLY, Weekly.class.getAnnotation(TestGroup.class).enabled()); - - /** Whether or not {@link Monster} tests should run. */ - public static final boolean TEST_MONSTER = - systemPropertyAsBoolean( - SYSPROP_MONSTER, Monster.class.getAnnotation(TestGroup.class).enabled()); - - /** Whether or not {@link AwaitsFix} tests should run. */ - public static final boolean TEST_AWAITSFIX = - systemPropertyAsBoolean( - SYSPROP_AWAITSFIX, AwaitsFix.class.getAnnotation(TestGroup.class).enabled()); - - /** Throttling, see {@link MockDirectoryWrapper#setThrottling(Throttling)}. */ - public static final Throttling TEST_THROTTLING = - TEST_NIGHTLY ? Throttling.SOMETIMES : Throttling.NEVER; - - /** - * A random multiplier which you should use when writing random tests: multiply it by the number - * of iterations to scale your tests (for nightly builds). - */ - public static final int RANDOM_MULTIPLIER = - systemPropertyAsInt("tests.multiplier", defaultRandomMultiplier()); - - /** Compute the default value of the random multiplier (based on {@link #TEST_NIGHTLY}). */ - static int defaultRandomMultiplier() { - return TEST_NIGHTLY ? 2 : 1; - } - - /** Leave temporary files on disk, even on successful runs. */ - public static final boolean LEAVE_TEMPORARY; - - static { - boolean defaultValue = false; - for (String property : - Arrays.asList( - "tests.leaveTemporary" /* ANT tasks' (junit4) flag. */, - "tests.leavetemporary" /* lowercase */, - "tests.leavetmpdir" /* default */)) { - defaultValue |= systemPropertyAsBoolean(property, false); - } - LEAVE_TEMPORARY = defaultValue; - } - - /** Filesystem-based {@link Directory} implementations. */ - private static final List FS_DIRECTORIES = - Arrays.asList("NIOFSDirectory", "MMapDirectory"); - - /** All {@link Directory} implementations. */ - private static final List CORE_DIRECTORIES; - - static { - CORE_DIRECTORIES = new ArrayList<>(FS_DIRECTORIES); - CORE_DIRECTORIES.add(ByteBuffersDirectory.class.getSimpleName()); - } - - /** A {@link org.apache.lucene.search.QueryCachingPolicy} that randomly caches. */ - public static final QueryCachingPolicy MAYBE_CACHE_POLICY = - new QueryCachingPolicy() { - - @Override - public void onUse(Query query) {} - - @Override - public boolean shouldCache(Query query) throws IOException { - return random().nextBoolean(); - } - }; - // ----------------------------------------------------------------- // Fields initialized in class or instance rules. // ----------------------------------------------------------------- @@ -576,7 +418,7 @@ public boolean shouldCache(Query query) throws IOException { // Class level (suite) rules. // ----------------------------------------------------------------- - /** Stores the currently class under test. */ + /** Stores the current class under test. */ private static final TestRuleStoreClassName classNameRule; /** @@ -643,6 +485,52 @@ public static TestRuleIgnoreAfterMaxFailures replaceMaxFailureRule( static { RuleChain r = RuleChain.outerRule(new TestRuleIgnoreTestSuites()) + .around( + new TestRuleAdapter() { + private static TestFrameworkInfra testFrameworkInfra; + + @Override + protected void before() throws Throwable { + int maxCalls = + Integer.parseInt(System.getProperty(SYSPROP_RANDOM_MAXCALLS, "0")); + Supplier supplier = () -> RandomizedContext.current().getRandom(); + if (maxCalls > 0) { + var finalizedSupplier = supplier; + supplier = () -> new MaxCallCountRandom(finalizedSupplier.get(), maxCalls); + } + + int maxAquires = + Integer.parseInt(System.getProperty(SYSPROP_RANDOM_MAXACQUIRES, "0")); + if (maxAquires > 0) { + var finalizedSupplier = supplier; + supplier = + () -> { + if (randomCalls.incrementAndGet() > maxAquires) { + throw new RuntimeException( + "Too many random() calls. Consider using LuceneTestCase.nonAssertingRandom for" + + " large loops or data generation."); + } + return finalizedSupplier.get(); + }; + } + + var finalizedSupplier = supplier; + setTestFrameworkInfra( + null, + testFrameworkInfra = + new TestFrameworkInfra() { + @Override + public Random threadRandom() { + return finalizedSupplier.get(); + } + }); + } + + @Override + protected void afterAlways(List errors) { + setTestFrameworkInfra(testFrameworkInfra, null); + } + }) .around(ignoreAfterMaxFailures) .around(suiteFailureMarker = new TestRuleMarkFailure()) .around( @@ -754,31 +642,6 @@ static void setLiveIWCFlushMode(LiveIWCFlushMode flushMode) { @SuppressWarnings("NonFinalStaticField") private static AtomicLong randomCalls = new AtomicLong(); - static { - int maxCalls = Integer.parseInt(System.getProperty(SYSPROP_RANDOM_MAXCALLS, "0")); - Supplier supplier = () -> RandomizedContext.current().getRandom(); - if (maxCalls > 0) { - var finalizedSupplier = supplier; - supplier = () -> new MaxCallCountRandom(finalizedSupplier.get(), maxCalls); - } - - int maxAquires = Integer.parseInt(System.getProperty(SYSPROP_RANDOM_MAXACQUIRES, "0")); - if (maxAquires > 0) { - var finalizedSupplier = supplier; - supplier = - () -> { - if (randomCalls.incrementAndGet() > maxAquires) { - throw new RuntimeException( - "Too many random() calls. Consider using LuceneTestCase.nonAssertingRandom for" - + " large loops or data generation."); - } - return finalizedSupplier.get(); - }; - } - - replaceRandomSupplier(supplier); - } - // ----------------------------------------------------------------- // Suite and test case setup/ cleanup. // ----------------------------------------------------------------- diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index c38eae27a0bd..1fb72ca10869 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -16,17 +16,27 @@ */ package org.apache.lucene.tests.util; +import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean; +import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsInt; + import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom; +import com.carrotsearch.randomizedtesting.annotations.TestGroup; import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Objects; import java.util.Random; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Supplier; -import org.junit.After; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.QueryCachingPolicy; +import org.apache.lucene.store.ByteBuffersDirectory; +import org.apache.lucene.store.Directory; +import org.apache.lucene.tests.store.MockDirectoryWrapper; +import org.apache.lucene.util.InfoStream; import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; /** * Private parent class for junit4 ({@link LuceneTestCase} and junit5 ({@link @@ -34,40 +44,199 @@ */ public abstract sealed class LuceneTestCaseParent extends Assert permits LuceneTestCase, LuceneTestCaseJupiter { - static TestRuleSetupAndRestoreClassEnv classEnvRule; - /** Suite failure marker (any error in the test or suite scope). */ - @SuppressWarnings("NonFinalStaticField") - protected static TestRuleMarkFailure suiteFailureMarker; + // -------------------------------------------------------------------- + // Test groups, system properties and other annotations modifying tests + // -------------------------------------------------------------------- - static TestRuleTemporaryFilesCleanup tempFilesCleanupRule; + public static final String SYSPROP_NIGHTLY = "tests.nightly"; + public static final String SYSPROP_WEEKLY = "tests.weekly"; + public static final String SYSPROP_MONSTER = "tests.monster"; + public static final String SYSPROP_AWAITSFIX = "tests.awaitsfix"; + public static final String SYSPROP_MAXFAILURES = "tests.maxfailures"; + public static final String SYSPROP_FAILFAST = "tests.failfast"; - private static volatile AtomicReference> randomSupplier = - new AtomicReference<>(); + /** + * True if and only if tests are run in verbose mode. If this flag is false tests are not expected + * to print any messages. Enforced with {@link TestRuleLimitSysouts}. + */ + public static final boolean VERBOSE = systemPropertyAsBoolean("tests.verbose", false); - static Supplier replaceRandomSupplier(Supplier rndSupplier) { - return randomSupplier.getAndSet(rndSupplier); - } + /** Enables or disables dumping of {@link InfoStream} messages. */ + public static final boolean INFOSTREAM = systemPropertyAsBoolean("tests.infostream", VERBOSE); /** - * Access to the current {@link RandomizedContext}'s Random instance. It is safe to use this - * method from multiple threads, etc., but it should be called while within a runner's scope (so - * no static initializers). The returned {@link Random} instance will be different when - * this method is called inside a {@link BeforeClass} hook (static suite scope) and within {@link - * Before}/ {@link After} hooks or test methods. - * - *

The returned instance must not be shared with other threads or cross a single scope's - * boundary. For example, a {@link Random} acquired within a test method shouldn't be reused for - * another test case. + * True if {@code tests.asserts} is enabled (either explicitly via the build option or, if not + * present, by the default assertion status on this class). + */ + public static final boolean TEST_ASSERTS_ENABLED = + systemPropertyAsBoolean("tests.asserts", LuceneTestCase.class.desiredAssertionStatus()); + + /** + * The default (embedded resource) lines file. * - *

There is an overhead connected with getting the {@link Random} for a particular context and - * thread. It is better to use a non-asserting {@link Random} instance locally if tight loops with - * multiple invocations are present. See {@link #nonAssertingRandom(Random)}. + * @see #TEST_LINE_DOCS_FILE + */ + public static final String DEFAULT_LINE_DOCS_FILE = "europarl.lines.txt.gz"; + + /** + * Random sample from enwiki used in tests. See {@code help/tests.txt}. gradle task downloading + * this data set: {@code gradlew getEnWikiRandomLines}. + */ + public static final String JENKINS_LARGE_LINE_DOCS_FILE = "enwiki.random.lines.txt"; + + /** Gets the codec to run tests with. */ + public static final String TEST_CODEC = System.getProperty("tests.codec", "random"); + + /** Gets the postingsFormat to run tests with. */ + public static final String TEST_POSTINGSFORMAT = + System.getProperty("tests.postingsformat", "random"); + + /** Gets the docValuesFormat to run tests with */ + public static final String TEST_DOCVALUESFORMAT = + System.getProperty("tests.docvaluesformat", "random"); + + /** Gets the directory to run tests with */ + public static final String TEST_DIRECTORY = System.getProperty("tests.directory", "random"); + + /** The line file used in tests (by {@link LineFileDocs}). */ + public static final String TEST_LINE_DOCS_FILE = + System.getProperty("tests.linedocsfile", DEFAULT_LINE_DOCS_FILE); + + /** Whether or not {@link LuceneTestCase.Nightly} tests should run. */ + public static final boolean TEST_NIGHTLY = + systemPropertyAsBoolean( + SYSPROP_NIGHTLY, LuceneTestCase.Nightly.class.getAnnotation(TestGroup.class).enabled()); + + /** Whether or not {@link LuceneTestCase.Weekly} tests should run. */ + public static final boolean TEST_WEEKLY = + systemPropertyAsBoolean( + SYSPROP_WEEKLY, LuceneTestCase.Weekly.class.getAnnotation(TestGroup.class).enabled()); + + /** Whether or not {@link LuceneTestCase.Monster} tests should run. */ + public static final boolean TEST_MONSTER = + systemPropertyAsBoolean( + SYSPROP_MONSTER, LuceneTestCase.Monster.class.getAnnotation(TestGroup.class).enabled()); + + /** Whether or not {@link LuceneTestCase.AwaitsFix} tests should run. */ + public static final boolean TEST_AWAITSFIX = + systemPropertyAsBoolean( + SYSPROP_AWAITSFIX, + LuceneTestCase.AwaitsFix.class.getAnnotation(TestGroup.class).enabled()); + + /** + * Throttling, see {@link MockDirectoryWrapper#setThrottling(MockDirectoryWrapper.Throttling)}. + */ + public static final MockDirectoryWrapper.Throttling TEST_THROTTLING = + TEST_NIGHTLY + ? MockDirectoryWrapper.Throttling.SOMETIMES + : MockDirectoryWrapper.Throttling.NEVER; + + /** + * A random multiplier which you should use when writing random tests: multiply it by the number + * of iterations to scale your tests (for nightly builds). */ + public static final int RANDOM_MULTIPLIER = + systemPropertyAsInt("tests.multiplier", defaultRandomMultiplier()); + + /** Compute the default value of the random multiplier (based on {@link #TEST_NIGHTLY}). */ + static int defaultRandomMultiplier() { + return TEST_NIGHTLY ? 2 : 1; + } + + /** Leave temporary files on disk, even on successful runs. */ + public static final boolean LEAVE_TEMPORARY; + + static { + boolean defaultValue = false; + for (String property : + Arrays.asList( + "tests.leaveTemporary" /* ANT tasks' (junit4) flag. */, + "tests.leavetemporary" /* lowercase */, + "tests.leavetmpdir" /* default */)) { + defaultValue |= systemPropertyAsBoolean(property, false); + } + LEAVE_TEMPORARY = defaultValue; + } + + /** Filesystem-based {@link Directory} implementations. */ + protected static final List FS_DIRECTORIES = + Arrays.asList("NIOFSDirectory", "MMapDirectory"); + + /** All {@link Directory} implementations. */ + protected static final List CORE_DIRECTORIES; + + static { + CORE_DIRECTORIES = new ArrayList<>(FS_DIRECTORIES); + CORE_DIRECTORIES.add(ByteBuffersDirectory.class.getSimpleName()); + } + + /** + * If specified, limits the number of method calls to each individual instance returned by {@link + * #random()}. + */ + public static final String SYSPROP_RANDOM_MAXCALLS = "tests.random.maxcalls"; + + /** If specified, limits the number of calls {@link #random()} itself. */ + public static final String SYSPROP_RANDOM_MAXACQUIRES = "tests.random.maxacquires"; + + // ----------------------------------------------------------------- + // This bit is for supporting all the static method calls we have all over the place. + // In order for both junit4 and junit5 to work, we need to make sure that each class + // runs in isolation (so no concurrent tests at the moment) and that it provides + // test-framework-dependent "infrastructure" like Random suppliers, test class names, etc. + // to this class. + // ----------------------------------------------------------------- + + protected interface TestFrameworkInfra { + Random threadRandom(); + } + + private static final AtomicReference testFrameworkInfra = + new AtomicReference<>(); + + public static void setTestFrameworkInfra( + TestFrameworkInfra expected, TestFrameworkInfra newInfra) { + TestFrameworkInfra prev; + if ((prev = testFrameworkInfra.compareAndExchange(expected, newInfra)) != expected) { + throw new RuntimeException( + "Test framework infrastructure is not set to the expected value: " + + prev + + ", expected: " + + expected); + } + } + + // ----------------------------------------------------------------- + // Truly immutable fields and constants, initialized once and valid + // for all suites ever since. + // ----------------------------------------------------------------- + + /** A {@link org.apache.lucene.search.QueryCachingPolicy} that randomly caches. */ + public static final QueryCachingPolicy MAYBE_CACHE_POLICY = + new QueryCachingPolicy() { + @Override + public void onUse(Query query) {} + + @Override + public boolean shouldCache(Query query) throws IOException { + return testFrameworkInfra.get().threadRandom().nextBoolean(); + } + }; + public static Random random() { - return Objects.requireNonNull(randomSupplier.get()).get(); + return Objects.requireNonNull(testFrameworkInfra.get(), "Test framework not initialized?") + .threadRandom(); } + static TestRuleSetupAndRestoreClassEnv classEnvRule; + + /** Suite failure marker (any error in the test or suite scope). */ + @SuppressWarnings("NonFinalStaticField") + protected static TestRuleMarkFailure suiteFailureMarker; + + static TestRuleTemporaryFilesCleanup tempFilesCleanupRule; + /** * Returns a Random instance based on the current state of another Random. The returned instance * should be faster for thousands of consecutive calls because it doesn't assert that it isn't From 4d44b5319fb74c507b92a6822a81020f8a733977 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Wed, 22 Apr 2026 14:21:45 +0200 Subject: [PATCH 17/68] Cleanups. --- .../lucene/search/join/TestJupiter.java | 76 ----------------- .../lucene/tests/util/GlobalStateSupport.java | 85 ++++++++++--------- .../lucene/tests/util/LuceneTestCase.java | 45 +++++----- .../tests/util/LuceneTestCaseParent.java | 71 +++++++++------- 4 files changed, 102 insertions(+), 175 deletions(-) delete mode 100644 lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java deleted file mode 100644 index 3fa2fa9d4497..000000000000 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestJupiter.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.lucene.search.join; - -import java.io.Closeable; -import java.io.IOException; -import java.util.Objects; -import java.util.Random; -import java.util.concurrent.TimeUnit; -import org.apache.lucene.tests.util.LuceneTestCase; -import org.apache.lucene.tests.util.LuceneTestCaseJupiter; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -@Timeout(value = 3, unit = TimeUnit.SECONDS) -public class TestJupiter { - @Nested - @LuceneTestCase.Nightly - class T1 extends LuceneTestCaseJupiter { - @Test - public void t1() throws Exception { - closeAfterSuite( - new Closeable() { - @Override - public void close() throws IOException { - System.out.println("Closed."); - } - }); - - Random r1 = LuceneTestCase.random(); - Random r2 = LuceneTestCase.random(); - Assertions.assertSame(r1, r2); - System.out.println("R: " + random().nextLong()); - } - - @Test - public void t2() throws Exception { - { - Random r1 = LuceneTestCase.random(); - System.out.println("R: " + Objects.hashCode(r1) + " " + r1.nextLong()); - } - var t = - new Thread( - () -> { - Random r1 = LuceneTestCase.random(); - Random r2 = LuceneTestCase.random(); - Assertions.assertSame(r1, r2); - System.out.println("R: " + Objects.hashCode(r1) + " " + r1.nextLong()); - }); - t.start(); - t.join(); - } - } - - @Nested - public class T2 extends LuceneTestCaseJupiter { - @Test - public void testNoParent(Random random) throws Exception {} - } -} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java index 2ada4585e892..31745f5723d5 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java @@ -18,7 +18,9 @@ package org.apache.lucene.tests.util; import java.io.Closeable; +import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Random; @@ -43,26 +45,16 @@ public final class GlobalStateSupport private static final class State { private LuceneTestCaseParent.TestFrameworkInfra frameworkInfra; - private TestRuleSetupAndRestoreClassEnv prevClassEnvRule; - private ConcurrentHashMap perThreadRandoms; - - private final List closeAfterTest = new ArrayList<>(); - private final List closeAfterSuite = new ArrayList<>(); void reset() { frameworkInfra = null; - perThreadRandoms = null; - closeAfterTest.clear(); - closeAfterSuite.clear(); } void initialize() { if (frameworkInfra != null) { throw new RuntimeException(); } - - perThreadRandoms = new ConcurrentHashMap<>(); } } @@ -76,35 +68,57 @@ public void beforeAll(ExtensionContext context) throws Exception { state.frameworkInfra = new LuceneTestCaseParent.TestFrameworkInfra() { - final ConcurrentHashMap perThreadRandoms = state.perThreadRandoms; + private final ConcurrentHashMap perThreadRandoms = + new ConcurrentHashMap<>(); + + private final List closeAfterTest = new ArrayList<>(); + private final List closeAfterSuite = new ArrayList<>(); + final Supplier rnd = getRandomSupplier(context.getExecutableInvoker()); @Override public Random threadRandom() { return perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get()); } - }; - - LuceneTestCaseParent.setTestFrameworkInfra(null, state.frameworkInfra); - LuceneTestCaseParent.closeAfter.set( - new LuceneTestCaseParent.CloseAfterHook() { @Override public T closeAfterTest(T resource) { - synchronized (state) { - state.closeAfterTest.add(resource); + synchronized (this) { + closeAfterTest.add(resource); } return resource; } @Override - public T closeAfterSuite(T resource) { - synchronized (state) { - state.closeAfterSuite.add(resource); + public T closeAfterClass(T resource) { + synchronized (this) { + closeAfterSuite.add(resource); } return resource; } - }); + + @Override + public void afterEach() throws IOException { + synchronized (this) { + IOUtils.close(closeAfterTest); + closeAfterTest.clear(); + } + } + + @Override + public void afterAll() throws IOException { + synchronized (this) { + IOUtils.close( + Stream.of(closeAfterTest, closeAfterSuite, perThreadRandoms.values()) + .flatMap(Collection::stream) + .filter(v -> v instanceof Closeable) + .map(v -> (Closeable) v) + .toList()); + } + } + }; + + LuceneTestCaseParent.setTestFrameworkInfra(null, state.frameworkInfra); state.prevClassEnvRule = LuceneTestCase.classEnvRule; var targetClass = context.getRequiredTestClass(); @@ -115,12 +129,7 @@ public T closeAfterSuite(T resource) { @Override public void afterEach(ExtensionContext context) throws Exception { - var state = getState(context); - List toClose; - synchronized (state) { - toClose = List.copyOf(state.closeAfterTest); - } - IOUtils.close(toClose); + getState(context).frameworkInfra.afterEach(); } @Override @@ -129,13 +138,7 @@ public void afterAll(ExtensionContext context) throws Exception { var rule = LuceneTestCaseParent.classEnvRule; try { LuceneTestCaseParent.classEnvRule = state.prevClassEnvRule; - IOUtils.close( - Stream.concat( - state.closeAfterSuite.stream(), - state.perThreadRandoms.values().stream() - .filter(rnd1 -> rnd1 instanceof Closeable) - .map(rnd1 -> (Closeable) rnd1)) - .toList()); + state.frameworkInfra.afterAll(); } finally { rule.after(); LuceneTestCaseParent.setTestFrameworkInfra(state.frameworkInfra, null); @@ -143,6 +146,12 @@ public void afterAll(ExtensionContext context) throws Exception { } } + private State getState(ExtensionContext context) { + return context + .getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS) + .computeIfAbsent(State.class); + } + // This trick is needed to get the Supplier injected by a parameter resolved // of the randomized testing framework. private Supplier getRandomSupplier(ExecutableInvoker executableInvoker) throws Exception { @@ -162,10 +171,4 @@ public Supplier captureParameter(Supplier rnd) { hack.getClass().getMethod("captureParameter", Supplier.class), hack)); return rnd; } - - private State getState(ExtensionContext context) { - return context - .getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS) - .computeIfAbsent(State.class); - } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index b0056d0f544a..2c33053e41b0 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -523,6 +523,24 @@ protected void before() throws Throwable { public Random threadRandom() { return finalizedSupplier.get(); } + + @Override + public T closeAfterTest(T resource) { + return RandomizedContext.current() + .closeAtEnd(resource, LifecycleScope.TEST); + } + + @Override + public T closeAfterClass(T resource) { + return RandomizedContext.current() + .closeAtEnd(resource, LifecycleScope.SUITE); + } + + @Override + public void afterAll() {} + + @Override + public void afterEach() {} }); } @@ -543,32 +561,7 @@ protected void afterAlways(List errors) { new TestRuleTemporaryFilesCleanup( suiteFailureMarker, LuceneTestCase::random, - () -> RandomizedContext.current().getTargetClass())) - .around( - new TestRuleAdapter() { - @Override - protected void before() throws Throwable { - LuceneTestCaseParent.closeAfter.set( - new CloseAfterHook() { - @Override - public T closeAfterTest(T resource) { - return RandomizedContext.current() - .closeAtEnd(resource, LifecycleScope.TEST); - } - - @Override - public T closeAfterSuite(T resource) { - return RandomizedContext.current() - .closeAtEnd(resource, LifecycleScope.SUITE); - } - }); - } - - @Override - protected void afterAlways(List errors) throws Throwable { - LuceneTestCaseParent.closeAfter.set(null); - } - }); + () -> RandomizedContext.current().getTargetClass())); classRules = r.around(new NoClassHooksShadowingRule()) .around( diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index 1fb72ca10869..46d4ec71dc19 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -180,6 +180,17 @@ static int defaultRandomMultiplier() { /** If specified, limits the number of calls {@link #random()} itself. */ public static final String SYSPROP_RANDOM_MAXACQUIRES = "tests.random.maxacquires"; + /** + * Returns a Random instance based on the current state of another Random. The returned instance + * should be faster for thousands of consecutive calls because it doesn't assert that it isn't + * shared between threads or used within the correct {@link RandomizedContext}. + * + *

Use this method for local tight loops that generate a lot of random data. + */ + public static Random nonAssertingRandom(Random rnd) { + return new Xoroshiro128PlusRandom(rnd.nextLong()); + } + // ----------------------------------------------------------------- // This bit is for supporting all the static method calls we have all over the place. // In order for both junit4 and junit5 to work, we need to make sure that each class @@ -190,12 +201,20 @@ static int defaultRandomMultiplier() { protected interface TestFrameworkInfra { Random threadRandom(); + + T closeAfterTest(T resource); + + T closeAfterClass(T resource); + + void afterEach() throws IOException; + + void afterAll() throws IOException; } private static final AtomicReference testFrameworkInfra = new AtomicReference<>(); - public static void setTestFrameworkInfra( + protected static void setTestFrameworkInfra( TestFrameworkInfra expected, TestFrameworkInfra newInfra) { TestFrameworkInfra prev; if ((prev = testFrameworkInfra.compareAndExchange(expected, newInfra)) != expected) { @@ -207,6 +226,11 @@ public static void setTestFrameworkInfra( } } + protected static TestFrameworkInfra getTestFrameworkInfra() { + return Objects.requireNonNull( + testFrameworkInfra.get(), "Expected test framework not to be null."); + } + // ----------------------------------------------------------------- // Truly immutable fields and constants, initialized once and valid // for all suites ever since. @@ -219,8 +243,8 @@ public static void setTestFrameworkInfra( public void onUse(Query query) {} @Override - public boolean shouldCache(Query query) throws IOException { - return testFrameworkInfra.get().threadRandom().nextBoolean(); + public boolean shouldCache(Query query) { + return getTestFrameworkInfra().threadRandom().nextBoolean(); } }; @@ -229,40 +253,13 @@ public static Random random() { .threadRandom(); } - static TestRuleSetupAndRestoreClassEnv classEnvRule; - - /** Suite failure marker (any error in the test or suite scope). */ - @SuppressWarnings("NonFinalStaticField") - protected static TestRuleMarkFailure suiteFailureMarker; - - static TestRuleTemporaryFilesCleanup tempFilesCleanupRule; - - /** - * Returns a Random instance based on the current state of another Random. The returned instance - * should be faster for thousands of consecutive calls because it doesn't assert that it isn't - * shared between threads or used within the correct {@link RandomizedContext}. - * - *

Use this method for local tight loops that generate a lot of random data. - */ - public static Random nonAssertingRandom(Random rnd) { - return new Xoroshiro128PlusRandom(rnd.nextLong()); - } - - interface CloseAfterHook { - T closeAfterTest(T resource); - - T closeAfterSuite(T resource); - } - - static volatile AtomicReference closeAfter = new AtomicReference<>(); - /** * Registers a {@link Closeable} resource that should be closed after the test completes. * * @return resource (for call chaining). */ public T closeAfterTest(T resource) { - return closeAfter.get().closeAfterTest(resource); + return getTestFrameworkInfra().closeAfterTest(resource); } /** @@ -271,6 +268,16 @@ public T closeAfterTest(T resource) { * @return resource (for call chaining). */ public static T closeAfterSuite(T resource) { - return closeAfter.get().closeAfterSuite(resource); + return getTestFrameworkInfra().closeAfterClass(resource); } + + // TODO: to remove from here? + + static TestRuleSetupAndRestoreClassEnv classEnvRule; + + /** Suite failure marker (any error in the test or suite scope). */ + @SuppressWarnings("NonFinalStaticField") + protected static TestRuleMarkFailure suiteFailureMarker; + + static TestRuleTemporaryFilesCleanup tempFilesCleanupRule; } From 9666bc6742a53340a4c13ac9b551ae6cafe4a3c7 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 23 Apr 2026 11:39:03 +0200 Subject: [PATCH 18/68] Cleanups. --- .../tests/util/BeforeAfterCallback.java | 24 ++++ .../tests/util/CallbacksToRuleAdapter.java | 50 +++++++ .../lucene/tests/util/GlobalStateSupport.java | 132 ++++++++++-------- .../lucene/tests/util/LuceneTestCase.java | 49 +++++-- .../tests/util/LuceneTestCaseParent.java | 4 +- .../util/RunListenerPrintReproduceInfo.java | 79 +++++++---- ...Env.java => SetupAndRestoreStaticEnv.java} | 10 +- .../apache/lucene/tests/util/TagState.java | 4 +- .../util/TestRuleTemporaryFilesCleanup.java | 3 +- .../search/TestBaseExplanationTestCase.java | 2 +- 10 files changed, 243 insertions(+), 114 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/CallbacksToRuleAdapter.java rename lucene/test-framework/src/java/org/apache/lucene/tests/util/{TestRuleSetupAndRestoreClassEnv.java => SetupAndRestoreStaticEnv.java} (97%) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java new file mode 100644 index 000000000000..dd5e83bed24d --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.tests.util; + +/** Abstraction for before-test/before-suite callbacks. */ +interface BeforeAfterCallback { + void before() throws Exception; + + void after() throws Exception; +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/CallbacksToRuleAdapter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/CallbacksToRuleAdapter.java new file mode 100644 index 000000000000..787517fa856e --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/CallbacksToRuleAdapter.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.tests.util; + +import java.util.ArrayList; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.MultipleFailureException; +import org.junit.runners.model.Statement; + +record CallbacksToRuleAdapter(BeforeAfterCallback callback) implements TestRule { + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + final ArrayList errors = new ArrayList<>(); + + try { + callback().before(); + base.evaluate(); + } catch (Throwable t) { + errors.add(t); + } + + try { + callback().after(); + } catch (Throwable t) { + errors.add(t); + } + + MultipleFailureException.assertEmpty(errors); + } + }; + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java index 31745f5723d5..9611643a83bb 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java @@ -45,7 +45,6 @@ public final class GlobalStateSupport private static final class State { private LuceneTestCaseParent.TestFrameworkInfra frameworkInfra; - private TestRuleSetupAndRestoreClassEnv prevClassEnvRule; void reset() { frameworkInfra = null; @@ -58,73 +57,89 @@ void initialize() { } } - @Override - public void beforeAll(ExtensionContext context) throws Exception { - State state = getState(context); - state.initialize(); + private static final class JupiterTestFrameworkInfra + implements LuceneTestCaseParent.TestFrameworkInfra { + private final ConcurrentHashMap perThreadRandoms = new ConcurrentHashMap<>(); - // touch LuceneTestCase to trigger static initializers. - LuceneTestCase.ensureInitialized(); + private final List closeAfterTest = new ArrayList<>(); + private final List closeAfterSuite = new ArrayList<>(); - state.frameworkInfra = - new LuceneTestCaseParent.TestFrameworkInfra() { - private final ConcurrentHashMap perThreadRandoms = - new ConcurrentHashMap<>(); + final Supplier rnd; + final SetupAndRestoreStaticEnv classEnvRule; - private final List closeAfterTest = new ArrayList<>(); - private final List closeAfterSuite = new ArrayList<>(); + JupiterTestFrameworkInfra(Class requiredTestClass, Supplier randomSupplier) { + this.rnd = randomSupplier; + this.classEnvRule = + new SetupAndRestoreStaticEnv( + this::threadRandom, () -> Objects.requireNonNull(requiredTestClass)); + } - final Supplier rnd = getRandomSupplier(context.getExecutableInvoker()); + @Override + public Random threadRandom() { + return perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get()); + } - @Override - public Random threadRandom() { - return perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get()); - } + @Override + public T closeAfterTest(T resource) { + synchronized (this) { + closeAfterTest.add(resource); + } + return resource; + } - @Override - public T closeAfterTest(T resource) { - synchronized (this) { - closeAfterTest.add(resource); - } - return resource; - } + @Override + public T closeAfterClass(T resource) { + synchronized (this) { + closeAfterSuite.add(resource); + } + return resource; + } - @Override - public T closeAfterClass(T resource) { - synchronized (this) { - closeAfterSuite.add(resource); - } - return resource; - } + @Override + public void afterEach() throws IOException { + synchronized (this) { + IOUtils.close(closeAfterTest); + closeAfterTest.clear(); + } + } - @Override - public void afterEach() throws IOException { - synchronized (this) { - IOUtils.close(closeAfterTest); - closeAfterTest.clear(); - } - } + @Override + public void afterAll() throws IOException { + synchronized (this) { + IOUtils.close( + Stream.of(closeAfterTest, closeAfterSuite, perThreadRandoms.values()) + .flatMap(Collection::stream) + .filter(v -> v instanceof Closeable) + .map(v -> (Closeable) v) + .toList()); + } + } - @Override - public void afterAll() throws IOException { - synchronized (this) { - IOUtils.close( - Stream.of(closeAfterTest, closeAfterSuite, perThreadRandoms.values()) - .flatMap(Collection::stream) - .filter(v -> v instanceof Closeable) - .map(v -> (Closeable) v) - .toList()); - } - } - }; + @Override + public SetupAndRestoreStaticEnv getClassEnv() { + return classEnvRule; + } + + public void beforeAll() throws Exception { + classEnvRule.before(); + } + } + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + State state = getState(context); + state.initialize(); + + // touch LuceneTestCase to trigger static initializers. + LuceneTestCase.ensureInitialized(); - LuceneTestCaseParent.setTestFrameworkInfra(null, state.frameworkInfra); + var frameworkInfra = + new JupiterTestFrameworkInfra( + context.getRequiredTestClass(), getRandomSupplier(context.getExecutableInvoker())); + state.frameworkInfra = frameworkInfra; - state.prevClassEnvRule = LuceneTestCase.classEnvRule; - var targetClass = context.getRequiredTestClass(); - LuceneTestCase.classEnvRule = - new TestRuleSetupAndRestoreClassEnv(state.frameworkInfra::threadRandom, () -> targetClass); - LuceneTestCase.classEnvRule.before(); + LuceneTestCaseParent.setTestFrameworkInfra(null, frameworkInfra); + frameworkInfra.beforeAll(); } @Override @@ -135,12 +150,9 @@ public void afterEach(ExtensionContext context) throws Exception { @Override public void afterAll(ExtensionContext context) throws Exception { var state = getState(context); - var rule = LuceneTestCaseParent.classEnvRule; try { - LuceneTestCaseParent.classEnvRule = state.prevClassEnvRule; state.frameworkInfra.afterAll(); } finally { - rule.after(); LuceneTestCaseParent.setTestFrameworkInfra(state.frameworkInfra, null); state.reset(); } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 2c33053e41b0..e9d5526a5b54 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -483,7 +483,12 @@ public static TestRuleIgnoreAfterMaxFailures replaceMaxFailureRule( @ClassRule public static final TestRule classRules; static { - RuleChain r = + var setupAndRestoreClassEnv = + new SetupAndRestoreStaticEnv( + () -> RandomizedContext.current().getRandom(), + () -> RandomizedContext.current().getTargetClass()); + + classRules = RuleChain.outerRule(new TestRuleIgnoreTestSuites()) .around( new TestRuleAdapter() { @@ -541,6 +546,11 @@ public void afterAll() {} @Override public void afterEach() {} + + @Override + public SetupAndRestoreStaticEnv getClassEnv() { + return setupAndRestoreClassEnv; + } }); } @@ -561,9 +571,8 @@ protected void afterAlways(List errors) { new TestRuleTemporaryFilesCleanup( suiteFailureMarker, LuceneTestCase::random, - () -> RandomizedContext.current().getTargetClass())); - classRules = - r.around(new NoClassHooksShadowingRule()) + () -> RandomizedContext.current().getTargetClass())) + .around(new NoClassHooksShadowingRule()) .around( new NoInstanceHooksOverridesRule() { @Override @@ -582,11 +591,23 @@ protected boolean verify(Method key) { // We reset the default locale and timezone; these properties change as a // side-effect "user.language", "user.timezone")) + .around(new CallbacksToRuleAdapter(setupAndRestoreClassEnv)) .around( - classEnvRule = - new TestRuleSetupAndRestoreClassEnv( - () -> RandomizedContext.current().getRandom(), - () -> RandomizedContext.current().getTargetClass())); + new CallbacksToRuleAdapter( + new BeforeAfterCallback() { + @Override + public void before() throws Exception { + RunListenerPrintReproduceInfo.env = + new RunListenerPrintReproduceInfo.Env( + setupAndRestoreClassEnv.codec, + setupAndRestoreClassEnv.similarity, + setupAndRestoreClassEnv.locale, + setupAndRestoreClassEnv.timeZone); + } + + @Override + public void after() throws Exception {} + })); } // ----------------------------------------------------------------- @@ -833,7 +854,7 @@ public static IndexWriterConfig newIndexWriterConfig(Analyzer a) { public static IndexWriterConfig newIndexWriterConfig(Random r, Analyzer a) { IndexWriterConfig c = new IndexWriterConfig(a); configureRandomCompoundFormat(r, c.getCodec().compoundFormat()); - c.setSimilarity(classEnvRule.similarity); + c.setSimilarity(getTestFrameworkInfra().getClassEnv().similarity); if (INFOSTREAM) { // Even though TestRuleSetupAndRestoreClassEnv calls // InfoStream.setDefault, we do it again here so that @@ -842,7 +863,7 @@ public static IndexWriterConfig newIndexWriterConfig(Random r, Analyzer a) { // IndexWriter created we see "IW 0", "IW 1", "IW 2", // ... instead of just always "IW 0": c.setInfoStream( - new TestRuleSetupAndRestoreClassEnv.ThreadNameFixingPrintStreamInfoStream(System.out)); + new SetupAndRestoreStaticEnv.ThreadNameFixingPrintStreamInfoStream(System.out)); } if (rarely(r)) { @@ -935,7 +956,7 @@ public static MergePolicy newMergePolicy(Random r, boolean includeMockMP) { } else if (r.nextBoolean()) { return newTieredMergePolicy(r); } else if (rarely(r)) { - return newAlcoholicMergePolicy(r, classEnvRule.timeZone); + return newAlcoholicMergePolicy(r, getTestFrameworkInfra().getClassEnv().timeZone); } return newLogMergePolicy(r); } @@ -953,7 +974,7 @@ public static TieredMergePolicy newTieredMergePolicy() { } public static AlcoholicMergePolicy newAlcoholicMergePolicy() { - return newAlcoholicMergePolicy(random(), classEnvRule.timeZone); + return newAlcoholicMergePolicy(random(), getTestFrameworkInfra().getClassEnv().timeZone); } public static AlcoholicMergePolicy newAlcoholicMergePolicy(Random r, TimeZone tz) { @@ -1871,7 +1892,7 @@ public static IndexSearcher newSearcher( } else { ret = random.nextBoolean() ? new IndexSearcher(r) : new IndexSearcher(r.getContext()); } - ret.setSimilarity(classEnvRule.similarity); + ret.setSimilarity(getTestFrameworkInfra().getClassEnv().similarity); return ret; } else { final ExecutorService ex; @@ -1916,7 +1937,7 @@ protected LeafSlice[] slices(List leaves) { } }; } - ret.setSimilarity(classEnvRule.similarity); + ret.setSimilarity(getTestFrameworkInfra().getClassEnv().similarity); ret.setQueryCachingPolicy(MAYBE_CACHE_POLICY); if (random().nextBoolean()) { ret.setTimeout(() -> false); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index 46d4ec71dc19..6fd439268c9b 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -209,6 +209,8 @@ protected interface TestFrameworkInfra { void afterEach() throws IOException; void afterAll() throws IOException; + + SetupAndRestoreStaticEnv getClassEnv(); } private static final AtomicReference testFrameworkInfra = @@ -273,8 +275,6 @@ public static T closeAfterSuite(T resource) { // TODO: to remove from here? - static TestRuleSetupAndRestoreClassEnv classEnvRule; - /** Suite failure marker (any error in the test or suite scope). */ @SuppressWarnings("NonFinalStaticField") protected static TestRuleMarkFailure suiteFailureMarker; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java index 7bdc3a710b8f..701a6faebdab 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java @@ -32,14 +32,21 @@ import static org.apache.lucene.tests.util.LuceneTestCase.TEST_NIGHTLY; import static org.apache.lucene.tests.util.LuceneTestCase.TEST_POSTINGSFORMAT; import static org.apache.lucene.tests.util.LuceneTestCase.TEST_WEEKLY; -import static org.apache.lucene.tests.util.LuceneTestCase.classEnvRule; import com.carrotsearch.randomizedtesting.LifecycleScope; import com.carrotsearch.randomizedtesting.RandomizedContext; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; +import java.util.TimeZone; import java.util.regex.Pattern; +import org.apache.lucene.codecs.Codec; +import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.util.Constants; import org.junit.runner.Description; import org.junit.runner.Result; @@ -66,12 +73,14 @@ public final class RunListenerPrintReproduceInfo extends RunListener { /** Suite-level code (initialization, rule, hook) failed. */ private boolean suiteFailed; - /** A marker to print full env. diagnostics after the suite. */ - private boolean printDiagnosticsAfterClass; + /** Either a test or something else has failed. */ + private boolean somethingFailed; /** true if we should skip the reproduce string (diagnostics are independent) */ private boolean suppressReproduceLine; + static Env env; + @Override public void testRunStarted(Description description) throws Exception { suiteFailed = false; @@ -97,13 +106,14 @@ public void testFailure(Failure failure) throws Exception { } else { suiteFailed = true; } - printDiagnosticsAfterClass = true; + somethingFailed = true; } @Override public void testFinished(Description description) throws Exception { if (testFailed) { - reportAdditionalFailureInfo(stripTestNameAugmentations(description.getMethodName())); + System.err.println( + getAdditionalFailureInfo(stripTestNameAugmentations(description.getMethodName()))); } scope = LifecycleScope.SUITE; testFailed = false; @@ -124,26 +134,35 @@ private String stripTestNameAugmentations(String methodName) { @Override public void testRunFinished(Result result) throws Exception { - if (printDiagnosticsAfterClass || LuceneTestCase.VERBOSE) { - RunListenerPrintReproduceInfo.printDebuggingInformation(); + if (somethingFailed || LuceneTestCase.VERBOSE) { + System.err.println(getDebuggingInformation()); } if (suiteFailed) { - reportAdditionalFailureInfo(null); + System.err.println(getAdditionalFailureInfo(null)); } } - /** print some useful debugging information about the environment */ - private static void printDebuggingInformation() { - if (classEnvRule != null && classEnvRule.isInitialized()) { - System.err.println( - ("NOTE: test params are: codec=" + classEnvRule.codec) - + (", sim=" + classEnvRule.similarity) - + (", locale=" + classEnvRule.locale.toLanguageTag()) - + (", timezone=" - + (classEnvRule.timeZone == null ? "(null)" : classEnvRule.timeZone.getID()))); + record Env(String codec, String similarity, String locale, String timeZone) { + Env(Codec codec, Similarity similarity, Locale locale, TimeZone timeZone) { + this( + Objects.toString(codec), + Objects.toString(similarity), + Optional.ofNullable(locale).map(Locale::toLanguageTag).orElse(null), + Optional.ofNullable(timeZone).map(TimeZone::getID).orElse(null)); } - System.err.println( + } + + /** print some useful debugging information about the environment */ + private static String getDebuggingInformation() { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + pw.println( + ("NOTE: test params are: codec=" + env.codec) + + (", sim=" + env.similarity) + + (", locale=" + env.locale) + + (", timezone=" + env.timeZone)); + pw.println( "NOTE: " + (System.getProperty("os.name") + " ") + (System.getProperty("os.version") + " ") @@ -158,14 +177,17 @@ private static void printDebuggingInformation() { + ("threads=" + Thread.activeCount() + ",") + ("free=" + Runtime.getRuntime().freeMemory() + ",") + ("total=" + Runtime.getRuntime().totalMemory())); - System.err.println( - "NOTE: All tests run in this JVM: " + Arrays.toString(testClassesRun.toArray())); + pw.println("NOTE: All tests run in this JVM: " + Arrays.toString(testClassesRun.toArray())); + pw.flush(); + + return sw.toString(); } - private void reportAdditionalFailureInfo(final String testName) { + private String getAdditionalFailureInfo(final String testName) { if (suppressReproduceLine) { - return; + return ""; } + if (TEST_LINE_DOCS_FILE.endsWith(JENKINS_LARGE_LINE_DOCS_FILE)) { System.err.println( "NOTE: large line-docs file was used in this run. You have to download " @@ -209,11 +231,12 @@ private void reportAdditionalFailureInfo(final String testName) { // Environment. if (!TEST_LINE_DOCS_FILE.equals(DEFAULT_LINE_DOCS_FILE)) addVmOpt(b, "tests.linedocsfile", TEST_LINE_DOCS_FILE); - if (classEnvRule != null && classEnvRule.isInitialized()) { - addVmOpt(b, "tests.locale", classEnvRule.locale.toLanguageTag()); - if (classEnvRule.timeZone != null) { - addVmOpt(b, "tests.timezone", classEnvRule.timeZone.getID()); - } + if (env.locale() != null) { + addVmOpt(b, "tests.locale", env.locale); + } + + if (env.timeZone() != null) { + addVmOpt(b, "tests.timezone", env.timeZone()); } if (LuceneTestCase.TEST_ASSERTS_ENABLED) { @@ -224,7 +247,7 @@ private void reportAdditionalFailureInfo(final String testName) { addVmOpt(b, "tests.file.encoding", System.getProperty("file.encoding")); - System.err.println(b.toString()); + return b.toString(); } /** diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreClassEnv.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/SetupAndRestoreStaticEnv.java similarity index 97% rename from lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreClassEnv.java rename to lucene/test-framework/src/java/org/apache/lucene/tests/util/SetupAndRestoreStaticEnv.java index 433fc425b01e..c2d10f73b939 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreClassEnv.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/SetupAndRestoreStaticEnv.java @@ -55,8 +55,8 @@ import org.apache.lucene.util.PrintStreamInfoStream; import org.junit.internal.AssumptionViolatedException; -/** Setup and restore suite-level environment (fine grained junk that doesn't fit anywhere else). */ -final class TestRuleSetupAndRestoreClassEnv extends AbstractBeforeAfterRule { +/** Setup and restore suite-level environment (fine-grained junk that doesn't fit anywhere else). */ +final class SetupAndRestoreStaticEnv implements BeforeAfterCallback { private final Supplier randomSupplier; private final Supplier> targetClassSupplier; @@ -78,7 +78,7 @@ final class TestRuleSetupAndRestoreClassEnv extends AbstractBeforeAfterRule { */ HashSet avoidCodecs; - TestRuleSetupAndRestoreClassEnv( + SetupAndRestoreStaticEnv( Supplier randomSupplier, Supplier> targetClassSupplier) { this.randomSupplier = randomSupplier; this.targetClassSupplier = targetClassSupplier; @@ -112,7 +112,7 @@ public boolean isInitialized() { } @Override - protected void before() throws Exception { + public void before() throws Exception { // if verbose: print some debugging stuff about which codecs are loaded. if (VERBOSE) { System.out.println("Loaded codecs: " + Codec.availableCodecs()); @@ -289,7 +289,7 @@ private void checkCodecRestrictions(Codec codec) { /** After suite cleanup (always invoked). */ @Override - protected void after() throws Exception { + public void after() throws Exception { Codec.setDefault(savedCodec); InfoStream.setDefault(savedInfoStream); if (savedLocale != null) Locale.setDefault(savedLocale); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java index 249ccf4d0f32..f4ba5e23dc0b 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java @@ -28,8 +28,8 @@ import org.junit.platform.commons.support.AnnotationSupport; /** - * Control the state (enabled/ disabled) of a test tag meta-annotation: provides the default state - * and system property to control it. + * Control the default state (enabled/ disabled) of a test tag meta-annotation. The state can be + * switched using a system property. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java index f33103a018d0..8d42720865a9 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java @@ -129,8 +129,7 @@ private FileSystem initializeFileSystem() { fs = new VerboseFS( fs, - new TestRuleSetupAndRestoreClassEnv.ThreadNameFixingPrintStreamInfoStream( - System.out)) + new SetupAndRestoreStaticEnv.ThreadNameFixingPrintStreamInfoStream(System.out)) .getFileSystem(null); } diff --git a/lucene/test-framework/src/test/org/apache/lucene/tests/search/TestBaseExplanationTestCase.java b/lucene/test-framework/src/test/org/apache/lucene/tests/search/TestBaseExplanationTestCase.java index 6d184fbbe3fd..c8027055a3a2 100644 --- a/lucene/test-framework/src/test/org/apache/lucene/tests/search/TestBaseExplanationTestCase.java +++ b/lucene/test-framework/src/test/org/apache/lucene/tests/search/TestBaseExplanationTestCase.java @@ -29,7 +29,7 @@ /** * Tests that the {@link BaseExplanationTestCase} helper code, as well as {@link - * CheckHits#checkNoMatchExplanations} are checking what they are suppose to. + * CheckHits#checkNoMatchExplanations} are checking what they are supposed to. */ public class TestBaseExplanationTestCase extends BaseExplanationTestCase { From c117e63a6ce7750be942eba31b135e3d1558cf62 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 23 Apr 2026 12:51:17 +0200 Subject: [PATCH 19/68] Moving framework-independent assertions and utilities up to the parent class --- .../TestMemoryIndexAgainstDirectory.java | 1 - .../lucene/tests/util/LuceneTestCase.java | 1707 +--------------- .../tests/util/LuceneTestCaseParent.java | 1717 ++++++++++++++++- .../tests/util/SetupAndRestoreStaticEnv.java | 30 +- 4 files changed, 1732 insertions(+), 1723 deletions(-) diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java index 191394bd382f..5d0fb1b6446b 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java @@ -17,7 +17,6 @@ package org.apache.lucene.index.memory; import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newDirectory; -import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newIndexWriterConfig; import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newSearcher; import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newTextField; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index e9d5526a5b54..18df1bbfae7a 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -17,18 +17,14 @@ package org.apache.lucene.tests.util; -import static com.carrotsearch.randomizedtesting.RandomizedTest.frequently; import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean; import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsInt; -import static org.apache.lucene.search.DocIdSetIterator.NO_MORE_DOCS; -import static org.apache.lucene.search.IndexSearcher.LeafSlice; import com.carrotsearch.randomizedtesting.JUnit4MethodProvider; import com.carrotsearch.randomizedtesting.LifecycleScope; import com.carrotsearch.randomizedtesting.MixWithSuiteName; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedRunner; -import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Listeners; import com.carrotsearch.randomizedtesting.annotations.SeedDecorators; import com.carrotsearch.randomizedtesting.annotations.TestGroup; @@ -44,18 +40,12 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Consequence; import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite; -import com.carrotsearch.randomizedtesting.generators.RandomNumbers; import com.carrotsearch.randomizedtesting.generators.RandomPicks; import com.carrotsearch.randomizedtesting.rules.NoClassHooksShadowingRule; import com.carrotsearch.randomizedtesting.rules.NoInstanceHooksOverridesRule; import com.carrotsearch.randomizedtesting.rules.TestRuleAdapter; import java.io.Closeable; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.lang.StackWalker.Option; -import java.lang.StackWalker.StackFrame; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -64,28 +54,18 @@ import java.lang.annotation.Target; import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TimeZone; -import java.util.TreeSet; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; @@ -95,66 +75,32 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; import java.util.regex.Pattern; -import junit.framework.AssertionFailedError; -import org.apache.lucene.analysis.Analyzer; -import org.apache.lucene.codecs.CompoundFormat; import org.apache.lucene.codecs.KnnVectorsFormat; import org.apache.lucene.codecs.bitvectors.HnswBitVectorsFormat; import org.apache.lucene.codecs.hnsw.FlatVectorsFormat; -import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.FieldType; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; -import org.apache.lucene.index.BinaryDocValues; import org.apache.lucene.index.CodecReader; import org.apache.lucene.index.CompositeReader; import org.apache.lucene.index.ConcurrentMergeScheduler; import org.apache.lucene.index.DirectoryReader; -import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.FieldInfo; -import org.apache.lucene.index.FieldInfos; -import org.apache.lucene.index.Fields; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.LeafReaderContext; -import org.apache.lucene.index.LiveIndexWriterConfig; import org.apache.lucene.index.LogByteSizeMergePolicy; -import org.apache.lucene.index.LogDocMergePolicy; import org.apache.lucene.index.LogMergePolicy; import org.apache.lucene.index.MergePolicy; -import org.apache.lucene.index.MergeScheduler; -import org.apache.lucene.index.MultiBits; -import org.apache.lucene.index.MultiDocValues; -import org.apache.lucene.index.MultiTerms; -import org.apache.lucene.index.NoDeletionPolicy; -import org.apache.lucene.index.NumericDocValues; import org.apache.lucene.index.ParallelCompositeReader; import org.apache.lucene.index.ParallelLeafReader; -import org.apache.lucene.index.PointValues; -import org.apache.lucene.index.PostingsEnum; -import org.apache.lucene.index.SerialMergeScheduler; -import org.apache.lucene.index.SimpleMergedSegmentWarmer; -import org.apache.lucene.index.SnapshotDeletionPolicy; -import org.apache.lucene.index.SortedDocValues; -import org.apache.lucene.index.SortedNumericDocValues; -import org.apache.lucene.index.SortedSetDocValues; -import org.apache.lucene.index.StoredFields; -import org.apache.lucene.index.TermVectors; -import org.apache.lucene.index.Terms; -import org.apache.lucene.index.TermsEnum; -import org.apache.lucene.index.TermsEnum.SeekStatus; import org.apache.lucene.index.TieredMergePolicy; import org.apache.lucene.index.VectorEncoding; -import org.apache.lucene.internal.tests.IndexPackageAccess; -import org.apache.lucene.internal.tests.TestSecrets; -import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.LRUQueryCache; import org.apache.lucene.search.QueryCache; @@ -170,9 +116,7 @@ import org.apache.lucene.store.MergeInfo; import org.apache.lucene.store.NRTCachingDirectory; import org.apache.lucene.store.ReadOnceHint; -import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.codecs.asserting.AssertingCodec; -import org.apache.lucene.tests.index.AlcoholicMergePolicy; import org.apache.lucene.tests.index.AssertingDirectoryReader; import org.apache.lucene.tests.index.AssertingLeafReader; import org.apache.lucene.tests.index.FieldFilterLeafReader; @@ -181,33 +125,20 @@ import org.apache.lucene.tests.index.MismatchedCodecReader; import org.apache.lucene.tests.index.MismatchedDirectoryReader; import org.apache.lucene.tests.index.MismatchedLeafReader; -import org.apache.lucene.tests.index.MockIndexWriterEventListener; -import org.apache.lucene.tests.index.MockRandomMergePolicy; import org.apache.lucene.tests.mockfile.VirusCheckingFS; import org.apache.lucene.tests.search.AssertingIndexSearcher; import org.apache.lucene.tests.store.BaseDirectoryWrapper; import org.apache.lucene.tests.store.MockDirectoryWrapper; import org.apache.lucene.tests.store.RawDirectoryWrapper; -import org.apache.lucene.tests.util.automaton.AutomatonTestUtil; -import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CommandLineUtil; -import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.NamedThreadFactory; -import org.apache.lucene.util.SuppressForbidden; -import org.apache.lucene.util.automaton.Automaton; -import org.apache.lucene.util.automaton.CompiledAutomaton; -import org.apache.lucene.util.automaton.Operations; -import org.apache.lucene.util.automaton.RegExp; -import org.hamcrest.Matcher; -import org.hamcrest.MatcherAssert; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; -import org.junit.internal.AssumptionViolatedException; import org.junit.jupiter.api.Tag; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; @@ -638,20 +569,6 @@ public void after() throws Exception {} private static final Map fieldToType = new HashMap<>(); - enum LiveIWCFlushMode { - BY_RAM, - BY_DOCS, - EITHER - } - - /** Set by TestRuleSetupAndRestoreClassEnv */ - @SuppressWarnings("NonFinalStaticField") - static LiveIWCFlushMode liveIWCFlushMode; - - static void setLiveIWCFlushMode(LiveIWCFlushMode flushMode) { - liveIWCFlushMode = flushMode; - } - /** A counter of calls to {@link #random()} if {@link #SYSPROP_RANDOM_MAXACQUIRES} is defined. */ @SuppressWarnings("NonFinalStaticField") private static AtomicLong randomCalls = new AtomicLong(); @@ -677,22 +594,6 @@ public void tearDown() throws Exception { restoreIndexWriterMaxDocs(); } - /** - * Tells {@link IndexWriter} to enforce the specified limit as the maximum number of documents in - * one index; call {@link #restoreIndexWriterMaxDocs} once your test is done. - */ - public void setIndexWriterMaxDocs(int limit) { - INDEX_PACKAGE_ACCESS.setIndexWriterMaxDocs(limit); - } - - /** Returns to the default {@link IndexWriter#MAX_DOCS} limit. */ - public void restoreIndexWriterMaxDocs() { - INDEX_PACKAGE_ACCESS.setIndexWriterMaxDocs(IndexWriter.MAX_DOCS); - } - - private static final IndexPackageAccess INDEX_PACKAGE_ACCESS = - TestSecrets.getIndexPackageAccess(); - // ----------------------------------------------------------------- // Test facilities and facades for subclasses. // ----------------------------------------------------------------- @@ -707,19 +608,6 @@ public String getTestName() { return threadAndTestNameRule.testMethodName; } - /** - * Some tests expect the directory to contain a single segment, and want to do tests on that - * segment's reader. This is an utility method to help them. - */ - public static LeafReader getOnlyLeafReader(IndexReader reader) { - List subReaders = reader.leaves(); - if (subReaders.size() != 1) { - throw new IllegalArgumentException( - reader + " has " + subReaders.size() + " segments instead of exactly one"); - } - return subReaders.get(0).reader(); - } - /** * Returns true if and only if the calling thread is the primary thread executing the test case. */ @@ -728,444 +616,6 @@ protected boolean isTestThread() { return Thread.currentThread() == threadAndTestNameRule.testCaseThread; } - /** - * Returns a number of at least i - * - *

The actual number returned will be influenced by whether {@link #TEST_NIGHTLY} is active and - * {@link #RANDOM_MULTIPLIER}, but also with some random fudge. - */ - public static int atLeast(Random random, int i) { - int min = i * RANDOM_MULTIPLIER; - int max = min + (min / 2); - return TestUtil.nextInt(random, min, max); - } - - public static int atLeast(int i) { - return atLeast(random(), i); - } - - /** - * Returns true if something should happen rarely, - * - *

The actual number returned will be influenced by whether {@link #TEST_NIGHTLY} is active and - * {@link #RANDOM_MULTIPLIER}. - */ - public static boolean rarely(Random random) { - int p = TEST_NIGHTLY ? 5 : 1; - p += (p * Math.log(RANDOM_MULTIPLIER)); - int min = 100 - Math.min(p, 20); // never more than 20 - return random.nextInt(100) >= min; - } - - public static boolean rarely() { - return rarely(random()); - } - - public static boolean usually(Random random) { - return !rarely(random); - } - - public static boolean usually() { - return usually(random()); - } - - public static void assumeTrue(String msg, boolean condition) { - RandomizedTest.assumeTrue(msg, condition); - } - - public static void assumeFalse(String msg, boolean condition) { - RandomizedTest.assumeFalse(msg, condition); - } - - public static void assumeNoException(String msg, Exception e) { - RandomizedTest.assumeNoException(msg, e); - } - - public static void assertFloatUlpEquals(final float x, final float y, final short maxUlps) { - assertTrue( - x + " and " + y + " are not within " + maxUlps + " ULPs of each other", - TestUtil.floatUlpEquals(x, y, maxUlps)); - } - - public static void assertDoubleUlpEquals(final double x, final double y, final int maxUlps) { - assertTrue( - x + " and " + y + " are not within " + maxUlps + " ULPs of each other", - TestUtil.doubleUlpEquals(x, y, maxUlps)); - } - - /** - * Return args as a {@link Set} instance. The order of elements is not preserved in - * iterators. - */ - @SafeVarargs - @SuppressWarnings("varargs") - public static Set asSet(T... args) { - return new HashSet<>(Arrays.asList(args)); - } - - /** - * Convenience method for logging an iterator. - * - * @param label String logged before/after the items in the iterator - * @param iter Each next() is toString()ed and logged on its own line. If iter is null this is - * logged differently then an empty iterator. - * @param stream Stream to log messages to. - */ - public static void dumpIterator(String label, Iterator iter, PrintStream stream) { - stream.println("*** BEGIN " + label + " ***"); - if (null == iter) { - stream.println(" ... NULL ..."); - } else { - while (iter.hasNext()) { - stream.println(iter.next().toString()); - } - } - stream.println("*** END " + label + " ***"); - } - - /** - * Convenience method for logging an array. Wraps the array in an iterator and delegates - * - * @see #dumpIterator(String, Iterator, PrintStream) - */ - public static void dumpArray(String label, Object[] objs, PrintStream stream) { - Iterator iter = (null == objs) ? null : Arrays.asList(objs).iterator(); - dumpIterator(label, iter, stream); - } - - /** create a new index writer config with a snapshot deletion policy */ - public static IndexWriterConfig newSnapshotIndexWriterConfig(Analyzer analyzer) { - IndexWriterConfig c = newIndexWriterConfig(analyzer); - c.setIndexDeletionPolicy(new SnapshotDeletionPolicy(NoDeletionPolicy.INSTANCE)); - return c; - } - - /** create a new index writer config with random defaults */ - public static IndexWriterConfig newIndexWriterConfig() { - return newIndexWriterConfig(new MockAnalyzer(random())); - } - - /** create a new index writer config with random defaults */ - public static IndexWriterConfig newIndexWriterConfig(Analyzer a) { - return newIndexWriterConfig(random(), a); - } - - /** create a new index writer config with random defaults using the specified random */ - public static IndexWriterConfig newIndexWriterConfig(Random r, Analyzer a) { - IndexWriterConfig c = new IndexWriterConfig(a); - configureRandomCompoundFormat(r, c.getCodec().compoundFormat()); - c.setSimilarity(getTestFrameworkInfra().getClassEnv().similarity); - if (INFOSTREAM) { - // Even though TestRuleSetupAndRestoreClassEnv calls - // InfoStream.setDefault, we do it again here so that - // the PrintStreamInfoStream.messageID increments so - // that when there are separate instances of - // IndexWriter created we see "IW 0", "IW 1", "IW 2", - // ... instead of just always "IW 0": - c.setInfoStream( - new SetupAndRestoreStaticEnv.ThreadNameFixingPrintStreamInfoStream(System.out)); - } - - if (rarely(r)) { - c.setMergeScheduler(new SerialMergeScheduler()); - } else if (rarely(r)) { - ConcurrentMergeScheduler cms; - if (r.nextBoolean()) { - cms = new TestConcurrentMergeScheduler(); - } else { - cms = - new TestConcurrentMergeScheduler() { - @Override - protected synchronized boolean maybeStall(MergeSource mergeSource) { - return true; - } - }; - } - int maxThreadCount = TestUtil.nextInt(r, 1, 4); - int maxMergeCount = TestUtil.nextInt(r, maxThreadCount, maxThreadCount + 4); - cms.setMaxMergesAndThreads(maxMergeCount, maxThreadCount); - if (r.nextBoolean()) { - cms.disableAutoIOThrottle(); - assertFalse(cms.getAutoIOThrottle()); - } - cms.setForceMergeMBPerSec(10 + 10 * r.nextDouble()); - c.setMergeScheduler(cms); - } else { - // Always use consistent settings, else CMS's dynamic (SSD or not) - // defaults can change, hurting reproducibility: - ConcurrentMergeScheduler cms = - r.nextBoolean() ? new TestConcurrentMergeScheduler() : new ConcurrentMergeScheduler(); - - // Only 1 thread can run at once (should maybe help reproducibility), - // with up to 3 pending merges before segment-producing threads are - // stalled: - cms.setMaxMergesAndThreads(3, 1); - c.setMergeScheduler(cms); - } - - if (r.nextBoolean()) { - if (rarely(r)) { - // crazy value - c.setMaxBufferedDocs(TestUtil.nextInt(r, 2, 15)); - } else { - // reasonable value - c.setMaxBufferedDocs(TestUtil.nextInt(r, 16, 1000)); - } - } - - c.setMergePolicy(newMergePolicy(r)); - - if (rarely(r)) { - c.setMergedSegmentWarmer(new SimpleMergedSegmentWarmer(c.getInfoStream())); - } - c.setUseCompoundFile(r.nextBoolean()); - c.setReaderPooling(r.nextBoolean()); - if (rarely(r)) { - c.setCheckPendingFlushUpdate(false); - } - - if (rarely(r)) { - c.setIndexWriterEventListener(new MockIndexWriterEventListener()); - } - switch (r.nextInt(3)) { - case 0: - // Disable merge on refresh - c.setMaxFullFlushMergeWaitMillis(0L); - break; - case 1: - // Very low timeout, merges will likely not be able to run in time - c.setMaxFullFlushMergeWaitMillis(1L); - break; - default: - // Very long timeout, merges will almost always be able to run in time - c.setMaxFullFlushMergeWaitMillis(1000L); - break; - } - - c.setMaxFullFlushMergeWaitMillis(rarely(r) ? atLeast(r, 1000) : atLeast(r, 200)); - return c; - } - - public static MergePolicy newMergePolicy(Random r) { - return newMergePolicy(r, true); - } - - public static MergePolicy newMergePolicy(Random r, boolean includeMockMP) { - if (includeMockMP && rarely(r)) { - return new MockRandomMergePolicy(r); - } else if (r.nextBoolean()) { - return newTieredMergePolicy(r); - } else if (rarely(r)) { - return newAlcoholicMergePolicy(r, getTestFrameworkInfra().getClassEnv().timeZone); - } - return newLogMergePolicy(r); - } - - public static MergePolicy newMergePolicy() { - return newMergePolicy(random()); - } - - public static LogMergePolicy newLogMergePolicy() { - return newLogMergePolicy(random()); - } - - public static TieredMergePolicy newTieredMergePolicy() { - return newTieredMergePolicy(random()); - } - - public static AlcoholicMergePolicy newAlcoholicMergePolicy() { - return newAlcoholicMergePolicy(random(), getTestFrameworkInfra().getClassEnv().timeZone); - } - - public static AlcoholicMergePolicy newAlcoholicMergePolicy(Random r, TimeZone tz) { - return new AlcoholicMergePolicy(tz, new Random(r.nextLong())); - } - - public static LogMergePolicy newLogMergePolicy(Random r) { - LogMergePolicy logmp = r.nextBoolean() ? new LogDocMergePolicy() : new LogByteSizeMergePolicy(); - logmp.setCalibrateSizeByDeletes(r.nextBoolean()); - logmp.setTargetSearchConcurrency(TestUtil.nextInt(r, 1, 16)); - if (rarely(r)) { - logmp.setMergeFactor(TestUtil.nextInt(r, 2, 9)); - } else { - logmp.setMergeFactor(TestUtil.nextInt(r, 10, 50)); - } - return logmp; - } - - private static void configureRandomCompoundFormat(Random r, CompoundFormat compoundFormat) { - compoundFormat.setShouldUseCompoundFile(r.nextBoolean()); - - if (rarely(r)) { - compoundFormat.setMaxCFSSegmentSizeMB(0.2 + r.nextDouble() * 2.0); - } else { - compoundFormat.setMaxCFSSegmentSizeMB(Double.POSITIVE_INFINITY); - } - } - - public static TieredMergePolicy newTieredMergePolicy(Random r) { - TieredMergePolicy tmp = new TieredMergePolicy(); - if (rarely(r)) { - tmp.setMaxMergedSegmentMB(0.2 + r.nextDouble() * 2.0); - } else { - tmp.setMaxMergedSegmentMB(10 + r.nextDouble() * 100); - } - tmp.setFloorSegmentMB(0.2 + r.nextDouble() * 2.0); - tmp.setForceMergeDeletesPctAllowed(0.0 + r.nextDouble() * 30.0); - if (rarely(r)) { - tmp.setSegmentsPerTier(TestUtil.nextInt(r, 2, 20)); - } else { - tmp.setSegmentsPerTier(TestUtil.nextInt(r, 10, 50)); - } - if (rarely(r)) { - tmp.setTargetSearchConcurrency(TestUtil.nextInt(r, 10, 50)); - } else { - tmp.setTargetSearchConcurrency(TestUtil.nextInt(r, 2, 20)); - } - - tmp.setDeletesPctAllowed(20 + r.nextDouble() * 30); - return tmp; - } - - public static LogMergePolicy newLogMergePolicy(int mergeFactor) { - LogMergePolicy logmp = newLogMergePolicy(); - logmp.setMergeFactor(mergeFactor); - return logmp; - } - - // if you want it in LiveIndexWriterConfig: it must and will be tested here. - public static void maybeChangeLiveIndexWriterConfig(Random r, LiveIndexWriterConfig c) { - boolean didChange = false; - - String previous = c.toString(); - - if (rarely(r)) { - // change flush parameters: - // this is complicated because the api requires you "invoke setters in a magical order!" - // LUCENE-5661: workaround for race conditions in the API - synchronized (c) { - boolean flushByRAM; - switch (liveIWCFlushMode) { - case BY_RAM: - flushByRAM = true; - break; - case BY_DOCS: - flushByRAM = false; - break; - case EITHER: - flushByRAM = r.nextBoolean(); - break; - default: - throw new AssertionError(); - } - if (flushByRAM) { - c.setRAMBufferSizeMB(TestUtil.nextInt(r, 1, 10)); - c.setMaxBufferedDocs(IndexWriterConfig.DISABLE_AUTO_FLUSH); - } else { - if (rarely(r)) { - // crazy value - c.setMaxBufferedDocs(TestUtil.nextInt(r, 2, 15)); - } else { - // reasonable value - c.setMaxBufferedDocs(TestUtil.nextInt(r, 16, 1000)); - } - c.setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH); - } - } - didChange = true; - } - - if (rarely(r)) { - IndexWriter.IndexReaderWarmer curWarmer = c.getMergedSegmentWarmer(); - if (curWarmer == null || curWarmer instanceof SimpleMergedSegmentWarmer) { - // change warmer parameters - if (r.nextBoolean()) { - c.setMergedSegmentWarmer(new SimpleMergedSegmentWarmer(c.getInfoStream())); - } else { - c.setMergedSegmentWarmer(null); - } - } - didChange = true; - } - - if (rarely(r)) { - // change CFS flush parameters - c.setUseCompoundFile(r.nextBoolean()); - didChange = true; - } - - if (rarely(r)) { - // change CMS merge parameters - MergeScheduler ms = c.getMergeScheduler(); - if (ms instanceof ConcurrentMergeScheduler cms) { - int maxThreadCount = TestUtil.nextInt(r, 1, 4); - int maxMergeCount = TestUtil.nextInt(r, maxThreadCount, maxThreadCount + 4); - boolean enableAutoIOThrottle = r.nextBoolean(); - if (enableAutoIOThrottle) { - cms.enableAutoIOThrottle(); - } else { - cms.disableAutoIOThrottle(); - } - cms.setMaxMergesAndThreads(maxMergeCount, maxThreadCount); - didChange = true; - } - } - - if (rarely(r)) { - MergePolicy mp = c.getMergePolicy(); - configureRandomCompoundFormat(r, c.getCodec().compoundFormat()); - if (mp instanceof LogMergePolicy logmp) { - logmp.setCalibrateSizeByDeletes(r.nextBoolean()); - if (rarely(r)) { - logmp.setMergeFactor(TestUtil.nextInt(r, 2, 9)); - } else { - logmp.setMergeFactor(TestUtil.nextInt(r, 10, 50)); - } - } else if (mp instanceof TieredMergePolicy tmp) { - if (rarely(r)) { - tmp.setMaxMergedSegmentMB(0.2 + r.nextDouble() * 2.0); - } else { - tmp.setMaxMergedSegmentMB(r.nextDouble() * 100); - } - tmp.setFloorSegmentMB(0.2 + r.nextDouble() * 2.0); - tmp.setForceMergeDeletesPctAllowed(0.0 + r.nextDouble() * 30.0); - if (rarely(r)) { - tmp.setSegmentsPerTier(TestUtil.nextInt(r, 2, 20)); - } else { - tmp.setSegmentsPerTier(TestUtil.nextInt(r, 10, 50)); - } - configureRandomCompoundFormat(r, c.getCodec().compoundFormat()); - tmp.setDeletesPctAllowed(20 + r.nextDouble() * 30); - } - didChange = true; - } - if (VERBOSE && didChange) { - String current = c.toString(); - String[] previousLines = previous.split("\n"); - String[] currentLines = current.split("\n"); - StringBuilder diff = new StringBuilder(); - - // this should always be the case, diff each line - if (previousLines.length == currentLines.length) { - for (int i = 0; i < previousLines.length; i++) { - if (!previousLines[i].equals(currentLines[i])) { - diff.append("- ").append(previousLines[i]).append("\n"); - diff.append("+ ").append(currentLines[i]).append("\n"); - } - } - } else { - // but just in case of something ridiculous... - diff.append(current); - } - - // its possible to be empty, if we "change" a value to what it had before. - if (diff.length() > 0) { - System.out.println("NOTE: LuceneTestCase: randomly changed IWC's live settings:"); - System.out.println(diff); - } - } - } - /** * Returns a new Directory instance. Use this when the test does not care about the specific * Directory implementation (most tests). @@ -1913,7 +1363,7 @@ public static IndexSearcher newSearcher( new AssertingIndexSearcher(random, r, ex) { @Override protected LeafSlice[] slices(List leaves) { - return LuceneTestCase.slices( + return LuceneTestCaseParent.slices( leaves, maxDocPerSlice, maxSegmentsPerSlice, concurrency); } }; @@ -1922,7 +1372,7 @@ protected LeafSlice[] slices(List leaves) { new AssertingIndexSearcher(random, r.getContext(), ex) { @Override protected LeafSlice[] slices(List leaves) { - return LuceneTestCase.slices( + return LuceneTestCaseParent.slices( leaves, maxDocPerSlice, maxSegmentsPerSlice, concurrency); } }; @@ -1932,7 +1382,7 @@ protected LeafSlice[] slices(List leaves) { new IndexSearcher(r, ex) { @Override protected LeafSlice[] slices(List leaves) { - return LuceneTestCase.slices( + return LuceneTestCaseParent.slices( leaves, maxDocPerSlice, maxSegmentsPerSlice, concurrency); } }; @@ -1946,1037 +1396,6 @@ protected LeafSlice[] slices(List leaves) { } } - /** - * Creates leaf slices according to the concurrency argument, that optionally leverage - * intra-segment concurrency by splitting segments into multiple partitions according to the - * maxDocsPerSlice argument. - */ - private static LeafSlice[] slices( - List leaves, - int maxDocsPerSlice, - int maxSegmentsPerSlice, - Concurrency concurrency) { - assert concurrency != Concurrency.NONE; - // Rarely test slices without partitions even though intra-segment concurrency is supported - return IndexSearcher.slices( - leaves, - maxDocsPerSlice, - maxSegmentsPerSlice, - concurrency == Concurrency.INTRA_SEGMENT && frequently()); - } - - /** - * Gets a resource from the test's classpath as {@link Path}. This method should only be used, if - * a real file is needed. To get a stream, code should prefer {@link #getDataInputStream(String)}. - */ - protected Path getDataPath(String name) throws IOException { - try { - return Paths.get( - IOUtils.requireResourceNonNull(this.getClass().getResource(name), name).toURI()); - } catch (URISyntaxException e) { - throw new AssertionError(e); - } - } - - /** Gets a resource from the test's classpath as {@link InputStream}. */ - protected InputStream getDataInputStream(String name) throws IOException { - return IOUtils.requireResourceNonNull(this.getClass().getResourceAsStream(name), name); - } - - // these hide the deprecated Assert.assertThat method - public static void assertThat(T actual, Matcher matcher) { - MatcherAssert.assertThat(actual, matcher); - } - - public static void assertThat(String reason, T actual, Matcher matcher) { - MatcherAssert.assertThat(reason, actual, matcher); - } - - public void assertReaderEquals(String info, IndexReader leftReader, IndexReader rightReader) - throws IOException { - assertReaderStatisticsEquals(info, leftReader, rightReader); - assertTermsEquals(info, leftReader, rightReader, true); - assertNormsEquals(info, leftReader, rightReader); - assertStoredFieldsEquals(info, leftReader, rightReader); - assertTermVectorsEquals(info, leftReader, rightReader); - assertDocValuesEquals(info, leftReader, rightReader); - assertDeletedDocsEquals(info, leftReader, rightReader); - assertFieldInfosEquals(info, leftReader, rightReader); - assertPointsEquals(info, leftReader, rightReader); - } - - /** checks that reader-level statistics are the same */ - public void assertReaderStatisticsEquals( - String info, IndexReader leftReader, IndexReader rightReader) throws IOException { - // Somewhat redundant: we never delete docs - assertEquals(info, leftReader.maxDoc(), rightReader.maxDoc()); - assertEquals(info, leftReader.numDocs(), rightReader.numDocs()); - assertEquals(info, leftReader.numDeletedDocs(), rightReader.numDeletedDocs()); - assertEquals(info, leftReader.hasDeletions(), rightReader.hasDeletions()); - } - - /** Fields api equivalency */ - public void assertTermsEquals( - String info, IndexReader leftReader, IndexReader rightReader, boolean deep) - throws IOException { - Set leftFields = new HashSet<>(FieldInfos.getIndexedFields(leftReader)); - Set rightFields = new HashSet<>(FieldInfos.getIndexedFields(rightReader)); - assertEquals(info, leftFields, rightFields); - - for (String field : leftFields) { - assertTermsEquals( - info, - leftReader, - MultiTerms.getTerms(leftReader, field), - MultiTerms.getTerms(rightReader, field), - deep); - } - } - - /** Terms api equivalency */ - public void assertTermsEquals( - String info, IndexReader leftReader, Terms leftTerms, Terms rightTerms, boolean deep) - throws IOException { - if (leftTerms == null || rightTerms == null) { - assertNull(info, leftTerms); - assertNull(info, rightTerms); - return; - } - assertTermsStatisticsEquals(info, leftTerms, rightTerms); - assertEquals("hasOffsets", leftTerms.hasOffsets(), rightTerms.hasOffsets()); - assertEquals("hasPositions", leftTerms.hasPositions(), rightTerms.hasPositions()); - assertEquals("hasPayloads", leftTerms.hasPayloads(), rightTerms.hasPayloads()); - - TermsEnum leftTermsEnum = leftTerms.iterator(); - TermsEnum rightTermsEnum = rightTerms.iterator(); - assertTermsEnumEquals(info, leftReader, leftTermsEnum, rightTermsEnum, true); - - assertTermsSeekingEquals(info, leftTerms, rightTerms); - - if (deep) { - int numIntersections = atLeast(3); - for (int i = 0; i < numIntersections; i++) { - String re = AutomatonTestUtil.randomRegexp(random()); - Automaton a = new RegExp(re, RegExp.NONE).toAutomaton(); - a = Operations.determinize(a, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT); - CompiledAutomaton automaton = new CompiledAutomaton(a); - if (automaton.type == CompiledAutomaton.AUTOMATON_TYPE.NORMAL) { - // TODO: test start term too - TermsEnum leftIntersection = leftTerms.intersect(automaton, null); - TermsEnum rightIntersection = rightTerms.intersect(automaton, null); - assertTermsEnumEquals(info, leftReader, leftIntersection, rightIntersection, rarely()); - } - } - } - } - - /** checks collection-level statistics on Terms */ - public void assertTermsStatisticsEquals(String info, Terms leftTerms, Terms rightTerms) - throws IOException { - assertEquals(info, leftTerms.getDocCount(), rightTerms.getDocCount()); - assertEquals(info, leftTerms.getSumDocFreq(), rightTerms.getSumDocFreq()); - assertEquals(info, leftTerms.getSumTotalTermFreq(), rightTerms.getSumTotalTermFreq()); - if (leftTerms.size() != -1 && rightTerms.size() != -1) { - assertEquals(info, leftTerms.size(), rightTerms.size()); - } - } - - /** - * checks the terms enum sequentially if deep is false, it does a 'shallow' test that doesnt go - * down to the docsenums - */ - public void assertTermsEnumEquals( - String info, - IndexReader leftReader, - TermsEnum leftTermsEnum, - TermsEnum rightTermsEnum, - boolean deep) - throws IOException { - BytesRef term; - PostingsEnum leftPositions = null; - PostingsEnum rightPositions = null; - PostingsEnum leftDocs = null; - PostingsEnum rightDocs = null; - - while ((term = leftTermsEnum.next()) != null) { - assertEquals(info, term, rightTermsEnum.next()); - assertTermStatsEquals(info, leftTermsEnum, rightTermsEnum); - if (deep) { - assertDocsAndPositionsEnumEquals( - info, - leftPositions = leftTermsEnum.postings(leftPositions, PostingsEnum.ALL), - rightPositions = rightTermsEnum.postings(rightPositions, PostingsEnum.ALL)); - - assertPositionsSkippingEquals( - info, - leftReader, - leftTermsEnum.docFreq(), - leftPositions = leftTermsEnum.postings(leftPositions, PostingsEnum.ALL), - rightPositions = rightTermsEnum.postings(rightPositions, PostingsEnum.ALL)); - - // with freqs: - assertDocsEnumEquals( - info, - leftDocs = leftTermsEnum.postings(leftDocs), - rightDocs = rightTermsEnum.postings(rightDocs), - true); - - // w/o freqs: - assertDocsEnumEquals( - info, - leftDocs = leftTermsEnum.postings(leftDocs, PostingsEnum.NONE), - rightDocs = rightTermsEnum.postings(rightDocs, PostingsEnum.NONE), - false); - - // with freqs: - assertDocsSkippingEquals( - info, - leftReader, - leftTermsEnum.docFreq(), - leftDocs = leftTermsEnum.postings(leftDocs), - rightDocs = rightTermsEnum.postings(rightDocs), - true); - - // w/o freqs: - assertDocsSkippingEquals( - info, - leftReader, - leftTermsEnum.docFreq(), - leftDocs = leftTermsEnum.postings(leftDocs, PostingsEnum.NONE), - rightDocs = rightTermsEnum.postings(rightDocs, PostingsEnum.NONE), - false); - } - } - assertNull(info, rightTermsEnum.next()); - } - - /** checks docs + freqs + positions + payloads, sequentially */ - public void assertDocsAndPositionsEnumEquals( - String info, PostingsEnum leftDocs, PostingsEnum rightDocs) throws IOException { - assertNotNull(leftDocs); - assertNotNull(rightDocs); - assertEquals(info, -1, leftDocs.docID()); - assertEquals(info, -1, rightDocs.docID()); - int docid; - while ((docid = leftDocs.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { - assertEquals(info, docid, rightDocs.nextDoc()); - int freq = leftDocs.freq(); - assertEquals(info, freq, rightDocs.freq()); - for (int i = 0; i < freq; i++) { - assertEquals(info, leftDocs.nextPosition(), rightDocs.nextPosition()); - assertEquals(info, leftDocs.getPayload(), rightDocs.getPayload()); - assertEquals(info, leftDocs.startOffset(), rightDocs.startOffset()); - assertEquals(info, leftDocs.endOffset(), rightDocs.endOffset()); - } - } - assertEquals(info, DocIdSetIterator.NO_MORE_DOCS, rightDocs.nextDoc()); - } - - /** checks docs + freqs, sequentially */ - public void assertDocsEnumEquals( - String info, PostingsEnum leftDocs, PostingsEnum rightDocs, boolean hasFreqs) - throws IOException { - if (leftDocs == null) { - assertNull(rightDocs); - return; - } - assertEquals(info, -1, leftDocs.docID()); - assertEquals(info, -1, rightDocs.docID()); - int docid; - while ((docid = leftDocs.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { - assertEquals(info, docid, rightDocs.nextDoc()); - if (hasFreqs) { - assertEquals(info, leftDocs.freq(), rightDocs.freq()); - } - } - assertEquals(info, DocIdSetIterator.NO_MORE_DOCS, rightDocs.nextDoc()); - } - - /** checks advancing docs */ - public void assertDocsSkippingEquals( - String info, - IndexReader leftReader, - int docFreq, - PostingsEnum leftDocs, - PostingsEnum rightDocs, - boolean hasFreqs) - throws IOException { - if (leftDocs == null) { - assertNull(rightDocs); - return; - } - int docid = -1; - int averageGap = leftReader.maxDoc() / (1 + docFreq); - int skipInterval = 16; - - while (true) { - if (random().nextBoolean()) { - // nextDoc() - docid = leftDocs.nextDoc(); - assertEquals(info, docid, rightDocs.nextDoc()); - } else { - // advance() - int skip = - docid + (int) Math.ceil(Math.abs(skipInterval + random().nextGaussian() * averageGap)); - docid = leftDocs.advance(skip); - assertEquals(info, docid, rightDocs.advance(skip)); - } - - if (docid == DocIdSetIterator.NO_MORE_DOCS) { - return; - } - if (hasFreqs) { - assertEquals(info, leftDocs.freq(), rightDocs.freq()); - } - } - } - - /** checks advancing docs + positions */ - public void assertPositionsSkippingEquals( - String info, - IndexReader leftReader, - int docFreq, - PostingsEnum leftDocs, - PostingsEnum rightDocs) - throws IOException { - if (leftDocs == null || rightDocs == null) { - assertNull(leftDocs); - assertNull(rightDocs); - return; - } - - int docid = -1; - int averageGap = leftReader.maxDoc() / (1 + docFreq); - int skipInterval = 16; - - while (true) { - if (random().nextBoolean()) { - // nextDoc() - docid = leftDocs.nextDoc(); - assertEquals(info, docid, rightDocs.nextDoc()); - } else { - // advance() - int skip = - docid + (int) Math.ceil(Math.abs(skipInterval + random().nextGaussian() * averageGap)); - docid = leftDocs.advance(skip); - assertEquals(info, docid, rightDocs.advance(skip)); - } - - if (docid == DocIdSetIterator.NO_MORE_DOCS) { - return; - } - int freq = leftDocs.freq(); - assertEquals(info, freq, rightDocs.freq()); - for (int i = 0; i < freq; i++) { - assertEquals(info, leftDocs.nextPosition(), rightDocs.nextPosition()); - assertEquals(info, leftDocs.getPayload(), rightDocs.getPayload()); - } - } - } - - private void assertTermsSeekingEquals(String info, Terms leftTerms, Terms rightTerms) - throws IOException { - - // just an upper bound - int numTests = atLeast(20); - Random random = random(); - - TermsEnum leftEnum = null; - - // collect this number of terms from the left side - HashSet tests = new HashSet<>(); - int numPasses = 0; - while (numPasses < 10 && tests.size() < numTests) { - leftEnum = leftTerms.iterator(); - BytesRef term; - while ((term = leftEnum.next()) != null) { - int code = random.nextInt(10); - if (code == 0) { - // the term - tests.add(BytesRef.deepCopyOf(term)); - } else if (code == 1) { - // truncated subsequence of term - term = BytesRef.deepCopyOf(term); - if (term.length > 0) { - // truncate it - term.length = random.nextInt(term.length); - } - } else if (code == 2) { - // term, but ensure a non-zero offset - byte[] newbytes = new byte[term.length + 5]; - System.arraycopy(term.bytes, term.offset, newbytes, 5, term.length); - tests.add(new BytesRef(newbytes, 5, term.length)); - } else if (code == 3) { - switch (random().nextInt(3)) { - case 0: - tests.add(new BytesRef()); // before the first term - break; - case 1: - tests.add(new BytesRef(new byte[] {(byte) 0xFF, (byte) 0xFF})); // past the last term - break; - case 2: - tests.add(new BytesRef(TestUtil.randomSimpleString(random()))); // random term - break; - default: - throw new AssertionError(); - } - } - } - numPasses++; - } - - TermsEnum rightEnum = rightTerms.iterator(); - - ArrayList shuffledTests = new ArrayList<>(tests); - Collections.shuffle(shuffledTests, random); - - for (BytesRef b : shuffledTests) { - if (rarely()) { - // make new enums - leftEnum = leftTerms.iterator(); - rightEnum = rightTerms.iterator(); - } - - final boolean seekExact = random().nextBoolean(); - - if (seekExact) { - assertEquals(info, leftEnum.seekExact(b), rightEnum.seekExact(b)); - } else { - SeekStatus leftStatus = leftEnum.seekCeil(b); - SeekStatus rightStatus = rightEnum.seekCeil(b); - assertEquals(info, leftStatus, rightStatus); - if (leftStatus != SeekStatus.END) { - assertEquals(info, leftEnum.term(), rightEnum.term()); - assertTermStatsEquals(info, leftEnum, rightEnum); - } - } - } - } - - /** checks term-level statistics */ - public void assertTermStatsEquals(String info, TermsEnum leftTermsEnum, TermsEnum rightTermsEnum) - throws IOException { - assertEquals(info, leftTermsEnum.docFreq(), rightTermsEnum.docFreq()); - assertEquals(info, leftTermsEnum.totalTermFreq(), rightTermsEnum.totalTermFreq()); - } - - /** checks that norms are the same across all fields */ - public void assertNormsEquals(String info, IndexReader leftReader, IndexReader rightReader) - throws IOException { - Set leftFields = new HashSet<>(FieldInfos.getIndexedFields(leftReader)); - Set rightFields = new HashSet<>(FieldInfos.getIndexedFields(rightReader)); - assertEquals(info, leftFields, rightFields); - - for (String field : leftFields) { - NumericDocValues leftNorms = MultiDocValues.getNormValues(leftReader, field); - NumericDocValues rightNorms = MultiDocValues.getNormValues(rightReader, field); - if (leftNorms != null && rightNorms != null) { - assertDocValuesEquals(info, leftReader.maxDoc(), leftNorms, rightNorms); - } else { - assertNull(info, leftNorms); - assertNull(info, rightNorms); - } - } - } - - /** checks that stored fields of all documents are the same */ - public void assertStoredFieldsEquals(String info, IndexReader leftReader, IndexReader rightReader) - throws IOException { - assert leftReader.maxDoc() == rightReader.maxDoc(); - StoredFields leftStoredFields = leftReader.storedFields(); - StoredFields rightStoredFields = rightReader.storedFields(); - for (int i = 0; i < leftReader.maxDoc(); i++) { - Document leftDoc = leftStoredFields.document(i); - Document rightDoc = rightStoredFields.document(i); - - // TODO: I think this is bogus because we don't document what the order should be - // from these iterators, etc. I think the codec/IndexReader should be free to order this stuff - // in whatever way it wants (e.g. maybe it packs related fields together or something) - // To fix this, we sort the fields in both documents by name, but - // we still assume that all instances with same name are in order: - Comparator comp = Comparator.comparing(IndexableField::name); - List leftFields = new ArrayList<>(leftDoc.getFields()); - List rightFields = new ArrayList<>(rightDoc.getFields()); - leftFields.sort(comp); - rightFields.sort(comp); - - Iterator leftIterator = leftFields.iterator(); - Iterator rightIterator = rightFields.iterator(); - while (leftIterator.hasNext()) { - assertTrue(info, rightIterator.hasNext()); - assertStoredFieldEquals(info, leftIterator.next(), rightIterator.next()); - } - assertFalse(info, rightIterator.hasNext()); - } - } - - /** checks that two stored fields are equivalent */ - public void assertStoredFieldEquals( - String info, IndexableField leftField, IndexableField rightField) { - assertEquals(info, leftField.name(), rightField.name()); - assertEquals(info, leftField.binaryValue(), rightField.binaryValue()); - assertEquals(info, leftField.stringValue(), rightField.stringValue()); - assertEquals(info, leftField.numericValue(), rightField.numericValue()); - // TODO: should we check the FT at all? - } - - /** checks that term vectors across all fields are equivalent */ - public void assertTermVectorsEquals(String info, IndexReader leftReader, IndexReader rightReader) - throws IOException { - assert leftReader.maxDoc() == rightReader.maxDoc(); - TermVectors leftVectors = leftReader.termVectors(); - TermVectors rightVectors = rightReader.termVectors(); - for (int i = 0; i < leftReader.maxDoc(); i++) { - Fields leftFields = leftVectors.get(i); - Fields rightFields = rightVectors.get(i); - - // Fields could be null if there are no postings, - // but then it must be null for both - if (leftFields == null || rightFields == null) { - assertNull(info, leftFields); - assertNull(info, rightFields); - return; - } - if (leftFields.size() != -1 && rightFields.size() != -1) { - assertEquals(info, leftFields.size(), rightFields.size()); - } - - Iterator leftEnum = leftFields.iterator(); - Iterator rightEnum = rightFields.iterator(); - while (leftEnum.hasNext()) { - String field = leftEnum.next(); - assertEquals(info, field, rightEnum.next()); - assertTermsEquals( - info, leftReader, leftFields.terms(field), rightFields.terms(field), rarely()); - } - assertFalse(rightEnum.hasNext()); - } - } - - private static Set getDVFields(IndexReader reader) { - Set fields = new HashSet<>(); - for (FieldInfo fi : FieldInfos.getMergedFieldInfos(reader)) { - if (fi.getDocValuesType() != DocValuesType.NONE) { - fields.add(fi.name); - } - } - - return fields; - } - - /** checks that docvalues across all fields are equivalent */ - public void assertDocValuesEquals(String info, IndexReader leftReader, IndexReader rightReader) - throws IOException { - Set leftFields = getDVFields(leftReader); - Set rightFields = getDVFields(rightReader); - assertEquals(info, leftFields, rightFields); - - for (String field : leftFields) { - // TODO: clean this up... very messy - { - NumericDocValues leftValues = MultiDocValues.getNumericValues(leftReader, field); - NumericDocValues rightValues = MultiDocValues.getNumericValues(rightReader, field); - if (leftValues != null && rightValues != null) { - assertDocValuesEquals(info, leftReader.maxDoc(), leftValues, rightValues); - } else { - assertTrue( - info + ": left numeric doc values for field=\"" + field + "\" are not null", - leftValues == null || leftValues.nextDoc() == NO_MORE_DOCS); - assertTrue( - info + ": right numeric doc values for field=\"" + field + "\" are not null", - rightValues == null || rightValues.nextDoc() == NO_MORE_DOCS); - } - } - - { - BinaryDocValues leftValues = MultiDocValues.getBinaryValues(leftReader, field); - BinaryDocValues rightValues = MultiDocValues.getBinaryValues(rightReader, field); - if (leftValues != null && rightValues != null) { - while (true) { - int docID = leftValues.nextDoc(); - assertEquals(docID, rightValues.nextDoc()); - if (docID == NO_MORE_DOCS) { - break; - } - assertEquals(leftValues.binaryValue(), rightValues.binaryValue()); - } - } else { - assertTrue(info, leftValues == null || leftValues.nextDoc() == NO_MORE_DOCS); - assertTrue(info, rightValues == null || rightValues.nextDoc() == NO_MORE_DOCS); - } - } - - { - SortedDocValues leftValues = MultiDocValues.getSortedValues(leftReader, field); - SortedDocValues rightValues = MultiDocValues.getSortedValues(rightReader, field); - if (leftValues != null && rightValues != null) { - // numOrds - assertEquals(info, leftValues.getValueCount(), rightValues.getValueCount()); - // ords - for (int i = 0; i < leftValues.getValueCount(); i++) { - final BytesRef left = BytesRef.deepCopyOf(leftValues.lookupOrd(i)); - final BytesRef right = rightValues.lookupOrd(i); - assertEquals(info, left, right); - } - // bytes - while (true) { - int docID = leftValues.nextDoc(); - assertEquals(docID, rightValues.nextDoc()); - if (docID == NO_MORE_DOCS) { - break; - } - final BytesRef left = BytesRef.deepCopyOf(leftValues.lookupOrd(leftValues.ordValue())); - final BytesRef right = rightValues.lookupOrd(rightValues.ordValue()); - assertEquals(info, left, right); - } - } else { - assertNull(info, leftValues); - assertNull(info, rightValues); - } - } - - { - SortedSetDocValues leftValues = MultiDocValues.getSortedSetValues(leftReader, field); - SortedSetDocValues rightValues = MultiDocValues.getSortedSetValues(rightReader, field); - if (leftValues != null && rightValues != null) { - // numOrds - assertEquals(info, leftValues.getValueCount(), rightValues.getValueCount()); - // ords - for (int i = 0; i < leftValues.getValueCount(); i++) { - final BytesRef left = BytesRef.deepCopyOf(leftValues.lookupOrd(i)); - final BytesRef right = rightValues.lookupOrd(i); - assertEquals(info, left, right); - } - // ord lists - while (true) { - int docID = leftValues.nextDoc(); - assertEquals(docID, rightValues.nextDoc()); - if (docID == NO_MORE_DOCS) { - break; - } - assertEquals(info, leftValues.docValueCount(), rightValues.docValueCount()); - for (int i = 0; i < leftValues.docValueCount(); i++) { - assertEquals(info, leftValues.nextOrd(), rightValues.nextOrd()); - } - } - } else { - assertNull(info, leftValues); - assertNull(info, rightValues); - } - } - - { - SortedNumericDocValues leftValues = - MultiDocValues.getSortedNumericValues(leftReader, field); - SortedNumericDocValues rightValues = - MultiDocValues.getSortedNumericValues(rightReader, field); - if (leftValues != null && rightValues != null) { - while (true) { - int docID = leftValues.nextDoc(); - assertEquals(docID, rightValues.nextDoc()); - if (docID == NO_MORE_DOCS) { - break; - } - assertEquals(info, leftValues.docValueCount(), rightValues.docValueCount()); - for (int j = 0; j < leftValues.docValueCount(); j++) { - assertEquals(info, leftValues.nextValue(), rightValues.nextValue()); - } - } - } else { - assertNull(info, leftValues); - assertNull(info, rightValues); - } - } - } - } - - public void assertDocValuesEquals( - String info, int num, NumericDocValues leftDocValues, NumericDocValues rightDocValues) - throws IOException { - assertNotNull(info, leftDocValues); - assertNotNull(info, rightDocValues); - while (true) { - int leftDocID = leftDocValues.nextDoc(); - int rightDocID = rightDocValues.nextDoc(); - assertEquals(leftDocID, rightDocID); - if (leftDocID == NO_MORE_DOCS) { - return; - } - assertEquals(leftDocValues.longValue(), rightDocValues.longValue()); - } - } - - // TODO: this is kinda stupid, we don't delete documents in the test. - public void assertDeletedDocsEquals(String info, IndexReader leftReader, IndexReader rightReader) - throws IOException { - assert leftReader.numDeletedDocs() == rightReader.numDeletedDocs(); - Bits leftBits = MultiBits.getLiveDocs(leftReader); - Bits rightBits = MultiBits.getLiveDocs(rightReader); - - if (leftBits == null || rightBits == null) { - assertNull(info, leftBits); - assertNull(info, rightBits); - return; - } - - assert leftReader.maxDoc() == rightReader.maxDoc(); - assertEquals(info, leftBits.length(), rightBits.length()); - for (int i = 0; i < leftReader.maxDoc(); i++) { - assertEquals(info, leftBits.get(i), rightBits.get(i)); - } - } - - public void assertFieldInfosEquals(String info, IndexReader leftReader, IndexReader rightReader) - throws IOException { - FieldInfos leftInfos = FieldInfos.getMergedFieldInfos(leftReader); - FieldInfos rightInfos = FieldInfos.getMergedFieldInfos(rightReader); - - // TODO: would be great to verify more than just the names of the fields! - TreeSet left = new TreeSet<>(); - TreeSet right = new TreeSet<>(); - - for (FieldInfo fi : leftInfos) { - left.add(fi.name); - } - - for (FieldInfo fi : rightInfos) { - right.add(fi.name); - } - - assertEquals(info, left, right); - } - - // naive silly memory heavy uninversion!! maps docID -> packed values (a Set because a given doc - // can be multi-valued) - private Map> uninvert(String fieldName, IndexReader reader) - throws IOException { - final Map> docValues = new HashMap<>(); - for (LeafReaderContext ctx : reader.leaves()) { - - PointValues points = ctx.reader().getPointValues(fieldName); - if (points == null) { - continue; - } - - points.intersect( - new PointValues.IntersectVisitor() { - @Override - public void visit(int docID) { - throw new UnsupportedOperationException(); - } - - @Override - public void visit(int docID, byte[] packedValue) throws IOException { - int topDocID = ctx.docBase + docID; - if (docValues.containsKey(topDocID) == false) { - docValues.put(topDocID, new HashSet<>()); - } - docValues.get(topDocID).add(new BytesRef(packedValue.clone())); - } - - @Override - public PointValues.Relation compare(byte[] minPackedValue, byte[] maxPackedValue) { - // We pretend our query shape is so hairy that it crosses every single cell: - return PointValues.Relation.CELL_CROSSES_QUERY; - } - }); - } - - return docValues; - } - - public void assertPointsEquals(String info, IndexReader leftReader, IndexReader rightReader) - throws IOException { - FieldInfos fieldInfos1 = FieldInfos.getMergedFieldInfos(leftReader); - FieldInfos fieldInfos2 = FieldInfos.getMergedFieldInfos(rightReader); - for (FieldInfo fieldInfo1 : fieldInfos1) { - if (fieldInfo1.getPointDimensionCount() != 0) { - FieldInfo fieldInfo2 = fieldInfos2.fieldInfo(fieldInfo1.name); - // same data dimension count? - assertEquals( - info, fieldInfo2.getPointDimensionCount(), fieldInfo2.getPointDimensionCount()); - // same index dimension count? - assertEquals( - info, - fieldInfo2.getPointIndexDimensionCount(), - fieldInfo2.getPointIndexDimensionCount()); - // same bytes per dimension? - assertEquals(info, fieldInfo2.getPointNumBytes(), fieldInfo2.getPointNumBytes()); - - assertEquals( - info + " field=" + fieldInfo1.name, - uninvert(fieldInfo1.name, leftReader), - uninvert(fieldInfo1.name, rightReader)); - } - } - - // make sure FieldInfos2 doesn't have any point fields that FieldInfo1 didn't have - for (FieldInfo fieldInfo2 : fieldInfos2) { - if (fieldInfo2.getPointDimensionCount() != 0) { - FieldInfo fieldInfo1 = fieldInfos1.fieldInfo(fieldInfo2.name); - // same data dimension count? - assertEquals( - info, fieldInfo2.getPointDimensionCount(), fieldInfo1.getPointDimensionCount()); - // same index dimension count? - assertEquals( - info, - fieldInfo2.getPointIndexDimensionCount(), - fieldInfo1.getPointIndexDimensionCount()); - // same bytes per dimension? - assertEquals(info, fieldInfo2.getPointNumBytes(), fieldInfo1.getPointNumBytes()); - - // we don't need to uninvert and compare here ... we did that in the first loop above - } - } - } - - private static final StackWalker SW_NO_METHODS = StackWalker.getInstance(Option.DROP_METHOD_INFO), - SW_WITH_METHODS = StackWalker.getInstance(); - - /** Inspects stack trace to figure out if a method of a specific class called us. */ - public static boolean callStackContains(Class clazz, String methodName) { - final String className = clazz.getName(); - return SW_WITH_METHODS.walk( - s -> - s.skip(1) // exclude this utility method - .anyMatch( - f -> - className.equals(f.getClassName()) - && methodName.equals(f.getMethodName()))); - } - - /** - * Inspects stack trace to figure out if one of the given method names (no class restriction) - * called us. - */ - public static boolean callStackContainsAnyOf(String... methodNames) { - return SW_WITH_METHODS.walk( - s -> - s.skip(1) // exclude this utility method - .map(StackFrame::getMethodName) - .anyMatch(Set.of(methodNames)::contains)); - } - - /** Inspects stack trace if the given class called us. */ - public static boolean callStackContains(Class clazz) { - return SW_NO_METHODS.walk( - s -> - s.skip(1) // exclude this utility method - .map(StackFrame::getClassName) - .anyMatch(clazz.getName()::equals)); - } - - /** A runnable that can throw any checked exception. */ - @FunctionalInterface - public interface ThrowingRunnable { - void run() throws Throwable; - } - - /** A {@link java.util.function.Consumer} that can throw any checked exception. */ - @FunctionalInterface - public interface ThrowingConsumer { - void accept(T t) throws Exception; - } - - /** Checks a specific exception class is thrown by the given runnable, and returns it. */ - public static T expectThrows( - Class expectedType, ThrowingRunnable runnable) { - return expectThrows( - expectedType, - "Expected exception " + expectedType.getSimpleName() + " but no exception was thrown", - runnable); - } - - /** Checks a specific exception class is thrown by the given runnable, and returns it. */ - public static T expectThrows( - Class expectedType, String noExceptionMessage, ThrowingRunnable runnable) { - final Throwable thrown = _expectThrows(Collections.singletonList(expectedType), runnable); - if (expectedType.isInstance(thrown)) { - return expectedType.cast(thrown); - } - if (null == thrown) { - throw new AssertionFailedError(noExceptionMessage); - } - AssertionFailedError assertion = - new AssertionFailedError( - "Unexpected exception type, expected " - + expectedType.getSimpleName() - + " but got " - + thrown); - assertion.initCause(thrown); - throw assertion; - } - - /** Checks a specific exception class is thrown by the given runnable, and returns it. */ - public static T expectThrowsAnyOf( - List> expectedTypes, ThrowingRunnable runnable) { - if (expectedTypes.isEmpty()) { - throw new AssertionError("At least one expected exception type is required?"); - } - - final Throwable thrown = _expectThrows(expectedTypes, runnable); - if (null != thrown) { - for (Class expectedType : expectedTypes) { - if (expectedType.isInstance(thrown)) { - return expectedType.cast(thrown); - } - } - } - - List exceptionTypes = expectedTypes.stream().map(Class::getSimpleName).toList(); - - if (thrown != null) { - AssertionFailedError assertion = - new AssertionFailedError( - "Unexpected exception type, expected any of " - + exceptionTypes - + " but got: " - + thrown); - assertion.initCause(thrown); - throw assertion; - } else { - throw new AssertionFailedError( - "Expected any of the following exception types: " - + exceptionTypes - + " but no exception was thrown."); - } - } - - /** - * Checks that specific wrapped and outer exception classes are thrown by the given runnable, and - * returns the wrapped exception. - */ - public static TW expectThrows( - Class expectedOuterType, Class expectedWrappedType, ThrowingRunnable runnable) { - final Throwable thrown = _expectThrows(Collections.singletonList(expectedOuterType), runnable); - if (null == thrown) { - throw new AssertionFailedError( - "Expected outer exception " - + expectedOuterType.getSimpleName() - + " but no exception was thrown."); - } - if (expectedOuterType.isInstance(thrown)) { - Throwable cause = thrown.getCause(); - if (expectedWrappedType.isInstance(cause)) { - return expectedWrappedType.cast(cause); - } else { - AssertionFailedError assertion = - new AssertionFailedError( - "Unexpected wrapped exception type, expected " - + expectedWrappedType.getSimpleName() - + " but got: " - + cause); - assertion.initCause(thrown); - throw assertion; - } - } - AssertionFailedError assertion = - new AssertionFailedError( - "Unexpected outer exception type, expected " - + expectedOuterType.getSimpleName() - + " but got: " - + thrown); - assertion.initCause(thrown); - throw assertion; - } - - /** - * Checks that one of the specified wrapped and outer exception classes are thrown by the given - * runnable, and returns the outer exception. - * - *

This method accepts outer exceptions with no wrapped exception; an empty list of expected - * wrapped exception types indicates no wrapped exception. - */ - public static TO expectThrowsAnyOf( - LinkedHashMap, List>> expectedOuterToWrappedTypes, - ThrowingRunnable runnable) { - final List> outerClasses = - new ArrayList<>(expectedOuterToWrappedTypes.keySet()); - final Throwable thrown = _expectThrows(outerClasses, runnable); - - if (null == thrown) { - List outerTypes = outerClasses.stream().map(Class::getSimpleName).toList(); - throw new AssertionFailedError( - "Expected any of the following outer exception types: " - + outerTypes - + " but no exception was thrown."); - } - for (Map.Entry, List>> entry : - expectedOuterToWrappedTypes.entrySet()) { - Class expectedOuterType = entry.getKey(); - List> expectedWrappedTypes = entry.getValue(); - Throwable cause = thrown.getCause(); - if (expectedOuterType.isInstance(thrown)) { - if (expectedWrappedTypes.isEmpty()) { - return null; // no wrapped exception - } else { - for (Class expectedWrappedType : expectedWrappedTypes) { - if (expectedWrappedType.isInstance(cause)) { - return expectedOuterType.cast(thrown); - } - } - List wrappedTypes = - expectedWrappedTypes.stream().map(Class::getSimpleName).toList(); - AssertionFailedError assertion = - new AssertionFailedError( - "Unexpected wrapped exception type, expected one of " - + wrappedTypes - + " but got: " - + cause); - assertion.initCause(thrown); - throw assertion; - } - } - } - List outerTypes = outerClasses.stream().map(Class::getSimpleName).toList(); - AssertionFailedError assertion = - new AssertionFailedError( - "Unexpected outer exception type, expected one of " - + outerTypes - + " but got: " - + thrown); - assertion.initCause(thrown); - throw assertion; - } - - /** - * Helper method for {@link #expectThrows} and {@link #expectThrowsAnyOf} that takes care of - * propagating any {@link AssertionError} or {@link AssumptionViolatedException} instances thrown - * if and only if they are super classes of the expectedTypes. Otherwise simply - * returns any {@link Throwable} thrown, regardless of type, or null if the runnable - * completed w/o error. - */ - private static Throwable _expectThrows( - List> expectedTypes, ThrowingRunnable runnable) { - - try { - runnable.run(); - } catch (AssertionError | AssumptionViolatedException ae) { - for (Class expectedType : expectedTypes) { - if (expectedType.isInstance(ae)) { // user is expecting this type explicitly - return ae; - } - } - throw ae; - } catch (Throwable e) { - return e; - } - return null; - } - - /** - * Returns true if the file exists (can be opened), false if it cannot be opened, and (unlike - * Java's File.exists) throws IOException if there's some unexpected error. - */ - public static boolean slowFileExists(Directory dir, String fileName) throws IOException { - try { - dir.openInput(fileName, IOContext.READONCE).close(); - return true; - } catch (NoSuchFileException | FileNotFoundException _) { - return false; - } - } - /** * Creates an empty, temporary folder (when the name of the folder is of no importance). * @@ -3015,38 +1434,6 @@ public static Path createTempFile() throws IOException { return createTempFile("tempFile", ".tmp"); } - /** - * Returns a set of JVM arguments to fork a JVM with the same class or module path (including any - * associated JVM options). The returned value may be empty. This method may throw an assertion - * error if fork options cannot be reliably acquired (at the moment they are collected and passed - * as an external file in gradle scripts). - * - *

JVM forking is strongly discouraged as it makes test slower and more resource-hungry. - * Consider all alternatives first. - */ - public static List getJvmForkArguments() throws IOException { - String forkArgsFile = System.getProperty("tests.jvmForkArgsFile"); - Path forkArgsPath; - if (forkArgsFile == null || !Files.isRegularFile(forkArgsPath = Paths.get(forkArgsFile))) { - throw new AssertionError("JVM fork arguments are not present."); - } - - return Files.readAllLines(forkArgsPath, StandardCharsets.UTF_8); - } - - /** - * Compares two strings with a collator, also looking to see if the strings are impacted by jdk - * bugs. may not avoid all jdk bugs in tests. see https://bugs.openjdk.java.net/browse/JDK-8071862 - */ - @SuppressForbidden(reason = "dodges JDK-8071862") - public static int collate(Collator collator, String s1, String s2) { - int v1 = collator.compare(s1, s2); - int v2 = collator.getCollationKey(s1).compareTo(collator.getCollationKey(s2)); - // if collation keys don't really respect collation order, things are screwed. - assumeTrue("hit JDK collator bug", Integer.signum(v1) == Integer.signum(v2)); - return v1; - } - /** Ensures that the MergePolicy has sane values for tests that test with lots of documents. */ protected static IndexWriterConfig ensureSaneIWCOnNightly(IndexWriterConfig conf) { if (LuceneTestCase.TEST_NIGHTLY) { @@ -3069,94 +1456,6 @@ protected static IndexWriterConfig ensureSaneIWCOnNightly(IndexWriterConfig conf return conf; } - /** - * Creates a {@link BytesRef} holding UTF-8 bytes for the incoming String, that sometimes uses a - * non-zero {@code offset}, and non-zero end-padding, to tickle latent bugs that fail to look at - * {@code BytesRef.offset}. - */ - public static BytesRef newBytesRef(String s) { - return newBytesRef(s.getBytes(StandardCharsets.UTF_8)); - } - - /** - * Creates a copy of the incoming {@link BytesRef} that sometimes uses a non-zero {@code offset}, - * and non-zero end-padding, to tickle latent bugs that fail to look at {@code BytesRef.offset}. - */ - public static BytesRef newBytesRef(BytesRef b) { - assert b.isValid(); - return newBytesRef(b.bytes, b.offset, b.length); - } - - /** - * Creates a random BytesRef from the incoming bytes that sometimes uses a non-zero {@code - * offset}, and non-zero end-padding, to tickle latent bugs that fail to look at {@code - * BytesRef.offset}. - */ - public static BytesRef newBytesRef(byte[] b) { - return newBytesRef(b, 0, b.length); - } - - /** - * Creates a random empty BytesRef that sometimes uses a non-zero {@code offset}, and non-zero - * end-padding, to tickle latent bugs that fail to look at {@code BytesRef.offset}. - */ - public static BytesRef newBytesRef() { - return newBytesRef(new byte[0], 0, 0); - } - - /** - * Creates a random empty BytesRef, with at least the requested length of bytes free, that - * sometimes uses a non-zero {@code offset}, and non-zero end-padding, to tickle latent bugs that - * fail to look at {@code BytesRef.offset}. - */ - public static BytesRef newBytesRef(int byteLength) { - return newBytesRef(new byte[byteLength], 0, byteLength); - } - - /** - * Creates a copy of the incoming bytes slice that sometimes uses a non-zero {@code offset}, and - * non-zero end-padding, to tickle latent bugs that fail to look at {@code BytesRef.offset}. - */ - public static BytesRef newBytesRef(byte[] bytesIn, int offset, int length) { - // System.out.println("LTC.newBytesRef! bytesIn.length=" + bytesIn.length + " offset=" + offset - // + " length=" + length); - - assert bytesIn.length >= offset + length - : "got offset=" + offset + " length=" + length + " bytesIn.length=" + bytesIn.length; - - // randomly set a non-zero offset - int startOffset; - if (random().nextBoolean()) { - startOffset = RandomNumbers.randomIntBetween(random(), 1, 20); - } else { - startOffset = 0; - } - - // also randomly set an end padding: - int endPadding; - if (random().nextBoolean()) { - endPadding = RandomNumbers.randomIntBetween(random(), 1, 20); - } else { - endPadding = 0; - } - - byte[] bytes = new byte[startOffset + length + endPadding]; - - System.arraycopy(bytesIn, offset, bytes, startOffset, length); - // System.out.println("LTC: return bytes.length=" + bytes.length + " startOffset=" + - // startOffset + " length=" + length); - - BytesRef it = new BytesRef(bytes, startOffset, length); - assert it.isValid(); - - if (RandomNumbers.randomIntBetween(random(), 1, 17) == 7) { - // try to ferret out bugs in this method too! - return newBytesRef(it.bytes, it.offset, it.length); - } - - return it; - } - private static boolean supportsVectorEncoding( KnnVectorsFormat format, VectorEncoding vectorEncoding) { if (format instanceof HnswBitVectorsFormat) { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index 6fd439268c9b..42fbcbc81e8d 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -16,30 +16,116 @@ */ package org.apache.lucene.tests.util; +import static com.carrotsearch.randomizedtesting.RandomizedTest.frequently; import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean; import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsInt; +import static org.apache.lucene.search.DocIdSetIterator.NO_MORE_DOCS; +import static org.apache.lucene.tests.util.LuceneTestCase.Concurrency; import com.carrotsearch.randomizedtesting.RandomizedContext; +import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom; import com.carrotsearch.randomizedtesting.annotations.TestGroup; +import com.carrotsearch.randomizedtesting.generators.RandomNumbers; import java.io.Closeable; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Random; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeSet; import java.util.concurrent.atomic.AtomicReference; +import junit.framework.AssertionFailedError; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.codecs.CompoundFormat; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.ConcurrentMergeScheduler; +import org.apache.lucene.index.DocValuesType; +import org.apache.lucene.index.FieldInfo; +import org.apache.lucene.index.FieldInfos; +import org.apache.lucene.index.Fields; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.LeafReader; +import org.apache.lucene.index.LeafReaderContext; +import org.apache.lucene.index.LiveIndexWriterConfig; +import org.apache.lucene.index.LogByteSizeMergePolicy; +import org.apache.lucene.index.LogDocMergePolicy; +import org.apache.lucene.index.LogMergePolicy; +import org.apache.lucene.index.MergePolicy; +import org.apache.lucene.index.MergeScheduler; +import org.apache.lucene.index.MultiBits; +import org.apache.lucene.index.MultiDocValues; +import org.apache.lucene.index.MultiTerms; +import org.apache.lucene.index.NoDeletionPolicy; +import org.apache.lucene.index.NumericDocValues; +import org.apache.lucene.index.PointValues; +import org.apache.lucene.index.PostingsEnum; +import org.apache.lucene.index.SerialMergeScheduler; +import org.apache.lucene.index.SimpleMergedSegmentWarmer; +import org.apache.lucene.index.SnapshotDeletionPolicy; +import org.apache.lucene.index.SortedDocValues; +import org.apache.lucene.index.SortedNumericDocValues; +import org.apache.lucene.index.SortedSetDocValues; +import org.apache.lucene.index.StoredFields; +import org.apache.lucene.index.TermVectors; +import org.apache.lucene.index.Terms; +import org.apache.lucene.index.TermsEnum; +import org.apache.lucene.index.TieredMergePolicy; +import org.apache.lucene.internal.tests.IndexPackageAccess; +import org.apache.lucene.internal.tests.TestSecrets; +import org.apache.lucene.search.DocIdSetIterator; +import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.QueryCachingPolicy; import org.apache.lucene.store.ByteBuffersDirectory; import org.apache.lucene.store.Directory; +import org.apache.lucene.store.IOContext; +import org.apache.lucene.tests.analysis.MockAnalyzer; +import org.apache.lucene.tests.index.AlcoholicMergePolicy; +import org.apache.lucene.tests.index.MockIndexWriterEventListener; +import org.apache.lucene.tests.index.MockRandomMergePolicy; import org.apache.lucene.tests.store.MockDirectoryWrapper; +import org.apache.lucene.tests.util.automaton.AutomatonTestUtil; +import org.apache.lucene.util.Bits; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.InfoStream; +import org.apache.lucene.util.SuppressForbidden; +import org.apache.lucene.util.automaton.Automaton; +import org.apache.lucene.util.automaton.CompiledAutomaton; +import org.apache.lucene.util.automaton.Operations; +import org.apache.lucene.util.automaton.RegExp; +import org.hamcrest.Matcher; +import org.hamcrest.MatcherAssert; import org.junit.Assert; +import org.junit.internal.AssumptionViolatedException; /** - * Private parent class for junit4 ({@link LuceneTestCase} and junit5 ({@link + * Private parent class for junit4 ({@link LuceneTestCase} and junit jupiter ({@link * LuceneTestCaseJupiter}). */ public abstract sealed class LuceneTestCaseParent extends Assert @@ -255,6 +341,790 @@ public static Random random() { .threadRandom(); } + /** Gets a resource from the test's classpath as {@link InputStream}. */ + protected InputStream getDataInputStream(String name) throws IOException { + return IOUtils.requireResourceNonNull(this.getClass().getResourceAsStream(name), name); + } + + // these hide the deprecated Assert.assertThat method + public static void assertThat(T actual, Matcher matcher) { + MatcherAssert.assertThat(actual, matcher); + } + + public static void assertThat(String reason, T actual, Matcher matcher) { + MatcherAssert.assertThat(reason, actual, matcher); + } + + public void assertReaderEquals(String info, IndexReader leftReader, IndexReader rightReader) + throws IOException { + assertReaderStatisticsEquals(info, leftReader, rightReader); + assertTermsEquals(info, leftReader, rightReader, true); + assertNormsEquals(info, leftReader, rightReader); + assertStoredFieldsEquals(info, leftReader, rightReader); + assertTermVectorsEquals(info, leftReader, rightReader); + assertDocValuesEquals(info, leftReader, rightReader); + assertDeletedDocsEquals(info, leftReader, rightReader); + assertFieldInfosEquals(info, leftReader, rightReader); + assertPointsEquals(info, leftReader, rightReader); + } + + /** checks that reader-level statistics are the same */ + public void assertReaderStatisticsEquals( + String info, IndexReader leftReader, IndexReader rightReader) throws IOException { + // Somewhat redundant: we never delete docs + assertEquals(info, leftReader.maxDoc(), rightReader.maxDoc()); + assertEquals(info, leftReader.numDocs(), rightReader.numDocs()); + assertEquals(info, leftReader.numDeletedDocs(), rightReader.numDeletedDocs()); + assertEquals(info, leftReader.hasDeletions(), rightReader.hasDeletions()); + } + + /** Fields api equivalency */ + public void assertTermsEquals( + String info, IndexReader leftReader, IndexReader rightReader, boolean deep) + throws IOException { + Set leftFields = new HashSet<>(FieldInfos.getIndexedFields(leftReader)); + Set rightFields = new HashSet<>(FieldInfos.getIndexedFields(rightReader)); + assertEquals(info, leftFields, rightFields); + + for (String field : leftFields) { + assertTermsEquals( + info, + leftReader, + MultiTerms.getTerms(leftReader, field), + MultiTerms.getTerms(rightReader, field), + deep); + } + } + + /** Terms api equivalency */ + public void assertTermsEquals( + String info, IndexReader leftReader, Terms leftTerms, Terms rightTerms, boolean deep) + throws IOException { + if (leftTerms == null || rightTerms == null) { + assertNull(info, leftTerms); + assertNull(info, rightTerms); + return; + } + assertTermsStatisticsEquals(info, leftTerms, rightTerms); + assertEquals("hasOffsets", leftTerms.hasOffsets(), rightTerms.hasOffsets()); + assertEquals("hasPositions", leftTerms.hasPositions(), rightTerms.hasPositions()); + assertEquals("hasPayloads", leftTerms.hasPayloads(), rightTerms.hasPayloads()); + + TermsEnum leftTermsEnum = leftTerms.iterator(); + TermsEnum rightTermsEnum = rightTerms.iterator(); + assertTermsEnumEquals(info, leftReader, leftTermsEnum, rightTermsEnum, true); + + assertTermsSeekingEquals(info, leftTerms, rightTerms); + + if (deep) { + int numIntersections = atLeast(3); + for (int i = 0; i < numIntersections; i++) { + String re = AutomatonTestUtil.randomRegexp(random()); + Automaton a = new RegExp(re, RegExp.NONE).toAutomaton(); + a = Operations.determinize(a, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT); + CompiledAutomaton automaton = new CompiledAutomaton(a); + if (automaton.type == CompiledAutomaton.AUTOMATON_TYPE.NORMAL) { + // TODO: test start term too + TermsEnum leftIntersection = leftTerms.intersect(automaton, null); + TermsEnum rightIntersection = rightTerms.intersect(automaton, null); + assertTermsEnumEquals(info, leftReader, leftIntersection, rightIntersection, rarely()); + } + } + } + } + + /** checks collection-level statistics on Terms */ + public void assertTermsStatisticsEquals(String info, Terms leftTerms, Terms rightTerms) + throws IOException { + assertEquals(info, leftTerms.getDocCount(), rightTerms.getDocCount()); + assertEquals(info, leftTerms.getSumDocFreq(), rightTerms.getSumDocFreq()); + assertEquals(info, leftTerms.getSumTotalTermFreq(), rightTerms.getSumTotalTermFreq()); + if (leftTerms.size() != -1 && rightTerms.size() != -1) { + assertEquals(info, leftTerms.size(), rightTerms.size()); + } + } + + /** + * checks the terms enum sequentially if deep is false, it does a 'shallow' test that doesnt go + * down to the docsenums + */ + public void assertTermsEnumEquals( + String info, + IndexReader leftReader, + TermsEnum leftTermsEnum, + TermsEnum rightTermsEnum, + boolean deep) + throws IOException { + BytesRef term; + PostingsEnum leftPositions = null; + PostingsEnum rightPositions = null; + PostingsEnum leftDocs = null; + PostingsEnum rightDocs = null; + + while ((term = leftTermsEnum.next()) != null) { + assertEquals(info, term, rightTermsEnum.next()); + assertTermStatsEquals(info, leftTermsEnum, rightTermsEnum); + if (deep) { + assertDocsAndPositionsEnumEquals( + info, + leftPositions = leftTermsEnum.postings(leftPositions, PostingsEnum.ALL), + rightPositions = rightTermsEnum.postings(rightPositions, PostingsEnum.ALL)); + + assertPositionsSkippingEquals( + info, + leftReader, + leftTermsEnum.docFreq(), + leftPositions = leftTermsEnum.postings(leftPositions, PostingsEnum.ALL), + rightPositions = rightTermsEnum.postings(rightPositions, PostingsEnum.ALL)); + + // with freqs: + assertDocsEnumEquals( + info, + leftDocs = leftTermsEnum.postings(leftDocs), + rightDocs = rightTermsEnum.postings(rightDocs), + true); + + // w/o freqs: + assertDocsEnumEquals( + info, + leftDocs = leftTermsEnum.postings(leftDocs, PostingsEnum.NONE), + rightDocs = rightTermsEnum.postings(rightDocs, PostingsEnum.NONE), + false); + + // with freqs: + assertDocsSkippingEquals( + info, + leftReader, + leftTermsEnum.docFreq(), + leftDocs = leftTermsEnum.postings(leftDocs), + rightDocs = rightTermsEnum.postings(rightDocs), + true); + + // w/o freqs: + assertDocsSkippingEquals( + info, + leftReader, + leftTermsEnum.docFreq(), + leftDocs = leftTermsEnum.postings(leftDocs, PostingsEnum.NONE), + rightDocs = rightTermsEnum.postings(rightDocs, PostingsEnum.NONE), + false); + } + } + assertNull(info, rightTermsEnum.next()); + } + + /** checks docs + freqs + positions + payloads, sequentially */ + public void assertDocsAndPositionsEnumEquals( + String info, PostingsEnum leftDocs, PostingsEnum rightDocs) throws IOException { + assertNotNull(leftDocs); + assertNotNull(rightDocs); + assertEquals(info, -1, leftDocs.docID()); + assertEquals(info, -1, rightDocs.docID()); + int docid; + while ((docid = leftDocs.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { + assertEquals(info, docid, rightDocs.nextDoc()); + int freq = leftDocs.freq(); + assertEquals(info, freq, rightDocs.freq()); + for (int i = 0; i < freq; i++) { + assertEquals(info, leftDocs.nextPosition(), rightDocs.nextPosition()); + assertEquals(info, leftDocs.getPayload(), rightDocs.getPayload()); + assertEquals(info, leftDocs.startOffset(), rightDocs.startOffset()); + assertEquals(info, leftDocs.endOffset(), rightDocs.endOffset()); + } + } + assertEquals(info, DocIdSetIterator.NO_MORE_DOCS, rightDocs.nextDoc()); + } + + /** checks docs + freqs, sequentially */ + public void assertDocsEnumEquals( + String info, PostingsEnum leftDocs, PostingsEnum rightDocs, boolean hasFreqs) + throws IOException { + if (leftDocs == null) { + assertNull(rightDocs); + return; + } + assertEquals(info, -1, leftDocs.docID()); + assertEquals(info, -1, rightDocs.docID()); + int docid; + while ((docid = leftDocs.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { + assertEquals(info, docid, rightDocs.nextDoc()); + if (hasFreqs) { + assertEquals(info, leftDocs.freq(), rightDocs.freq()); + } + } + assertEquals(info, DocIdSetIterator.NO_MORE_DOCS, rightDocs.nextDoc()); + } + + /** checks advancing docs */ + public void assertDocsSkippingEquals( + String info, + IndexReader leftReader, + int docFreq, + PostingsEnum leftDocs, + PostingsEnum rightDocs, + boolean hasFreqs) + throws IOException { + if (leftDocs == null) { + assertNull(rightDocs); + return; + } + int docid = -1; + int averageGap = leftReader.maxDoc() / (1 + docFreq); + int skipInterval = 16; + + while (true) { + if (random().nextBoolean()) { + // nextDoc() + docid = leftDocs.nextDoc(); + assertEquals(info, docid, rightDocs.nextDoc()); + } else { + // advance() + int skip = + docid + (int) Math.ceil(Math.abs(skipInterval + random().nextGaussian() * averageGap)); + docid = leftDocs.advance(skip); + assertEquals(info, docid, rightDocs.advance(skip)); + } + + if (docid == DocIdSetIterator.NO_MORE_DOCS) { + return; + } + if (hasFreqs) { + assertEquals(info, leftDocs.freq(), rightDocs.freq()); + } + } + } + + /** checks advancing docs + positions */ + public void assertPositionsSkippingEquals( + String info, + IndexReader leftReader, + int docFreq, + PostingsEnum leftDocs, + PostingsEnum rightDocs) + throws IOException { + if (leftDocs == null || rightDocs == null) { + assertNull(leftDocs); + assertNull(rightDocs); + return; + } + + int docid = -1; + int averageGap = leftReader.maxDoc() / (1 + docFreq); + int skipInterval = 16; + + while (true) { + if (random().nextBoolean()) { + // nextDoc() + docid = leftDocs.nextDoc(); + assertEquals(info, docid, rightDocs.nextDoc()); + } else { + // advance() + int skip = + docid + (int) Math.ceil(Math.abs(skipInterval + random().nextGaussian() * averageGap)); + docid = leftDocs.advance(skip); + assertEquals(info, docid, rightDocs.advance(skip)); + } + + if (docid == DocIdSetIterator.NO_MORE_DOCS) { + return; + } + int freq = leftDocs.freq(); + assertEquals(info, freq, rightDocs.freq()); + for (int i = 0; i < freq; i++) { + assertEquals(info, leftDocs.nextPosition(), rightDocs.nextPosition()); + assertEquals(info, leftDocs.getPayload(), rightDocs.getPayload()); + } + } + } + + private void assertTermsSeekingEquals(String info, Terms leftTerms, Terms rightTerms) + throws IOException { + + // just an upper bound + int numTests = atLeast(20); + Random random = random(); + + TermsEnum leftEnum = null; + + // collect this number of terms from the left side + HashSet tests = new HashSet<>(); + int numPasses = 0; + while (numPasses < 10 && tests.size() < numTests) { + leftEnum = leftTerms.iterator(); + BytesRef term; + while ((term = leftEnum.next()) != null) { + int code = random.nextInt(10); + if (code == 0) { + // the term + tests.add(BytesRef.deepCopyOf(term)); + } else if (code == 1) { + // truncated subsequence of term + term = BytesRef.deepCopyOf(term); + if (term.length > 0) { + // truncate it + term.length = random.nextInt(term.length); + } + } else if (code == 2) { + // term, but ensure a non-zero offset + byte[] newbytes = new byte[term.length + 5]; + System.arraycopy(term.bytes, term.offset, newbytes, 5, term.length); + tests.add(new BytesRef(newbytes, 5, term.length)); + } else if (code == 3) { + switch (random().nextInt(3)) { + case 0: + tests.add(new BytesRef()); // before the first term + break; + case 1: + tests.add(new BytesRef(new byte[] {(byte) 0xFF, (byte) 0xFF})); // past the last term + break; + case 2: + tests.add(new BytesRef(TestUtil.randomSimpleString(random()))); // random term + break; + default: + throw new AssertionError(); + } + } + } + numPasses++; + } + + TermsEnum rightEnum = rightTerms.iterator(); + + ArrayList shuffledTests = new ArrayList<>(tests); + Collections.shuffle(shuffledTests, random); + + for (BytesRef b : shuffledTests) { + if (rarely()) { + // make new enums + leftEnum = leftTerms.iterator(); + rightEnum = rightTerms.iterator(); + } + + final boolean seekExact = random().nextBoolean(); + + if (seekExact) { + assertEquals(info, leftEnum.seekExact(b), rightEnum.seekExact(b)); + } else { + TermsEnum.SeekStatus leftStatus = leftEnum.seekCeil(b); + TermsEnum.SeekStatus rightStatus = rightEnum.seekCeil(b); + assertEquals(info, leftStatus, rightStatus); + if (leftStatus != TermsEnum.SeekStatus.END) { + assertEquals(info, leftEnum.term(), rightEnum.term()); + assertTermStatsEquals(info, leftEnum, rightEnum); + } + } + } + } + + /** checks term-level statistics */ + public void assertTermStatsEquals(String info, TermsEnum leftTermsEnum, TermsEnum rightTermsEnum) + throws IOException { + assertEquals(info, leftTermsEnum.docFreq(), rightTermsEnum.docFreq()); + assertEquals(info, leftTermsEnum.totalTermFreq(), rightTermsEnum.totalTermFreq()); + } + + /** checks that norms are the same across all fields */ + public void assertNormsEquals(String info, IndexReader leftReader, IndexReader rightReader) + throws IOException { + Set leftFields = new HashSet<>(FieldInfos.getIndexedFields(leftReader)); + Set rightFields = new HashSet<>(FieldInfos.getIndexedFields(rightReader)); + assertEquals(info, leftFields, rightFields); + + for (String field : leftFields) { + NumericDocValues leftNorms = MultiDocValues.getNormValues(leftReader, field); + NumericDocValues rightNorms = MultiDocValues.getNormValues(rightReader, field); + if (leftNorms != null && rightNorms != null) { + assertDocValuesEquals(info, leftReader.maxDoc(), leftNorms, rightNorms); + } else { + assertNull(info, leftNorms); + assertNull(info, rightNorms); + } + } + } + + /** checks that stored fields of all documents are the same */ + public void assertStoredFieldsEquals(String info, IndexReader leftReader, IndexReader rightReader) + throws IOException { + assert leftReader.maxDoc() == rightReader.maxDoc(); + StoredFields leftStoredFields = leftReader.storedFields(); + StoredFields rightStoredFields = rightReader.storedFields(); + for (int i = 0; i < leftReader.maxDoc(); i++) { + Document leftDoc = leftStoredFields.document(i); + Document rightDoc = rightStoredFields.document(i); + + // TODO: I think this is bogus because we don't document what the order should be + // from these iterators, etc. I think the codec/IndexReader should be free to order this stuff + // in whatever way it wants (e.g. maybe it packs related fields together or something) + // To fix this, we sort the fields in both documents by name, but + // we still assume that all instances with same name are in order: + Comparator comp = Comparator.comparing(IndexableField::name); + List leftFields = new ArrayList<>(leftDoc.getFields()); + List rightFields = new ArrayList<>(rightDoc.getFields()); + leftFields.sort(comp); + rightFields.sort(comp); + + Iterator leftIterator = leftFields.iterator(); + Iterator rightIterator = rightFields.iterator(); + while (leftIterator.hasNext()) { + assertTrue(info, rightIterator.hasNext()); + assertStoredFieldEquals(info, leftIterator.next(), rightIterator.next()); + } + assertFalse(info, rightIterator.hasNext()); + } + } + + /** checks that two stored fields are equivalent */ + public void assertStoredFieldEquals( + String info, IndexableField leftField, IndexableField rightField) { + assertEquals(info, leftField.name(), rightField.name()); + assertEquals(info, leftField.binaryValue(), rightField.binaryValue()); + assertEquals(info, leftField.stringValue(), rightField.stringValue()); + assertEquals(info, leftField.numericValue(), rightField.numericValue()); + // TODO: should we check the FT at all? + } + + /** checks that term vectors across all fields are equivalent */ + public void assertTermVectorsEquals(String info, IndexReader leftReader, IndexReader rightReader) + throws IOException { + assert leftReader.maxDoc() == rightReader.maxDoc(); + TermVectors leftVectors = leftReader.termVectors(); + TermVectors rightVectors = rightReader.termVectors(); + for (int i = 0; i < leftReader.maxDoc(); i++) { + Fields leftFields = leftVectors.get(i); + Fields rightFields = rightVectors.get(i); + + // Fields could be null if there are no postings, + // but then it must be null for both + if (leftFields == null || rightFields == null) { + assertNull(info, leftFields); + assertNull(info, rightFields); + return; + } + if (leftFields.size() != -1 && rightFields.size() != -1) { + assertEquals(info, leftFields.size(), rightFields.size()); + } + + Iterator leftEnum = leftFields.iterator(); + Iterator rightEnum = rightFields.iterator(); + while (leftEnum.hasNext()) { + String field = leftEnum.next(); + assertEquals(info, field, rightEnum.next()); + assertTermsEquals( + info, leftReader, leftFields.terms(field), rightFields.terms(field), rarely()); + } + assertFalse(rightEnum.hasNext()); + } + } + + private static Set getDVFields(IndexReader reader) { + Set fields = new HashSet<>(); + for (FieldInfo fi : FieldInfos.getMergedFieldInfos(reader)) { + if (fi.getDocValuesType() != DocValuesType.NONE) { + fields.add(fi.name); + } + } + + return fields; + } + + /** checks that docvalues across all fields are equivalent */ + public void assertDocValuesEquals(String info, IndexReader leftReader, IndexReader rightReader) + throws IOException { + Set leftFields = getDVFields(leftReader); + Set rightFields = getDVFields(rightReader); + assertEquals(info, leftFields, rightFields); + + for (String field : leftFields) { + // TODO: clean this up... very messy + { + NumericDocValues leftValues = MultiDocValues.getNumericValues(leftReader, field); + NumericDocValues rightValues = MultiDocValues.getNumericValues(rightReader, field); + if (leftValues != null && rightValues != null) { + assertDocValuesEquals(info, leftReader.maxDoc(), leftValues, rightValues); + } else { + assertTrue( + info + ": left numeric doc values for field=\"" + field + "\" are not null", + leftValues == null || leftValues.nextDoc() == NO_MORE_DOCS); + assertTrue( + info + ": right numeric doc values for field=\"" + field + "\" are not null", + rightValues == null || rightValues.nextDoc() == NO_MORE_DOCS); + } + } + + { + BinaryDocValues leftValues = MultiDocValues.getBinaryValues(leftReader, field); + BinaryDocValues rightValues = MultiDocValues.getBinaryValues(rightReader, field); + if (leftValues != null && rightValues != null) { + while (true) { + int docID = leftValues.nextDoc(); + assertEquals(docID, rightValues.nextDoc()); + if (docID == NO_MORE_DOCS) { + break; + } + assertEquals(leftValues.binaryValue(), rightValues.binaryValue()); + } + } else { + assertTrue(info, leftValues == null || leftValues.nextDoc() == NO_MORE_DOCS); + assertTrue(info, rightValues == null || rightValues.nextDoc() == NO_MORE_DOCS); + } + } + + { + SortedDocValues leftValues = MultiDocValues.getSortedValues(leftReader, field); + SortedDocValues rightValues = MultiDocValues.getSortedValues(rightReader, field); + if (leftValues != null && rightValues != null) { + // numOrds + assertEquals(info, leftValues.getValueCount(), rightValues.getValueCount()); + // ords + for (int i = 0; i < leftValues.getValueCount(); i++) { + final BytesRef left = BytesRef.deepCopyOf(leftValues.lookupOrd(i)); + final BytesRef right = rightValues.lookupOrd(i); + assertEquals(info, left, right); + } + // bytes + while (true) { + int docID = leftValues.nextDoc(); + assertEquals(docID, rightValues.nextDoc()); + if (docID == NO_MORE_DOCS) { + break; + } + final BytesRef left = BytesRef.deepCopyOf(leftValues.lookupOrd(leftValues.ordValue())); + final BytesRef right = rightValues.lookupOrd(rightValues.ordValue()); + assertEquals(info, left, right); + } + } else { + assertNull(info, leftValues); + assertNull(info, rightValues); + } + } + + { + SortedSetDocValues leftValues = MultiDocValues.getSortedSetValues(leftReader, field); + SortedSetDocValues rightValues = MultiDocValues.getSortedSetValues(rightReader, field); + if (leftValues != null && rightValues != null) { + // numOrds + assertEquals(info, leftValues.getValueCount(), rightValues.getValueCount()); + // ords + for (int i = 0; i < leftValues.getValueCount(); i++) { + final BytesRef left = BytesRef.deepCopyOf(leftValues.lookupOrd(i)); + final BytesRef right = rightValues.lookupOrd(i); + assertEquals(info, left, right); + } + // ord lists + while (true) { + int docID = leftValues.nextDoc(); + assertEquals(docID, rightValues.nextDoc()); + if (docID == NO_MORE_DOCS) { + break; + } + assertEquals(info, leftValues.docValueCount(), rightValues.docValueCount()); + for (int i = 0; i < leftValues.docValueCount(); i++) { + assertEquals(info, leftValues.nextOrd(), rightValues.nextOrd()); + } + } + } else { + assertNull(info, leftValues); + assertNull(info, rightValues); + } + } + + { + SortedNumericDocValues leftValues = + MultiDocValues.getSortedNumericValues(leftReader, field); + SortedNumericDocValues rightValues = + MultiDocValues.getSortedNumericValues(rightReader, field); + if (leftValues != null && rightValues != null) { + while (true) { + int docID = leftValues.nextDoc(); + assertEquals(docID, rightValues.nextDoc()); + if (docID == NO_MORE_DOCS) { + break; + } + assertEquals(info, leftValues.docValueCount(), rightValues.docValueCount()); + for (int j = 0; j < leftValues.docValueCount(); j++) { + assertEquals(info, leftValues.nextValue(), rightValues.nextValue()); + } + } + } else { + assertNull(info, leftValues); + assertNull(info, rightValues); + } + } + } + } + + public void assertDocValuesEquals( + String info, int num, NumericDocValues leftDocValues, NumericDocValues rightDocValues) + throws IOException { + assertNotNull(info, leftDocValues); + assertNotNull(info, rightDocValues); + while (true) { + int leftDocID = leftDocValues.nextDoc(); + int rightDocID = rightDocValues.nextDoc(); + assertEquals(leftDocID, rightDocID); + if (leftDocID == NO_MORE_DOCS) { + return; + } + assertEquals(leftDocValues.longValue(), rightDocValues.longValue()); + } + } + + // TODO: this is kinda stupid, we don't delete documents in the test. + public void assertDeletedDocsEquals(String info, IndexReader leftReader, IndexReader rightReader) + throws IOException { + assert leftReader.numDeletedDocs() == rightReader.numDeletedDocs(); + Bits leftBits = MultiBits.getLiveDocs(leftReader); + Bits rightBits = MultiBits.getLiveDocs(rightReader); + + if (leftBits == null || rightBits == null) { + assertNull(info, leftBits); + assertNull(info, rightBits); + return; + } + + assert leftReader.maxDoc() == rightReader.maxDoc(); + assertEquals(info, leftBits.length(), rightBits.length()); + for (int i = 0; i < leftReader.maxDoc(); i++) { + assertEquals(info, leftBits.get(i), rightBits.get(i)); + } + } + + public void assertFieldInfosEquals(String info, IndexReader leftReader, IndexReader rightReader) + throws IOException { + FieldInfos leftInfos = FieldInfos.getMergedFieldInfos(leftReader); + FieldInfos rightInfos = FieldInfos.getMergedFieldInfos(rightReader); + + // TODO: would be great to verify more than just the names of the fields! + TreeSet left = new TreeSet<>(); + TreeSet right = new TreeSet<>(); + + for (FieldInfo fi : leftInfos) { + left.add(fi.name); + } + + for (FieldInfo fi : rightInfos) { + right.add(fi.name); + } + + assertEquals(info, left, right); + } + + // naive silly memory heavy uninversion!! maps docID -> packed values (a Set because a given doc + // can be multi-valued) + private Map> uninvert(String fieldName, IndexReader reader) + throws IOException { + final Map> docValues = new HashMap<>(); + for (LeafReaderContext ctx : reader.leaves()) { + + PointValues points = ctx.reader().getPointValues(fieldName); + if (points == null) { + continue; + } + + points.intersect( + new PointValues.IntersectVisitor() { + @Override + public void visit(int docID) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(int docID, byte[] packedValue) throws IOException { + int topDocID = ctx.docBase + docID; + if (docValues.containsKey(topDocID) == false) { + docValues.put(topDocID, new HashSet<>()); + } + docValues.get(topDocID).add(new BytesRef(packedValue.clone())); + } + + @Override + public PointValues.Relation compare(byte[] minPackedValue, byte[] maxPackedValue) { + // We pretend our query shape is so hairy that it crosses every single cell: + return PointValues.Relation.CELL_CROSSES_QUERY; + } + }); + } + + return docValues; + } + + public void assertPointsEquals(String info, IndexReader leftReader, IndexReader rightReader) + throws IOException { + FieldInfos fieldInfos1 = FieldInfos.getMergedFieldInfos(leftReader); + FieldInfos fieldInfos2 = FieldInfos.getMergedFieldInfos(rightReader); + for (FieldInfo fieldInfo1 : fieldInfos1) { + if (fieldInfo1.getPointDimensionCount() != 0) { + FieldInfo fieldInfo2 = fieldInfos2.fieldInfo(fieldInfo1.name); + // same data dimension count? + assertEquals( + info, fieldInfo2.getPointDimensionCount(), fieldInfo2.getPointDimensionCount()); + // same index dimension count? + assertEquals( + info, + fieldInfo2.getPointIndexDimensionCount(), + fieldInfo2.getPointIndexDimensionCount()); + // same bytes per dimension? + assertEquals(info, fieldInfo2.getPointNumBytes(), fieldInfo2.getPointNumBytes()); + + assertEquals( + info + " field=" + fieldInfo1.name, + uninvert(fieldInfo1.name, leftReader), + uninvert(fieldInfo1.name, rightReader)); + } + } + + // make sure FieldInfos2 doesn't have any point fields that FieldInfo1 didn't have + for (FieldInfo fieldInfo2 : fieldInfos2) { + if (fieldInfo2.getPointDimensionCount() != 0) { + FieldInfo fieldInfo1 = fieldInfos1.fieldInfo(fieldInfo2.name); + // same data dimension count? + assertEquals( + info, fieldInfo2.getPointDimensionCount(), fieldInfo1.getPointDimensionCount()); + // same index dimension count? + assertEquals( + info, + fieldInfo2.getPointIndexDimensionCount(), + fieldInfo1.getPointIndexDimensionCount()); + // same bytes per dimension? + assertEquals(info, fieldInfo2.getPointNumBytes(), fieldInfo1.getPointNumBytes()); + + // we don't need to uninvert and compare here ... we did that in the first loop above + } + } + } + + /** + * Creates leaf slices according to the concurrency argument, that optionally leverage + * intra-segment concurrency by splitting segments into multiple partitions according to the + * maxDocsPerSlice argument. + */ + protected static IndexSearcher.LeafSlice[] slices( + List leaves, + int maxDocsPerSlice, + int maxSegmentsPerSlice, + LuceneTestCase.Concurrency concurrency) { + assert concurrency != Concurrency.NONE; + // Rarely test slices without partitions even though intra-segment concurrency is supported + return IndexSearcher.slices( + leaves, + maxDocsPerSlice, + maxSegmentsPerSlice, + concurrency == Concurrency.INTRA_SEGMENT && frequently()); + } + + /** + * Gets a resource from the test's classpath as {@link Path}. This method should only be used, if + * a real file is needed. To get a stream, code should prefer {@link #getDataInputStream(String)}. + */ + protected Path getDataPath(String name) throws IOException { + try { + return Paths.get( + IOUtils.requireResourceNonNull(this.getClass().getResource(name), name).toURI()); + } catch (URISyntaxException e) { + throw new AssertionError(e); + } + } + /** * Registers a {@link Closeable} resource that should be closed after the test completes. * @@ -273,7 +1143,852 @@ public static T closeAfterSuite(T resource) { return getTestFrameworkInfra().closeAfterClass(resource); } + /** + * Creates a {@link BytesRef} holding UTF-8 bytes for the incoming String, that sometimes uses a + * non-zero {@code offset}, and non-zero end-padding, to tickle latent bugs that fail to look at + * {@code BytesRef.offset}. + */ + public static BytesRef newBytesRef(String s) { + return newBytesRef(s.getBytes(StandardCharsets.UTF_8)); + } + + /** + * Creates a copy of the incoming {@link BytesRef} that sometimes uses a non-zero {@code offset}, + * and non-zero end-padding, to tickle latent bugs that fail to look at {@code BytesRef.offset}. + */ + public static BytesRef newBytesRef(BytesRef b) { + assert b.isValid(); + return newBytesRef(b.bytes, b.offset, b.length); + } + + /** + * Creates a random BytesRef from the incoming bytes that sometimes uses a non-zero {@code + * offset}, and non-zero end-padding, to tickle latent bugs that fail to look at {@code + * BytesRef.offset}. + */ + public static BytesRef newBytesRef(byte[] b) { + return newBytesRef(b, 0, b.length); + } + + /** + * Creates a random empty BytesRef that sometimes uses a non-zero {@code offset}, and non-zero + * end-padding, to tickle latent bugs that fail to look at {@code BytesRef.offset}. + */ + public static BytesRef newBytesRef() { + return newBytesRef(new byte[0], 0, 0); + } + + /** + * Creates a random empty BytesRef, with at least the requested length of bytes free, that + * sometimes uses a non-zero {@code offset}, and non-zero end-padding, to tickle latent bugs that + * fail to look at {@code BytesRef.offset}. + */ + public static BytesRef newBytesRef(int byteLength) { + return newBytesRef(new byte[byteLength], 0, byteLength); + } + + /** + * Creates a copy of the incoming bytes slice that sometimes uses a non-zero {@code offset}, and + * non-zero end-padding, to tickle latent bugs that fail to look at {@code BytesRef.offset}. + */ + public static BytesRef newBytesRef(byte[] bytesIn, int offset, int length) { + // System.out.println("LTC.newBytesRef! bytesIn.length=" + bytesIn.length + " offset=" + offset + // + " length=" + length); + + assert bytesIn.length >= offset + length + : "got offset=" + offset + " length=" + length + " bytesIn.length=" + bytesIn.length; + + // randomly set a non-zero offset + int startOffset; + if (random().nextBoolean()) { + startOffset = RandomNumbers.randomIntBetween(random(), 1, 20); + } else { + startOffset = 0; + } + + // also randomly set an end padding: + int endPadding; + if (random().nextBoolean()) { + endPadding = RandomNumbers.randomIntBetween(random(), 1, 20); + } else { + endPadding = 0; + } + + byte[] bytes = new byte[startOffset + length + endPadding]; + + System.arraycopy(bytesIn, offset, bytes, startOffset, length); + // System.out.println("LTC: return bytes.length=" + bytes.length + " startOffset=" + + // startOffset + " length=" + length); + + BytesRef it = new BytesRef(bytes, startOffset, length); + assert it.isValid(); + + if (RandomNumbers.randomIntBetween(random(), 1, 17) == 7) { + // try to ferret out bugs in this method too! + return newBytesRef(it.bytes, it.offset, it.length); + } + + return it; + } + + /** + * Returns a set of JVM arguments to fork a JVM with the same class or module path (including any + * associated JVM options). The returned value may be empty. This method may throw an assertion + * error if fork options cannot be reliably acquired (at the moment they are collected and passed + * as an external file in gradle scripts). + * + *

JVM forking is strongly discouraged as it makes test slower and more resource-hungry. + * Consider all alternatives first. + */ + public static List getJvmForkArguments() throws IOException { + String forkArgsFile = System.getProperty("tests.jvmForkArgsFile"); + Path forkArgsPath; + if (forkArgsFile == null || !Files.isRegularFile(forkArgsPath = Paths.get(forkArgsFile))) { + throw new AssertionError("JVM fork arguments are not present."); + } + + return Files.readAllLines(forkArgsPath, StandardCharsets.UTF_8); + } + + /** + * Compares two strings with a collator, also looking to see if the strings are impacted by jdk + * bugs. may not avoid all jdk bugs in tests. see https://bugs.openjdk.java.net/browse/JDK-8071862 + */ + @SuppressForbidden(reason = "dodges JDK-8071862") + public static int collate(Collator collator, String s1, String s2) { + int v1 = collator.compare(s1, s2); + int v2 = collator.getCollationKey(s1).compareTo(collator.getCollationKey(s2)); + // if collation keys don't really respect collation order, things are screwed. + assumeTrue("hit JDK collator bug", Integer.signum(v1) == Integer.signum(v2)); + return v1; + } + + /** + * Returns a number of at least i + * + *

The actual number returned will be influenced by whether {@link #TEST_NIGHTLY} is active and + * {@link #RANDOM_MULTIPLIER}, but also with some random fudge. + */ + public static int atLeast(Random random, int i) { + int min = i * RANDOM_MULTIPLIER; + int max = min + (min / 2); + return TestUtil.nextInt(random, min, max); + } + + public static int atLeast(int i) { + return atLeast(random(), i); + } + + /** + * Returns true if something should happen rarely, + * + *

The actual number returned will be influenced by whether {@link #TEST_NIGHTLY} is active and + * {@link #RANDOM_MULTIPLIER}. + */ + public static boolean rarely(Random random) { + int p = TEST_NIGHTLY ? 5 : 1; + p += (p * Math.log(RANDOM_MULTIPLIER)); + int min = 100 - Math.min(p, 20); // never more than 20 + return random.nextInt(100) >= min; + } + + public static boolean rarely() { + return rarely(random()); + } + + public static boolean usually(Random random) { + return !rarely(random); + } + + public static boolean usually() { + return usually(random()); + } + + public static void assumeTrue(String msg, boolean condition) { + RandomizedTest.assumeTrue(msg, condition); + } + + public static void assumeFalse(String msg, boolean condition) { + RandomizedTest.assumeFalse(msg, condition); + } + + public static void assumeNoException(String msg, Exception e) { + RandomizedTest.assumeNoException(msg, e); + } + + public static void assertFloatUlpEquals(final float x, final float y, final short maxUlps) { + assertTrue( + x + " and " + y + " are not within " + maxUlps + " ULPs of each other", + TestUtil.floatUlpEquals(x, y, maxUlps)); + } + + public static void assertDoubleUlpEquals(final double x, final double y, final int maxUlps) { + assertTrue( + x + " and " + y + " are not within " + maxUlps + " ULPs of each other", + TestUtil.doubleUlpEquals(x, y, maxUlps)); + } + + /** + * Return args as a {@link Set} instance. The order of elements is not preserved in + * iterators. + */ + @SafeVarargs + @SuppressWarnings("varargs") + public static Set asSet(T... args) { + return new HashSet<>(Arrays.asList(args)); + } + + /** + * Convenience method for logging an iterator. + * + * @param label String logged before/after the items in the iterator + * @param iter Each next() is toString()ed and logged on its own line. If iter is null this is + * logged differently then an empty iterator. + * @param stream Stream to log messages to. + */ + public static void dumpIterator(String label, Iterator iter, PrintStream stream) { + stream.println("*** BEGIN " + label + " ***"); + if (null == iter) { + stream.println(" ... NULL ..."); + } else { + while (iter.hasNext()) { + stream.println(iter.next().toString()); + } + } + stream.println("*** END " + label + " ***"); + } + + /** + * Convenience method for logging an array. Wraps the array in an iterator and delegates + * + * @see #dumpIterator(String, Iterator, PrintStream) + */ + public static void dumpArray(String label, Object[] objs, PrintStream stream) { + Iterator iter = (null == objs) ? null : Arrays.asList(objs).iterator(); + dumpIterator(label, iter, stream); + } + + /** + * Returns true if the file exists (can be opened), false if it cannot be opened, and (unlike + * Java's File.exists) throws IOException if there's some unexpected error. + */ + public static boolean slowFileExists(Directory dir, String fileName) throws IOException { + try { + dir.openInput(fileName, IOContext.READONCE).close(); + return true; + } catch (NoSuchFileException | FileNotFoundException _) { + return false; + } + } + + /** A runnable that can throw any checked exception. */ + @FunctionalInterface + public interface ThrowingRunnable { + void run() throws Throwable; + } + + /** A {@link java.util.function.Consumer} that can throw any checked exception. */ + @FunctionalInterface + public interface ThrowingConsumer { + void accept(T t) throws Exception; + } + + /** Checks a specific exception class is thrown by the given runnable, and returns it. */ + public static T expectThrows( + Class expectedType, ThrowingRunnable runnable) { + return expectThrows( + expectedType, + "Expected exception " + expectedType.getSimpleName() + " but no exception was thrown", + runnable); + } + + /** Checks a specific exception class is thrown by the given runnable, and returns it. */ + public static T expectThrows( + Class expectedType, String noExceptionMessage, ThrowingRunnable runnable) { + final Throwable thrown = _expectThrows(Collections.singletonList(expectedType), runnable); + if (expectedType.isInstance(thrown)) { + return expectedType.cast(thrown); + } + if (null == thrown) { + throw new AssertionFailedError(noExceptionMessage); + } + AssertionFailedError assertion = + new AssertionFailedError( + "Unexpected exception type, expected " + + expectedType.getSimpleName() + + " but got " + + thrown); + assertion.initCause(thrown); + throw assertion; + } + + /** Checks a specific exception class is thrown by the given runnable, and returns it. */ + public static T expectThrowsAnyOf( + List> expectedTypes, ThrowingRunnable runnable) { + if (expectedTypes.isEmpty()) { + throw new AssertionError("At least one expected exception type is required?"); + } + + final Throwable thrown = _expectThrows(expectedTypes, runnable); + if (null != thrown) { + for (Class expectedType : expectedTypes) { + if (expectedType.isInstance(thrown)) { + return expectedType.cast(thrown); + } + } + } + + List exceptionTypes = expectedTypes.stream().map(Class::getSimpleName).toList(); + + if (thrown != null) { + AssertionFailedError assertion = + new AssertionFailedError( + "Unexpected exception type, expected any of " + + exceptionTypes + + " but got: " + + thrown); + assertion.initCause(thrown); + throw assertion; + } else { + throw new AssertionFailedError( + "Expected any of the following exception types: " + + exceptionTypes + + " but no exception was thrown."); + } + } + + /** + * Checks that specific wrapped and outer exception classes are thrown by the given runnable, and + * returns the wrapped exception. + */ + public static TW expectThrows( + Class expectedOuterType, Class expectedWrappedType, ThrowingRunnable runnable) { + final Throwable thrown = _expectThrows(Collections.singletonList(expectedOuterType), runnable); + if (null == thrown) { + throw new AssertionFailedError( + "Expected outer exception " + + expectedOuterType.getSimpleName() + + " but no exception was thrown."); + } + if (expectedOuterType.isInstance(thrown)) { + Throwable cause = thrown.getCause(); + if (expectedWrappedType.isInstance(cause)) { + return expectedWrappedType.cast(cause); + } else { + AssertionFailedError assertion = + new AssertionFailedError( + "Unexpected wrapped exception type, expected " + + expectedWrappedType.getSimpleName() + + " but got: " + + cause); + assertion.initCause(thrown); + throw assertion; + } + } + AssertionFailedError assertion = + new AssertionFailedError( + "Unexpected outer exception type, expected " + + expectedOuterType.getSimpleName() + + " but got: " + + thrown); + assertion.initCause(thrown); + throw assertion; + } + + /** + * Checks that one of the specified wrapped and outer exception classes are thrown by the given + * runnable, and returns the outer exception. + * + *

This method accepts outer exceptions with no wrapped exception; an empty list of expected + * wrapped exception types indicates no wrapped exception. + */ + public static TO expectThrowsAnyOf( + LinkedHashMap, List>> expectedOuterToWrappedTypes, + ThrowingRunnable runnable) { + final List> outerClasses = + new ArrayList<>(expectedOuterToWrappedTypes.keySet()); + final Throwable thrown = _expectThrows(outerClasses, runnable); + + if (null == thrown) { + List outerTypes = outerClasses.stream().map(Class::getSimpleName).toList(); + throw new AssertionFailedError( + "Expected any of the following outer exception types: " + + outerTypes + + " but no exception was thrown."); + } + for (Map.Entry, List>> entry : + expectedOuterToWrappedTypes.entrySet()) { + Class expectedOuterType = entry.getKey(); + List> expectedWrappedTypes = entry.getValue(); + Throwable cause = thrown.getCause(); + if (expectedOuterType.isInstance(thrown)) { + if (expectedWrappedTypes.isEmpty()) { + return null; // no wrapped exception + } else { + for (Class expectedWrappedType : expectedWrappedTypes) { + if (expectedWrappedType.isInstance(cause)) { + return expectedOuterType.cast(thrown); + } + } + List wrappedTypes = + expectedWrappedTypes.stream().map(Class::getSimpleName).toList(); + AssertionFailedError assertion = + new AssertionFailedError( + "Unexpected wrapped exception type, expected one of " + + wrappedTypes + + " but got: " + + cause); + assertion.initCause(thrown); + throw assertion; + } + } + } + List outerTypes = outerClasses.stream().map(Class::getSimpleName).toList(); + AssertionFailedError assertion = + new AssertionFailedError( + "Unexpected outer exception type, expected one of " + + outerTypes + + " but got: " + + thrown); + assertion.initCause(thrown); + throw assertion; + } + + /** + * Helper method for {@link #expectThrows} and {@link #expectThrowsAnyOf} that takes care of + * propagating any {@link AssertionError} or {@link AssumptionViolatedException} instances thrown + * if and only if they are super classes of the expectedTypes. Otherwise simply + * returns any {@link Throwable} thrown, regardless of type, or null if the runnable + * completed w/o error. + */ + private static Throwable _expectThrows( + List> expectedTypes, ThrowingRunnable runnable) { + + try { + runnable.run(); + } catch (AssertionError | AssumptionViolatedException ae) { + for (Class expectedType : expectedTypes) { + if (expectedType.isInstance(ae)) { // user is expecting this type explicitly + return ae; + } + } + throw ae; + } catch (Throwable e) { + return e; + } + return null; + } + + private static final StackWalker + SW_NO_METHODS = StackWalker.getInstance(StackWalker.Option.DROP_METHOD_INFO), + SW_WITH_METHODS = StackWalker.getInstance(); + + /** Inspects stack trace to figure out if a method of a specific class called us. */ + public static boolean callStackContains(Class clazz, String methodName) { + final String className = clazz.getName(); + return SW_WITH_METHODS.walk( + s -> + s.skip(1) // exclude this utility method + .anyMatch( + f -> + className.equals(f.getClassName()) + && methodName.equals(f.getMethodName()))); + } + + /** + * Inspects stack trace to figure out if one of the given method names (no class restriction) + * called us. + */ + public static boolean callStackContainsAnyOf(String... methodNames) { + return SW_WITH_METHODS.walk( + s -> + s.skip(1) // exclude this utility method + .map(StackWalker.StackFrame::getMethodName) + .anyMatch(Set.of(methodNames)::contains)); + } + + /** Inspects stack trace if the given class called us. */ + public static boolean callStackContains(Class clazz) { + return SW_NO_METHODS.walk( + s -> + s.skip(1) // exclude this utility method + .map(StackWalker.StackFrame::getClassName) + .anyMatch(clazz.getName()::equals)); + } + + /** + * Tells {@link IndexWriter} to enforce the specified limit as the maximum number of documents in + * one index; call {@link #restoreIndexWriterMaxDocs} once your test is done. + */ + public void setIndexWriterMaxDocs(int limit) { + INDEX_PACKAGE_ACCESS.setIndexWriterMaxDocs(limit); + } + + /** Returns to the default {@link IndexWriter#MAX_DOCS} limit. */ + public void restoreIndexWriterMaxDocs() { + INDEX_PACKAGE_ACCESS.setIndexWriterMaxDocs(IndexWriter.MAX_DOCS); + } + + private static final IndexPackageAccess INDEX_PACKAGE_ACCESS = + TestSecrets.getIndexPackageAccess(); + + private static void configureRandomCompoundFormat(Random r, CompoundFormat compoundFormat) { + compoundFormat.setShouldUseCompoundFile(r.nextBoolean()); + + if (rarely(r)) { + compoundFormat.setMaxCFSSegmentSizeMB(0.2 + r.nextDouble() * 2.0); + } else { + compoundFormat.setMaxCFSSegmentSizeMB(Double.POSITIVE_INFINITY); + } + } + + /** + * Some tests expect the directory to contain a single segment, and want to do tests on that + * segment's reader. This is an utility method to help them. + */ + public static LeafReader getOnlyLeafReader(IndexReader reader) { + List subReaders = reader.leaves(); + if (subReaders.size() != 1) { + throw new IllegalArgumentException( + reader + " has " + subReaders.size() + " segments instead of exactly one"); + } + return subReaders.get(0).reader(); + } + + /** create a new index writer config with a snapshot deletion policy */ + public static IndexWriterConfig newSnapshotIndexWriterConfig(Analyzer analyzer) { + IndexWriterConfig c = newIndexWriterConfig(analyzer); + c.setIndexDeletionPolicy(new SnapshotDeletionPolicy(NoDeletionPolicy.INSTANCE)); + return c; + } + + /** create a new index writer config with random defaults */ + public static IndexWriterConfig newIndexWriterConfig() { + return newIndexWriterConfig(new MockAnalyzer(random())); + } + + /** create a new index writer config with random defaults */ + public static IndexWriterConfig newIndexWriterConfig(Analyzer a) { + return newIndexWriterConfig(random(), a); + } + + /** create a new index writer config with random defaults using the specified random */ + public static IndexWriterConfig newIndexWriterConfig(Random r, Analyzer a) { + IndexWriterConfig c = new IndexWriterConfig(a); + configureRandomCompoundFormat(r, c.getCodec().compoundFormat()); + c.setSimilarity(getTestFrameworkInfra().getClassEnv().similarity); + if (INFOSTREAM) { + // Even though TestRuleSetupAndRestoreClassEnv calls + // InfoStream.setDefault, we do it again here so that + // the PrintStreamInfoStream.messageID increments so + // that when there are separate instances of + // IndexWriter created we see "IW 0", "IW 1", "IW 2", + // ... instead of just always "IW 0": + c.setInfoStream( + new SetupAndRestoreStaticEnv.ThreadNameFixingPrintStreamInfoStream(System.out)); + } + + if (rarely(r)) { + c.setMergeScheduler(new SerialMergeScheduler()); + } else if (rarely(r)) { + ConcurrentMergeScheduler cms; + if (r.nextBoolean()) { + cms = new LuceneTestCase.TestConcurrentMergeScheduler(); + } else { + cms = + new LuceneTestCase.TestConcurrentMergeScheduler() { + @Override + protected synchronized boolean maybeStall(MergeSource mergeSource) { + return true; + } + }; + } + int maxThreadCount = TestUtil.nextInt(r, 1, 4); + int maxMergeCount = TestUtil.nextInt(r, maxThreadCount, maxThreadCount + 4); + cms.setMaxMergesAndThreads(maxMergeCount, maxThreadCount); + if (r.nextBoolean()) { + cms.disableAutoIOThrottle(); + assertFalse(cms.getAutoIOThrottle()); + } + cms.setForceMergeMBPerSec(10 + 10 * r.nextDouble()); + c.setMergeScheduler(cms); + } else { + // Always use consistent settings, else CMS's dynamic (SSD or not) + // defaults can change, hurting reproducibility: + ConcurrentMergeScheduler cms = + r.nextBoolean() + ? new LuceneTestCase.TestConcurrentMergeScheduler() + : new ConcurrentMergeScheduler(); + + // Only 1 thread can run at once (should maybe help reproducibility), + // with up to 3 pending merges before segment-producing threads are + // stalled: + cms.setMaxMergesAndThreads(3, 1); + c.setMergeScheduler(cms); + } + + if (r.nextBoolean()) { + if (rarely(r)) { + // crazy value + c.setMaxBufferedDocs(TestUtil.nextInt(r, 2, 15)); + } else { + // reasonable value + c.setMaxBufferedDocs(TestUtil.nextInt(r, 16, 1000)); + } + } + + c.setMergePolicy(newMergePolicy(r)); + + if (rarely(r)) { + c.setMergedSegmentWarmer(new SimpleMergedSegmentWarmer(c.getInfoStream())); + } + c.setUseCompoundFile(r.nextBoolean()); + c.setReaderPooling(r.nextBoolean()); + if (rarely(r)) { + c.setCheckPendingFlushUpdate(false); + } + + if (rarely(r)) { + c.setIndexWriterEventListener(new MockIndexWriterEventListener()); + } + switch (r.nextInt(3)) { + case 0: + // Disable merge on refresh + c.setMaxFullFlushMergeWaitMillis(0L); + break; + case 1: + // Very low timeout, merges will likely not be able to run in time + c.setMaxFullFlushMergeWaitMillis(1L); + break; + default: + // Very long timeout, merges will almost always be able to run in time + c.setMaxFullFlushMergeWaitMillis(1000L); + break; + } + + c.setMaxFullFlushMergeWaitMillis(rarely(r) ? atLeast(r, 1000) : atLeast(r, 200)); + return c; + } + + public static MergePolicy newMergePolicy(Random r) { + return newMergePolicy(r, true); + } + + public static MergePolicy newMergePolicy(Random r, boolean includeMockMP) { + if (includeMockMP && rarely(r)) { + return new MockRandomMergePolicy(r); + } else if (r.nextBoolean()) { + return newTieredMergePolicy(r); + } else if (rarely(r)) { + return newAlcoholicMergePolicy(r, getTestFrameworkInfra().getClassEnv().timeZone); + } + return newLogMergePolicy(r); + } + + public static MergePolicy newMergePolicy() { + return newMergePolicy(random()); + } + + public static LogMergePolicy newLogMergePolicy() { + return newLogMergePolicy(random()); + } + + public static TieredMergePolicy newTieredMergePolicy() { + return newTieredMergePolicy(random()); + } + + public static AlcoholicMergePolicy newAlcoholicMergePolicy() { + return newAlcoholicMergePolicy(random(), getTestFrameworkInfra().getClassEnv().timeZone); + } + + public static AlcoholicMergePolicy newAlcoholicMergePolicy(Random r, TimeZone tz) { + return new AlcoholicMergePolicy(tz, new Random(r.nextLong())); + } + + public static LogMergePolicy newLogMergePolicy(Random r) { + LogMergePolicy logmp = r.nextBoolean() ? new LogDocMergePolicy() : new LogByteSizeMergePolicy(); + logmp.setCalibrateSizeByDeletes(r.nextBoolean()); + logmp.setTargetSearchConcurrency(TestUtil.nextInt(r, 1, 16)); + if (rarely(r)) { + logmp.setMergeFactor(TestUtil.nextInt(r, 2, 9)); + } else { + logmp.setMergeFactor(TestUtil.nextInt(r, 10, 50)); + } + return logmp; + } + + public static TieredMergePolicy newTieredMergePolicy(Random r) { + TieredMergePolicy tmp = new TieredMergePolicy(); + if (rarely(r)) { + tmp.setMaxMergedSegmentMB(0.2 + r.nextDouble() * 2.0); + } else { + tmp.setMaxMergedSegmentMB(10 + r.nextDouble() * 100); + } + tmp.setFloorSegmentMB(0.2 + r.nextDouble() * 2.0); + tmp.setForceMergeDeletesPctAllowed(0.0 + r.nextDouble() * 30.0); + if (rarely(r)) { + tmp.setSegmentsPerTier(TestUtil.nextInt(r, 2, 20)); + } else { + tmp.setSegmentsPerTier(TestUtil.nextInt(r, 10, 50)); + } + if (rarely(r)) { + tmp.setTargetSearchConcurrency(TestUtil.nextInt(r, 10, 50)); + } else { + tmp.setTargetSearchConcurrency(TestUtil.nextInt(r, 2, 20)); + } + + tmp.setDeletesPctAllowed(20 + r.nextDouble() * 30); + return tmp; + } + + public static LogMergePolicy newLogMergePolicy(int mergeFactor) { + LogMergePolicy logmp = newLogMergePolicy(); + logmp.setMergeFactor(mergeFactor); + return logmp; + } + + enum LiveIWCFlushMode { + BY_RAM, + BY_DOCS, + EITHER + } + + // if you want it in LiveIndexWriterConfig: it must and will be tested here. + public static void maybeChangeLiveIndexWriterConfig(Random r, LiveIndexWriterConfig c) { + boolean didChange = false; + + String previous = c.toString(); + + if (rarely(r)) { + // change flush parameters: + // this is complicated because the api requires you "invoke setters in a magical order!" + // LUCENE-5661: workaround for race conditions in the API + synchronized (c) { + boolean flushByRAM; + switch (getTestFrameworkInfra().getClassEnv().getLiveIWCFlushMode()) { + case BY_RAM: + flushByRAM = true; + break; + case BY_DOCS: + flushByRAM = false; + break; + case EITHER: + flushByRAM = r.nextBoolean(); + break; + default: + throw new AssertionError(); + } + if (flushByRAM) { + c.setRAMBufferSizeMB(TestUtil.nextInt(r, 1, 10)); + c.setMaxBufferedDocs(IndexWriterConfig.DISABLE_AUTO_FLUSH); + } else { + if (rarely(r)) { + // crazy value + c.setMaxBufferedDocs(TestUtil.nextInt(r, 2, 15)); + } else { + // reasonable value + c.setMaxBufferedDocs(TestUtil.nextInt(r, 16, 1000)); + } + c.setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH); + } + } + didChange = true; + } + + if (rarely(r)) { + IndexWriter.IndexReaderWarmer curWarmer = c.getMergedSegmentWarmer(); + if (curWarmer == null || curWarmer instanceof SimpleMergedSegmentWarmer) { + // change warmer parameters + if (r.nextBoolean()) { + c.setMergedSegmentWarmer(new SimpleMergedSegmentWarmer(c.getInfoStream())); + } else { + c.setMergedSegmentWarmer(null); + } + } + didChange = true; + } + + if (rarely(r)) { + // change CFS flush parameters + c.setUseCompoundFile(r.nextBoolean()); + didChange = true; + } + + if (rarely(r)) { + // change CMS merge parameters + MergeScheduler ms = c.getMergeScheduler(); + if (ms instanceof ConcurrentMergeScheduler cms) { + int maxThreadCount = TestUtil.nextInt(r, 1, 4); + int maxMergeCount = TestUtil.nextInt(r, maxThreadCount, maxThreadCount + 4); + boolean enableAutoIOThrottle = r.nextBoolean(); + if (enableAutoIOThrottle) { + cms.enableAutoIOThrottle(); + } else { + cms.disableAutoIOThrottle(); + } + cms.setMaxMergesAndThreads(maxMergeCount, maxThreadCount); + didChange = true; + } + } + + if (rarely(r)) { + MergePolicy mp = c.getMergePolicy(); + configureRandomCompoundFormat(r, c.getCodec().compoundFormat()); + if (mp instanceof LogMergePolicy logmp) { + logmp.setCalibrateSizeByDeletes(r.nextBoolean()); + if (rarely(r)) { + logmp.setMergeFactor(TestUtil.nextInt(r, 2, 9)); + } else { + logmp.setMergeFactor(TestUtil.nextInt(r, 10, 50)); + } + } else if (mp instanceof TieredMergePolicy tmp) { + if (rarely(r)) { + tmp.setMaxMergedSegmentMB(0.2 + r.nextDouble() * 2.0); + } else { + tmp.setMaxMergedSegmentMB(r.nextDouble() * 100); + } + tmp.setFloorSegmentMB(0.2 + r.nextDouble() * 2.0); + tmp.setForceMergeDeletesPctAllowed(0.0 + r.nextDouble() * 30.0); + if (rarely(r)) { + tmp.setSegmentsPerTier(TestUtil.nextInt(r, 2, 20)); + } else { + tmp.setSegmentsPerTier(TestUtil.nextInt(r, 10, 50)); + } + configureRandomCompoundFormat(r, c.getCodec().compoundFormat()); + tmp.setDeletesPctAllowed(20 + r.nextDouble() * 30); + } + didChange = true; + } + if (VERBOSE && didChange) { + String current = c.toString(); + String[] previousLines = previous.split("\n"); + String[] currentLines = current.split("\n"); + StringBuilder diff = new StringBuilder(); + + // this should always be the case, diff each line + if (previousLines.length == currentLines.length) { + for (int i = 0; i < previousLines.length; i++) { + if (!previousLines[i].equals(currentLines[i])) { + diff.append("- ").append(previousLines[i]).append("\n"); + diff.append("+ ").append(currentLines[i]).append("\n"); + } + } + } else { + // but just in case of something ridiculous... + diff.append(current); + } + + // its possible to be empty, if we "change" a value to what it had before. + if (diff.length() > 0) { + System.out.println("NOTE: LuceneTestCase: randomly changed IWC's live settings:"); + System.out.println(diff); + } + } + } + + // // TODO: to remove from here? + // /** Suite failure marker (any error in the test or suite scope). */ @SuppressWarnings("NonFinalStaticField") diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/SetupAndRestoreStaticEnv.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/SetupAndRestoreStaticEnv.java index c2d10f73b939..347c5c754e45 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/SetupAndRestoreStaticEnv.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/SetupAndRestoreStaticEnv.java @@ -49,8 +49,8 @@ import org.apache.lucene.tests.index.RandomCodec; import org.apache.lucene.tests.search.similarities.AssertingSimilarity; import org.apache.lucene.tests.search.similarities.RandomSimilarity; -import org.apache.lucene.tests.util.LuceneTestCase.LiveIWCFlushMode; import org.apache.lucene.tests.util.LuceneTestCase.SuppressCodecs; +import org.apache.lucene.tests.util.LuceneTestCaseParent.LiveIWCFlushMode; import org.apache.lucene.util.InfoStream; import org.apache.lucene.util.PrintStreamInfoStream; import org.junit.internal.AssumptionViolatedException; @@ -64,6 +64,7 @@ final class SetupAndRestoreStaticEnv implements BeforeAfterCallback { private Locale savedLocale; private TimeZone savedTimeZone; private InfoStream savedInfoStream; + private LiveIWCFlushMode flushMode; Locale locale; TimeZone timeZone; @@ -84,6 +85,10 @@ final class SetupAndRestoreStaticEnv implements BeforeAfterCallback { this.targetClassSupplier = targetClassSupplier; } + LuceneTestCaseParent.LiveIWCFlushMode getLiveIWCFlushMode() { + return flushMode; + } + static class ThreadNameFixingPrintStreamInfoStream extends PrintStreamInfoStream { public ThreadNameFixingPrintStreamInfoStream(PrintStream out) { super(out); @@ -240,22 +245,13 @@ public String toString() { // just the doc count to flush by, else both. // This way the assertMemory in DocumentsWriterFlushControl sometimes runs (when we always flush // by RAM). - LiveIWCFlushMode flushMode; - switch (random.nextInt(3)) { - case 0: - flushMode = LiveIWCFlushMode.BY_RAM; - break; - case 1: - flushMode = LiveIWCFlushMode.BY_DOCS; - break; - case 2: - flushMode = LiveIWCFlushMode.EITHER; - break; - default: - throw new AssertionError(); - } - - LuceneTestCase.setLiveIWCFlushMode(flushMode); + this.flushMode = + switch (random.nextInt(3)) { + case 0 -> LiveIWCFlushMode.BY_RAM; + case 1 -> LiveIWCFlushMode.BY_DOCS; + case 2 -> LiveIWCFlushMode.EITHER; + default -> throw new AssertionError(); + }; initialized = true; } From 13ad951a1e0c9eb3ad90b26acb74c6ac4668a2fc Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 23 Apr 2026 13:12:41 +0200 Subject: [PATCH 20/68] More cleanups. --- .../TestMemoryIndexAgainstDirectory.java | 1 - .../lucene/tests/util/LuceneTestCase.java | 186 +---------------- .../tests/util/LuceneTestCaseJupiter.java | 16 +- .../tests/util/LuceneTestCaseParent.java | 188 ++++++++++++++++++ 4 files changed, 204 insertions(+), 187 deletions(-) diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java index 5d0fb1b6446b..f288bee7b7c5 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java @@ -18,7 +18,6 @@ import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newDirectory; import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newSearcher; -import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newTextField; import java.io.BufferedReader; import java.io.IOException; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 18df1bbfae7a..9aa12fdc92ca 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -58,14 +58,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Locale; -import java.util.Map; import java.util.Random; import java.util.Set; -import java.util.TimeZone; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; @@ -78,18 +74,12 @@ import org.apache.lucene.codecs.KnnVectorsFormat; import org.apache.lucene.codecs.bitvectors.HnswBitVectorsFormat; import org.apache.lucene.codecs.hnsw.FlatVectorsFormat; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.FieldType; -import org.apache.lucene.document.StringField; -import org.apache.lucene.document.TextField; import org.apache.lucene.index.CodecReader; import org.apache.lucene.index.CompositeReader; import org.apache.lucene.index.ConcurrentMergeScheduler; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.IndexFileNames; -import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.LeafReader; @@ -130,7 +120,6 @@ import org.apache.lucene.tests.store.BaseDirectoryWrapper; import org.apache.lucene.tests.store.MockDirectoryWrapper; import org.apache.lucene.tests.store.RawDirectoryWrapper; -import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CommandLineUtil; import org.apache.lucene.util.NamedThreadFactory; import org.junit.After; @@ -567,8 +556,6 @@ public void after() throws Exception {} .around(new TestRuleSetupAndRestoreInstanceEnv()) .around(parentChainCallRule); - private static final Map fieldToType = new HashMap<>(); - /** A counter of calls to {@link #random()} if {@link #SYSPROP_RANDOM_MAXACQUIRES} is defined. */ @SuppressWarnings("NonFinalStaticField") private static AtomicLong randomCalls = new AtomicLong(); @@ -579,16 +566,19 @@ public void after() throws Exception {} /** For subclasses to override. Overrides must call {@code super.setUp()}. */ @Before + @Override public void setUp() throws Exception { + super.setUp(); randomCalls.set(0); parentChainCallRule.setupCalled = true; } /** For subclasses to override. Overrides must call {@code super.tearDown()}. */ @After + @Override public void tearDown() throws Exception { + super.tearDown(); parentChainCallRule.teardownCalled = true; - fieldToType.clear(); // Test is supposed to call this itself, but we do this defensively in case it forgot: restoreIndexWriterMaxDocs(); @@ -780,174 +770,6 @@ private static BaseDirectoryWrapper wrapDirectory( } } - public static Field newStringField(String name, String value, Store stored) { - return newField( - random(), - name, - value, - stored == Store.YES ? StringField.TYPE_STORED : StringField.TYPE_NOT_STORED); - } - - public static Field newStringField(String name, BytesRef value, Store stored) { - return newField( - random(), - name, - value, - stored == Store.YES ? StringField.TYPE_STORED : StringField.TYPE_NOT_STORED); - } - - public static Field newTextField(String name, String value, Store stored) { - return newField( - random(), - name, - value, - stored == Store.YES ? TextField.TYPE_STORED : TextField.TYPE_NOT_STORED); - } - - public static Field newStringField(Random random, String name, String value, Store stored) { - return newField( - random, - name, - value, - stored == Store.YES ? StringField.TYPE_STORED : StringField.TYPE_NOT_STORED); - } - - public static Field newStringField(Random random, String name, BytesRef value, Store stored) { - return newField( - random, - name, - value, - stored == Store.YES ? StringField.TYPE_STORED : StringField.TYPE_NOT_STORED); - } - - public static Field newTextField(Random random, String name, String value, Store stored) { - return newField( - random, - name, - value, - stored == Store.YES ? TextField.TYPE_STORED : TextField.TYPE_NOT_STORED); - } - - public static Field newField(String name, String value, FieldType type) { - return newField(random(), name, value, type); - } - - // TODO: if we can pull out the "make term vector options - // consistent across all instances of the same field name" - // write-once schema sort of helper class then we can - // remove the sync here. We can also fold the random - // "enable norms" (now commented out, below) into that: - public static synchronized Field newField( - Random random, String name, Object value, FieldType type) { - - // Defeat any consumers that illegally rely on intern'd - // strings (we removed this from Lucene a while back): - name = new String(name); - - FieldType prevType = fieldToType.get(name); - if (prevType != null) { - // always use the same fieldType for the same field name - return createField(name, value, prevType); - } - - // TODO: once all core & test codecs can index - // offsets, sometimes randomly turn on offsets if we are - // already indexing positions... - - FieldType newType = new FieldType(type); - if (!newType.stored() && random.nextBoolean()) { - newType.setStored(true); // randomly store it - } - if (newType.indexOptions() != IndexOptions.NONE) { - if (!newType.storeTermVectors() && random.nextBoolean()) { - newType.setStoreTermVectors(true); - if (!newType.storeTermVectorPositions()) { - newType.setStoreTermVectorPositions(random.nextBoolean()); - if (newType.storeTermVectorPositions()) { - if (!newType.storeTermVectorPayloads()) { - newType.setStoreTermVectorPayloads(random.nextBoolean()); - } - } - } - // Check for strings as offsets are disallowed on binary fields - if (value instanceof String && !newType.storeTermVectorOffsets()) { - newType.setStoreTermVectorOffsets(random.nextBoolean()); - } - - if (VERBOSE) { - System.out.println("NOTE: LuceneTestCase: upgrade name=" + name + " type=" + newType); - } - } - } - newType.freeze(); - fieldToType.put(name, newType); - - // TODO: we need to do this, but smarter, ie, most of - // the time we set the same value for a given field but - // sometimes (rarely) we change it up: - /* - if (newType.omitNorms()) { - newType.setOmitNorms(random.nextBoolean()); - } - */ - - return createField(name, value, newType); - } - - private static Field createField(String name, Object value, FieldType fieldType) { - if (value instanceof String) { - return new Field(name, (String) value, fieldType); - } else if (value instanceof BytesRef) { - return new Field(name, (BytesRef) value, fieldType); - } else { - throw new IllegalArgumentException("value must be String or BytesRef"); - } - } - - private static final String[] availableLanguageTags = - Arrays.stream(Locale.getAvailableLocales()) - .map(Locale::toLanguageTag) - .sorted() - .distinct() - .toArray(String[]::new); - - /** - * Return a random Locale from the available locales on the system. - * - * @see LUCENE-4020 - */ - public static Locale randomLocale(Random random) { - return localeForLanguageTag( - availableLanguageTags[random.nextInt(availableLanguageTags.length)]); - } - - /** Time zone IDs that cause a deprecation warning in JDK 25. */ - private static final Set DEPRECATED_TIME_ZONE_IDS_JDK25 = - Set.of( - "ACT", "AET", "AGT", "ART", "AST", "BET", "BST", "CAT", "CNT", "CST", "CTT", "EAT", "ECT", - "EST", "HST", "IET", "IST", "JST", "MIT", "MST", "NET", "NST", "PLT", "PNT", "PRT", "PST", - "SST", "VST"); - - /** - * Return a random TimeZone from the available timezones on the system - * - * @see LUCENE-4020 - */ - public static TimeZone randomTimeZone(Random random) { - List tzIds = Arrays.asList(TimeZone.getAvailableIDs()); - // Remove time zones that cause deprecation warnings as these can break - // certain tests that expect exact output. - if (Runtime.version().feature() >= 25) { - tzIds = tzIds.stream().filter(id -> !DEPRECATED_TIME_ZONE_IDS_JDK25.contains(id)).toList(); - } - return TimeZone.getTimeZone(RandomPicks.randomFrom(random, tzIds)); - } - - /** return a Locale object equivalent to its programmatic name */ - public static Locale localeForLanguageTag(String languageTag) { - return new Locale.Builder().setLanguageTag(languageTag).build(); - } - private static Directory newFSDirectoryImpl( Class clazz, Path path, LockFactory lf) throws IOException { FSDirectory d = null; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 1472bc03064b..4bd20e8da213 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -224,11 +224,19 @@ public void allTestMethodsAreAnnotated() { } } - /** Use jupiter's {@link BeforeEach} instead. */ - protected final void setUp() throws Exception {} + /** Use methods marked with jupiter's {@link BeforeEach} instead. */ + @Override + @BeforeEach + protected final void setUp() throws Exception { + super.setUp(); + } - /** Use jupiter's {@link AfterEach} instead. */ - protected final void tearDown() throws Exception {} + /** Use methods marked with jupiter's {@link AfterEach} instead. */ + @Override + @AfterEach + protected final void tearDown() throws Exception { + super.tearDown(); + } public static T expectThrows( Class expectedType, LuceneTestCase.ThrowingRunnable runnable) { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index 42fbcbc81e8d..f0262b01c331 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -27,6 +27,7 @@ import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom; import com.carrotsearch.randomizedtesting.annotations.TestGroup; import com.carrotsearch.randomizedtesting.generators.RandomNumbers; +import com.carrotsearch.randomizedtesting.generators.RandomPicks; import java.io.Closeable; import java.io.FileNotFoundException; import java.io.IOException; @@ -48,6 +49,7 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Random; @@ -59,12 +61,17 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.codecs.CompoundFormat; import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; import org.apache.lucene.index.BinaryDocValues; import org.apache.lucene.index.ConcurrentMergeScheduler; import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.FieldInfos; import org.apache.lucene.index.Fields; +import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -319,6 +326,14 @@ protected static TestFrameworkInfra getTestFrameworkInfra() { testFrameworkInfra.get(), "Expected test framework not to be null."); } + protected void setUp() throws Exception {} + + protected void tearDown() throws Exception { + synchronized (fieldToType) { + fieldToType.clear(); + } + } + // ----------------------------------------------------------------- // Truly immutable fields and constants, initialized once and valid // for all suites ever since. @@ -1986,6 +2001,179 @@ public static void maybeChangeLiveIndexWriterConfig(Random r, LiveIndexWriterCon } } + public static Field newStringField(String name, String value, Field.Store stored) { + return newField( + random(), + name, + value, + stored == Field.Store.YES ? StringField.TYPE_STORED : StringField.TYPE_NOT_STORED); + } + + public static Field newStringField(String name, BytesRef value, Field.Store stored) { + return newField( + random(), + name, + value, + stored == Field.Store.YES ? StringField.TYPE_STORED : StringField.TYPE_NOT_STORED); + } + + public static Field newTextField(String name, String value, Field.Store stored) { + return newField( + random(), + name, + value, + stored == Field.Store.YES ? TextField.TYPE_STORED : TextField.TYPE_NOT_STORED); + } + + public static Field newStringField(Random random, String name, String value, Field.Store stored) { + return newField( + random, + name, + value, + stored == Field.Store.YES ? StringField.TYPE_STORED : StringField.TYPE_NOT_STORED); + } + + public static Field newStringField( + Random random, String name, BytesRef value, Field.Store stored) { + return newField( + random, + name, + value, + stored == Field.Store.YES ? StringField.TYPE_STORED : StringField.TYPE_NOT_STORED); + } + + public static Field newTextField(Random random, String name, String value, Field.Store stored) { + return newField( + random, + name, + value, + stored == Field.Store.YES ? TextField.TYPE_STORED : TextField.TYPE_NOT_STORED); + } + + public static Field newField(String name, String value, FieldType type) { + return newField(random(), name, value, type); + } + + private static final Map fieldToType = new HashMap<>(); + + // TODO: if we can pull out the "make term vector options + // consistent across all instances of the same field name" + // write-once schema sort of helper class then we can + // remove the sync here. We can also fold the random + // "enable norms" (now commented out, below) into that: + public static Field newField(Random random, String name, Object value, FieldType type) { + + // Defeat any consumers that illegally rely on interned + // strings (we removed this from Lucene a while back): + name = new String(name); + + synchronized (fieldToType) { + FieldType prevType = fieldToType.get(name); + + if (prevType != null) { + // always use the same fieldType for the same field name + return createField(name, value, prevType); + } + + // TODO: once all core & test codecs can index + // offsets, sometimes randomly turn on offsets if we are + // already indexing positions... + + FieldType newType = new FieldType(type); + if (!newType.stored() && random.nextBoolean()) { + newType.setStored(true); // randomly store it + } + if (newType.indexOptions() != IndexOptions.NONE) { + if (!newType.storeTermVectors() && random.nextBoolean()) { + newType.setStoreTermVectors(true); + if (!newType.storeTermVectorPositions()) { + newType.setStoreTermVectorPositions(random.nextBoolean()); + if (newType.storeTermVectorPositions()) { + if (!newType.storeTermVectorPayloads()) { + newType.setStoreTermVectorPayloads(random.nextBoolean()); + } + } + } + // Check for strings as offsets are disallowed on binary fields + if (value instanceof String && !newType.storeTermVectorOffsets()) { + newType.setStoreTermVectorOffsets(random.nextBoolean()); + } + + if (VERBOSE) { + System.out.println("NOTE: LuceneTestCase: upgrade name=" + name + " type=" + newType); + } + } + } + newType.freeze(); + fieldToType.put(name, newType); + + // TODO: we need to do this, but smarter, ie, most of + // the time we set the same value for a given field but + // sometimes (rarely) we change it up: + /* + if (newType.omitNorms()) { + newType.setOmitNorms(random.nextBoolean()); + } + */ + + return createField(name, value, newType); + } + } + + private static Field createField(String name, Object value, FieldType fieldType) { + if (value instanceof String) { + return new Field(name, (String) value, fieldType); + } else if (value instanceof BytesRef) { + return new Field(name, (BytesRef) value, fieldType); + } else { + throw new IllegalArgumentException("value must be String or BytesRef"); + } + } + + private static final String[] availableLanguageTags = + Arrays.stream(Locale.getAvailableLocales()) + .map(Locale::toLanguageTag) + .sorted() + .distinct() + .toArray(String[]::new); + + /** + * Return a random Locale from the available locales on the system. + * + * @see LUCENE-4020 + */ + public static Locale randomLocale(Random random) { + return localeForLanguageTag( + availableLanguageTags[random.nextInt(availableLanguageTags.length)]); + } + + /** Time zone IDs that cause a deprecation warning in JDK 25. */ + private static final Set DEPRECATED_TIME_ZONE_IDS_JDK25 = + Set.of( + "ACT", "AET", "AGT", "ART", "AST", "BET", "BST", "CAT", "CNT", "CST", "CTT", "EAT", "ECT", + "EST", "HST", "IET", "IST", "JST", "MIT", "MST", "NET", "NST", "PLT", "PNT", "PRT", "PST", + "SST", "VST"); + + /** + * Return a random TimeZone from the available timezones on the system + * + * @see LUCENE-4020 + */ + public static TimeZone randomTimeZone(Random random) { + List tzIds = Arrays.asList(TimeZone.getAvailableIDs()); + // Remove time zones that cause deprecation warnings as these can break + // certain tests that expect exact output. + if (Runtime.version().feature() >= 25) { + tzIds = tzIds.stream().filter(id -> !DEPRECATED_TIME_ZONE_IDS_JDK25.contains(id)).toList(); + } + return TimeZone.getTimeZone(RandomPicks.randomFrom(random, tzIds)); + } + + /** return a Locale object equivalent to its programmatic name */ + public static Locale localeForLanguageTag(String languageTag) { + return new Locale.Builder().setLanguageTag(languageTag).build(); + } + // // TODO: to remove from here? // From c3e50f903906e57db8dc0a0ac998a2e279441e72 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 24 Apr 2026 08:49:40 +0200 Subject: [PATCH 21/68] Separated test-framework dep. infrastructure. --- .../TestMemoryIndexAgainstDirectory.java | 3 - .../tests/util/BeforeAfterCallback.java | 6 +- .../lucene/tests/util/GlobalStateSupport.java | 28 +- .../lucene/tests/util/LuceneTestCase.java | 806 +----------------- .../tests/util/LuceneTestCaseJupiter.java | 18 +- .../tests/util/LuceneTestCaseParent.java | 762 ++++++++++++++++- ...eanup.java => TemporaryFilesSupplier.java} | 11 +- 7 files changed, 815 insertions(+), 819 deletions(-) rename lucene/test-framework/src/java/org/apache/lucene/tests/util/{TestRuleTemporaryFilesCleanup.java => TemporaryFilesSupplier.java} (97%) diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java index f288bee7b7c5..e902c1f02d6d 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java @@ -16,9 +16,6 @@ */ package org.apache.lucene.index.memory; -import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newDirectory; -import static org.apache.lucene.tests.analysis.BaseTokenStreamTestCase.newSearcher; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java index dd5e83bed24d..8adbca3e44d8 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java @@ -18,7 +18,9 @@ /** Abstraction for before-test/before-suite callbacks. */ interface BeforeAfterCallback { - void before() throws Exception; + default void before() throws Exception {} + ; - void after() throws Exception; + default void after() throws Exception {} + ; } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java index 9611643a83bb..7d12f8df9961 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java @@ -67,11 +67,18 @@ private static final class JupiterTestFrameworkInfra final Supplier rnd; final SetupAndRestoreStaticEnv classEnvRule; + private final TemporaryFilesSupplier tempFilesSupplier; + private final TestRuleMarkFailure failureMarker; + JupiterTestFrameworkInfra(Class requiredTestClass, Supplier randomSupplier) { this.rnd = randomSupplier; this.classEnvRule = new SetupAndRestoreStaticEnv( this::threadRandom, () -> Objects.requireNonNull(requiredTestClass)); + this.failureMarker = new TestRuleMarkFailure(); + this.tempFilesSupplier = + new TemporaryFilesSupplier( + failureMarker, this::threadRandom, () -> Objects.requireNonNull(requiredTestClass)); } @Override @@ -107,7 +114,19 @@ public void afterEach() throws IOException { public void afterAll() throws IOException { synchronized (this) { IOUtils.close( - Stream.of(closeAfterTest, closeAfterSuite, perThreadRandoms.values()) + Stream.of( + List.of( + () -> { + try { + tempFilesSupplier.after(); + classEnvRule.after(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }), + closeAfterTest, + closeAfterSuite, + perThreadRandoms.values()) .flatMap(Collection::stream) .filter(v -> v instanceof Closeable) .map(v -> (Closeable) v) @@ -120,8 +139,15 @@ public SetupAndRestoreStaticEnv getClassEnv() { return classEnvRule; } + @Override + public TemporaryFilesSupplier getTempFilesSupplier() { + return tempFilesSupplier; + } + public void beforeAll() throws Exception { classEnvRule.before(); + failureMarker.reset(); + tempFilesSupplier.before(); } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 9aa12fdc92ca..d7b2b6093586 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -40,92 +40,26 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Consequence; import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite; -import com.carrotsearch.randomizedtesting.generators.RandomPicks; import com.carrotsearch.randomizedtesting.rules.NoClassHooksShadowingRule; import com.carrotsearch.randomizedtesting.rules.NoInstanceHooksOverridesRule; import com.carrotsearch.randomizedtesting.rules.TestRuleAdapter; import java.io.Closeable; -import java.io.IOException; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Random; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; import java.util.regex.Pattern; -import org.apache.lucene.codecs.KnnVectorsFormat; -import org.apache.lucene.codecs.bitvectors.HnswBitVectorsFormat; -import org.apache.lucene.codecs.hnsw.FlatVectorsFormat; -import org.apache.lucene.index.CodecReader; -import org.apache.lucene.index.CompositeReader; -import org.apache.lucene.index.ConcurrentMergeScheduler; -import org.apache.lucene.index.DirectoryReader; -import org.apache.lucene.index.FieldInfo; -import org.apache.lucene.index.IndexFileNames; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.index.LeafReader; -import org.apache.lucene.index.LeafReaderContext; -import org.apache.lucene.index.LogByteSizeMergePolicy; -import org.apache.lucene.index.LogMergePolicy; -import org.apache.lucene.index.MergePolicy; -import org.apache.lucene.index.ParallelCompositeReader; -import org.apache.lucene.index.ParallelLeafReader; -import org.apache.lucene.index.TieredMergePolicy; -import org.apache.lucene.index.VectorEncoding; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.LRUQueryCache; -import org.apache.lucene.search.QueryCache; -import org.apache.lucene.search.QueryCachingPolicy; -import org.apache.lucene.store.ByteBuffersDirectory; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.FSDirectory; -import org.apache.lucene.store.FSLockFactory; -import org.apache.lucene.store.FileSwitchDirectory; -import org.apache.lucene.store.FlushInfo; -import org.apache.lucene.store.IOContext; -import org.apache.lucene.store.LockFactory; -import org.apache.lucene.store.MergeInfo; -import org.apache.lucene.store.NRTCachingDirectory; -import org.apache.lucene.store.ReadOnceHint; import org.apache.lucene.tests.codecs.asserting.AssertingCodec; -import org.apache.lucene.tests.index.AssertingDirectoryReader; -import org.apache.lucene.tests.index.AssertingLeafReader; -import org.apache.lucene.tests.index.FieldFilterLeafReader; -import org.apache.lucene.tests.index.MergingCodecReader; -import org.apache.lucene.tests.index.MergingDirectoryReaderWrapper; -import org.apache.lucene.tests.index.MismatchedCodecReader; -import org.apache.lucene.tests.index.MismatchedDirectoryReader; -import org.apache.lucene.tests.index.MismatchedLeafReader; -import org.apache.lucene.tests.mockfile.VirusCheckingFS; -import org.apache.lucene.tests.search.AssertingIndexSearcher; -import org.apache.lucene.tests.store.BaseDirectoryWrapper; -import org.apache.lucene.tests.store.MockDirectoryWrapper; -import org.apache.lucene.tests.store.RawDirectoryWrapper; -import org.apache.lucene.util.CommandLineUtil; -import org.apache.lucene.util.NamedThreadFactory; import org.junit.After; -import org.junit.AfterClass; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; import org.junit.jupiter.api.Tag; @@ -135,10 +69,13 @@ /// Base class for all Lucene unit tests (JUnit4 variant). /// +/// **Please consider using the new JUnit Jupiter base class [LuceneTestCaseJupiter] instead. This class +/// will be eventually removed from Lucene codebase.** +/// /// ## Class and instance setup /// /// The preferred way to specify class (suite-level) setup/cleanup is to use static methods -/// annotated with [BeforeClass] and [AfterClass]. Any code in these methods is executed +/// annotated with [org.junit.BeforeClass] and [org.junit.AfterClass]. Any code in these methods is executed /// within the test framework's control and ensure proper setup has been made. **Try not to use /// static initializers (including complex final field initializers).** Static initializers are /// executed before any setup rules are fired and may cause you (or somebody else) headaches. @@ -408,6 +345,14 @@ public static TestRuleIgnoreAfterMaxFailures replaceMaxFailureRule( () -> RandomizedContext.current().getRandom(), () -> RandomizedContext.current().getTargetClass()); + LuceneTestCase.suiteFailureMarker = new TestRuleMarkFailure(); + + var tempFilesSupplier = + new TemporaryFilesSupplier( + suiteFailureMarker, + LuceneTestCase::random, + () -> RandomizedContext.current().getTargetClass()); + classRules = RuleChain.outerRule(new TestRuleIgnoreTestSuites()) .around( @@ -471,6 +416,11 @@ public void afterEach() {} public SetupAndRestoreStaticEnv getClassEnv() { return setupAndRestoreClassEnv; } + + @Override + public TemporaryFilesSupplier getTempFilesSupplier() { + return tempFilesSupplier; + } }); } @@ -480,18 +430,13 @@ protected void afterAlways(List errors) { } }) .around(ignoreAfterMaxFailures) - .around(suiteFailureMarker = new TestRuleMarkFailure()) + .around(suiteFailureMarker) .around( new VerifyTestClassNamingConvention( "org.apache.lucene", Pattern.compile("(.+\\.)(Test)([^.]+)"))) .around(new TestRuleAssertionsRequired()) .around(new TestRuleLimitSysouts(suiteFailureMarker)) - .around( - tempFilesCleanupRule = - new TestRuleTemporaryFilesCleanup( - suiteFailureMarker, - LuceneTestCase::random, - () -> RandomizedContext.current().getTargetClass())) + .around(new CallbacksToRuleAdapter(tempFilesSupplier)) .around(new NoClassHooksShadowingRule()) .around( new NoInstanceHooksOverridesRule() { @@ -516,7 +461,7 @@ protected boolean verify(Method key) { new CallbacksToRuleAdapter( new BeforeAfterCallback() { @Override - public void before() throws Exception { + public void before() { RunListenerPrintReproduceInfo.env = new RunListenerPrintReproduceInfo.Env( setupAndRestoreClassEnv.codec, @@ -524,9 +469,6 @@ public void before() throws Exception { setupAndRestoreClassEnv.locale, setupAndRestoreClassEnv.timeZone); } - - @Override - public void after() throws Exception {} })); } @@ -605,712 +547,4 @@ protected boolean isTestThread() { assertNotNull("Test case thread not set?", threadAndTestNameRule.testCaseThread); return Thread.currentThread() == threadAndTestNameRule.testCaseThread; } - - /** - * Returns a new Directory instance. Use this when the test does not care about the specific - * Directory implementation (most tests). - * - *

The Directory is wrapped with {@link BaseDirectoryWrapper}. this means usually it will be - * picky, such as ensuring that you properly close it and all open files in your test. It will - * emulate some features of Windows, such as not allowing open files to be overwritten. - */ - public static BaseDirectoryWrapper newDirectory() { - return newDirectory(random()); - } - - /** Like {@link #newDirectory} except randomly the {@link VirusCheckingFS} may be installed */ - public static BaseDirectoryWrapper newMaybeVirusCheckingDirectory() { - if (random().nextInt(5) == 4) { - Path path = addVirusChecker(createTempDir()); - return newFSDirectory(path); - } else { - return newDirectory(random()); - } - } - - /** - * Returns a new Directory instance, using the specified random. See {@link #newDirectory()} for - * more information. - */ - public static BaseDirectoryWrapper newDirectory(Random r) { - return wrapDirectory(r, newDirectoryImpl(r, TEST_DIRECTORY), rarely(r), false); - } - - /** - * Returns a new Directory instance, using the specified random. See {@link #newDirectory()} for - * more information. - */ - public static BaseDirectoryWrapper newDirectory(Random r, LockFactory lf) { - return wrapDirectory(r, newDirectoryImpl(r, TEST_DIRECTORY, lf), rarely(r), false); - } - - public static MockDirectoryWrapper newMockDirectory() { - return newMockDirectory(random()); - } - - public static MockDirectoryWrapper newMockDirectory(Random r) { - return (MockDirectoryWrapper) - wrapDirectory(r, newDirectoryImpl(r, TEST_DIRECTORY), false, false); - } - - public static MockDirectoryWrapper newMockDirectory(Random r, LockFactory lf) { - return (MockDirectoryWrapper) - wrapDirectory(r, newDirectoryImpl(r, TEST_DIRECTORY, lf), false, false); - } - - public static MockDirectoryWrapper newMockFSDirectory(Path f) { - return (MockDirectoryWrapper) newFSDirectory(f, FSLockFactory.getDefault(), false); - } - - public static MockDirectoryWrapper newMockFSDirectory(Path f, LockFactory lf) { - return (MockDirectoryWrapper) newFSDirectory(f, lf, false); - } - - public static Path addVirusChecker(Path path) { - if (TestUtil.hasVirusChecker(path) == false) { - VirusCheckingFS fs = new VirusCheckingFS(path.getFileSystem(), random().nextLong()); - path = fs.wrapPath(path); - } - return path; - } - - /** - * Returns a new Directory instance, with contents copied from the provided directory. See {@link - * #newDirectory()} for more information. - */ - public static BaseDirectoryWrapper newDirectory(Directory d) throws IOException { - return newDirectory(random(), d); - } - - /** Returns a new FSDirectory instance over the given file, which must be a folder. */ - public static BaseDirectoryWrapper newFSDirectory(Path f) { - return newFSDirectory(f, FSLockFactory.getDefault()); - } - - /** Like {@link #newFSDirectory(Path)}, but randomly insert {@link VirusCheckingFS} */ - public static BaseDirectoryWrapper newMaybeVirusCheckingFSDirectory(Path f) { - if (random().nextInt(5) == 4) { - f = addVirusChecker(f); - } - return newFSDirectory(f, FSLockFactory.getDefault()); - } - - /** Returns a new FSDirectory instance over the given file, which must be a folder. */ - public static BaseDirectoryWrapper newFSDirectory(Path f, LockFactory lf) { - return newFSDirectory(f, lf, rarely()); - } - - private static BaseDirectoryWrapper newFSDirectory(Path f, LockFactory lf, boolean bare) { - String fsdirClass = TEST_DIRECTORY; - if (fsdirClass.equals("random")) { - fsdirClass = RandomPicks.randomFrom(random(), FS_DIRECTORIES); - } - - Class clazz; - try { - try { - clazz = CommandLineUtil.loadFSDirectoryClass(fsdirClass); - } catch (ClassCastException _) { - // TEST_DIRECTORY is not a sub-class of FSDirectory, so draw one at random - fsdirClass = RandomPicks.randomFrom(random(), FS_DIRECTORIES); - clazz = CommandLineUtil.loadFSDirectoryClass(fsdirClass); - } - - Directory fsdir = newFSDirectoryImpl(clazz, f, lf); - return wrapDirectory(random(), fsdir, bare, true); - } catch (Exception e) { - Rethrow.rethrow(e); - throw null; // dummy to prevent compiler failure - } - } - - private static Directory newFileSwitchDirectory(Random random, Directory dir1, Directory dir2) { - List fileExtensions = - Arrays.asList( - "fdt", "fdx", "tim", "tip", "si", "fnm", "pos", "dii", "dim", "nvm", "nvd", "dvm", - "dvd"); - Collections.shuffle(fileExtensions, random); - fileExtensions = fileExtensions.subList(0, 1 + random.nextInt(fileExtensions.size())); - return new FileSwitchDirectory(new HashSet<>(fileExtensions), dir1, dir2, true); - } - - /** - * Returns a new Directory instance, using the specified random with contents copied from the - * provided directory. See {@link #newDirectory()} for more information. - */ - public static BaseDirectoryWrapper newDirectory(Random r, Directory d) throws IOException { - Directory impl = newDirectoryImpl(r, TEST_DIRECTORY); - for (String file : d.listAll()) { - if (file.startsWith(IndexFileNames.SEGMENTS) - || IndexFileNames.CODEC_FILE_PATTERN.matcher(file).matches()) { - impl.copyFrom(d, file, file, newIOContext(r)); - } - } - return wrapDirectory(r, impl, rarely(r), false); - } - - private static BaseDirectoryWrapper wrapDirectory( - Random random, Directory directory, boolean bare, boolean filesystem) { - // IOContext randomization might make NRTCachingDirectory make bad decisions, so avoid - // using it if the user requested a filesystem directory. - if (rarely(random) && !bare && filesystem == false) { - directory = new NRTCachingDirectory(directory, random.nextDouble(), random.nextDouble()); - } - - if (bare) { - BaseDirectoryWrapper base = new RawDirectoryWrapper(directory); - closeAfterSuite(new CloseableDirectory(base, suiteFailureMarker)); - return base; - } else { - MockDirectoryWrapper mock = new MockDirectoryWrapper(random, directory); - - mock.setThrottling(TEST_THROTTLING); - closeAfterSuite(new CloseableDirectory(mock, suiteFailureMarker)); - return mock; - } - } - - private static Directory newFSDirectoryImpl( - Class clazz, Path path, LockFactory lf) throws IOException { - FSDirectory d = null; - try { - d = CommandLineUtil.newFSDirectory(clazz, path, lf); - } catch (ReflectiveOperationException e) { - Rethrow.rethrow(e); - } - return d; - } - - static Directory newDirectoryImpl(Random random, String clazzName) { - return newDirectoryImpl(random, clazzName, FSLockFactory.getDefault()); - } - - static Directory newDirectoryImpl(Random random, String clazzName, LockFactory lf) { - if (clazzName.equals("random")) { - if (rarely(random)) { - clazzName = RandomPicks.randomFrom(random, CORE_DIRECTORIES); - } else if (rarely(random)) { - String clazzName1 = - rarely(random) - ? RandomPicks.randomFrom(random, CORE_DIRECTORIES) - : ByteBuffersDirectory.class.getName(); - String clazzName2 = - rarely(random) - ? RandomPicks.randomFrom(random, CORE_DIRECTORIES) - : ByteBuffersDirectory.class.getName(); - return newFileSwitchDirectory( - random, - newDirectoryImpl(random, clazzName1, lf), - newDirectoryImpl(random, clazzName2, lf)); - } else { - clazzName = ByteBuffersDirectory.class.getName(); - } - } - - try { - final Class clazz = CommandLineUtil.loadDirectoryClass(clazzName); - // If it is a FSDirectory type, try its ctor(Path) - if (FSDirectory.class.isAssignableFrom(clazz)) { - final Path dir = createTempDir("index-" + clazzName); - return newFSDirectoryImpl(clazz.asSubclass(FSDirectory.class), dir, lf); - } - - // See if it has a Path/LockFactory ctor even though it's not an - // FSDir subclass: - try { - Constructor pathCtor = - clazz.getConstructor(Path.class, LockFactory.class); - final Path dir = createTempDir("index"); - return pathCtor.newInstance(dir, lf); - } catch (NoSuchMethodException _) { - // Ignore - } - - // the remaining dirs are no longer filesystem based, so we must check that the - // passedLockFactory is not file based: - if (!(lf instanceof FSLockFactory)) { - // try ctor with only LockFactory - try { - return clazz.getConstructor(LockFactory.class).newInstance(lf); - } catch (NoSuchMethodException _) { - // Ignore - } - } - - // try empty ctor - return clazz.getConstructor().newInstance(); - } catch (Exception e) { - Rethrow.rethrow(e); - throw null; // dummy to prevent compiler failure - } - } - - public static IndexReader wrapReader(IndexReader r) throws IOException { - Random random = random(); - - for (int i = 0, c = random.nextInt(6) + 1; i < c; i++) { - switch (random.nextInt(5)) { - case 0: - // will create no FC insanity in atomic case, as ParallelLeafReader has own cache key: - if (VERBOSE) { - System.out.println( - "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" - + r - + " with ParallelLeaf/CompositeReader"); - } - r = - (r instanceof LeafReader) - ? new ParallelLeafReader((LeafReader) r) - : new ParallelCompositeReader((CompositeReader) r); - break; - case 1: - if (r instanceof LeafReader ar) { - final List allFields = new ArrayList<>(); - for (FieldInfo fi : ar.getFieldInfos()) { - allFields.add(fi.name); - } - Collections.shuffle(allFields, random); - final int end = allFields.isEmpty() ? 0 : random.nextInt(allFields.size()); - final Set fields = new HashSet<>(allFields.subList(0, end)); - // will create no FC insanity as ParallelLeafReader has own cache key: - if (VERBOSE) { - System.out.println( - "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" - + r - + " with ParallelLeafReader"); - } - r = - new ParallelLeafReader( - new FieldFilterLeafReader(ar, fields, false), - new FieldFilterLeafReader(ar, fields, true)); - } - break; - case 2: - // Häckidy-Hick-Hack: a standard Reader will cause FC insanity, so we use - // QueryUtils' reader with a fake cache key, so insanity checker cannot walk - // along our reader: - if (VERBOSE) { - System.out.println( - "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" - + r - + " with AssertingLeaf/DirectoryReader"); - } - if (r instanceof LeafReader) { - r = new AssertingLeafReader((LeafReader) r); - } else if (r instanceof DirectoryReader) { - r = new AssertingDirectoryReader((DirectoryReader) r); - } - break; - case 3: - if (VERBOSE) { - System.out.println( - "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" - + r - + " with MismatchedLeaf/Directory/CodecReader"); - } - if (r instanceof LeafReader) { - r = new MismatchedLeafReader((LeafReader) r, random); - } else if (r instanceof DirectoryReader) { - r = new MismatchedDirectoryReader((DirectoryReader) r, random); - } else if (r instanceof CodecReader) { - r = new MismatchedCodecReader((CodecReader) r, random); - } - break; - case 4: - if (VERBOSE) { - System.out.println( - "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" - + r - + " with MergingCodecReader"); - } - if (r instanceof CodecReader) { - r = new MergingCodecReader((CodecReader) r); - } else if (r instanceof DirectoryReader) { - boolean allLeavesAreCodecReaders = true; - for (LeafReaderContext ctx : r.leaves()) { - if (ctx.reader() instanceof CodecReader == false) { - allLeavesAreCodecReaders = false; - break; - } - } - if (allLeavesAreCodecReaders) { - r = new MergingDirectoryReaderWrapper((DirectoryReader) r); - } - } - break; - default: - fail("should not get here"); - } - } - - if (VERBOSE) { - System.out.println("wrapReader wrapped: " + r); - } - - return r; - } - - /** Sometimes wrap the IndexReader as slow, parallel or filter reader (or combinations of that) */ - public static IndexReader maybeWrapReader(IndexReader r) throws IOException { - if (rarely()) { - r = wrapReader(r); - } - return r; - } - - /** TODO: javadoc */ - public static IOContext newIOContext(Random random) { - return newIOContext(random, IOContext.DEFAULT); - } - - /** TODO: javadoc */ - public static IOContext newIOContext(Random random, IOContext oldContext) { - if (oldContext.hints().contains(ReadOnceHint.INSTANCE)) { - return oldContext; // just return as-is - } - final int randomNumDocs = random.nextInt(4192); - final int size = random.nextInt(512) * randomNumDocs; - if (oldContext.flushInfo() != null) { - // Always return at least the estimatedSegmentSize of - // the incoming IOContext: - return IOContext.flush( - new FlushInfo( - randomNumDocs, Math.max(oldContext.flushInfo().estimatedSegmentSize(), size))); - } else if (oldContext.mergeInfo() != null) { - // Always return at least the estimatedMergeBytes of - // the incoming IOContext: - return IOContext.merge( - new MergeInfo( - randomNumDocs, - Math.max(oldContext.mergeInfo().estimatedMergeBytes(), size), - random.nextBoolean(), - TestUtil.nextInt(random, 1, 100))); - } else { - // Make a totally random IOContext - final IOContext context; - switch (random.nextInt(3)) { - case 0: - context = IOContext.DEFAULT; - break; - case 1: - context = IOContext.merge(new MergeInfo(randomNumDocs, size, true, -1)); - break; - case 2: - context = IOContext.flush(new FlushInfo(randomNumDocs, size)); - break; - default: - context = IOContext.DEFAULT; - } - return context; - } - } - - private static final QueryCache DEFAULT_QUERY_CACHE = IndexSearcher.getDefaultQueryCache(); - private static final QueryCachingPolicy DEFAULT_CACHING_POLICY = - IndexSearcher.getDefaultQueryCachingPolicy(); - private static final List queryCacheList = new ArrayList<>(); - - @Before - public void overrideTestDefaultQueryCache() { - // Make sure each test method has its own cache - overrideDefaultQueryCache(); - } - - @BeforeClass - public static void overrideDefaultQueryCache() { - // we need to reset the query cache in an @BeforeClass so that tests that - // instantiate an IndexSearcher in an @BeforeClass method use a fresh new cache - LRUQueryCache queryCacheTemp = - new LRUQueryCache(10000, 1 << 25, _ -> true, Float.POSITIVE_INFINITY); - queryCacheList.add(queryCacheTemp); - IndexSearcher.setDefaultQueryCache(queryCacheTemp); - IndexSearcher.setDefaultQueryCachingPolicy(MAYBE_CACHE_POLICY); - } - - @AfterClass - public static void resetDefaultQueryCache() { - IndexSearcher.setDefaultQueryCache(DEFAULT_QUERY_CACHE); - IndexSearcher.setDefaultQueryCachingPolicy(DEFAULT_CACHING_POLICY); - for (int i = 0; i < queryCacheList.size(); i++) { - try { - queryCacheList.get(i).close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - @BeforeClass - public static void setupCPUCoreCount() { - // Randomize core count so CMS varies its dynamic defaults, and this also "fixes" core - // count from the master seed so it will always be the same on reproduce: - int numCores = TestUtil.nextInt(random(), 1, 4); - System.setProperty( - ConcurrentMergeScheduler.DEFAULT_CPU_CORE_COUNT_PROPERTY, Integer.toString(numCores)); - } - - @AfterClass - public static void restoreCPUCoreCount() { - System.clearProperty(ConcurrentMergeScheduler.DEFAULT_CPU_CORE_COUNT_PROPERTY); - } - - private static ExecutorService executor; - - @BeforeClass - public static void setUpExecutorService() { - int threads = TestUtil.nextInt(random(), 1, 2); - executor = - new ThreadPoolExecutor( - threads, - threads, - 0L, - TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<>(), - new NamedThreadFactory("LuceneTestCase")); - // uncomment to intensify LUCENE-3840 - // executor.prestartAllCoreThreads(); - if (VERBOSE) { - System.out.println("NOTE: Created shared ExecutorService with " + threads + " threads"); - } - } - - @AfterClass - public static void shutdownExecutorService() { - TestUtil.shutdownExecutorService(executor); - executor = null; - } - - /** Create a new searcher over the reader. This searcher might randomly use threads. */ - public static IndexSearcher newSearcher(IndexReader r) { - return newSearcher(r, true); - } - - /** Create a new searcher over the reader. This searcher might randomly use threads. */ - public static IndexSearcher newSearcher(IndexReader r, boolean maybeWrap) { - return newSearcher(r, maybeWrap, true); - } - - /** - * Create a new searcher over the reader. This searcher might randomly use threads. if - * maybeWrap is true, this searcher might wrap the reader with one that returns null for - * getSequentialSubReaders. If wrapWithAssertions is true, this searcher might be an - * {@link AssertingIndexSearcher} instance. - */ - public static IndexSearcher newSearcher( - IndexReader r, boolean maybeWrap, boolean wrapWithAssertions) { - return newSearcher(r, maybeWrap, wrapWithAssertions, random().nextBoolean()); - } - - /** - * Create a new searcher over the reader. If - * maybeWrap is true, this searcher might wrap the reader with one that returns null for - * getSequentialSubReaders. If wrapWithAssertions is true, this searcher might be an - * {@link AssertingIndexSearcher} instance. The searcher will use threads if useThreads - * is set to true. - */ - public static IndexSearcher newSearcher( - IndexReader r, boolean maybeWrap, boolean wrapWithAssertions, boolean useThreads) { - if (useThreads) { - return newSearcher(r, maybeWrap, wrapWithAssertions, Concurrency.INTRA_SEGMENT); - } - return newSearcher(r, maybeWrap, wrapWithAssertions, Concurrency.NONE); - } - - /** What level of concurrency is supported by the searcher being created */ - public enum Concurrency { - /** No concurrency, meaning an executor won't be provided to the searcher */ - NONE, - /** - * Inter-segment concurrency, meaning an executor will be provided to the searcher and slices - * will be randomly created to concurrently search entire segments - */ - INTER_SEGMENT, - /** - * Intra-segment concurrency, meaning an executor will be provided to the searcher and slices - * will be randomly created to concurrently search segment partitions - */ - INTRA_SEGMENT - } - - public static IndexSearcher newSearcher( - IndexReader r, boolean maybeWrap, boolean wrapWithAssertions, Concurrency concurrency) { - Random random = random(); - if (concurrency == Concurrency.NONE) { - if (maybeWrap) { - try { - r = maybeWrapReader(r); - } catch (IOException e) { - Rethrow.rethrow(e); - } - } - // TODO: this whole check is a coverage hack, we should move it to tests for various - // filterreaders. - // ultimately whatever you do will be checkIndex'd at the end anyway. - if (random.nextInt(500) == 0 && r instanceof LeafReader) { - // TODO: not useful to check DirectoryReader (redundant with checkindex) - // but maybe sometimes run this on the other crazy readers maybeWrapReader creates? - try { - TestUtil.checkReader(r); - } catch (IOException e) { - Rethrow.rethrow(e); - } - } - final IndexSearcher ret; - if (wrapWithAssertions) { - ret = - random.nextBoolean() - ? new AssertingIndexSearcher(random, r) - : new AssertingIndexSearcher(random, r.getContext()); - } else { - ret = random.nextBoolean() ? new IndexSearcher(r) : new IndexSearcher(r.getContext()); - } - ret.setSimilarity(getTestFrameworkInfra().getClassEnv().similarity); - return ret; - } else { - final ExecutorService ex; - if (random.nextBoolean()) { - ex = null; - } else { - ex = executor; - if (VERBOSE) { - System.out.println("NOTE: newSearcher using shared ExecutorService"); - } - } - IndexSearcher ret; - int maxDocPerSlice = random.nextBoolean() ? 1 : 1 + random.nextInt(1000); - int maxSegmentsPerSlice = random.nextBoolean() ? 1 : 1 + random.nextInt(10); - if (wrapWithAssertions) { - if (random.nextBoolean()) { - ret = - new AssertingIndexSearcher(random, r, ex) { - @Override - protected LeafSlice[] slices(List leaves) { - return LuceneTestCaseParent.slices( - leaves, maxDocPerSlice, maxSegmentsPerSlice, concurrency); - } - }; - } else { - ret = - new AssertingIndexSearcher(random, r.getContext(), ex) { - @Override - protected LeafSlice[] slices(List leaves) { - return LuceneTestCaseParent.slices( - leaves, maxDocPerSlice, maxSegmentsPerSlice, concurrency); - } - }; - } - } else { - ret = - new IndexSearcher(r, ex) { - @Override - protected LeafSlice[] slices(List leaves) { - return LuceneTestCaseParent.slices( - leaves, maxDocPerSlice, maxSegmentsPerSlice, concurrency); - } - }; - } - ret.setSimilarity(getTestFrameworkInfra().getClassEnv().similarity); - ret.setQueryCachingPolicy(MAYBE_CACHE_POLICY); - if (random().nextBoolean()) { - ret.setTimeout(() -> false); - } - return ret; - } - } - - /** - * Creates an empty, temporary folder (when the name of the folder is of no importance). - * - * @see #createTempDir(String) - */ - public static Path createTempDir() { - return createTempDir("tempDir"); - } - - /** - * Creates an empty, temporary folder with the given name prefix. - * - *

The folder will be automatically removed after the test class completes successfully. The - * test should close any file handles that would prevent the folder from being removed. - */ - public static Path createTempDir(String prefix) { - return tempFilesCleanupRule.createTempDir(prefix); - } - - /** - * Creates an empty file with the given prefix and suffix. - * - *

The file will be automatically removed after the test class completes successfully. The test - * should close any file handles that would prevent the folder from being removed. - */ - public static Path createTempFile(String prefix, String suffix) throws IOException { - return tempFilesCleanupRule.createTempFile(prefix, suffix); - } - - /** - * Creates an empty temporary file. - * - * @see #createTempFile(String, String) - */ - public static Path createTempFile() throws IOException { - return createTempFile("tempFile", ".tmp"); - } - - /** Ensures that the MergePolicy has sane values for tests that test with lots of documents. */ - protected static IndexWriterConfig ensureSaneIWCOnNightly(IndexWriterConfig conf) { - if (LuceneTestCase.TEST_NIGHTLY) { - // newIWConfig makes smallish max seg size, which - // results in tons and tons of segments for this test - // when run nightly: - MergePolicy mp = conf.getMergePolicy(); - if (mp instanceof TieredMergePolicy) { - ((TieredMergePolicy) mp).setMaxMergedSegmentMB(5000.); - } else if (mp instanceof LogByteSizeMergePolicy) { - ((LogByteSizeMergePolicy) mp).setMaxMergeMB(1000.); - } else if (mp instanceof LogMergePolicy) { - ((LogMergePolicy) mp).setMaxMergeDocs(100000); - } - // when running nightly, merging can still have crazy parameters, - // and might use many per-field codecs. turn on CFS for IW flushes - // and ensure CFS ratio is reasonable to keep it contained. - conf.setUseCompoundFile(true); - } - return conf; - } - - private static boolean supportsVectorEncoding( - KnnVectorsFormat format, VectorEncoding vectorEncoding) { - if (format instanceof HnswBitVectorsFormat) { - // special case, this only supports BYTE - return vectorEncoding == VectorEncoding.BYTE; - } - return true; - } - - private static boolean supportsVectorSearch(KnnVectorsFormat format) { - return (format instanceof FlatVectorsFormat) == false; - } - - protected static KnnVectorsFormat randomVectorFormat(VectorEncoding vectorEncoding) { - List availableFormats = - KnnVectorsFormat.availableKnnVectorsFormats().stream() - .map(KnnVectorsFormat::forName) - .filter(format -> supportsVectorEncoding(format, vectorEncoding)) - .filter(format -> supportsVectorSearch(format)) - .toList(); - return RandomPicks.randomFrom(random(), availableFormats); - } - - /** - * This is a test merge scheduler that will always use the intra merge executor to ensure we test - * it. - */ - static class TestConcurrentMergeScheduler extends ConcurrentMergeScheduler { - @Override - public Executor getIntraMergeExecutor(MergePolicy.OneMerge merge) { - assert intraMergeExecutor != null : "scaledExecutor is not initialized"; - // Always do the intra merge executor to ensure we test it - return intraMergeExecutor; - } - } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 4bd20e8da213..20b69d35e7fb 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -20,8 +20,6 @@ import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; import com.carrotsearch.randomizedtesting.jupiter.Randomized; import com.carrotsearch.randomizedtesting.jupiter.SystemThreadFilter; -import java.util.List; -import java.util.Objects; import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; @@ -133,7 +131,7 @@ public boolean test(Thread t) { } } - static TestRuleTemporaryFilesCleanup tempFilesCleanupRule_; + // TODO: this should be in use (marker when tests failed). static TestRuleMarkFailure failureMarker = new TestRuleMarkFailure(); @RegisterExtension @@ -151,26 +149,18 @@ public void testFailed(ExtensionContext context, @Nullable Throwable cause) { }; @BeforeAll - public static void setupClass(TestInfo testInfo) throws Throwable { + static void setupClass(TestInfo testInfo) throws Throwable { var newRule = - new TestRuleTemporaryFilesCleanup( + new TemporaryFilesSupplier( failureMarker, LuceneTestCaseJupiter::random, () -> testInfo.getTestClass().orElseThrow()); failureMarker.reset(); newRule.before(); - - tempFilesCleanupRule_ = Objects.requireNonNull(tempFilesCleanupRule); - tempFilesCleanupRule = newRule; } @AfterAll - public static void teardownClass() throws Throwable { - if (tempFilesCleanupRule != null) { - tempFilesCleanupRule.afterAlways(List.of()); - tempFilesCleanupRule = tempFilesCleanupRule_; - } - } + static void teardownClass() throws Throwable {} // // Custom assertion methods. diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index f0262b01c331..fce22819a454 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -20,7 +20,6 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean; import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsInt; import static org.apache.lucene.search.DocIdSetIterator.NO_MORE_DOCS; -import static org.apache.lucene.tests.util.LuceneTestCase.Concurrency; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedTest; @@ -33,6 +32,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; +import java.lang.reflect.Constructor; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -56,21 +56,33 @@ import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import junit.framework.AssertionFailedError; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.codecs.CompoundFormat; +import org.apache.lucene.codecs.KnnVectorsFormat; +import org.apache.lucene.codecs.bitvectors.HnswBitVectorsFormat; +import org.apache.lucene.codecs.hnsw.FlatVectorsFormat; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.FieldType; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.CodecReader; +import org.apache.lucene.index.CompositeReader; import org.apache.lucene.index.ConcurrentMergeScheduler; +import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.FieldInfos; import org.apache.lucene.index.Fields; +import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; @@ -89,6 +101,8 @@ import org.apache.lucene.index.MultiTerms; import org.apache.lucene.index.NoDeletionPolicy; import org.apache.lucene.index.NumericDocValues; +import org.apache.lucene.index.ParallelCompositeReader; +import org.apache.lucene.index.ParallelLeafReader; import org.apache.lucene.index.PointValues; import org.apache.lucene.index.PostingsEnum; import org.apache.lucene.index.SerialMergeScheduler; @@ -102,25 +116,50 @@ import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.TieredMergePolicy; +import org.apache.lucene.index.VectorEncoding; import org.apache.lucene.internal.tests.IndexPackageAccess; import org.apache.lucene.internal.tests.TestSecrets; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.LRUQueryCache; import org.apache.lucene.search.Query; +import org.apache.lucene.search.QueryCache; import org.apache.lucene.search.QueryCachingPolicy; import org.apache.lucene.store.ByteBuffersDirectory; import org.apache.lucene.store.Directory; +import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.store.FSLockFactory; +import org.apache.lucene.store.FileSwitchDirectory; +import org.apache.lucene.store.FlushInfo; import org.apache.lucene.store.IOContext; +import org.apache.lucene.store.LockFactory; +import org.apache.lucene.store.MergeInfo; +import org.apache.lucene.store.NRTCachingDirectory; +import org.apache.lucene.store.ReadOnceHint; import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.index.AlcoholicMergePolicy; +import org.apache.lucene.tests.index.AssertingDirectoryReader; +import org.apache.lucene.tests.index.AssertingLeafReader; +import org.apache.lucene.tests.index.FieldFilterLeafReader; +import org.apache.lucene.tests.index.MergingCodecReader; +import org.apache.lucene.tests.index.MergingDirectoryReaderWrapper; +import org.apache.lucene.tests.index.MismatchedCodecReader; +import org.apache.lucene.tests.index.MismatchedDirectoryReader; +import org.apache.lucene.tests.index.MismatchedLeafReader; import org.apache.lucene.tests.index.MockIndexWriterEventListener; import org.apache.lucene.tests.index.MockRandomMergePolicy; +import org.apache.lucene.tests.mockfile.VirusCheckingFS; +import org.apache.lucene.tests.search.AssertingIndexSearcher; +import org.apache.lucene.tests.store.BaseDirectoryWrapper; import org.apache.lucene.tests.store.MockDirectoryWrapper; +import org.apache.lucene.tests.store.RawDirectoryWrapper; import org.apache.lucene.tests.util.automaton.AutomatonTestUtil; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.CommandLineUtil; import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.InfoStream; +import org.apache.lucene.util.NamedThreadFactory; import org.apache.lucene.util.SuppressForbidden; import org.apache.lucene.util.automaton.Automaton; import org.apache.lucene.util.automaton.CompiledAutomaton; @@ -128,7 +167,10 @@ import org.apache.lucene.util.automaton.RegExp; import org.hamcrest.Matcher; import org.hamcrest.MatcherAssert; +import org.junit.AfterClass; import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; import org.junit.internal.AssumptionViolatedException; /** @@ -304,6 +346,8 @@ protected interface TestFrameworkInfra { void afterAll() throws IOException; SetupAndRestoreStaticEnv getClassEnv(); + + TemporaryFilesSupplier getTempFilesSupplier(); } private static final AtomicReference testFrameworkInfra = @@ -1708,10 +1752,10 @@ public static IndexWriterConfig newIndexWriterConfig(Random r, Analyzer a) { } else if (rarely(r)) { ConcurrentMergeScheduler cms; if (r.nextBoolean()) { - cms = new LuceneTestCase.TestConcurrentMergeScheduler(); + cms = new IntraMergeConcurrentMergeScheduler(); } else { cms = - new LuceneTestCase.TestConcurrentMergeScheduler() { + new IntraMergeConcurrentMergeScheduler() { @Override protected synchronized boolean maybeStall(MergeSource mergeSource) { return true; @@ -1732,7 +1776,7 @@ protected synchronized boolean maybeStall(MergeSource mergeSource) { // defaults can change, hurting reproducibility: ConcurrentMergeScheduler cms = r.nextBoolean() - ? new LuceneTestCase.TestConcurrentMergeScheduler() + ? new IntraMergeConcurrentMergeScheduler() : new ConcurrentMergeScheduler(); // Only 1 thread can run at once (should maybe help reproducibility), @@ -2174,6 +2218,714 @@ public static Locale localeForLanguageTag(String languageTag) { return new Locale.Builder().setLanguageTag(languageTag).build(); } + /** + * Returns a new Directory instance. Use this when the test does not care about the specific + * Directory implementation (most tests). + * + *

The Directory is wrapped with {@link BaseDirectoryWrapper}. this means usually it will be + * picky, such as ensuring that you properly close it and all open files in your test. It will + * emulate some features of Windows, such as not allowing open files to be overwritten. + */ + public static BaseDirectoryWrapper newDirectory() { + return newDirectory(random()); + } + + /** Like {@link #newDirectory} except randomly the {@link VirusCheckingFS} may be installed */ + public static BaseDirectoryWrapper newMaybeVirusCheckingDirectory() { + if (random().nextInt(5) == 4) { + Path path = addVirusChecker(createTempDir()); + return newFSDirectory(path); + } else { + return newDirectory(random()); + } + } + + /** + * Returns a new Directory instance, using the specified random. See {@link #newDirectory()} for + * more information. + */ + public static BaseDirectoryWrapper newDirectory(Random r) { + return wrapDirectory(r, newDirectoryImpl(r, TEST_DIRECTORY), rarely(r), false); + } + + /** + * Returns a new Directory instance, using the specified random. See {@link #newDirectory()} for + * more information. + */ + public static BaseDirectoryWrapper newDirectory(Random r, LockFactory lf) { + return wrapDirectory(r, newDirectoryImpl(r, TEST_DIRECTORY, lf), rarely(r), false); + } + + public static MockDirectoryWrapper newMockDirectory() { + return newMockDirectory(random()); + } + + public static MockDirectoryWrapper newMockDirectory(Random r) { + return (MockDirectoryWrapper) + wrapDirectory(r, newDirectoryImpl(r, TEST_DIRECTORY), false, false); + } + + public static MockDirectoryWrapper newMockDirectory(Random r, LockFactory lf) { + return (MockDirectoryWrapper) + wrapDirectory(r, newDirectoryImpl(r, TEST_DIRECTORY, lf), false, false); + } + + public static MockDirectoryWrapper newMockFSDirectory(Path f) { + return (MockDirectoryWrapper) newFSDirectory(f, FSLockFactory.getDefault(), false); + } + + public static MockDirectoryWrapper newMockFSDirectory(Path f, LockFactory lf) { + return (MockDirectoryWrapper) newFSDirectory(f, lf, false); + } + + public static Path addVirusChecker(Path path) { + if (TestUtil.hasVirusChecker(path) == false) { + VirusCheckingFS fs = new VirusCheckingFS(path.getFileSystem(), random().nextLong()); + path = fs.wrapPath(path); + } + return path; + } + + /** + * Returns a new Directory instance, with contents copied from the provided directory. See {@link + * #newDirectory()} for more information. + */ + public static BaseDirectoryWrapper newDirectory(Directory d) throws IOException { + return newDirectory(random(), d); + } + + /** Returns a new FSDirectory instance over the given file, which must be a folder. */ + public static BaseDirectoryWrapper newFSDirectory(Path f) { + return newFSDirectory(f, FSLockFactory.getDefault()); + } + + /** Like {@link #newFSDirectory(Path)}, but randomly insert {@link VirusCheckingFS} */ + public static BaseDirectoryWrapper newMaybeVirusCheckingFSDirectory(Path f) { + if (random().nextInt(5) == 4) { + f = addVirusChecker(f); + } + return newFSDirectory(f, FSLockFactory.getDefault()); + } + + /** Returns a new FSDirectory instance over the given file, which must be a folder. */ + public static BaseDirectoryWrapper newFSDirectory(Path f, LockFactory lf) { + return newFSDirectory(f, lf, rarely()); + } + + private static BaseDirectoryWrapper newFSDirectory(Path f, LockFactory lf, boolean bare) { + String fsdirClass = TEST_DIRECTORY; + if (fsdirClass.equals("random")) { + fsdirClass = RandomPicks.randomFrom(random(), FS_DIRECTORIES); + } + + Class clazz; + try { + try { + clazz = CommandLineUtil.loadFSDirectoryClass(fsdirClass); + } catch (ClassCastException _) { + // TEST_DIRECTORY is not a sub-class of FSDirectory, so draw one at random + fsdirClass = RandomPicks.randomFrom(random(), FS_DIRECTORIES); + clazz = CommandLineUtil.loadFSDirectoryClass(fsdirClass); + } + + Directory fsdir = newFSDirectoryImpl(clazz, f, lf); + return wrapDirectory(random(), fsdir, bare, true); + } catch (Exception e) { + Rethrow.rethrow(e); + throw null; // dummy to prevent compiler failure + } + } + + private static Directory newFileSwitchDirectory(Random random, Directory dir1, Directory dir2) { + List fileExtensions = + Arrays.asList( + "fdt", "fdx", "tim", "tip", "si", "fnm", "pos", "dii", "dim", "nvm", "nvd", "dvm", + "dvd"); + Collections.shuffle(fileExtensions, random); + fileExtensions = fileExtensions.subList(0, 1 + random.nextInt(fileExtensions.size())); + return new FileSwitchDirectory(new HashSet<>(fileExtensions), dir1, dir2, true); + } + + /** + * Returns a new Directory instance, using the specified random with contents copied from the + * provided directory. See {@link #newDirectory()} for more information. + */ + public static BaseDirectoryWrapper newDirectory(Random r, Directory d) throws IOException { + Directory impl = newDirectoryImpl(r, TEST_DIRECTORY); + for (String file : d.listAll()) { + if (file.startsWith(IndexFileNames.SEGMENTS) + || IndexFileNames.CODEC_FILE_PATTERN.matcher(file).matches()) { + impl.copyFrom(d, file, file, newIOContext(r)); + } + } + return wrapDirectory(r, impl, rarely(r), false); + } + + private static BaseDirectoryWrapper wrapDirectory( + Random random, Directory directory, boolean bare, boolean filesystem) { + // IOContext randomization might make NRTCachingDirectory make bad decisions, so avoid + // using it if the user requested a filesystem directory. + if (rarely(random) && !bare && filesystem == false) { + directory = new NRTCachingDirectory(directory, random.nextDouble(), random.nextDouble()); + } + + if (bare) { + BaseDirectoryWrapper base = new RawDirectoryWrapper(directory); + closeAfterSuite(new CloseableDirectory(base, suiteFailureMarker)); + return base; + } else { + MockDirectoryWrapper mock = new MockDirectoryWrapper(random, directory); + + mock.setThrottling(TEST_THROTTLING); + closeAfterSuite(new CloseableDirectory(mock, suiteFailureMarker)); + return mock; + } + } + + private static Directory newFSDirectoryImpl( + Class clazz, Path path, LockFactory lf) throws IOException { + FSDirectory d = null; + try { + d = CommandLineUtil.newFSDirectory(clazz, path, lf); + } catch (ReflectiveOperationException e) { + Rethrow.rethrow(e); + } + return d; + } + + static Directory newDirectoryImpl(Random random, String clazzName) { + return newDirectoryImpl(random, clazzName, FSLockFactory.getDefault()); + } + + static Directory newDirectoryImpl(Random random, String clazzName, LockFactory lf) { + if (clazzName.equals("random")) { + if (rarely(random)) { + clazzName = RandomPicks.randomFrom(random, CORE_DIRECTORIES); + } else if (rarely(random)) { + String clazzName1 = + rarely(random) + ? RandomPicks.randomFrom(random, CORE_DIRECTORIES) + : ByteBuffersDirectory.class.getName(); + String clazzName2 = + rarely(random) + ? RandomPicks.randomFrom(random, CORE_DIRECTORIES) + : ByteBuffersDirectory.class.getName(); + return newFileSwitchDirectory( + random, + newDirectoryImpl(random, clazzName1, lf), + newDirectoryImpl(random, clazzName2, lf)); + } else { + clazzName = ByteBuffersDirectory.class.getName(); + } + } + + try { + final Class clazz = CommandLineUtil.loadDirectoryClass(clazzName); + // If it is a FSDirectory type, try its ctor(Path) + if (FSDirectory.class.isAssignableFrom(clazz)) { + final Path dir = createTempDir("index-" + clazzName); + return newFSDirectoryImpl(clazz.asSubclass(FSDirectory.class), dir, lf); + } + + // See if it has a Path/LockFactory ctor even though it's not an + // FSDir subclass: + try { + Constructor pathCtor = + clazz.getConstructor(Path.class, LockFactory.class); + final Path dir = createTempDir("index"); + return pathCtor.newInstance(dir, lf); + } catch (NoSuchMethodException _) { + // Ignore + } + + // the remaining dirs are no longer filesystem based, so we must check that the + // passedLockFactory is not file based: + if (!(lf instanceof FSLockFactory)) { + // try ctor with only LockFactory + try { + return clazz.getConstructor(LockFactory.class).newInstance(lf); + } catch (NoSuchMethodException _) { + // Ignore + } + } + + // try empty ctor + return clazz.getConstructor().newInstance(); + } catch (Exception e) { + Rethrow.rethrow(e); + throw null; // dummy to prevent compiler failure + } + } + + public static IndexReader wrapReader(IndexReader r) throws IOException { + Random random = random(); + + for (int i = 0, c = random.nextInt(6) + 1; i < c; i++) { + switch (random.nextInt(5)) { + case 0: + // will create no FC insanity in atomic case, as ParallelLeafReader has own cache key: + if (VERBOSE) { + System.out.println( + "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" + + r + + " with ParallelLeaf/CompositeReader"); + } + r = + (r instanceof LeafReader) + ? new ParallelLeafReader((LeafReader) r) + : new ParallelCompositeReader((CompositeReader) r); + break; + case 1: + if (r instanceof LeafReader ar) { + final List allFields = new ArrayList<>(); + for (FieldInfo fi : ar.getFieldInfos()) { + allFields.add(fi.name); + } + Collections.shuffle(allFields, random); + final int end = allFields.isEmpty() ? 0 : random.nextInt(allFields.size()); + final Set fields = new HashSet<>(allFields.subList(0, end)); + // will create no FC insanity as ParallelLeafReader has own cache key: + if (VERBOSE) { + System.out.println( + "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" + + r + + " with ParallelLeafReader"); + } + r = + new ParallelLeafReader( + new FieldFilterLeafReader(ar, fields, false), + new FieldFilterLeafReader(ar, fields, true)); + } + break; + case 2: + // Häckidy-Hick-Hack: a standard Reader will cause FC insanity, so we use + // QueryUtils' reader with a fake cache key, so insanity checker cannot walk + // along our reader: + if (VERBOSE) { + System.out.println( + "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" + + r + + " with AssertingLeaf/DirectoryReader"); + } + if (r instanceof LeafReader) { + r = new AssertingLeafReader((LeafReader) r); + } else if (r instanceof DirectoryReader) { + r = new AssertingDirectoryReader((DirectoryReader) r); + } + break; + case 3: + if (VERBOSE) { + System.out.println( + "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" + + r + + " with MismatchedLeaf/Directory/CodecReader"); + } + if (r instanceof LeafReader) { + r = new MismatchedLeafReader((LeafReader) r, random); + } else if (r instanceof DirectoryReader) { + r = new MismatchedDirectoryReader((DirectoryReader) r, random); + } else if (r instanceof CodecReader) { + r = new MismatchedCodecReader((CodecReader) r, random); + } + break; + case 4: + if (VERBOSE) { + System.out.println( + "NOTE: LuceneTestCase.wrapReader: wrapping previous reader=" + + r + + " with MergingCodecReader"); + } + if (r instanceof CodecReader) { + r = new MergingCodecReader((CodecReader) r); + } else if (r instanceof DirectoryReader) { + boolean allLeavesAreCodecReaders = true; + for (LeafReaderContext ctx : r.leaves()) { + if (ctx.reader() instanceof CodecReader == false) { + allLeavesAreCodecReaders = false; + break; + } + } + if (allLeavesAreCodecReaders) { + r = new MergingDirectoryReaderWrapper((DirectoryReader) r); + } + } + break; + default: + fail("should not get here"); + } + } + + if (VERBOSE) { + System.out.println("wrapReader wrapped: " + r); + } + + return r; + } + + /** Sometimes wrap the IndexReader as slow, parallel or filter reader (or combinations of that) */ + public static IndexReader maybeWrapReader(IndexReader r) throws IOException { + if (rarely()) { + r = wrapReader(r); + } + return r; + } + + /** TODO: javadoc */ + public static IOContext newIOContext(Random random) { + return newIOContext(random, IOContext.DEFAULT); + } + + /** TODO: javadoc */ + public static IOContext newIOContext(Random random, IOContext oldContext) { + if (oldContext.hints().contains(ReadOnceHint.INSTANCE)) { + return oldContext; // just return as-is + } + final int randomNumDocs = random.nextInt(4192); + final int size = random.nextInt(512) * randomNumDocs; + if (oldContext.flushInfo() != null) { + // Always return at least the estimatedSegmentSize of + // the incoming IOContext: + return IOContext.flush( + new FlushInfo( + randomNumDocs, Math.max(oldContext.flushInfo().estimatedSegmentSize(), size))); + } else if (oldContext.mergeInfo() != null) { + // Always return at least the estimatedMergeBytes of + // the incoming IOContext: + return IOContext.merge( + new MergeInfo( + randomNumDocs, + Math.max(oldContext.mergeInfo().estimatedMergeBytes(), size), + random.nextBoolean(), + TestUtil.nextInt(random, 1, 100))); + } else { + // Make a totally random IOContext + final IOContext context; + switch (random.nextInt(3)) { + case 0: + context = IOContext.DEFAULT; + break; + case 1: + context = IOContext.merge(new MergeInfo(randomNumDocs, size, true, -1)); + break; + case 2: + context = IOContext.flush(new FlushInfo(randomNumDocs, size)); + break; + default: + context = IOContext.DEFAULT; + } + return context; + } + } + + private static final QueryCache DEFAULT_QUERY_CACHE = IndexSearcher.getDefaultQueryCache(); + private static final QueryCachingPolicy DEFAULT_CACHING_POLICY = + IndexSearcher.getDefaultQueryCachingPolicy(); + private static final List queryCacheList = new ArrayList<>(); + + @Before + public void overrideTestDefaultQueryCache() { + // Make sure each test method has its own cache + overrideDefaultQueryCache(); + } + + @BeforeClass + public static void overrideDefaultQueryCache() { + // we need to reset the query cache in an @BeforeClass so that tests that + // instantiate an IndexSearcher in an @BeforeClass method use a fresh new cache + LRUQueryCache queryCacheTemp = + new LRUQueryCache(10000, 1 << 25, _ -> true, Float.POSITIVE_INFINITY); + queryCacheList.add(queryCacheTemp); + IndexSearcher.setDefaultQueryCache(queryCacheTemp); + IndexSearcher.setDefaultQueryCachingPolicy(MAYBE_CACHE_POLICY); + } + + @AfterClass + public static void resetDefaultQueryCache() { + IndexSearcher.setDefaultQueryCache(DEFAULT_QUERY_CACHE); + IndexSearcher.setDefaultQueryCachingPolicy(DEFAULT_CACHING_POLICY); + for (int i = 0; i < queryCacheList.size(); i++) { + try { + queryCacheList.get(i).close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + @BeforeClass + public static void setupCPUCoreCount() { + // Randomize core count so CMS varies its dynamic defaults, and this also "fixes" core + // count from the master seed so it will always be the same on reproduce: + int numCores = TestUtil.nextInt(random(), 1, 4); + System.setProperty( + ConcurrentMergeScheduler.DEFAULT_CPU_CORE_COUNT_PROPERTY, Integer.toString(numCores)); + } + + @AfterClass + public static void restoreCPUCoreCount() { + System.clearProperty(ConcurrentMergeScheduler.DEFAULT_CPU_CORE_COUNT_PROPERTY); + } + + private static ExecutorService executor; + + @BeforeClass + public static void setUpExecutorService() { + int threads = TestUtil.nextInt(random(), 1, 2); + executor = + new ThreadPoolExecutor( + threads, + threads, + 0L, + TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), + new NamedThreadFactory("LuceneTestCase")); + // uncomment to intensify LUCENE-3840 + // executor.prestartAllCoreThreads(); + if (VERBOSE) { + System.out.println("NOTE: Created shared ExecutorService with " + threads + " threads"); + } + } + + @AfterClass + public static void shutdownExecutorService() { + TestUtil.shutdownExecutorService(executor); + executor = null; + } + + /** Create a new searcher over the reader. This searcher might randomly use threads. */ + public static IndexSearcher newSearcher(IndexReader r) { + return newSearcher(r, true); + } + + /** Create a new searcher over the reader. This searcher might randomly use threads. */ + public static IndexSearcher newSearcher(IndexReader r, boolean maybeWrap) { + return newSearcher(r, maybeWrap, true); + } + + /** + * Create a new searcher over the reader. This searcher might randomly use threads. if + * maybeWrap is true, this searcher might wrap the reader with one that returns null for + * getSequentialSubReaders. If wrapWithAssertions is true, this searcher might be an + * {@link AssertingIndexSearcher} instance. + */ + public static IndexSearcher newSearcher( + IndexReader r, boolean maybeWrap, boolean wrapWithAssertions) { + return newSearcher(r, maybeWrap, wrapWithAssertions, random().nextBoolean()); + } + + /** + * Create a new searcher over the reader. If + * maybeWrap is true, this searcher might wrap the reader with one that returns null for + * getSequentialSubReaders. If wrapWithAssertions is true, this searcher might be an + * {@link AssertingIndexSearcher} instance. The searcher will use threads if useThreads + * is set to true. + */ + public static IndexSearcher newSearcher( + IndexReader r, boolean maybeWrap, boolean wrapWithAssertions, boolean useThreads) { + if (useThreads) { + return newSearcher(r, maybeWrap, wrapWithAssertions, Concurrency.INTRA_SEGMENT); + } + return newSearcher(r, maybeWrap, wrapWithAssertions, Concurrency.NONE); + } + + /** What level of concurrency is supported by the searcher being created */ + public enum Concurrency { + /** No concurrency, meaning an executor won't be provided to the searcher */ + NONE, + /** + * Inter-segment concurrency, meaning an executor will be provided to the searcher and slices + * will be randomly created to concurrently search entire segments + */ + INTER_SEGMENT, + /** + * Intra-segment concurrency, meaning an executor will be provided to the searcher and slices + * will be randomly created to concurrently search segment partitions + */ + INTRA_SEGMENT + } + + public static IndexSearcher newSearcher( + IndexReader r, boolean maybeWrap, boolean wrapWithAssertions, Concurrency concurrency) { + Random random = random(); + if (concurrency == Concurrency.NONE) { + if (maybeWrap) { + try { + r = maybeWrapReader(r); + } catch (IOException e) { + Rethrow.rethrow(e); + } + } + // TODO: this whole check is a coverage hack, we should move it to tests for various + // filterreaders. + // ultimately whatever you do will be checkIndex'd at the end anyway. + if (random.nextInt(500) == 0 && r instanceof LeafReader) { + // TODO: not useful to check DirectoryReader (redundant with checkindex) + // but maybe sometimes run this on the other crazy readers maybeWrapReader creates? + try { + TestUtil.checkReader(r); + } catch (IOException e) { + Rethrow.rethrow(e); + } + } + final IndexSearcher ret; + if (wrapWithAssertions) { + ret = + random.nextBoolean() + ? new AssertingIndexSearcher(random, r) + : new AssertingIndexSearcher(random, r.getContext()); + } else { + ret = random.nextBoolean() ? new IndexSearcher(r) : new IndexSearcher(r.getContext()); + } + ret.setSimilarity(getTestFrameworkInfra().getClassEnv().similarity); + return ret; + } else { + final ExecutorService ex; + if (random.nextBoolean()) { + ex = null; + } else { + ex = executor; + if (VERBOSE) { + System.out.println("NOTE: newSearcher using shared ExecutorService"); + } + } + IndexSearcher ret; + int maxDocPerSlice = random.nextBoolean() ? 1 : 1 + random.nextInt(1000); + int maxSegmentsPerSlice = random.nextBoolean() ? 1 : 1 + random.nextInt(10); + if (wrapWithAssertions) { + if (random.nextBoolean()) { + ret = + new AssertingIndexSearcher(random, r, ex) { + @Override + protected LeafSlice[] slices(List leaves) { + return LuceneTestCaseParent.slices( + leaves, maxDocPerSlice, maxSegmentsPerSlice, concurrency); + } + }; + } else { + ret = + new AssertingIndexSearcher(random, r.getContext(), ex) { + @Override + protected LeafSlice[] slices(List leaves) { + return LuceneTestCaseParent.slices( + leaves, maxDocPerSlice, maxSegmentsPerSlice, concurrency); + } + }; + } + } else { + ret = + new IndexSearcher(r, ex) { + @Override + protected LeafSlice[] slices(List leaves) { + return LuceneTestCaseParent.slices( + leaves, maxDocPerSlice, maxSegmentsPerSlice, concurrency); + } + }; + } + ret.setSimilarity(getTestFrameworkInfra().getClassEnv().similarity); + ret.setQueryCachingPolicy(MAYBE_CACHE_POLICY); + if (random().nextBoolean()) { + ret.setTimeout(() -> false); + } + return ret; + } + } + + /** + * Creates an empty, temporary folder (when the name of the folder is of no importance). + * + * @see #createTempDir(String) + */ + public static Path createTempDir() { + return createTempDir("tempDir"); + } + + /** + * Creates an empty temporary file. + * + * @see #createTempFile(String, String) + */ + public static Path createTempFile() throws IOException { + return createTempFile("tempFile", ".tmp"); + } + + /** Ensures that the MergePolicy has sane values for tests that test with lots of documents. */ + protected static IndexWriterConfig ensureSaneIWCOnNightly(IndexWriterConfig conf) { + if (LuceneTestCase.TEST_NIGHTLY) { + // newIWConfig makes smallish max seg size, which + // results in tons and tons of segments for this test + // when run nightly: + MergePolicy mp = conf.getMergePolicy(); + if (mp instanceof TieredMergePolicy) { + ((TieredMergePolicy) mp).setMaxMergedSegmentMB(5000.); + } else if (mp instanceof LogByteSizeMergePolicy) { + ((LogByteSizeMergePolicy) mp).setMaxMergeMB(1000.); + } else if (mp instanceof LogMergePolicy) { + ((LogMergePolicy) mp).setMaxMergeDocs(100000); + } + // when running nightly, merging can still have crazy parameters, + // and might use many per-field codecs. turn on CFS for IW flushes + // and ensure CFS ratio is reasonable to keep it contained. + conf.setUseCompoundFile(true); + } + return conf; + } + + private static boolean supportsVectorEncoding( + KnnVectorsFormat format, VectorEncoding vectorEncoding) { + if (format instanceof HnswBitVectorsFormat) { + // special case, this only supports BYTE + return vectorEncoding == VectorEncoding.BYTE; + } + return true; + } + + private static boolean supportsVectorSearch(KnnVectorsFormat format) { + return (format instanceof FlatVectorsFormat) == false; + } + + protected static KnnVectorsFormat randomVectorFormat(VectorEncoding vectorEncoding) { + List availableFormats = + KnnVectorsFormat.availableKnnVectorsFormats().stream() + .map(KnnVectorsFormat::forName) + .filter(format -> supportsVectorEncoding(format, vectorEncoding)) + .filter(format -> supportsVectorSearch(format)) + .toList(); + return RandomPicks.randomFrom(random(), availableFormats); + } + + /** + * This is a test merge scheduler that will always use the intra merge executor to ensure we test + * it. + */ + private static class IntraMergeConcurrentMergeScheduler extends ConcurrentMergeScheduler { + @Override + public Executor getIntraMergeExecutor(MergePolicy.OneMerge merge) { + assert intraMergeExecutor != null : "scaledExecutor is not initialized"; + // Always do the intra merge executor to ensure we test it + return intraMergeExecutor; + } + } + + /** + * Creates an empty, temporary folder with the given name prefix. + * + *

The folder will be automatically removed after the test class completes successfully. The + * test should close any file handles that would prevent the folder from being removed. + */ + public static Path createTempDir(String prefix) { + return getTestFrameworkInfra().getTempFilesSupplier().createTempDir(prefix); + } + + /** + * Creates an empty file with the given prefix and suffix. + * + *

The file will be automatically removed after the test class completes successfully. The test + * should close any file handles that would prevent the folder from being removed. + */ + public static Path createTempFile(String prefix, String suffix) throws IOException { + return getTestFrameworkInfra().getTempFilesSupplier().createTempFile(prefix, suffix); + } + // // TODO: to remove from here? // @@ -2181,6 +2933,4 @@ public static Locale localeForLanguageTag(String languageTag) { /** Suite failure marker (any error in the test or suite scope). */ @SuppressWarnings("NonFinalStaticField") protected static TestRuleMarkFailure suiteFailureMarker; - - static TestRuleTemporaryFilesCleanup tempFilesCleanupRule; } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java similarity index 97% rename from lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java rename to lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java index 8d42720865a9..e6586d87a2cd 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleTemporaryFilesCleanup.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java @@ -16,7 +16,6 @@ */ package org.apache.lucene.tests.util; -import com.carrotsearch.randomizedtesting.rules.TestRuleAdapter; import java.io.IOException; import java.net.URI; import java.nio.file.FileSystem; @@ -51,7 +50,7 @@ * @see LuceneTestCase#createTempDir() * @see LuceneTestCase#createTempFile() */ -final class TestRuleTemporaryFilesCleanup extends TestRuleAdapter { +final class TemporaryFilesSupplier implements BeforeAfterCallback { private final Supplier randomSupplier; private final Supplier> targetClassSupplier; @@ -77,7 +76,7 @@ final class TestRuleTemporaryFilesCleanup extends TestRuleAdapter { */ private static final List cleanupQueue = new ArrayList<>(); - public TestRuleTemporaryFilesCleanup( + public TemporaryFilesSupplier( TestRuleMarkFailure failureMarker, Supplier randomSupplier, Supplier> targetClassSupplier) { @@ -101,9 +100,7 @@ void registerToRemoveAfterSuite(Path f) { } @Override - protected void before() throws Throwable { - super.before(); - + public void before() throws Exception { assert tempDirBase == null; fileSystem = initializeFileSystem(); javaTempDir = initializeJavaTempDir(); @@ -189,7 +186,7 @@ private Path initializeJavaTempDir() throws IOException { } @Override - protected void afterAlways(List errors) throws Throwable { + public void after() throws Exception { // Drain cleanup queue and clear it. final Path[] everything; final String tempDirBasePath; From 4634b801d84498db0dbaaabec36b5ea289fc19e3 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 24 Apr 2026 10:09:23 +0200 Subject: [PATCH 22/68] Add todos. --- .../lucene/tests/util/LuceneTestCaseJupiter.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 20b69d35e7fb..2cd7bd0142f3 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -46,6 +46,20 @@ import org.junit.platform.commons.support.ModifierSupport; import org.junit.platform.commons.support.ReflectionSupport; +/* +TODOs. + +- pick a smaller module and move (some?) of the tests to jupiter. Ensure both frameworks can coexist (jupiter and +vintage engine running both). +- add tests of the LuceneTestCaseJupiter infrastructure (if what was previously implemented +as rules in LuceneTestCase still provides the same functionality). Nested classes should be perhaps +excluded from discovery entirely (unless they're really needed/loaded?). +- resign from using GlobalStateSupport and move it to this class itself? +- add a check ensuring junit jupiter runs in single-thread mode (unfortunately this can't be +changed, at least for now). +- add all remaining class and test rules from LuceneTestCase; this is now the minimum subset. + */ + /// Base class for all Lucene unit tests (JUnit5/ Jupiter variant). /// /// ## Class and instance setup From 9f4259032b53a55ba060a117d88e699f30dfc97a Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 24 Apr 2026 13:31:02 +0200 Subject: [PATCH 23/68] Cleanups. --- .../complexPhrase/TestComplexPhraseQuery.java | 26 +++-- .../apache/lucene/tests/util/FieldToType.java | 96 +++++++++++++++++++ .../lucene/tests/util/LuceneTestCase.java | 6 +- .../tests/util/LuceneTestCaseJupiter.java | 24 +---- .../tests/util/LuceneTestCaseParent.java | 89 ++--------------- 5 files changed, 127 insertions(+), 114 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/FieldToType.java diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java index 3e6c12d18978..9173ce8955eb 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java @@ -37,9 +37,12 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.analysis.MockSynonymAnalyzer; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class TestComplexPhraseQuery extends LuceneTestCase { +public class TestComplexPhraseQuery extends LuceneTestCaseJupiter { Directory rd; Analyzer analyzer; DocData[] docsContent = { @@ -60,6 +63,7 @@ public class TestComplexPhraseQuery extends LuceneTestCase { boolean inOrder = true; + @Test public void testComplexPhrases() throws Exception { checkMatches("\"john smith\"", "1"); // Simple multi-term still works checkMatches("\"j* smyth~\"", "1,2"); // wildcards and fuzzies are OK in @@ -85,6 +89,7 @@ public void testComplexPhrases() throws Exception { checkBadQuery("\"jo* \"smith\" \""); // phrases inside phrases is bad } + @Test public void testSingleTermPhrase() throws Exception { checkMatches("\"joh*\"", "1,2,3,5"); checkMatches("\"joh~\"", "1,3,5"); @@ -94,6 +99,7 @@ public void testSingleTermPhrase() throws Exception { checkMatches("+\"j*hn\" +\"sm*h\"", "1,3"); } + @Test public void testSynonyms() throws Exception { checkMatches("\"dogs\"", "8"); MockSynonymAnalyzer synonym = new MockSynonymAnalyzer(); @@ -109,6 +115,7 @@ public void testSynonyms() throws Exception { checkMatches("\"dog cigar*\"~2", "7", synonym); } + @Test public void testUnOrderedProximitySearches() throws Exception { inOrder = true; @@ -159,6 +166,7 @@ private void checkMatches(String qString, String expectedVals, Analyzer anAnalyz assertEquals(qString + " missing some matches ", 0, expecteds.size()); } + @Test public void testFieldedQuery() throws Exception { checkMatches("name:\"john smith\"", "1"); checkMatches("name:\"j* smyth~\"", "1,2"); @@ -171,6 +179,7 @@ public void testFieldedQuery() throws Exception { checkMatches("name:\"john smith\"~2 AND role:designer AND id:3", "3"); } + @Test public void testToStringContainsSlop() throws Exception { ComplexPhraseQueryParser qp = new ComplexPhraseQueryParser("", analyzer); int slop = random().nextInt(31) + 1; @@ -186,6 +195,7 @@ public void testToStringContainsSlop() throws Exception { assertEquals("Don't show implicit slop of zero", q.toString(), string); } + @Test public void testHashcodeEquals() throws Exception { ComplexPhraseQueryParser qp = new ComplexPhraseQueryParser(defaultFieldName, analyzer); qp.setInOrder(true); @@ -213,6 +223,7 @@ public void testHashcodeEquals() throws Exception { assertTrue(!q2.equals(q)); } + @Test public void testBoosts() throws Exception { // top-level boosts should be preserved, interior boosts are ignored as they don't apply to @@ -234,10 +245,8 @@ public void testBoosts() throws Exception { assertEquals(expected, actual); } - @Override - public void setUp() throws Exception { - super.setUp(); - + @BeforeEach + void setUp() throws Exception { analyzer = new MockAnalyzer(random()); rd = newDirectory(); IndexWriter w = new IndexWriter(rd, newIndexWriterConfig(analyzer)); @@ -253,11 +262,10 @@ public void setUp() throws Exception { searcher = newSearcher(reader); } - @Override - public void tearDown() throws Exception { + @AfterEach + void tearDown() throws Exception { reader.close(); rd.close(); - super.tearDown(); } static class DocData { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/FieldToType.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/FieldToType.java new file mode 100644 index 000000000000..a7281b176c51 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/FieldToType.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.tests.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.index.IndexOptions; +import org.apache.lucene.util.BytesRef; + +class FieldToType implements BeforeAfterCallback { + private final Map fieldToType = new HashMap<>(); + + @Override + public synchronized void after() throws Exception { + fieldToType.clear(); + } + + private static Field createField(String name, Object value, FieldType fieldType) { + if (value instanceof String) { + return new Field(name, (String) value, fieldType); + } else if (value instanceof BytesRef) { + return new Field(name, (BytesRef) value, fieldType); + } else { + throw new IllegalArgumentException("value must be String or BytesRef"); + } + } + + public synchronized Field newField(Random random, String name, Object value, FieldType type) { + FieldType prevType = fieldToType.get(name); + + if (prevType != null) { + // always use the same fieldType for the same field name + return createField(name, value, prevType); + } + + // TODO: once all core & test codecs can index + // offsets, sometimes randomly turn on offsets if we are + // already indexing positions... + + FieldType newType = new FieldType(type); + if (!newType.stored() && random.nextBoolean()) { + newType.setStored(true); // randomly store it + } + if (newType.indexOptions() != IndexOptions.NONE) { + if (!newType.storeTermVectors() && random.nextBoolean()) { + newType.setStoreTermVectors(true); + if (!newType.storeTermVectorPositions()) { + newType.setStoreTermVectorPositions(random.nextBoolean()); + if (newType.storeTermVectorPositions()) { + if (!newType.storeTermVectorPayloads()) { + newType.setStoreTermVectorPayloads(random.nextBoolean()); + } + } + } + // Check for strings as offsets are disallowed on binary fields + if (value instanceof String && !newType.storeTermVectorOffsets()) { + newType.setStoreTermVectorOffsets(random.nextBoolean()); + } + + if (LuceneTestCaseParent.VERBOSE) { + System.out.println("NOTE: LuceneTestCase: upgrade name=" + name + " type=" + newType); + } + } + } + newType.freeze(); + fieldToType.put(name, newType); + + // TODO: we need to do this, but smarter, ie, most of + // the time we set the same value for a given field but + // sometimes (rarely) we change it up: + /* + if (newType.omitNorms()) { + newType.setOmitNorms(random.nextBoolean()); + } + */ + + return createField(name, value, newType); + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index d7b2b6093586..53872bfd0218 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -508,22 +508,20 @@ public void before() { /** For subclasses to override. Overrides must call {@code super.setUp()}. */ @Before - @Override public void setUp() throws Exception { - super.setUp(); randomCalls.set(0); parentChainCallRule.setupCalled = true; } /** For subclasses to override. Overrides must call {@code super.tearDown()}. */ @After - @Override public void tearDown() throws Exception { - super.tearDown(); parentChainCallRule.teardownCalled = true; // Test is supposed to call this itself, but we do this defensively in case it forgot: restoreIndexWriterMaxDocs(); + + fieldToType.after(); } // ----------------------------------------------------------------- diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 2cd7bd0142f3..8b29a3434576 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -27,10 +27,8 @@ import java.util.stream.Stream; import org.apache.lucene.util.Constants; import org.jspecify.annotations.Nullable; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.Timeout; @@ -68,7 +66,7 @@ - add all remaining class and test rules from LuceneTestCase; this is now the mi /// annotated with [org.junit.jupiter.api.BeforeAll] and [org.junit.jupiter.api.AfterAll]. /// **Do not use static initializers (including complex final field initializers).** /// -/// For instance-level setup, use [BeforeEach] and +/// For instance-level setup, use [org.junit.jupiter.api.BeforeEach] and /// [AfterEach] annotated methods. /// /// ## Specifying test cases @@ -173,8 +171,10 @@ static void setupClass(TestInfo testInfo) throws Throwable { newRule.before(); } - @AfterAll - static void teardownClass() throws Throwable {} + @AfterEach + void afterEach() throws Exception { + fieldToType.after(); + } // // Custom assertion methods. @@ -228,20 +228,6 @@ public void allTestMethodsAreAnnotated() { } } - /** Use methods marked with jupiter's {@link BeforeEach} instead. */ - @Override - @BeforeEach - protected final void setUp() throws Exception { - super.setUp(); - } - - /** Use methods marked with jupiter's {@link AfterEach} instead. */ - @Override - @AfterEach - protected final void tearDown() throws Exception { - super.tearDown(); - } - public static T expectThrows( Class expectedType, LuceneTestCase.ThrowingRunnable runnable) { return LuceneTestCase.expectThrows(expectedType, runnable); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index fce22819a454..6e51bbdf2ada 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -83,7 +83,6 @@ import org.apache.lucene.index.FieldInfos; import org.apache.lucene.index.Fields; import org.apache.lucene.index.IndexFileNames; -import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -370,14 +369,6 @@ protected static TestFrameworkInfra getTestFrameworkInfra() { testFrameworkInfra.get(), "Expected test framework not to be null."); } - protected void setUp() throws Exception {} - - protected void tearDown() throws Exception { - synchronized (fieldToType) { - fieldToType.clear(); - } - } - // ----------------------------------------------------------------- // Truly immutable fields and constants, initialized once and valid // for all suites ever since. @@ -2098,80 +2089,13 @@ public static Field newField(String name, String value, FieldType type) { return newField(random(), name, value, type); } - private static final Map fieldToType = new HashMap<>(); - - // TODO: if we can pull out the "make term vector options - // consistent across all instances of the same field name" - // write-once schema sort of helper class then we can - // remove the sync here. We can also fold the random - // "enable norms" (now commented out, below) into that: public static Field newField(Random random, String name, Object value, FieldType type) { - - // Defeat any consumers that illegally rely on interned - // strings (we removed this from Lucene a while back): - name = new String(name); - - synchronized (fieldToType) { - FieldType prevType = fieldToType.get(name); - - if (prevType != null) { - // always use the same fieldType for the same field name - return createField(name, value, prevType); - } - - // TODO: once all core & test codecs can index - // offsets, sometimes randomly turn on offsets if we are - // already indexing positions... - - FieldType newType = new FieldType(type); - if (!newType.stored() && random.nextBoolean()) { - newType.setStored(true); // randomly store it - } - if (newType.indexOptions() != IndexOptions.NONE) { - if (!newType.storeTermVectors() && random.nextBoolean()) { - newType.setStoreTermVectors(true); - if (!newType.storeTermVectorPositions()) { - newType.setStoreTermVectorPositions(random.nextBoolean()); - if (newType.storeTermVectorPositions()) { - if (!newType.storeTermVectorPayloads()) { - newType.setStoreTermVectorPayloads(random.nextBoolean()); - } - } - } - // Check for strings as offsets are disallowed on binary fields - if (value instanceof String && !newType.storeTermVectorOffsets()) { - newType.setStoreTermVectorOffsets(random.nextBoolean()); - } - - if (VERBOSE) { - System.out.println("NOTE: LuceneTestCase: upgrade name=" + name + " type=" + newType); - } - } - } - newType.freeze(); - fieldToType.put(name, newType); - - // TODO: we need to do this, but smarter, ie, most of - // the time we set the same value for a given field but - // sometimes (rarely) we change it up: - /* - if (newType.omitNorms()) { - newType.setOmitNorms(random.nextBoolean()); - } - */ - - return createField(name, value, newType); - } - } - - private static Field createField(String name, Object value, FieldType fieldType) { - if (value instanceof String) { - return new Field(name, (String) value, fieldType); - } else if (value instanceof BytesRef) { - return new Field(name, (BytesRef) value, fieldType); - } else { - throw new IllegalArgumentException("value must be String or BytesRef"); - } + // TODO: if we can pull out the "make term vector options + // consistent across all instances of the same field name" + // write-once schema sort of helper class then we can + // remove the sync here. We can also fold the random + // "enable norms" (now commented out, below) into that: + return fieldToType.newField(random, name, value, type); } private static final String[] availableLanguageTags = @@ -2929,6 +2853,7 @@ public static Path createTempFile(String prefix, String suffix) throws IOExcepti // // TODO: to remove from here? // + static FieldToType fieldToType = new FieldToType(); /** Suite failure marker (any error in the test or suite scope). */ @SuppressWarnings("NonFinalStaticField") From 2a95f10e16fefdfcd97a7f38abcf5992db260298 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 24 Apr 2026 20:41:02 +0200 Subject: [PATCH 24/68] Simplify. --- .../lucene/tests/util/GlobalStateSupport.java | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java index 7d12f8df9961..03aff3d7572e 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java @@ -43,20 +43,6 @@ public final class GlobalStateSupport private final ExtensionContext.Namespace NS = ExtensionContext.Namespace.create(getClass().getName()); - private static final class State { - private LuceneTestCaseParent.TestFrameworkInfra frameworkInfra; - - void reset() { - frameworkInfra = null; - } - - void initialize() { - if (frameworkInfra != null) { - throw new RuntimeException(); - } - } - } - private static final class JupiterTestFrameworkInfra implements LuceneTestCaseParent.TestFrameworkInfra { private final ConcurrentHashMap perThreadRandoms = new ConcurrentHashMap<>(); @@ -153,8 +139,10 @@ public void beforeAll() throws Exception { @Override public void beforeAll(ExtensionContext context) throws Exception { - State state = getState(context); - state.initialize(); + var store = context.getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS); + if (store.get(JupiterTestFrameworkInfra.class) != null) { + throw new RuntimeException(); + } // touch LuceneTestCase to trigger static initializers. LuceneTestCase.ensureInitialized(); @@ -162,7 +150,7 @@ public void beforeAll(ExtensionContext context) throws Exception { var frameworkInfra = new JupiterTestFrameworkInfra( context.getRequiredTestClass(), getRandomSupplier(context.getExecutableInvoker())); - state.frameworkInfra = frameworkInfra; + store.put(JupiterTestFrameworkInfra.class, frameworkInfra); LuceneTestCaseParent.setTestFrameworkInfra(null, frameworkInfra); frameworkInfra.beforeAll(); @@ -170,24 +158,26 @@ public void beforeAll(ExtensionContext context) throws Exception { @Override public void afterEach(ExtensionContext context) throws Exception { - getState(context).frameworkInfra.afterEach(); + getFrameworkInfra(context).afterEach(); } @Override public void afterAll(ExtensionContext context) throws Exception { - var state = getState(context); + var frameworkInfra = getFrameworkInfra(context); try { - state.frameworkInfra.afterAll(); + frameworkInfra.afterAll(); } finally { - LuceneTestCaseParent.setTestFrameworkInfra(state.frameworkInfra, null); - state.reset(); + LuceneTestCaseParent.setTestFrameworkInfra(frameworkInfra, null); + context + .getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS) + .remove(JupiterTestFrameworkInfra.class); } } - private State getState(ExtensionContext context) { + private JupiterTestFrameworkInfra getFrameworkInfra(ExtensionContext context) { return context .getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS) - .computeIfAbsent(State.class); + .get(JupiterTestFrameworkInfra.class, JupiterTestFrameworkInfra.class); } // This trick is needed to get the Supplier injected by a parameter resolved From a1e8c9fe5a6bdfd37be021a6f7694712a19b8a12 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 24 Apr 2026 20:51:53 +0200 Subject: [PATCH 25/68] Inline what was previously an extension into LuceneTestCaseJupiter to simplify the code. --- .../lucene/tests/util/GlobalStateSupport.java | 202 ------------------ .../tests/util/LuceneTestCaseJupiter.java | 142 ++++++++++-- 2 files changed, 127 insertions(+), 217 deletions(-) delete mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java deleted file mode 100644 index 03aff3d7572e..000000000000 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/GlobalStateSupport.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.lucene.tests.util; - -import java.io.Closeable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; -import java.util.stream.Stream; -import org.apache.lucene.util.IOUtils; -import org.junit.jupiter.api.extension.AfterAllCallback; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeAllCallback; -import org.junit.jupiter.api.extension.ExecutableInvoker; -import org.junit.jupiter.api.extension.ExtensionContext; - -/** - * Simulate global state for backward compatibility with static methods from {@link LuceneTestCase} - * that are used all over the place. - */ -public final class GlobalStateSupport - implements BeforeAllCallback, AfterAllCallback, AfterEachCallback { - private final ExtensionContext.Namespace NS = - ExtensionContext.Namespace.create(getClass().getName()); - - private static final class JupiterTestFrameworkInfra - implements LuceneTestCaseParent.TestFrameworkInfra { - private final ConcurrentHashMap perThreadRandoms = new ConcurrentHashMap<>(); - - private final List closeAfterTest = new ArrayList<>(); - private final List closeAfterSuite = new ArrayList<>(); - - final Supplier rnd; - final SetupAndRestoreStaticEnv classEnvRule; - - private final TemporaryFilesSupplier tempFilesSupplier; - private final TestRuleMarkFailure failureMarker; - - JupiterTestFrameworkInfra(Class requiredTestClass, Supplier randomSupplier) { - this.rnd = randomSupplier; - this.classEnvRule = - new SetupAndRestoreStaticEnv( - this::threadRandom, () -> Objects.requireNonNull(requiredTestClass)); - this.failureMarker = new TestRuleMarkFailure(); - this.tempFilesSupplier = - new TemporaryFilesSupplier( - failureMarker, this::threadRandom, () -> Objects.requireNonNull(requiredTestClass)); - } - - @Override - public Random threadRandom() { - return perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get()); - } - - @Override - public T closeAfterTest(T resource) { - synchronized (this) { - closeAfterTest.add(resource); - } - return resource; - } - - @Override - public T closeAfterClass(T resource) { - synchronized (this) { - closeAfterSuite.add(resource); - } - return resource; - } - - @Override - public void afterEach() throws IOException { - synchronized (this) { - IOUtils.close(closeAfterTest); - closeAfterTest.clear(); - } - } - - @Override - public void afterAll() throws IOException { - synchronized (this) { - IOUtils.close( - Stream.of( - List.of( - () -> { - try { - tempFilesSupplier.after(); - classEnvRule.after(); - } catch (Exception e) { - throw new RuntimeException(e); - } - }), - closeAfterTest, - closeAfterSuite, - perThreadRandoms.values()) - .flatMap(Collection::stream) - .filter(v -> v instanceof Closeable) - .map(v -> (Closeable) v) - .toList()); - } - } - - @Override - public SetupAndRestoreStaticEnv getClassEnv() { - return classEnvRule; - } - - @Override - public TemporaryFilesSupplier getTempFilesSupplier() { - return tempFilesSupplier; - } - - public void beforeAll() throws Exception { - classEnvRule.before(); - failureMarker.reset(); - tempFilesSupplier.before(); - } - } - - @Override - public void beforeAll(ExtensionContext context) throws Exception { - var store = context.getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS); - if (store.get(JupiterTestFrameworkInfra.class) != null) { - throw new RuntimeException(); - } - - // touch LuceneTestCase to trigger static initializers. - LuceneTestCase.ensureInitialized(); - - var frameworkInfra = - new JupiterTestFrameworkInfra( - context.getRequiredTestClass(), getRandomSupplier(context.getExecutableInvoker())); - store.put(JupiterTestFrameworkInfra.class, frameworkInfra); - - LuceneTestCaseParent.setTestFrameworkInfra(null, frameworkInfra); - frameworkInfra.beforeAll(); - } - - @Override - public void afterEach(ExtensionContext context) throws Exception { - getFrameworkInfra(context).afterEach(); - } - - @Override - public void afterAll(ExtensionContext context) throws Exception { - var frameworkInfra = getFrameworkInfra(context); - try { - frameworkInfra.afterAll(); - } finally { - LuceneTestCaseParent.setTestFrameworkInfra(frameworkInfra, null); - context - .getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS) - .remove(JupiterTestFrameworkInfra.class); - } - } - - private JupiterTestFrameworkInfra getFrameworkInfra(ExtensionContext context) { - return context - .getStore(ExtensionContext.StoreScope.EXECUTION_REQUEST, NS) - .get(JupiterTestFrameworkInfra.class, JupiterTestFrameworkInfra.class); - } - - // This trick is needed to get the Supplier injected by a parameter resolved - // of the randomized testing framework. - private Supplier getRandomSupplier(ExecutableInvoker executableInvoker) throws Exception { - var hack = - new Object() { - @SuppressWarnings("unused") - public Supplier captureParameter(Supplier rnd) { - return rnd; - } - }; - - @SuppressWarnings("unchecked") - Supplier rnd = - (Supplier) - Objects.requireNonNull( - executableInvoker.invoke( - hack.getClass().getMethod("captureParameter", Supplier.class), hack)); - return rnd; - } -} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 8b29a3434576..6744785c3448 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -20,19 +20,28 @@ import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; import com.carrotsearch.randomizedtesting.jupiter.Randomized; import com.carrotsearch.randomizedtesting.jupiter.SystemThreadFilter; +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.lucene.util.Constants; +import org.apache.lucene.util.IOUtils; import org.jspecify.annotations.Nullable; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.Timeout; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.Extension; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.RegisterExtension; @@ -52,7 +61,6 @@ - add tests of the LuceneTestCaseJupiter infrastructure (if what was previously implemented as rules in LuceneTestCase still provides the same functionality). Nested classes should be perhaps excluded from discovery entirely (unless they're really needed/loaded?). -- resign from using GlobalStateSupport and move it to this class itself? - add a check ensuring junit jupiter runs in single-thread mode (unfortunately this can't be changed, at least for now). - add all remaining class and test rules from LuceneTestCase; this is now the minimum subset. @@ -110,7 +118,6 @@ - add all remaining class and test rules from LuceneTestCase; this is now the mi @Execution( value = ExecutionMode.SAME_THREAD, reason = "single-threaded for backward compatibility.") -@ExtendWith({GlobalStateSupport.class}) public abstract non-sealed class LuceneTestCaseJupiter extends LuceneTestCaseParent { /** * This predicate should return {@code true} for threads that should be ignored in {@linkplain @@ -143,39 +150,144 @@ public boolean test(Thread t) { } } - // TODO: this should be in use (marker when tests failed). - static TestRuleMarkFailure failureMarker = new TestRuleMarkFailure(); + private static final class JupiterTestFrameworkInfra + implements LuceneTestCaseParent.TestFrameworkInfra { + private final ConcurrentHashMap perThreadRandoms = new ConcurrentHashMap<>(); + + private final List closeAfterTest = new ArrayList<>(); + private final List closeAfterSuite = new ArrayList<>(); + + final Supplier rnd; + final SetupAndRestoreStaticEnv classEnvRule; + + private final TemporaryFilesSupplier tempFilesSupplier; + private final TestRuleMarkFailure failureMarker; + + JupiterTestFrameworkInfra(Class requiredTestClass, Supplier randomSupplier) { + this.rnd = randomSupplier; + this.classEnvRule = + new SetupAndRestoreStaticEnv( + this::threadRandom, () -> Objects.requireNonNull(requiredTestClass)); + this.failureMarker = new TestRuleMarkFailure(); + this.tempFilesSupplier = + new TemporaryFilesSupplier( + failureMarker, this::threadRandom, () -> Objects.requireNonNull(requiredTestClass)); + } + + @Override + public Random threadRandom() { + return perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get()); + } + + @Override + public T closeAfterTest(T resource) { + synchronized (this) { + closeAfterTest.add(resource); + } + return resource; + } + + @Override + public T closeAfterClass(T resource) { + synchronized (this) { + closeAfterSuite.add(resource); + } + return resource; + } + + @Override + public void afterEach() throws IOException { + synchronized (this) { + IOUtils.close(closeAfterTest); + closeAfterTest.clear(); + } + } + + @Override + public void afterAll() throws IOException { + synchronized (this) { + IOUtils.close( + Stream.of( + List.of( + () -> { + try { + tempFilesSupplier.after(); + classEnvRule.after(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }), + closeAfterTest, + closeAfterSuite, + perThreadRandoms.values()) + .flatMap(Collection::stream) + .filter(v -> v instanceof Closeable) + .map(v -> (Closeable) v) + .toList()); + } + } + + @Override + public SetupAndRestoreStaticEnv getClassEnv() { + return classEnvRule; + } + + @Override + public TemporaryFilesSupplier getTempFilesSupplier() { + return tempFilesSupplier; + } + + void beforeAll() throws Exception { + classEnvRule.before(); + failureMarker.reset(); + tempFilesSupplier.before(); + } + } + + private static JupiterTestFrameworkInfra frameworkInfra; @RegisterExtension static Extension failureListener = new TestWatcher() { @Override public void testAborted(ExtensionContext context, @Nullable Throwable cause) { - failureMarker.markFailed(); + frameworkInfra.failureMarker.markFailed(); } @Override public void testFailed(ExtensionContext context, @Nullable Throwable cause) { - failureMarker.markFailed(); + frameworkInfra.failureMarker.markFailed(); } }; @BeforeAll - static void setupClass(TestInfo testInfo) throws Throwable { - var newRule = - new TemporaryFilesSupplier( - failureMarker, - LuceneTestCaseJupiter::random, - () -> testInfo.getTestClass().orElseThrow()); - failureMarker.reset(); - newRule.before(); + static void setupClass(Supplier randomSupplier, TestInfo testInfo) throws Exception { + // touch LuceneTestCase to trigger static initializers. + LuceneTestCase.ensureInitialized(); + + frameworkInfra = + new JupiterTestFrameworkInfra(testInfo.getTestClass().orElseThrow(), randomSupplier); + LuceneTestCaseParent.setTestFrameworkInfra(null, frameworkInfra); + frameworkInfra.beforeAll(); } @AfterEach void afterEach() throws Exception { + frameworkInfra.afterEach(); fieldToType.after(); } + @AfterAll + static void teardownClass() throws Exception { + var infra = frameworkInfra; + try { + infra.afterAll(); + } finally { + LuceneTestCaseParent.setTestFrameworkInfra(infra, null); + frameworkInfra = null; + } + } + // // Custom assertion methods. // From 75d0c9ef640bdf7a61121019c3b5c40b8e9f179a Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Mon, 27 Apr 2026 20:58:56 +0200 Subject: [PATCH 26/68] Cleanups. --- .../test-framework/src/java/module-info.java | 1 + .../tests/util/BeforeAfterCallback.java | 2 - .../lucene/tests/util/IsSystemThread.java | 54 ++++ .../lucene/tests/util/LuceneTestCase.java | 6 - .../tests/util/LuceneTestCaseJupiter.java | 282 +++++++++--------- .../tests/util/LuceneTestCaseParent.java | 4 - .../tests/util/QuickPatchThreadsFilter.java | 34 +-- .../tests/util/TestRuleMarkFailure.java | 7 +- 8 files changed, 205 insertions(+), 185 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/IsSystemThread.java diff --git a/lucene/test-framework/src/java/module-info.java b/lucene/test-framework/src/java/module-info.java index 54d06485e1eb..644d10b58d85 100644 --- a/lucene/test-framework/src/java/module-info.java +++ b/lucene/test-framework/src/java/module-info.java @@ -26,6 +26,7 @@ requires transitive org.junit.jupiter.api; requires org.hamcrest; requires java.management; + requires org.junit.platform.engine; // Open certain packages for junit because it scans methods via reflection. opens org.apache.lucene.tests.index to diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java index 8adbca3e44d8..b4e61f5c3be1 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/BeforeAfterCallback.java @@ -19,8 +19,6 @@ /** Abstraction for before-test/before-suite callbacks. */ interface BeforeAfterCallback { default void before() throws Exception {} - ; default void after() throws Exception {} - ; } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/IsSystemThread.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/IsSystemThread.java new file mode 100644 index 000000000000..d6df8e1a2775 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/IsSystemThread.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.tests.util; + +import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; +import java.util.function.Predicate; +import java.util.stream.Stream; +import org.apache.lucene.util.Constants; + +/** + * This predicate should return {@code true} for threads that should be ignored in {@linkplain + * DetectThreadLeaks thread leak detection}. + */ +public class IsSystemThread implements Predicate { + static final boolean isJ9; + + static { + isJ9 = Constants.JAVA_VENDOR.startsWith("IBM"); + } + + @Override + public boolean test(Thread t) { + var threadName = t.getName(); + switch (threadName) { + case "ClassCache Reaper": // LUCENE-6518 + case "junit-jupiter-timeout-watcher": // junit5/jupiter timeouts. + case "JNA Cleaner": // JNA cleaner thread (system). + return true; + } + + if (isJ9 + && Stream.of(t.getStackTrace()) + .anyMatch(frame -> frame.getClassName().equals("java.util.Timer$TimerImpl"))) { + return true; + } + + return false; + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 53872bfd0218..d075ea55a5dc 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -406,12 +406,6 @@ public T closeAfterClass(T resource) { .closeAtEnd(resource, LifecycleScope.SUITE); } - @Override - public void afterAll() {} - - @Override - public void afterEach() {} - @Override public SetupAndRestoreStaticEnv getClassEnv() { return setupAndRestoreClassEnv; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 6744785c3448..583a728d0da6 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -21,7 +21,7 @@ import com.carrotsearch.randomizedtesting.jupiter.Randomized; import com.carrotsearch.randomizedtesting.jupiter.SystemThreadFilter; import java.io.Closeable; -import java.io.IOException; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -29,23 +29,20 @@ import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.apache.lucene.util.Constants; import org.apache.lucene.util.IOUtils; -import org.jspecify.annotations.Nullable; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExecutableInvoker; import org.junit.jupiter.api.extension.Extension; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.api.extension.TestWatcher; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; import org.junit.platform.commons.support.AnnotationSupport; @@ -75,7 +72,7 @@ - add all remaining class and test rules from LuceneTestCase; this is now the mi /// **Do not use static initializers (including complex final field initializers).** /// /// For instance-level setup, use [org.junit.jupiter.api.BeforeEach] and -/// [AfterEach] annotated methods. +/// [org.junit.jupiter.api.AfterEach] annotated methods. /// /// ## Specifying test cases /// @@ -110,46 +107,12 @@ - add all remaining class and test rules from LuceneTestCase; this is now the mi @Randomized @DetectThreadLeaks(scope = DetectThreadLeaks.Scope.SUITE) @DetectThreadLeaks.LingerTime(millis = 20_000) -@DetectThreadLeaks.ExcludeThreads({ - SystemThreadFilter.class, - LuceneTestCaseJupiter.IsSystemThread.class -}) +@DetectThreadLeaks.ExcludeThreads({SystemThreadFilter.class, IsSystemThread.class}) @Timeout(value = 2, unit = TimeUnit.HOURS) @Execution( value = ExecutionMode.SAME_THREAD, reason = "single-threaded for backward compatibility.") public abstract non-sealed class LuceneTestCaseJupiter extends LuceneTestCaseParent { - /** - * This predicate should return {@code true} for threads that should be ignored in {@linkplain - * DetectThreadLeaks thread leak detection}. - */ - public static class IsSystemThread implements Predicate { - static final boolean isJ9; - - static { - isJ9 = Constants.JAVA_VENDOR.startsWith("IBM"); - } - - @Override - public boolean test(Thread t) { - var threadName = t.getName(); - switch (threadName) { - case "ClassCache Reaper": // LUCENE-6518 - case "junit-jupiter-timeout-watcher": // junit5/jupiter timeouts. - case "JNA Cleaner": // JNA cleaner thread (system). - return true; - } - - if (isJ9 - && Stream.of(t.getStackTrace()) - .anyMatch(frame -> frame.getClassName().equals("java.util.Timer$TimerImpl"))) { - return true; - } - - return false; - } - } - private static final class JupiterTestFrameworkInfra implements LuceneTestCaseParent.TestFrameworkInfra { private final ConcurrentHashMap perThreadRandoms = new ConcurrentHashMap<>(); @@ -158,20 +121,17 @@ private static final class JupiterTestFrameworkInfra private final List closeAfterSuite = new ArrayList<>(); final Supplier rnd; - final SetupAndRestoreStaticEnv classEnvRule; private final TemporaryFilesSupplier tempFilesSupplier; - private final TestRuleMarkFailure failureMarker; + private final SetupAndRestoreStaticEnv classEnvRule; - JupiterTestFrameworkInfra(Class requiredTestClass, Supplier randomSupplier) { + JupiterTestFrameworkInfra( + SetupAndRestoreStaticEnv classEnvRule, + TemporaryFilesSupplier tempFileSupplier, + Supplier randomSupplier) { + this.classEnvRule = classEnvRule; this.rnd = randomSupplier; - this.classEnvRule = - new SetupAndRestoreStaticEnv( - this::threadRandom, () -> Objects.requireNonNull(requiredTestClass)); - this.failureMarker = new TestRuleMarkFailure(); - this.tempFilesSupplier = - new TemporaryFilesSupplier( - failureMarker, this::threadRandom, () -> Objects.requireNonNull(requiredTestClass)); + this.tempFilesSupplier = tempFileSupplier; } @Override @@ -195,38 +155,6 @@ public T closeAfterClass(T resource) { return resource; } - @Override - public void afterEach() throws IOException { - synchronized (this) { - IOUtils.close(closeAfterTest); - closeAfterTest.clear(); - } - } - - @Override - public void afterAll() throws IOException { - synchronized (this) { - IOUtils.close( - Stream.of( - List.of( - () -> { - try { - tempFilesSupplier.after(); - classEnvRule.after(); - } catch (Exception e) { - throw new RuntimeException(e); - } - }), - closeAfterTest, - closeAfterSuite, - perThreadRandoms.values()) - .flatMap(Collection::stream) - .filter(v -> v instanceof Closeable) - .map(v -> (Closeable) v) - .toList()); - } - } - @Override public SetupAndRestoreStaticEnv getClassEnv() { return classEnvRule; @@ -236,65 +164,146 @@ public SetupAndRestoreStaticEnv getClassEnv() { public TemporaryFilesSupplier getTempFilesSupplier() { return tempFilesSupplier; } + } + + static final class OrderedBeforeAfterCallback implements BeforeAfterCallback { + final List callbacks; + final ArrayDeque executed = new ArrayDeque<>(); - void beforeAll() throws Exception { - classEnvRule.before(); - failureMarker.reset(); - tempFilesSupplier.before(); + OrderedBeforeAfterCallback(List callbacks) { + this.callbacks = callbacks; } - } - private static JupiterTestFrameworkInfra frameworkInfra; + @Override + public void before() throws Exception { + assert executed.isEmpty(); + for (var c : callbacks) { + c.before(); + executed.addLast(c); + } + } - @RegisterExtension - static Extension failureListener = - new TestWatcher() { - @Override - public void testAborted(ExtensionContext context, @Nullable Throwable cause) { - frameworkInfra.failureMarker.markFailed(); + @Override + public void after() throws Exception { + Throwable t = null; + while (!executed.isEmpty()) { + var c = executed.removeLast(); + try { + c.after(); + } catch (Throwable ex) { + if (t == null) { + t = ex; + } else { + t.addSuppressed(ex); + } } + } - @Override - public void testFailed(ExtensionContext context, @Nullable Throwable cause) { - frameworkInfra.failureMarker.markFailed(); + if (t != null) { + if (t instanceof Exception ex) { + throw ex; + } else if (t instanceof Error err) { + throw err; + } else /* only theoretically possible? */ { + throw new RuntimeException(t); } - }; + } + } + } - @BeforeAll - static void setupClass(Supplier randomSupplier, TestInfo testInfo) throws Exception { - // touch LuceneTestCase to trigger static initializers. - LuceneTestCase.ensureInitialized(); + static class SetupTestFrameworkInfra implements BeforeAllCallback, AfterAllCallback { + private JupiterTestFrameworkInfra jupiterFrameworkInfra; - frameworkInfra = - new JupiterTestFrameworkInfra(testInfo.getTestClass().orElseThrow(), randomSupplier); - LuceneTestCaseParent.setTestFrameworkInfra(null, frameworkInfra); - frameworkInfra.beforeAll(); - } + TestRuleMarkFailure failureMarker; + SetupAndRestoreStaticEnv classEnvRule; + TemporaryFilesSupplier tempFileSupplier; - @AfterEach - void afterEach() throws Exception { - frameworkInfra.afterEach(); - fieldToType.after(); - } + private OrderedBeforeAfterCallback beforeAfters; + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + // touch LuceneTestCase to trigger static initializers. + LuceneTestCase.ensureInitialized(); + + var activeTestClass = context.getRequiredTestClass(); + this.classEnvRule = + new SetupAndRestoreStaticEnv(LuceneTestCaseJupiter::random, () -> activeTestClass); + this.failureMarker = new TestRuleMarkFailure(); + this.tempFileSupplier = + new TemporaryFilesSupplier( + failureMarker, LuceneTestCaseJupiter::random, () -> activeTestClass); + this.jupiterFrameworkInfra = + new JupiterTestFrameworkInfra( + classEnvRule, tempFileSupplier, getRandomSupplier(context.getExecutableInvoker())); + + var setFramework = + new BeforeAfterCallback() { + @Override + public void before() { + LuceneTestCaseParent.setTestFrameworkInfra(null, jupiterFrameworkInfra); + } + + @Override + public void after() throws Exception { + IOUtils.close( + Stream.of( + jupiterFrameworkInfra.closeAfterTest, + jupiterFrameworkInfra.closeAfterSuite, + jupiterFrameworkInfra.perThreadRandoms.values()) + .flatMap(Collection::stream) + .filter(v -> v instanceof Closeable) + .map(v -> (Closeable) v) + .toList()); + + LuceneTestCaseParent.setTestFrameworkInfra(jupiterFrameworkInfra, null); + } + }; + + this.beforeAfters = + new OrderedBeforeAfterCallback( + List.of(setFramework, classEnvRule, failureMarker, tempFileSupplier)); + beforeAfters.before(); + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + beforeAfters.after(); + } - @AfterAll - static void teardownClass() throws Exception { - var infra = frameworkInfra; - try { - infra.afterAll(); - } finally { - LuceneTestCaseParent.setTestFrameworkInfra(infra, null); - frameworkInfra = null; + // This trick is needed to get the Supplier injected by a parameter resolved + // of the randomized testing framework. + private Supplier getRandomSupplier(ExecutableInvoker executableInvoker) + throws Exception { + var hack = + new Object() { + @SuppressWarnings("unused") + public Supplier captureParameter(Supplier rnd) { + return rnd; + } + }; + + @SuppressWarnings("unchecked") + Supplier rnd = + (Supplier) + Objects.requireNonNull( + executableInvoker.invoke( + hack.getClass().getMethod("captureParameter", Supplier.class), hack)); + return rnd; } } - // - // Custom assertion methods. - // + @RegisterExtension + @Order(0) + static SetupTestFrameworkInfra classCallbacks = new SetupTestFrameworkInfra(); - public static int atLeast(Random random, int i) { - return LuceneTestCase.atLeast(random, i); - } + @RegisterExtension + Extension testCallbackChain = + new AfterEachCallback() { + @Override + public void afterEach(ExtensionContext context) throws Exception { + fieldToType.after(); + } + }; // // Deprecated or removed methods (LuceneTestCase) and other backward-compatibility @@ -302,10 +311,8 @@ public static int atLeast(Random random, int i) { // /** - * Whenever possible, you should use an injected {@link Random} or {@code Supplier} - * parameter on junit5 test methods. - * - *

Global static methods make running test suites in parallel impossible. + * Use explicit, injected {@link Random} or {@code Supplier} parameters on junit jupiter + * test methods (or callbacks). */ @Deprecated public static Random random() { @@ -339,9 +346,4 @@ public void allTestMethodsAreAnnotated() { .collect(Collectors.joining())); } } - - public static T expectThrows( - Class expectedType, LuceneTestCase.ThrowingRunnable runnable) { - return LuceneTestCase.expectThrows(expectedType, runnable); - } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index 6e51bbdf2ada..233d9e10085d 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -340,10 +340,6 @@ protected interface TestFrameworkInfra { T closeAfterClass(T resource); - void afterEach() throws IOException; - - void afterAll() throws IOException; - SetupAndRestoreStaticEnv getClassEnv(); TemporaryFilesSupplier getTempFilesSupplier(); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/QuickPatchThreadsFilter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/QuickPatchThreadsFilter.java index 42dbe4a1c020..d7bb24c56a4a 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/QuickPatchThreadsFilter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/QuickPatchThreadsFilter.java @@ -17,43 +17,13 @@ package org.apache.lucene.tests.util; import com.carrotsearch.randomizedtesting.ThreadFilter; -import java.util.concurrent.ForkJoinWorkerThread; -import org.apache.lucene.util.Constants; /** Last minute patches. */ public class QuickPatchThreadsFilter implements ThreadFilter { - static final boolean isJ9; - - static { - isJ9 = Constants.JAVA_VENDOR.startsWith("IBM"); - } + private static final IsSystemThread delegate = new IsSystemThread(); @Override public boolean reject(Thread t) { - if (isJ9) { - // LUCENE-6518 - if ("ClassCache Reaper".equals(t.getName())) { - return true; - } - - // LUCENE-4736 - StackTraceElement[] stack = t.getStackTrace(); - if (stack.length > 0 - && stack[stack.length - 1].getClassName().equals("java.util.Timer$TimerImpl")) { - return true; - } - } - - if (t instanceof ForkJoinWorkerThread - && t.getName().startsWith("ForkJoinPool.commonPool-worker") - && t.isDaemon()) { - // GH-14066: filter out common pool's worker threads. Assume they have completed - // all background tasks and are idle. - return true; - } - - // Also filter out JNA Cleaner threads, which is static per-JVM and not under the - // control of a test suite. - return t.getName().equals("JNA Cleaner"); + return delegate.test(t); } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java index 127ce4afb2db..753c5eddb029 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java @@ -24,7 +24,7 @@ import org.junit.runners.model.Statement; /** A rule for marking failed tests and suites. */ -public final class TestRuleMarkFailure implements TestRule { +public final class TestRuleMarkFailure implements TestRule, BeforeAfterCallback { private final TestRuleMarkFailure[] chained; private volatile boolean failures; @@ -32,6 +32,11 @@ public TestRuleMarkFailure(TestRuleMarkFailure... chained) { this.chained = chained; } + @Override + public void before() throws Exception { + reset(); + } + @Override public Statement apply(final Statement s, Description d) { return new Statement() { From 5dafbfb86b20202df1526db6bda5985b71fea7bc Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Tue, 28 Apr 2026 19:11:48 +0200 Subject: [PATCH 27/68] Remove closeAfterTest completely. Cleanups. --- gradle/libs.versions.toml | 1 + .../junit-platform-testkit-6.0.3.jar.sha1 | 1 + lucene/test-framework/build.gradle | 3 + .../lucene/tests/util/LuceneTestCase.java | 6 - .../tests/util/LuceneTestCaseJupiter.java | 168 +++++++-------- .../tests/util/LuceneTestCaseParent.java | 11 - .../tests/util/TestLuceneTestCaseJupiter.java | 99 +++++++++ versions.lock | 197 +++++++++++++++++- 8 files changed, 383 insertions(+), 103 deletions(-) create mode 100644 lucene/licenses/junit-platform-testkit-6.0.3.jar.sha1 create mode 100644 lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c4507cfd378d..a271e3a94f50 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -87,6 +87,7 @@ jts = { module = "org.locationtech.jts:jts-core", version.ref = "jts" } junit = { module = "junit:junit", version.ref = "junit" } junitplatform-jupiter = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit5" } junitplatform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit5" } +junitplatform-testkit = { module = "org.junit.platform:junit-platform-testkit", version.ref = "junit5" } junitplatform-vintage = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" } morfologik-polish = { module = "org.carrot2:morfologik-polish", version.ref = "morfologik" } morfologik-stemming = { module = "org.carrot2:morfologik-stemming", version.ref = "morfologik" } diff --git a/lucene/licenses/junit-platform-testkit-6.0.3.jar.sha1 b/lucene/licenses/junit-platform-testkit-6.0.3.jar.sha1 new file mode 100644 index 000000000000..4bf5e448d2bf --- /dev/null +++ b/lucene/licenses/junit-platform-testkit-6.0.3.jar.sha1 @@ -0,0 +1 @@ +61051eac88ffe34d24cb32146e2fc9539d177281 diff --git a/lucene/test-framework/build.gradle b/lucene/test-framework/build.gradle index bb6cde3bddda..0b5ea3335217 100644 --- a/lucene/test-framework/build.gradle +++ b/lucene/test-framework/build.gradle @@ -34,6 +34,9 @@ dependencies { moduleApi(deps.junitplatform.jupiter) moduleImplementation project(':lucene:codecs') + + moduleTestImplementation deps.junitplatform.testkit + moduleTestImplementation deps.assertj } // diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index d075ea55a5dc..41259895dd5a 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -394,12 +394,6 @@ public Random threadRandom() { return finalizedSupplier.get(); } - @Override - public T closeAfterTest(T resource) { - return RandomizedContext.current() - .closeAtEnd(resource, LifecycleScope.TEST); - } - @Override public T closeAfterClass(T resource) { return RandomizedContext.current() diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 583a728d0da6..50080842664b 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -23,7 +23,6 @@ import java.io.Closeable; import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Random; @@ -31,7 +30,6 @@ import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.lucene.util.IOUtils; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; @@ -40,7 +38,6 @@ import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.ExecutableInvoker; -import org.junit.jupiter.api.extension.Extension; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.parallel.Execution; @@ -113,64 +110,34 @@ - add all remaining class and test rules from LuceneTestCase; this is now the mi value = ExecutionMode.SAME_THREAD, reason = "single-threaded for backward compatibility.") public abstract non-sealed class LuceneTestCaseJupiter extends LuceneTestCaseParent { - private static final class JupiterTestFrameworkInfra - implements LuceneTestCaseParent.TestFrameworkInfra { - private final ConcurrentHashMap perThreadRandoms = new ConcurrentHashMap<>(); - - private final List closeAfterTest = new ArrayList<>(); - private final List closeAfterSuite = new ArrayList<>(); - - final Supplier rnd; - - private final TemporaryFilesSupplier tempFilesSupplier; - private final SetupAndRestoreStaticEnv classEnvRule; - - JupiterTestFrameworkInfra( - SetupAndRestoreStaticEnv classEnvRule, - TemporaryFilesSupplier tempFileSupplier, - Supplier randomSupplier) { - this.classEnvRule = classEnvRule; - this.rnd = randomSupplier; - this.tempFilesSupplier = tempFileSupplier; - } - @Override - public Random threadRandom() { - return perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> rnd.get()); - } - - @Override - public T closeAfterTest(T resource) { - synchronized (this) { - closeAfterTest.add(resource); - } - return resource; - } + static final class PerThreadRandom implements BeforeAfterCallback { + private final ConcurrentHashMap perThreadRandoms = new ConcurrentHashMap<>(); + private final Supplier supplier; - @Override - public T closeAfterClass(T resource) { - synchronized (this) { - closeAfterSuite.add(resource); - } - return resource; + PerThreadRandom(Supplier randomSupplier) { + this.supplier = randomSupplier; } @Override - public SetupAndRestoreStaticEnv getClassEnv() { - return classEnvRule; + public void after() throws Exception { + IOUtils.close( + perThreadRandoms.values().stream() + .filter(v -> v instanceof Closeable) + .map(v -> (Closeable) v) + .toList()); } - @Override - public TemporaryFilesSupplier getTempFilesSupplier() { - return tempFilesSupplier; + Random get() { + return perThreadRandoms.computeIfAbsent(Thread.currentThread(), _ -> supplier.get()); } } - static final class OrderedBeforeAfterCallback implements BeforeAfterCallback { + static final class OrderedBeforeAfterCallbacks implements BeforeAfterCallback { final List callbacks; final ArrayDeque executed = new ArrayDeque<>(); - OrderedBeforeAfterCallback(List callbacks) { + OrderedBeforeAfterCallbacks(List callbacks) { this.callbacks = callbacks; } @@ -211,14 +178,31 @@ public void after() throws Exception { } } - static class SetupTestFrameworkInfra implements BeforeAllCallback, AfterAllCallback { - private JupiterTestFrameworkInfra jupiterFrameworkInfra; + static class CloseAfterScopeSupport implements BeforeAfterCallback { + private final List closeAfterSuite = new ArrayList<>(); - TestRuleMarkFailure failureMarker; - SetupAndRestoreStaticEnv classEnvRule; - TemporaryFilesSupplier tempFileSupplier; + @Override + public synchronized void after() throws Exception { + IOUtils.close(closeAfterSuite); + closeAfterSuite.clear(); + } - private OrderedBeforeAfterCallback beforeAfters; + T registerToClose(T resource) { + this.closeAfterSuite.add(Objects.requireNonNull(resource)); + return resource; + } + } + + /// This extension sets up junit-jupiter implementations of the + /// test framework-dependent infrastructure in [LuceneTestCaseParent]. + /// + /// It tries to simulate before-after rules as they are implemented in junit4 + /// (call order, unwinding in case of failures, etc.). + static class ClassLevelCallbackChain + implements BeforeAllCallback, AfterAllCallback, AfterEachCallback { + private TestFrameworkInfra jupiterFrameworkInfra; + private OrderedBeforeAfterCallbacks beforeAfters; + private CloseAfterScopeSupport closeAfterScopeSupport; @Override public void beforeAll(ExtensionContext context) throws Exception { @@ -226,17 +210,42 @@ public void beforeAll(ExtensionContext context) throws Exception { LuceneTestCase.ensureInitialized(); var activeTestClass = context.getRequiredTestClass(); - this.classEnvRule = + + // these hooks need to run in the right order of before-after calls, + // with the expected nesting. + var classEnvRule = new SetupAndRestoreStaticEnv(LuceneTestCaseJupiter::random, () -> activeTestClass); - this.failureMarker = new TestRuleMarkFailure(); - this.tempFileSupplier = + var failureMarker = new TestRuleMarkFailure(); + var tempFileSupplier = new TemporaryFilesSupplier( failureMarker, LuceneTestCaseJupiter::random, () -> activeTestClass); + var perThreadRandom = new PerThreadRandom(getRandomSupplier(context.getExecutableInvoker())); + this.closeAfterScopeSupport = new CloseAfterScopeSupport(); + this.jupiterFrameworkInfra = - new JupiterTestFrameworkInfra( - classEnvRule, tempFileSupplier, getRandomSupplier(context.getExecutableInvoker())); + new TestFrameworkInfra() { + @Override + public Random threadRandom() { + return perThreadRandom.get(); + } + + @Override + public T closeAfterClass(T resource) { + return closeAfterScopeSupport.registerToClose(resource); + } + + @Override + public SetupAndRestoreStaticEnv getClassEnv() { + return classEnvRule; + } - var setFramework = + @Override + public TemporaryFilesSupplier getTempFilesSupplier() { + return tempFileSupplier; + } + }; + + var installFrameworkInfraSupport = new BeforeAfterCallback() { @Override public void before() { @@ -244,27 +253,29 @@ public void before() { } @Override - public void after() throws Exception { - IOUtils.close( - Stream.of( - jupiterFrameworkInfra.closeAfterTest, - jupiterFrameworkInfra.closeAfterSuite, - jupiterFrameworkInfra.perThreadRandoms.values()) - .flatMap(Collection::stream) - .filter(v -> v instanceof Closeable) - .map(v -> (Closeable) v) - .toList()); - + public void after() { LuceneTestCaseParent.setTestFrameworkInfra(jupiterFrameworkInfra, null); } }; this.beforeAfters = - new OrderedBeforeAfterCallback( - List.of(setFramework, classEnvRule, failureMarker, tempFileSupplier)); + new OrderedBeforeAfterCallbacks( + List.of( + perThreadRandom, + installFrameworkInfraSupport, + classEnvRule, + failureMarker, + tempFileSupplier, + closeAfterScopeSupport)); + beforeAfters.before(); } + @Override + public void afterEach(ExtensionContext context) throws Exception { + fieldToType.after(); + } + @Override public void afterAll(ExtensionContext context) throws Exception { beforeAfters.after(); @@ -294,16 +305,7 @@ public Supplier captureParameter(Supplier rnd) { @RegisterExtension @Order(0) - static SetupTestFrameworkInfra classCallbacks = new SetupTestFrameworkInfra(); - - @RegisterExtension - Extension testCallbackChain = - new AfterEachCallback() { - @Override - public void afterEach(ExtensionContext context) throws Exception { - fieldToType.after(); - } - }; + static ClassLevelCallbackChain classLevelCallbackChain = new ClassLevelCallbackChain(); // // Deprecated or removed methods (LuceneTestCase) and other backward-compatibility diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index 233d9e10085d..2fa31e03cde6 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -336,8 +336,6 @@ public static Random nonAssertingRandom(Random rnd) { protected interface TestFrameworkInfra { Random threadRandom(); - T closeAfterTest(T resource); - T closeAfterClass(T resource); SetupAndRestoreStaticEnv getClassEnv(); @@ -1171,15 +1169,6 @@ protected Path getDataPath(String name) throws IOException { } } - /** - * Registers a {@link Closeable} resource that should be closed after the test completes. - * - * @return resource (for call chaining). - */ - public T closeAfterTest(T resource) { - return getTestFrameworkInfra().closeAfterTest(resource); - } - /** * Registers a {@link Closeable} resource that should be closed after the suite completes. * diff --git a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java new file mode 100644 index 000000000000..cf2a0c3ae32f --- /dev/null +++ b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.tests.util; + +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; +import static org.junit.platform.testkit.engine.EventConditions.event; +import static org.junit.platform.testkit.engine.EventConditions.finishedWithFailure; + +import com.carrotsearch.randomizedtesting.jupiter.SysProps; +import java.util.Random; +import java.util.function.Supplier; +import org.junit.Assert; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.platform.testkit.engine.EngineTestKit; + +/// groups all tests of the junit5/ jupiter parent class and its infrastructure. +@Execution(value = ExecutionMode.SAME_THREAD, reason = "single-threaded.") +public class TestLuceneTestCaseJupiter { + /// Test cases should use parameter-injected [java.util.Random] or a supplier + /// of [java.util.Random]. Avoid using static methods. + @Nested + class RandomInjection { + @Test + public void testRandomParameterInjected() { + testKitBuilder(T1.class) + .configurationParameter(SysProps.TESTS_SEED.propertyKey, "dead:beef:cafe") + .execute() + .allEvents() + .assertThatEvents() + .doNotHave(event(finishedWithFailure())); + } + + static class T1 extends LuceneTestCaseJupiter { + public T1(Random rnd) { + Assert.assertNotNull(rnd); + } + + @BeforeAll + static void beforeAll(Random rnd) { + Assert.assertNotNull(rnd); + } + + @BeforeEach + void beforeEach(Random rnd) { + Assert.assertNotNull(rnd); + } + + @Test + void testMethod(Random rnd) { + Assert.assertNotNull(rnd); + } + + @Test + void testMethodWithSupplier(Supplier supplier) { + Assert.assertNotNull(supplier); + Assert.assertNotNull(supplier.get()); + } + + @AfterEach + void afterEach(Random rnd) { + Assert.assertNotNull(rnd); + } + + @AfterAll + static void afterAll(Random rnd) { + Assert.assertNotNull(rnd); + } + } + } + + public static EngineTestKit.Builder testKitBuilder(Class testClass) { + return testKitBuilder().selectors(selectClass(testClass)); + } + + public static EngineTestKit.Builder testKitBuilder() { + return EngineTestKit.engine("junit-jupiter"); + } +} diff --git a/versions.lock b/versions.lock index 6c55ccbeb062..dffe5ea79848 100644 --- a/versions.lock +++ b/versions.lock @@ -63,7 +63,7 @@ "io.sgr:s2-geometry-library-java:1.0.0" : "1d5a4b2b,refs=4", "javax.inject:javax.inject:1" : "90685606,refs=39", "junit:junit:4.13.2" : "129da9bf,refs=76", - "net.bytebuddy:byte-buddy:1.18.3" : "b7ba1646,refs=2", + "net.bytebuddy:byte-buddy:1.18.3" : "39ba18cb,refs=4", "net.sf.jopt-simple:jopt-simple:5.0.4" : "152d9f78,refs=3", "net.sourceforge.nekohtml:nekohtml:1.9.22" : "6f16ff86,refs=2", "org.antlr:antlr4-runtime:4.13.2" : "6fbc4021,refs=5", @@ -72,7 +72,7 @@ "org.apache.commons:commons-math3:3.6.1" : "152d9f78,refs=3", "org.apache.opennlp:opennlp-tools:2.5.8" : "b91715f0,refs=6", "org.apiguardian:apiguardian-api:1.1.2" : "cab355bc,refs=37", - "org.assertj:assertj-core:3.27.7" : "b7ba1646,refs=2", + "org.assertj:assertj-core:3.27.7" : "39ba18cb,refs=4", "org.carrot2:morfologik-fsa:2.1.9" : "e077a675,refs=8", "org.carrot2:morfologik-polish:2.1.9" : "cb00cecf,refs=5", "org.carrot2:morfologik-stemming:2.1.9" : "e077a675,refs=8", @@ -85,7 +85,8 @@ "org.junit.jupiter:junit-jupiter-params:6.0.3" : "543b6dba,refs=74", "org.junit.platform:junit-platform-commons:6.0.3" : "7b83bd93,refs=76", "org.junit.platform:junit-platform-engine:6.0.3" : "7b83bd93,refs=76", - "org.junit.platform:junit-platform-launcher:6.0.3" : "1ec8e4d2,refs=39", + "org.junit.platform:junit-platform-launcher:6.0.3" : "09b4d43b,refs=40", + "org.junit.platform:junit-platform-testkit:6.0.3" : "882c7fc6,refs=2", "org.junit.vintage:junit-vintage-engine:6.0.3" : "1ec8e4d2,refs=39", "org.junit:junit-bom:6.0.3" : "7b83bd93,refs=76", "org.locationtech.jts:jts-core:1.20.0" : "180518e6,refs=2", @@ -100,6 +101,168 @@ } }, "because" : { + "09b4d43b" : [ + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":build-tools:missing-doclet" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:backward-codecs" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:benchmark" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:benchmark-jmh" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:classification" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:codecs" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:core" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:core.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:demo" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:distribution.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:expressions" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:facet" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:grouping" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:highlighter" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:join" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:luke" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:memory" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:misc" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:monitor" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:queries" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:queryparser" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:replicator" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:sandbox" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:spatial-extras" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:spatial-test-fixtures" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:spatial3d" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:suggest" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:common" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:icu" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:kuromoji" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:morfologik" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:morfologik.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:nori" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:opennlp" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:phonetic" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:smartcn" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:analysis:stempel" + } + ], "129da9bf" : [ { "configuration" : "testCompileClasspath", @@ -624,6 +787,24 @@ "projectPath" : ":lucene:analysis:opennlp" } ], + "39ba18cb" : [ + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:distribution.tests" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:distribution.tests" + }, + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:test-framework" + } + ], "47ea4550" : [ { "configuration" : "compileClasspath", @@ -1324,6 +1505,16 @@ "projectPath" : ":lucene:benchmark-jmh" } ], + "882c7fc6" : [ + { + "configuration" : "testCompileClasspath", + "projectPath" : ":lucene:test-framework" + }, + { + "configuration" : "testRuntimeClasspath", + "projectPath" : ":lucene:test-framework" + } + ], "8b117b59" : [ { "configuration" : "annotationProcessor", From d15f86f51db7add7742c320c2a637f13521da6dc Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Tue, 28 Apr 2026 21:09:37 +0200 Subject: [PATCH 28/68] Remove unused class. --- .../lucene/tests/util/RemoveUponClose.java | 60 ------------------- .../tests/util/TestRuleMarkFailure.java | 2 +- 2 files changed, 1 insertion(+), 61 deletions(-) delete mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/RemoveUponClose.java diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RemoveUponClose.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/RemoveUponClose.java deleted file mode 100644 index 3149bfd92090..000000000000 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RemoveUponClose.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.lucene.tests.util; - -import java.io.Closeable; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.apache.lucene.util.IOUtils; - -/** A {@link Closeable} that attempts to remove a given file/folder. */ -final class RemoveUponClose implements Closeable { - private final Path path; - private final TestRuleMarkFailure failureMarker; - private final String creationStack; - - public RemoveUponClose(Path path, TestRuleMarkFailure failureMarker) { - this.path = path; - this.failureMarker = failureMarker; - - StringBuilder b = new StringBuilder(); - for (StackTraceElement e : Thread.currentThread().getStackTrace()) { - b.append('\t').append(e.toString()).append('\n'); - } - creationStack = b.toString(); - } - - @Override - public void close() throws IOException { - // only if there were no other test failures. - if (failureMarker.wasSuccessful()) { - if (Files.exists(path)) { - try { - IOUtils.rm(path); - } catch (IOException e) { - throw new IOException( - "Could not remove temporary location '" - + path.toAbsolutePath() - + "', created at stack trace:\n" - + creationStack, - e); - } - } - } - } -} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java index 753c5eddb029..e725f32dacb5 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java @@ -103,7 +103,7 @@ public boolean wasSuccessful() { return !hadFailures(); } - public void reset() { + private void reset() { failures = false; } } From 22181b9ef99e8ed4d7447f151ebb8099bd2e5dbe Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Tue, 28 Apr 2026 22:29:51 +0200 Subject: [PATCH 29/68] Rework failure tracking. --- .../lucene/tests/util/CloseableDirectory.java | 4 +- .../lucene/tests/util/LuceneTestCase.java | 10 +- .../tests/util/LuceneTestCaseJupiter.java | 71 ++++++++- .../tests/util/LuceneTestCaseParent.java | 10 +- .../lucene/tests/util/SuiteFailureState.java | 22 +++ .../tests/util/TemporaryFilesSupplier.java | 4 +- .../tests/util/TestRuleLimitSysouts.java | 4 +- .../tests/util/TestRuleMarkFailure.java | 3 +- .../tests/util/TestLuceneTestCaseJupiter.java | 135 ++++++++++++++++++ 9 files changed, 245 insertions(+), 18 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/SuiteFailureState.java diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/CloseableDirectory.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/CloseableDirectory.java index 4df658841509..86b0c138565e 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/CloseableDirectory.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/CloseableDirectory.java @@ -27,9 +27,9 @@ */ final class CloseableDirectory implements Closeable { private final BaseDirectoryWrapper dir; - private final TestRuleMarkFailure failureMarker; + private final SuiteFailureState failureMarker; - public CloseableDirectory(BaseDirectoryWrapper dir, TestRuleMarkFailure failureMarker) { + public CloseableDirectory(BaseDirectoryWrapper dir, SuiteFailureState failureMarker) { this.dir = dir; this.failureMarker = failureMarker; } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 41259895dd5a..a2c2f4ea8cff 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -339,13 +339,16 @@ public static TestRuleIgnoreAfterMaxFailures replaceMaxFailureRule( */ @ClassRule public static final TestRule classRules; + @SuppressWarnings("NonFinalStaticField") + private static TestRuleMarkFailure suiteFailureMarker; + static { var setupAndRestoreClassEnv = new SetupAndRestoreStaticEnv( () -> RandomizedContext.current().getRandom(), () -> RandomizedContext.current().getTargetClass()); - LuceneTestCase.suiteFailureMarker = new TestRuleMarkFailure(); + suiteFailureMarker = new TestRuleMarkFailure(); var tempFilesSupplier = new TemporaryFilesSupplier( @@ -409,6 +412,11 @@ public SetupAndRestoreStaticEnv getClassEnv() { public TemporaryFilesSupplier getTempFilesSupplier() { return tempFilesSupplier; } + + @Override + public SuiteFailureState getSuiteFailureState() { + return suiteFailureMarker; + } }); } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 50080842664b..675ae352181b 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -40,6 +40,7 @@ import org.junit.jupiter.api.extension.ExecutableInvoker; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.extension.TestWatcher; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; import org.junit.platform.commons.support.AnnotationSupport; @@ -193,6 +194,55 @@ T registerToClose(T resource) { } } + /// Tracks whether any test in the current suite had a failure. + /// Registered before [ClassLevelCallbackChain] so its state is available during suite teardown. + static final class SuiteFailureTracker + implements AfterAllCallback, BeforeAllCallback, TestWatcher, SuiteFailureState { + private static final ExtensionContext.Namespace NAMESPACE = + ExtensionContext.Namespace.create(SuiteFailureTracker.class); + + private volatile boolean hadFailures; + + @Override + public void beforeAll(ExtensionContext context) { + hadFailures = false; + // Register a Closeable to capture failures that TestWatcher cannot see: + // @BeforeAll/@AfterAll lifecycle methods and peer extension afterAll callbacks + // (e.g. DetectThreadLeaks). Closeable's close runs during cleanUp(), which + // is after all afterAll callbacks have completed, so the throwableCollector backing + // context.getExecutionException() is fully populated by then. + context + .getStore(NAMESPACE) + .put( + "failureCheck", + (AutoCloseable) + () -> { + if (context.getExecutionException().isPresent()) { + hadFailures = true; + } + }); + } + + @Override + public void afterAll(ExtensionContext context) { + if (context.getExecutionException().isPresent()) { + hadFailures = true; + } + } + + @Override + public void testFailed(ExtensionContext context, Throwable cause) { + // Handles individual test method failures (not visible via class-level + // context.getExecutionException()). + hadFailures = true; + } + + @Override + public boolean wasSuccessful() { + return !hadFailures; + } + } + /// This extension sets up junit-jupiter implementations of the /// test framework-dependent infrastructure in [LuceneTestCaseParent]. /// @@ -200,10 +250,15 @@ T registerToClose(T resource) { /// (call order, unwinding in case of failures, etc.). static class ClassLevelCallbackChain implements BeforeAllCallback, AfterAllCallback, AfterEachCallback { + private final SuiteFailureTracker suiteFailureTracker; private TestFrameworkInfra jupiterFrameworkInfra; private OrderedBeforeAfterCallbacks beforeAfters; private CloseAfterScopeSupport closeAfterScopeSupport; + ClassLevelCallbackChain(SuiteFailureTracker suiteFailureTracker) { + this.suiteFailureTracker = suiteFailureTracker; + } + @Override public void beforeAll(ExtensionContext context) throws Exception { // touch LuceneTestCase to trigger static initializers. @@ -215,10 +270,9 @@ public void beforeAll(ExtensionContext context) throws Exception { // with the expected nesting. var classEnvRule = new SetupAndRestoreStaticEnv(LuceneTestCaseJupiter::random, () -> activeTestClass); - var failureMarker = new TestRuleMarkFailure(); var tempFileSupplier = new TemporaryFilesSupplier( - failureMarker, LuceneTestCaseJupiter::random, () -> activeTestClass); + suiteFailureTracker, LuceneTestCaseJupiter::random, () -> activeTestClass); var perThreadRandom = new PerThreadRandom(getRandomSupplier(context.getExecutableInvoker())); this.closeAfterScopeSupport = new CloseAfterScopeSupport(); @@ -243,6 +297,11 @@ public SetupAndRestoreStaticEnv getClassEnv() { public TemporaryFilesSupplier getTempFilesSupplier() { return tempFileSupplier; } + + @Override + public SuiteFailureState getSuiteFailureState() { + return suiteFailureTracker; + } }; var installFrameworkInfraSupport = @@ -264,7 +323,6 @@ public void after() { perThreadRandom, installFrameworkInfraSupport, classEnvRule, - failureMarker, tempFileSupplier, closeAfterScopeSupport)); @@ -305,7 +363,12 @@ public Supplier captureParameter(Supplier rnd) { @RegisterExtension @Order(0) - static ClassLevelCallbackChain classLevelCallbackChain = new ClassLevelCallbackChain(); + static final SuiteFailureTracker suiteFailureTracker = new SuiteFailureTracker(); + + @RegisterExtension + @Order(1) + static ClassLevelCallbackChain classLevelCallbackChain = + new ClassLevelCallbackChain(suiteFailureTracker); // // Deprecated or removed methods (LuceneTestCase) and other backward-compatibility diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index 2fa31e03cde6..a29976e1c02d 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -341,6 +341,8 @@ protected interface TestFrameworkInfra { SetupAndRestoreStaticEnv getClassEnv(); TemporaryFilesSupplier getTempFilesSupplier(); + + SuiteFailureState getSuiteFailureState(); } private static final AtomicReference testFrameworkInfra = @@ -2280,13 +2282,13 @@ private static BaseDirectoryWrapper wrapDirectory( if (bare) { BaseDirectoryWrapper base = new RawDirectoryWrapper(directory); - closeAfterSuite(new CloseableDirectory(base, suiteFailureMarker)); + closeAfterSuite(new CloseableDirectory(base, getTestFrameworkInfra().getSuiteFailureState())); return base; } else { MockDirectoryWrapper mock = new MockDirectoryWrapper(random, directory); mock.setThrottling(TEST_THROTTLING); - closeAfterSuite(new CloseableDirectory(mock, suiteFailureMarker)); + closeAfterSuite(new CloseableDirectory(mock, getTestFrameworkInfra().getSuiteFailureState())); return mock; } } @@ -2839,8 +2841,4 @@ public static Path createTempFile(String prefix, String suffix) throws IOExcepti // TODO: to remove from here? // static FieldToType fieldToType = new FieldToType(); - - /** Suite failure marker (any error in the test or suite scope). */ - @SuppressWarnings("NonFinalStaticField") - protected static TestRuleMarkFailure suiteFailureMarker; } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/SuiteFailureState.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/SuiteFailureState.java new file mode 100644 index 000000000000..b6b4fe829c6b --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/SuiteFailureState.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.tests.util; + +/** Signals whether the current test suite had any failures. */ +interface SuiteFailureState { + boolean wasSuccessful(); +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java index e6586d87a2cd..678c5fba2515 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java @@ -67,7 +67,7 @@ final class TemporaryFilesSupplier implements BeforeAfterCallback { private FileSystem fileSystem; /** Suite failure marker. */ - private final TestRuleMarkFailure failureMarker; + private final SuiteFailureState failureMarker; /** * A queue of temporary resources to be removed after the suite completes. @@ -77,7 +77,7 @@ final class TemporaryFilesSupplier implements BeforeAfterCallback { private static final List cleanupQueue = new ArrayList<>(); public TemporaryFilesSupplier( - TestRuleMarkFailure failureMarker, + SuiteFailureState failureMarker, Supplier randomSupplier, Supplier> targetClassSupplier) { this.failureMarker = failureMarker; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleLimitSysouts.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleLimitSysouts.java index 865b465a9562..20f68cf26bcf 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleLimitSysouts.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleLimitSysouts.java @@ -138,7 +138,7 @@ public class TestRuleLimitSysouts extends TestRuleAdapter { } /** Test failures from any tests or rules before. */ - private final TestRuleMarkFailure failureMarker; + private final SuiteFailureState failureMarker; interface LimitPredicate { void check(long before, long after) throws IOException; @@ -196,7 +196,7 @@ private void checkLimit(int bytes) throws IOException { } } - public TestRuleLimitSysouts(TestRuleMarkFailure failureMarker) { + public TestRuleLimitSysouts(SuiteFailureState failureMarker) { this.failureMarker = failureMarker; } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java index e725f32dacb5..2d0c6b0e4b09 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleMarkFailure.java @@ -24,7 +24,7 @@ import org.junit.runners.model.Statement; /** A rule for marking failed tests and suites. */ -public final class TestRuleMarkFailure implements TestRule, BeforeAfterCallback { +public final class TestRuleMarkFailure implements TestRule, BeforeAfterCallback, SuiteFailureState { private final TestRuleMarkFailure[] chained; private volatile boolean failures; @@ -99,6 +99,7 @@ public boolean hadFailures() { } /** Check if this object was successful (the opposite of {@link #hadFailures()}). */ + @Override public boolean wasSuccessful() { return !hadFailures(); } diff --git a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java index cf2a0c3ae32f..12fa93eae2de 100644 --- a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java @@ -20,16 +20,24 @@ import static org.junit.platform.testkit.engine.EventConditions.event; import static org.junit.platform.testkit.engine.EventConditions.finishedWithFailure; +import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; import com.carrotsearch.randomizedtesting.jupiter.SysProps; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; import java.util.Random; import java.util.function.Supplier; +import java.util.stream.Stream; +import org.apache.lucene.util.SuppressForbidden; import org.junit.Assert; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; import org.junit.platform.testkit.engine.EngineTestKit; @@ -89,6 +97,133 @@ static void afterAll(Random rnd) { } } + /// Verifies that [LuceneTestCaseJupiter.SuiteFailureTracker] correctly tracks test failures + /// across various lifecycle methods of a [LuceneTestCaseJupiter] subclass. + @Nested + class SuiteFailureTracking { + private static final List forkedThreads = new ArrayList<>(); + + @AfterEach + void interruptAndJoinForkedThreads() throws InterruptedException { + for (var t : forkedThreads) t.interrupt(); + for (var t : forkedThreads) t.join(); + forkedThreads.clear(); + } + + @SuppressForbidden(reason = "Thread sleep") + private static void startSleepingThread(Duration duration) { + startThread( + "sleeping-thread", + () -> { + try { + Thread.sleep(duration.toMillis()); + } catch (InterruptedException _) { + } + }); + } + + private static Thread startThread(String name, Runnable r) { + var t = new Thread(r, name); + forkedThreads.add(t); + t.start(); + return t; + } + + @Test + public void testNoFailureLeavesMarkerClear() { + testKitBuilder(SuccessfulSuite.class) + .execute() + .allEvents() + .assertThatEvents() + .doNotHave(event(finishedWithFailure())); + Assert.assertTrue(LuceneTestCaseJupiter.suiteFailureTracker.wasSuccessful()); + } + + @TestFactory + Stream suiteFailureIsTracked() { + return Stream.of( + FailInTestMethod.class, + FailInBeforeEach.class, + FailInAfterEach.class, + FailInBeforeAll.class, + FailInAfterAll.class, + FailBecauseOfLeakedThreads.class) + .map( + clazz -> + DynamicTest.dynamicTest( + clazz.getSimpleName(), + () -> { + testKitBuilder(clazz) + .execute() + .allEvents() + .assertThatEvents() + .haveAtLeast(1, event(finishedWithFailure())); + Assert.assertFalse( + LuceneTestCaseJupiter.suiteFailureTracker.wasSuccessful()); + })); + } + + static class SuccessfulSuite extends LuceneTestCaseJupiter { + @Test + void testOk() {} + } + + static class FailInTestMethod extends LuceneTestCaseJupiter { + @Test + void testFails() { + throw new AssertionError(); + } + } + + static class FailInBeforeEach extends LuceneTestCaseJupiter { + @BeforeEach + void beforeEach() { + throw new AssertionError(); + } + + @Test + void testMethod() {} + } + + static class FailInAfterEach extends LuceneTestCaseJupiter { + @AfterEach + void afterEach() { + throw new AssertionError(); + } + + @Test + void testMethod() {} + } + + static class FailInBeforeAll extends LuceneTestCaseJupiter { + @BeforeAll + static void setUpSuite() { + throw new AssertionError(); + } + + @Test + void testMethod() {} + } + + static class FailInAfterAll extends LuceneTestCaseJupiter { + @AfterAll + static void tearDownSuite() { + throw new AssertionError(); + } + + @Test + void testMethod() {} + } + + @DetectThreadLeaks.LingerTime(millis = 0) + static class FailBecauseOfLeakedThreads extends LuceneTestCaseJupiter { + @Test + void testMethod() { + startSleepingThread(Duration.ofSeconds(10)); + } + } + } + public static EngineTestKit.Builder testKitBuilder(Class testClass) { return testKitBuilder().selectors(selectClass(testClass)); } From 0e3a1e64eecf80ef63ed236322854338d0018415 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Wed, 29 Apr 2026 18:13:55 +0200 Subject: [PATCH 30/68] More cleanups. --- ...ectory.java => AssertDirectoryClosed.java} | 20 ++-- .../lucene/tests/util/LuceneTestCase.java | 8 -- .../tests/util/LuceneTestCaseJupiter.java | 32 +----- .../tests/util/LuceneTestCaseParent.java | 28 ++--- .../tests/util/TemporaryFilesSupplier.java | 101 +++++++++++------- .../util/TestFailIfDirectoryNotClosed.java | 9 +- .../tests/util/TestLuceneTestCaseJupiter.java | 28 +++++ 7 files changed, 121 insertions(+), 105 deletions(-) rename lucene/test-framework/src/java/org/apache/lucene/tests/util/{CloseableDirectory.java => AssertDirectoryClosed.java} (73%) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/CloseableDirectory.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/AssertDirectoryClosed.java similarity index 73% rename from lucene/test-framework/src/java/org/apache/lucene/tests/util/CloseableDirectory.java rename to lucene/test-framework/src/java/org/apache/lucene/tests/util/AssertDirectoryClosed.java index 86b0c138565e..6c8c9fc771b9 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/CloseableDirectory.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/AssertDirectoryClosed.java @@ -21,15 +21,16 @@ import org.junit.Assert; /** - * Attempts to close a {@link BaseDirectoryWrapper}. - * - * @see LuceneTestCase#newDirectory(java.util.Random) + * Fails the test if the {@link BaseDirectoryWrapper} hasn't been closed and the test has no other + * failures. */ -final class CloseableDirectory implements Closeable { +final class AssertDirectoryClosed implements Closeable { + static final String MSG_PREFIX = "Directory not closed: "; + private final BaseDirectoryWrapper dir; private final SuiteFailureState failureMarker; - public CloseableDirectory(BaseDirectoryWrapper dir, SuiteFailureState failureMarker) { + AssertDirectoryClosed(BaseDirectoryWrapper dir, SuiteFailureState failureMarker) { this.dir = dir; this.failureMarker = failureMarker; } @@ -40,11 +41,14 @@ public void close() { // failures. try { if (failureMarker.wasSuccessful() && dir.isOpen()) { - Assert.fail("Directory not closed: " + dir); + Assert.fail(MSG_PREFIX + dir); } } finally { - // TODO: perform real close of the delegate: LUCENE-4058 - // dir.close(); + try { + dir.close(); + } catch (Throwable _) { + // ignore, we can't do much about it. LUCENE-4058 + } } } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index a2c2f4ea8cff..a0b2a4aabb20 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -21,7 +21,6 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsInt; import com.carrotsearch.randomizedtesting.JUnit4MethodProvider; -import com.carrotsearch.randomizedtesting.LifecycleScope; import com.carrotsearch.randomizedtesting.MixWithSuiteName; import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedRunner; @@ -43,7 +42,6 @@ import com.carrotsearch.randomizedtesting.rules.NoClassHooksShadowingRule; import com.carrotsearch.randomizedtesting.rules.NoInstanceHooksOverridesRule; import com.carrotsearch.randomizedtesting.rules.TestRuleAdapter; -import java.io.Closeable; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -397,12 +395,6 @@ public Random threadRandom() { return finalizedSupplier.get(); } - @Override - public T closeAfterClass(T resource) { - return RandomizedContext.current() - .closeAtEnd(resource, LifecycleScope.SUITE); - } - @Override public SetupAndRestoreStaticEnv getClassEnv() { return setupAndRestoreClassEnv; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 675ae352181b..5113f73f8759 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -22,7 +22,6 @@ import com.carrotsearch.randomizedtesting.jupiter.SystemThreadFilter; import java.io.Closeable; import java.util.ArrayDeque; -import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Random; @@ -179,23 +178,9 @@ public void after() throws Exception { } } - static class CloseAfterScopeSupport implements BeforeAfterCallback { - private final List closeAfterSuite = new ArrayList<>(); - - @Override - public synchronized void after() throws Exception { - IOUtils.close(closeAfterSuite); - closeAfterSuite.clear(); - } - - T registerToClose(T resource) { - this.closeAfterSuite.add(Objects.requireNonNull(resource)); - return resource; - } - } - /// Tracks whether any test in the current suite had a failure. /// Registered before [ClassLevelCallbackChain] so its state is available during suite teardown. + /// We plug into multiple jupiter extensions, hoping they will be sufficient to detect failure state. static final class SuiteFailureTracker implements AfterAllCallback, BeforeAllCallback, TestWatcher, SuiteFailureState { private static final ExtensionContext.Namespace NAMESPACE = @@ -232,8 +217,6 @@ public void afterAll(ExtensionContext context) { @Override public void testFailed(ExtensionContext context, Throwable cause) { - // Handles individual test method failures (not visible via class-level - // context.getExecutionException()). hadFailures = true; } @@ -253,7 +236,6 @@ static class ClassLevelCallbackChain private final SuiteFailureTracker suiteFailureTracker; private TestFrameworkInfra jupiterFrameworkInfra; private OrderedBeforeAfterCallbacks beforeAfters; - private CloseAfterScopeSupport closeAfterScopeSupport; ClassLevelCallbackChain(SuiteFailureTracker suiteFailureTracker) { this.suiteFailureTracker = suiteFailureTracker; @@ -274,7 +256,6 @@ public void beforeAll(ExtensionContext context) throws Exception { new TemporaryFilesSupplier( suiteFailureTracker, LuceneTestCaseJupiter::random, () -> activeTestClass); var perThreadRandom = new PerThreadRandom(getRandomSupplier(context.getExecutableInvoker())); - this.closeAfterScopeSupport = new CloseAfterScopeSupport(); this.jupiterFrameworkInfra = new TestFrameworkInfra() { @@ -283,11 +264,6 @@ public Random threadRandom() { return perThreadRandom.get(); } - @Override - public T closeAfterClass(T resource) { - return closeAfterScopeSupport.registerToClose(resource); - } - @Override public SetupAndRestoreStaticEnv getClassEnv() { return classEnvRule; @@ -320,11 +296,7 @@ public void after() { this.beforeAfters = new OrderedBeforeAfterCallbacks( List.of( - perThreadRandom, - installFrameworkInfraSupport, - classEnvRule, - tempFileSupplier, - closeAfterScopeSupport)); + perThreadRandom, installFrameworkInfraSupport, classEnvRule, tempFileSupplier)); beforeAfters.before(); } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index a29976e1c02d..ab9a311a349b 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -27,7 +27,6 @@ import com.carrotsearch.randomizedtesting.annotations.TestGroup; import com.carrotsearch.randomizedtesting.generators.RandomNumbers; import com.carrotsearch.randomizedtesting.generators.RandomPicks; -import java.io.Closeable; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -336,8 +335,6 @@ public static Random nonAssertingRandom(Random rnd) { protected interface TestFrameworkInfra { Random threadRandom(); - T closeAfterClass(T resource); - SetupAndRestoreStaticEnv getClassEnv(); TemporaryFilesSupplier getTempFilesSupplier(); @@ -1171,15 +1168,6 @@ protected Path getDataPath(String name) throws IOException { } } - /** - * Registers a {@link Closeable} resource that should be closed after the suite completes. - * - * @return resource (for call chaining). - */ - public static T closeAfterSuite(T resource) { - return getTestFrameworkInfra().closeAfterClass(resource); - } - /** * Creates a {@link BytesRef} holding UTF-8 bytes for the incoming String, that sometimes uses a * non-zero {@code offset}, and non-zero end-padding, to tickle latent bugs that fail to look at @@ -2280,17 +2268,21 @@ private static BaseDirectoryWrapper wrapDirectory( directory = new NRTCachingDirectory(directory, random.nextDouble(), random.nextDouble()); } + BaseDirectoryWrapper dir; if (bare) { - BaseDirectoryWrapper base = new RawDirectoryWrapper(directory); - closeAfterSuite(new CloseableDirectory(base, getTestFrameworkInfra().getSuiteFailureState())); - return base; + dir = new RawDirectoryWrapper(directory); } else { MockDirectoryWrapper mock = new MockDirectoryWrapper(random, directory); - mock.setThrottling(TEST_THROTTLING); - closeAfterSuite(new CloseableDirectory(mock, getTestFrameworkInfra().getSuiteFailureState())); - return mock; + dir = mock; } + + getTestFrameworkInfra() + .getTempFilesSupplier() + .registerToCloseAfterSuite( + new AssertDirectoryClosed(dir, getTestFrameworkInfra().getSuiteFailureState())); + + return dir; } private static Directory newFSDirectoryImpl( diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java index 678c5fba2515..32669aa3ed44 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TemporaryFilesSupplier.java @@ -16,6 +16,7 @@ */ package org.apache.lucene.tests.util; +import java.io.Closeable; import java.io.IOException; import java.net.URI; import java.nio.file.FileSystem; @@ -25,9 +26,7 @@ import java.nio.file.spi.FileSystemProvider; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Locale; import java.util.Random; import java.util.Set; @@ -70,11 +69,18 @@ final class TemporaryFilesSupplier implements BeforeAfterCallback { private final SuiteFailureState failureMarker; /** - * A queue of temporary resources to be removed after the suite completes. + * A queue of paths to be removed after the suite completes. * - * @see #registerToRemoveAfterSuite(Path) + * @see #registerToCloseAfterSuite(Path) */ - private static final List cleanupQueue = new ArrayList<>(); + private static final ArrayList pathQueue = new ArrayList<>(); + + /** + * A queue of closeables to be closed after the suite completes. + * + * @see #registerToCloseAfterSuite(Closeable) + */ + private static final ArrayList closeableQueue = new ArrayList<>(); public TemporaryFilesSupplier( SuiteFailureState failureMarker, @@ -86,7 +92,14 @@ public TemporaryFilesSupplier( } /** Register temporary folder for removal after the suite completes. */ - void registerToRemoveAfterSuite(Path f) { + void registerToCloseAfterSuite(Closeable c) { + synchronized (closeableQueue) { + closeableQueue.addLast(c); + } + } + + /** Register temporary folder for removal after the suite completes. */ + void registerToCloseAfterSuite(Path f) { assert f != null; if (LuceneTestCase.LEAVE_TEMPORARY) { @@ -94,15 +107,21 @@ void registerToRemoveAfterSuite(Path f) { return; } - synchronized (cleanupQueue) { - cleanupQueue.add(f); + synchronized (pathQueue) { + pathQueue.addLast(f); } } @Override public void before() throws Exception { assert tempDirBase == null; + assert pathQueue.isEmpty() && closeableQueue.isEmpty(); + fileSystem = initializeFileSystem(); + if (fileSystem != FileSystems.getDefault()) { + registerToCloseAfterSuite(fileSystem); + } + javaTempDir = initializeJavaTempDir(); } @@ -187,45 +206,51 @@ private Path initializeJavaTempDir() throws IOException { @Override public void after() throws Exception { + final String tempDirBasePath = + (tempDirBase != null ? tempDirBase.toAbsolutePath().toString() : null); + tempDirBase = null; + // Drain cleanup queue and clear it. - final Path[] everything; - final String tempDirBasePath; - synchronized (cleanupQueue) { - tempDirBasePath = (tempDirBase != null ? tempDirBase.toAbsolutePath().toString() : null); - tempDirBase = null; - - Collections.reverse(cleanupQueue); - everything = new Path[cleanupQueue.size()]; - cleanupQueue.toArray(everything); - cleanupQueue.clear(); + final Path[] paths; + synchronized (pathQueue) { + paths = pathQueue.reversed().toArray(Path[]::new); + pathQueue.clear(); } // Only check and throw an IOException on un-removable files if the test // was successful. Otherwise, just report the path of temporary files // and leave them there. if (failureMarker.wasSuccessful()) { - try { - IOUtils.rm(everything); - } catch (IOException e) { - Class suiteClass = targetClassSupplier.get(); - if (suiteClass.isAnnotationPresent(SuppressTempFileChecks.class)) { - System.err.println( - "WARNING: Leftover undeleted temporary files (bugUrl: " - + suiteClass.getAnnotation(SuppressTempFileChecks.class).bugUrl() - + "): " - + e.getMessage()); - return; - } - throw e; - } - if (fileSystem != FileSystems.getDefault()) { - fileSystem.close(); - } + registerToCloseAfterSuite( + () -> { + try { + IOUtils.rm(paths); + } catch (IOException e) { + Class suiteClass = targetClassSupplier.get(); + if (suiteClass.isAnnotationPresent(SuppressTempFileChecks.class)) { + System.err.println( + "WARNING: Leftover undeleted temporary files (bugUrl: " + + suiteClass.getAnnotation(SuppressTempFileChecks.class).bugUrl() + + "): " + + e.getMessage()); + return; + } + throw e; + } + }); } else { if (tempDirBasePath != null) { System.err.println("NOTE: leaving temporary files on disk at: " + tempDirBasePath); } } + + Closeable[] toClose; + synchronized (closeableQueue) { + toClose = closeableQueue.reversed().toArray(Closeable[]::new); + closeableQueue.clear(); + } + + IOUtils.close(toClose); } Path getPerTestClassTempDir() { @@ -252,7 +277,7 @@ Path getPerTestClassTempDir() { } while (!success); tempDirBase = f; - registerToRemoveAfterSuite(tempDirBase); + registerToCloseAfterSuite(tempDirBase); } return tempDirBase; } @@ -280,7 +305,7 @@ public Path createTempDir(String prefix) { } } while (!success); - registerToRemoveAfterSuite(f); + registerToCloseAfterSuite(f); return f; } @@ -307,7 +332,7 @@ public Path createTempFile(String prefix, String suffix) throws IOException { } } while (!success); - registerToRemoveAfterSuite(f); + registerToCloseAfterSuite(f); return f; } } diff --git a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestFailIfDirectoryNotClosed.java b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestFailIfDirectoryNotClosed.java index f622d326c3f1..c0cddb844258 100644 --- a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestFailIfDirectoryNotClosed.java +++ b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestFailIfDirectoryNotClosed.java @@ -18,7 +18,7 @@ import com.carrotsearch.randomizedtesting.RandomizedTest; import org.apache.lucene.store.Directory; -import org.junit.Assert; +import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; @@ -41,7 +41,10 @@ public void testFailIfDirectoryNotClosed() { RandomizedTest.assumeTrue( "Ignoring nested test, very likely zombie threads present.", r.getIgnoreCount() == 0); assertFailureCount(1, r); - Assert.assertTrue( - r.getFailures().get(0).toString().contains("Resource in scope SUITE failed to close")); + Assertions.assertThat(r.getFailures()) + .anyMatch( + failure -> { + return failure.toString().contains(AssertDirectoryClosed.MSG_PREFIX); + }); } } diff --git a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java index 12fa93eae2de..6a935985774c 100644 --- a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java @@ -19,6 +19,8 @@ import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; import static org.junit.platform.testkit.engine.EventConditions.event; import static org.junit.platform.testkit.engine.EventConditions.finishedWithFailure; +import static org.junit.platform.testkit.engine.TestExecutionResultConditions.instanceOf; +import static org.junit.platform.testkit.engine.TestExecutionResultConditions.message; import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; import com.carrotsearch.randomizedtesting.jupiter.SysProps; @@ -224,6 +226,32 @@ void testMethod() { } } + /// Verifies that failing to close a [org.apache.lucene.store.Directory] created during + /// a test causes a test failure, mirroring the behavior of [TestFailIfDirectoryNotClosed] + @Nested + class UnclosedDirectoryTracking { + @Test + void testFailIfDirectoryNotClosed() { + testKitBuilder(LeakyDirectorySuite.class) + .execute() + .allEvents() + .assertThatEvents() + .haveAtLeast( + 1, + event( + finishedWithFailure( + instanceOf(AssertionError.class), + message(msg -> msg.contains(AssertDirectoryClosed.MSG_PREFIX))))); + } + + static class LeakyDirectorySuite extends LuceneTestCaseJupiter { + @Test + void testLeaksDirectory() { + LuceneTestCaseParent.newDirectory(); + } + } + } + public static EngineTestKit.Builder testKitBuilder(Class testClass) { return testKitBuilder().selectors(selectClass(testClass)); } From d22b39d0c74e618f610095aa7feceef49b2f68d9 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Wed, 29 Apr 2026 18:24:25 +0200 Subject: [PATCH 31/68] Ensure tests are run sequentially. --- .../tests/util/EnsureSequentialExecution.java | 31 +++++++++++++++++++ .../tests/util/LuceneTestCaseJupiter.java | 4 ++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/EnsureSequentialExecution.java diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/EnsureSequentialExecution.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/EnsureSequentialExecution.java new file mode 100644 index 000000000000..42b18ad93242 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/EnsureSequentialExecution.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.tests.util; + +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.parallel.ExecutionMode; + +public class EnsureSequentialExecution implements BeforeAllCallback { + @Override + public void beforeAll(ExtensionContext context) throws Exception { + if (context.getExecutionMode() != ExecutionMode.SAME_THREAD) { + throw new AssertionError( + "Lucene tests must be run sequentially (static globals everywhere)."); + } + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 5113f73f8759..a386e539c88a 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -37,6 +37,7 @@ import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.ExecutableInvoker; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.TestWatcher; @@ -94,7 +95,7 @@ - add all remaining class and test rules from LuceneTestCase; this is now the mi /// /* // TODO: port these. -- reproduce info listener, failuremarker? @Listeners({RunListenerPrintReproduceInfo.class, FailureMarker.class}) +- reproduce info listener, @Listeners({RunListenerPrintReproduceInfo.class}) - predictable test ordering - test sysout rule @TestRuleLimitSysouts.Limit( @@ -109,6 +110,7 @@ - add all remaining class and test rules from LuceneTestCase; this is now the mi @Execution( value = ExecutionMode.SAME_THREAD, reason = "single-threaded for backward compatibility.") +@ExtendWith(EnsureSequentialExecution.class) public abstract non-sealed class LuceneTestCaseJupiter extends LuceneTestCaseParent { static final class PerThreadRandom implements BeforeAfterCallback { From 117d352b046b17a6b0793523a9a65b14b6704d84 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Wed, 29 Apr 2026 18:36:53 +0200 Subject: [PATCH 32/68] Custom method orderer. --- .../tests/util/CustomMethodOrderer.java | 49 +++++++++++++++++++ .../tests/util/LuceneTestCaseJupiter.java | 23 ++++----- 2 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/CustomMethodOrderer.java diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/CustomMethodOrderer.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/CustomMethodOrderer.java new file mode 100644 index 000000000000..e63bf6da4755 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/CustomMethodOrderer.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.tests.util; + +import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom; +import com.carrotsearch.randomizedtesting.jupiter.Hashing; +import com.carrotsearch.randomizedtesting.jupiter.Seed; +import com.carrotsearch.randomizedtesting.jupiter.SeedChain; +import com.carrotsearch.randomizedtesting.jupiter.SysProps; +import java.util.Collections; +import java.util.Optional; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.MethodOrdererContext; +import org.junit.jupiter.api.parallel.ExecutionMode; + +public final class CustomMethodOrderer implements MethodOrderer { + @Override + public void orderMethods(MethodOrdererContext context) { + var seed = + SeedChain.parse( + context + .getConfigurationParameter(SysProps.TESTS_SEED.propertyKey) + .orElse(new Seed(Hashing.hash(context.getTestClass().getName())).toString())) + .seeds() + .getFirst() + .value(); + + Collections.shuffle(context.getMethodDescriptors(), new Xoroshiro128PlusRandom(seed)); + } + + @Override + public Optional getDefaultExecutionMode() { + return Optional.of(ExecutionMode.SAME_THREAD); + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index a386e539c88a..e94bf884258b 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -32,6 +32,7 @@ import org.apache.lucene.util.IOUtils; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterEachCallback; @@ -48,19 +49,6 @@ import org.junit.platform.commons.support.ModifierSupport; import org.junit.platform.commons.support.ReflectionSupport; -/* -TODOs. - -- pick a smaller module and move (some?) of the tests to jupiter. Ensure both frameworks can coexist (jupiter and -vintage engine running both). -- add tests of the LuceneTestCaseJupiter infrastructure (if what was previously implemented -as rules in LuceneTestCase still provides the same functionality). Nested classes should be perhaps -excluded from discovery entirely (unless they're really needed/loaded?). -- add a check ensuring junit jupiter runs in single-thread mode (unfortunately this can't be -changed, at least for now). -- add all remaining class and test rules from LuceneTestCase; this is now the minimum subset. - */ - /// Base class for all Lucene unit tests (JUnit5/ Jupiter variant). /// /// ## Class and instance setup @@ -96,11 +84,17 @@ - add all remaining class and test rules from LuceneTestCase; this is now the mi /* // TODO: port these. - reproduce info listener, @Listeners({RunListenerPrintReproduceInfo.class}) -- predictable test ordering - test sysout rule @TestRuleLimitSysouts.Limit( bytes = TestRuleLimitSysouts.DEFAULT_LIMIT, hardLimit = TestRuleLimitSysouts.DEFAULT_HARD_LIMIT) + +- pick a smaller module and move (some?) of the tests to jupiter. Ensure both frameworks can coexist (jupiter and +vintage engine running both). +- add tests of the LuceneTestCaseJupiter infrastructure (if what was previously implemented +as rules in LuceneTestCase still provides the same functionality). Nested classes should be perhaps +excluded from discovery entirely (unless they're really needed/loaded?). + */ @Randomized @DetectThreadLeaks(scope = DetectThreadLeaks.Scope.SUITE) @@ -111,6 +105,7 @@ - add all remaining class and test rules from LuceneTestCase; this is now the mi value = ExecutionMode.SAME_THREAD, reason = "single-threaded for backward compatibility.") @ExtendWith(EnsureSequentialExecution.class) +@TestMethodOrder(CustomMethodOrderer.class) public abstract non-sealed class LuceneTestCaseJupiter extends LuceneTestCaseParent { static final class PerThreadRandom implements BeforeAfterCallback { From c73d4bc835fba0145e5b39f868bde9e7063b0f24 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 30 Apr 2026 14:11:48 +0200 Subject: [PATCH 33/68] Reproduce line for jupiter. --- .../lucene/tests/util/LuceneTestCase.java | 7 +- .../tests/util/LuceneTestCaseJupiter.java | 226 ++++++++++++++-- .../util/RunListenerPrintReproduceInfo.java | 205 +++----------- .../apache/lucene/tests/util/TestEnvInfo.java | 147 ++++++++++ .../tests/util/TestLuceneTestCaseJupiter.java | 250 ++++++++++++++---- 5 files changed, 584 insertions(+), 251 deletions(-) create mode 100644 lucene/test-framework/src/java/org/apache/lucene/tests/util/TestEnvInfo.java diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index a0b2a4aabb20..1985ad37e67d 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -450,8 +450,11 @@ protected boolean verify(Method key) { new BeforeAfterCallback() { @Override public void before() { - RunListenerPrintReproduceInfo.env = - new RunListenerPrintReproduceInfo.Env( + // Save environment information to reproduce-info listener. + // This listener can be invoked after all the tests and other callbacks have + // completed; I don't see any clean way to pass it there. + RunListenerPrintReproduceInfo.envInfoJunit4 = + new TestEnvInfo( setupAndRestoreClassEnv.codec, setupAndRestoreClassEnv.similarity, setupAndRestoreClassEnv.locale, diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index e94bf884258b..4d6cedc9b566 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -19,17 +19,21 @@ import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; import com.carrotsearch.randomizedtesting.jupiter.Randomized; +import com.carrotsearch.randomizedtesting.jupiter.RandomizedContext; import com.carrotsearch.randomizedtesting.jupiter.SystemThreadFilter; import java.io.Closeable; +import java.io.PrintStream; import java.util.ArrayDeque; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import java.util.stream.Collectors; import org.apache.lucene.util.IOUtils; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; @@ -37,9 +41,11 @@ import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.DynamicTestInvocationContext; import org.junit.jupiter.api.extension.ExecutableInvoker; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.InvocationInterceptor; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.TestWatcher; import org.junit.jupiter.api.parallel.Execution; @@ -48,6 +54,7 @@ import org.junit.platform.commons.support.HierarchyTraversalMode; import org.junit.platform.commons.support.ModifierSupport; import org.junit.platform.commons.support.ReflectionSupport; +import org.opentest4j.TestAbortedException; /// Base class for all Lucene unit tests (JUnit5/ Jupiter variant). /// @@ -83,12 +90,10 @@ /// /* // TODO: port these. -- reproduce info listener, @Listeners({RunListenerPrintReproduceInfo.class}) - test sysout rule @TestRuleLimitSysouts.Limit( bytes = TestRuleLimitSysouts.DEFAULT_LIMIT, hardLimit = TestRuleLimitSysouts.DEFAULT_HARD_LIMIT) - - pick a smaller module and move (some?) of the tests to jupiter. Ensure both frameworks can coexist (jupiter and vintage engine running both). - add tests of the LuceneTestCaseJupiter infrastructure (if what was previously implemented @@ -177,9 +182,14 @@ public void after() throws Exception { /// Tracks whether any test in the current suite had a failure. /// Registered before [ClassLevelCallbackChain] so its state is available during suite teardown. - /// We plug into multiple jupiter extensions, hoping they will be sufficient to detect failure state. + /// We plug into multiple jupiter extensions, hoping they will be sufficient to detect failure + // state. static final class SuiteFailureTracker - implements AfterAllCallback, BeforeAllCallback, TestWatcher, SuiteFailureState { + implements AfterAllCallback, + BeforeAllCallback, + TestWatcher, + SuiteFailureState, + InvocationInterceptor { private static final ExtensionContext.Namespace NAMESPACE = ExtensionContext.Namespace.create(SuiteFailureTracker.class); @@ -188,35 +198,64 @@ static final class SuiteFailureTracker @Override public void beforeAll(ExtensionContext context) { hadFailures = false; - // Register a Closeable to capture failures that TestWatcher cannot see: + // Register a Closeable invoked after all the other callbacks have been called: // @BeforeAll/@AfterAll lifecycle methods and peer extension afterAll callbacks - // (e.g. DetectThreadLeaks). Closeable's close runs during cleanUp(), which - // is after all afterAll callbacks have completed, so the throwableCollector backing - // context.getExecutionException() is fully populated by then. + // (e.g. DetectThreadLeaks). context .getStore(NAMESPACE) - .put( - "failureCheck", - (AutoCloseable) - () -> { - if (context.getExecutionException().isPresent()) { - hadFailures = true; - } - }); + .put("failureCheck", (AutoCloseable) () -> checkContextException(context)); } @Override public void afterAll(ExtensionContext context) { + checkContextException(context); + } + + private void checkContextException(ExtensionContext context) { if (context.getExecutionException().isPresent()) { - hadFailures = true; + if (!isFailedAssumption(context.getExecutionException().get())) { + hadFailures = true; + } } } + public static boolean isFailedAssumption(Throwable t) { + return t instanceof TestAbortedException + || t.getClass().getName().equals("org.junit.AssumptionViolatedException"); + } + @Override public void testFailed(ExtensionContext context, Throwable cause) { hadFailures = true; } + @Override + public void testAborted(ExtensionContext context, @Nullable Throwable cause) { + // This means the test threw an assumption exception. Ignored. + } + + @Override + public void testDisabled(ExtensionContext context, Optional reason) { + // This means the test is ignored for some other reason. + } + + // required to detect failures in dynamic tests. + @Override + public void interceptDynamicTest( + Invocation<@Nullable Void> invocation, + DynamicTestInvocationContext invocationContext, + ExtensionContext extensionContext) + throws Throwable { + try { + invocation.proceed(); + } catch (Throwable t) { + if (!isFailedAssumption(t)) { + hadFailures = true; + } + throw t; + } + } + @Override public boolean wasSuccessful() { return !hadFailures; @@ -231,11 +270,16 @@ public boolean wasSuccessful() { static class ClassLevelCallbackChain implements BeforeAllCallback, AfterAllCallback, AfterEachCallback { private final SuiteFailureTracker suiteFailureTracker; + private final PrintReproduceInfoExtension printReproduceInfo; + private TestFrameworkInfra jupiterFrameworkInfra; private OrderedBeforeAfterCallbacks beforeAfters; - ClassLevelCallbackChain(SuiteFailureTracker suiteFailureTracker) { + ClassLevelCallbackChain( + SuiteFailureTracker suiteFailureTracker, + PrintReproduceInfoExtension printReproduceInfoExtension) { this.suiteFailureTracker = suiteFailureTracker; + this.printReproduceInfo = printReproduceInfoExtension; } @Override @@ -290,10 +334,30 @@ public void after() { } }; + var installEnvInfo = + new BeforeAfterCallback() { + @Override + public void before() throws Exception { + printReproduceInfo.testEnvInfo = + new TestEnvInfo( + classEnvRule.codec, + classEnvRule.similarity, + classEnvRule.locale, + classEnvRule.timeZone); + } + }; + + // This is the chain of before-after callbacks that must be called in the right order for + // compatibility + // with junit4 implementation. this.beforeAfters = new OrderedBeforeAfterCallbacks( List.of( - perThreadRandom, installFrameworkInfraSupport, classEnvRule, tempFileSupplier)); + perThreadRandom, + installFrameworkInfraSupport, + classEnvRule, + installEnvInfo, + tempFileSupplier)); beforeAfters.before(); } @@ -330,14 +394,136 @@ public Supplier captureParameter(Supplier rnd) { } } + static class PrintReproduceInfoExtension + implements BeforeAllCallback, TestWatcher, InvocationInterceptor { + public static final CharSequence TEST_REPRO_LEAD = TestEnvInfo.TEST_REPRO_LEAD; + public static final CharSequence TEST_ENV_LEAD = TestEnvInfo.TEST_ENV_LEAD; + + // Used for tests only to replace syserrs. + public static PrintStream debugStream; + + TestEnvInfo testEnvInfo; + + private String rootSeed; + private boolean somethingFailed; + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + this.rootSeed = getRandomSupplier(context.getExecutableInvoker()).getRootSeed().toString(); + + // Register a Closeable invoked after all the other callbacks have been called: + // @BeforeAll/@AfterAll lifecycle methods and peer extension afterAll callbacks + // (e.g. DetectThreadLeaks). + context + .getStore(ExtensionContext.Namespace.create(PrintReproduceInfoExtension.class)) + .put( + "failureCheck", + (AutoCloseable) + () -> { + if (context.getExecutionException().isPresent()) { + if (!SuiteFailureTracker.isFailedAssumption( + context.getExecutionException().get())) { + printReproduceInfo(context); + somethingFailed = true; + } + } + + if (somethingFailed && testEnvInfo != null) { + println(testEnvInfo.getDebuggingInformation()); + } + }); + } + + @Override + public void testFailed(ExtensionContext context, @Nullable Throwable cause) { + somethingFailed = true; + printReproduceInfo(context); + } + + // Required to detect failures in dynamic tests. + @Override + public void interceptDynamicTest( + Invocation<@Nullable Void> invocation, + DynamicTestInvocationContext invocationContext, + ExtensionContext extensionContext) + throws Throwable { + try { + invocation.proceed(); + } catch (Throwable t) { + if (!SuiteFailureTracker.isFailedAssumption(t)) { + somethingFailed = true; + printReproduceInfo(extensionContext); + } + throw t; + } + } + + private void printReproduceInfo(ExtensionContext context) { + if (testEnvInfo == null || rootSeed == null) { + println( + "NOTE: test failed but no environment information is present to construct the reproduce-line."); + } else { + println( + testEnvInfo.getAdditionalFailureInfo( + rootSeed, + b -> { + // TODO: add gradle infrastructure to rerun tests based on their uniqueid + // instead of their class/method. This would allow dynamic tests to be + // repeatable. + + if (context.getTestClass().isPresent()) { + b.append("--tests "); + b.append(context.getRequiredTestClass().getName()); + if (context.getTestMethod().isPresent()) { + b.append(".").append(context.getRequiredTestMethod().getName()); + } + } + })); + } + } + + private void println(String msg) { + if (debugStream != null) { + debugStream.println(msg); + } else { + System.err.println(msg); + } + } + + // This trick is needed to get the Supplier injected by a parameter resolved + // of the randomized testing framework. + private RandomizedContext getRandomSupplier(ExecutableInvoker executableInvoker) + throws Exception { + var hack = + new Object() { + @SuppressWarnings("unused") + public RandomizedContext captureParameter(RandomizedContext ctx) { + return ctx; + } + }; + + return (RandomizedContext) + Objects.requireNonNull( + executableInvoker.invoke( + hack.getClass().getMethod("captureParameter", RandomizedContext.class), hack)); + } + } + @RegisterExtension @Order(0) static final SuiteFailureTracker suiteFailureTracker = new SuiteFailureTracker(); @RegisterExtension @Order(1) + static final PrintReproduceInfoExtension printReproduceInfoExtension = + new PrintReproduceInfoExtension(); + + @RegisterExtension + @Order(2) static ClassLevelCallbackChain classLevelCallbackChain = - new ClassLevelCallbackChain(suiteFailureTracker); + new ClassLevelCallbackChain( + Objects.requireNonNull(suiteFailureTracker), + Objects.requireNonNull(printReproduceInfoExtension)); // // Deprecated or removed methods (LuceneTestCase) and other backward-compatibility diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java index 701a6faebdab..f06259bc410b 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java @@ -16,54 +16,20 @@ */ package org.apache.lucene.tests.util; -import static org.apache.lucene.tests.util.LuceneTestCase.DEFAULT_LINE_DOCS_FILE; -import static org.apache.lucene.tests.util.LuceneTestCase.JENKINS_LARGE_LINE_DOCS_FILE; -import static org.apache.lucene.tests.util.LuceneTestCase.RANDOM_MULTIPLIER; -import static org.apache.lucene.tests.util.LuceneTestCase.SYSPROP_AWAITSFIX; -import static org.apache.lucene.tests.util.LuceneTestCase.SYSPROP_MONSTER; -import static org.apache.lucene.tests.util.LuceneTestCase.SYSPROP_NIGHTLY; -import static org.apache.lucene.tests.util.LuceneTestCase.SYSPROP_WEEKLY; -import static org.apache.lucene.tests.util.LuceneTestCase.TEST_AWAITSFIX; -import static org.apache.lucene.tests.util.LuceneTestCase.TEST_CODEC; -import static org.apache.lucene.tests.util.LuceneTestCase.TEST_DIRECTORY; -import static org.apache.lucene.tests.util.LuceneTestCase.TEST_DOCVALUESFORMAT; -import static org.apache.lucene.tests.util.LuceneTestCase.TEST_LINE_DOCS_FILE; -import static org.apache.lucene.tests.util.LuceneTestCase.TEST_MONSTER; -import static org.apache.lucene.tests.util.LuceneTestCase.TEST_NIGHTLY; -import static org.apache.lucene.tests.util.LuceneTestCase.TEST_POSTINGSFORMAT; -import static org.apache.lucene.tests.util.LuceneTestCase.TEST_WEEKLY; - import com.carrotsearch.randomizedtesting.LifecycleScope; import com.carrotsearch.randomizedtesting.RandomizedContext; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Objects; import java.util.Optional; -import java.util.TimeZone; -import java.util.regex.Pattern; -import org.apache.lucene.codecs.Codec; -import org.apache.lucene.search.similarities.Similarity; -import org.apache.lucene.util.Constants; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; /** - * A suite listener printing a "reproduce string". This ensures test result events are always - * captured properly even if exceptions happen at initialization or suite/ hooks level. + * A suite listener printing a "reproduce string" (junit4/ randomizedtesting). This ensures test + * result events are always captured properly even if exceptions happen at initialization or suite/ + * hooks level. */ public final class RunListenerPrintReproduceInfo extends RunListener { - /** - * A list of all test suite classes executed so far in this JVM (ehm, under this class's - * classloader). - */ - private static final List testClassesRun = new ArrayList<>(); - /** The currently executing scope. */ private LifecycleScope scope; @@ -79,18 +45,20 @@ public final class RunListenerPrintReproduceInfo extends RunListener { /** true if we should skip the reproduce string (diagnostics are independent) */ private boolean suppressReproduceLine; - static Env env; + /** Environment settings for the run. Set by {@link LuceneTestCase}. */ + static TestEnvInfo envInfoJunit4; @Override public void testRunStarted(Description description) throws Exception { suiteFailed = false; testFailed = false; scope = LifecycleScope.SUITE; + envInfoJunit4 = null; - Class targetClass = RandomizedContext.current().getTargetClass(); suppressReproduceLine = - targetClass.isAnnotationPresent(LuceneTestCase.SuppressReproduceLine.class); - testClassesRun.add(targetClass.getSimpleName()); + RandomizedContext.current() + .getTargetClass() + .isAnnotationPresent(LuceneTestCase.SuppressReproduceLine.class); } @Override @@ -111,14 +79,29 @@ public void testFailure(Failure failure) throws Exception { @Override public void testFinished(Description description) throws Exception { - if (testFailed) { + if (testFailed && !suppressReproduceLine) { System.err.println( - getAdditionalFailureInfo(stripTestNameAugmentations(description.getMethodName()))); + envInfoJunit4.getAdditionalFailureInfo( + RandomizedContext.current().getRunnerSeedAsString(), + b -> { + appendSelectorArguments( + b, Optional.of(stripTestNameAugmentations(description.getMethodName()))); + })); } scope = LifecycleScope.SUITE; testFailed = false; } + private void appendSelectorArguments(StringBuilder b, Optional testMethod) { + // Figure out the test case name and method, if any. + String testClass = RandomizedContext.current().getTargetClass().getSimpleName(); + b.append("--tests "); + b.append(testClass); + if (testMethod.isPresent()) { + b.append(".").append(testMethod.get()); + } + } + /** * The {@link Description} object in JUnit does not expose the actual test method, instead it has * the concept of a unique "name" of a test. To run the same method (tests) repeatedly, @@ -134,136 +117,16 @@ private String stripTestNameAugmentations(String methodName) { @Override public void testRunFinished(Result result) throws Exception { - if (somethingFailed || LuceneTestCase.VERBOSE) { - System.err.println(getDebuggingInformation()); - } - - if (suiteFailed) { - System.err.println(getAdditionalFailureInfo(null)); - } - } - - record Env(String codec, String similarity, String locale, String timeZone) { - Env(Codec codec, Similarity similarity, Locale locale, TimeZone timeZone) { - this( - Objects.toString(codec), - Objects.toString(similarity), - Optional.ofNullable(locale).map(Locale::toLanguageTag).orElse(null), - Optional.ofNullable(timeZone).map(TimeZone::getID).orElse(null)); - } - } - - /** print some useful debugging information about the environment */ - private static String getDebuggingInformation() { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - pw.println( - ("NOTE: test params are: codec=" + env.codec) - + (", sim=" + env.similarity) - + (", locale=" + env.locale) - + (", timezone=" + env.timeZone)); - pw.println( - "NOTE: " - + (System.getProperty("os.name") + " ") - + (System.getProperty("os.version") + " ") - + (System.getProperty("os.arch") + "/" + System.getProperty("java.vendor")) - + (" " + System.getProperty("java.version")) - + (" " - + (Constants.JRE_IS_64BIT ? "(64-bit)" : "(32-bit)") - + "/" - + "cpus=" - + Runtime.getRuntime().availableProcessors() - + ",") - + ("threads=" + Thread.activeCount() + ",") - + ("free=" + Runtime.getRuntime().freeMemory() + ",") - + ("total=" + Runtime.getRuntime().totalMemory())); - pw.println("NOTE: All tests run in this JVM: " + Arrays.toString(testClassesRun.toArray())); - pw.flush(); - - return sw.toString(); - } - - private String getAdditionalFailureInfo(final String testName) { - if (suppressReproduceLine) { - return ""; - } - - if (TEST_LINE_DOCS_FILE.endsWith(JENKINS_LARGE_LINE_DOCS_FILE)) { + if (suiteFailed && !suppressReproduceLine) { System.err.println( - "NOTE: large line-docs file was used in this run. You have to download " - + "it manually ('gradlew getEnWikiRandomLines') and use -P" - + TEST_LINE_DOCS_FILE - + "=... property to point to it."); + envInfoJunit4.getAdditionalFailureInfo( + RandomizedContext.current().getRunnerSeedAsString(), + b -> { + appendSelectorArguments(b, Optional.empty()); + })); } - - final StringBuilder b = new StringBuilder(); - b.append("NOTE: reproduce with: gradlew test "); - - // Figure out the test case name and method, if any. - String testClass = RandomizedContext.current().getTargetClass().getSimpleName(); - b.append("--tests "); - b.append(testClass); - if (testName != null) { - b.append(".").append(testName); - } - - // Pass the master seed. - addVmOpt(b, "tests.seed", RandomizedContext.current().getRunnerSeedAsString()); - - addVmOpt(b, "tests.jvmargs", System.getProperty("tests.jvmargs")); - - // Test groups and multipliers. - if (RANDOM_MULTIPLIER != LuceneTestCase.defaultRandomMultiplier()) - addVmOpt(b, "tests.multiplier", RANDOM_MULTIPLIER); - if (TEST_NIGHTLY) addVmOpt(b, SYSPROP_NIGHTLY, TEST_NIGHTLY); - if (TEST_WEEKLY) addVmOpt(b, SYSPROP_WEEKLY, TEST_WEEKLY); - if (TEST_MONSTER) addVmOpt(b, SYSPROP_MONSTER, TEST_MONSTER); - if (TEST_AWAITSFIX) addVmOpt(b, SYSPROP_AWAITSFIX, TEST_AWAITSFIX); - - // Codec, postings, directories. - if (!TEST_CODEC.equals("random")) addVmOpt(b, "tests.codec", TEST_CODEC); - if (!TEST_POSTINGSFORMAT.equals("random")) - addVmOpt(b, "tests.postingsformat", TEST_POSTINGSFORMAT); - if (!TEST_DOCVALUESFORMAT.equals("random")) - addVmOpt(b, "tests.docvaluesformat", TEST_DOCVALUESFORMAT); - if (!TEST_DIRECTORY.equals("random")) addVmOpt(b, "tests.directory", TEST_DIRECTORY); - - // Environment. - if (!TEST_LINE_DOCS_FILE.equals(DEFAULT_LINE_DOCS_FILE)) - addVmOpt(b, "tests.linedocsfile", TEST_LINE_DOCS_FILE); - if (env.locale() != null) { - addVmOpt(b, "tests.locale", env.locale); - } - - if (env.timeZone() != null) { - addVmOpt(b, "tests.timezone", env.timeZone()); - } - - if (LuceneTestCase.TEST_ASSERTS_ENABLED) { - addVmOpt(b, "tests.asserts", "true"); - } else { - addVmOpt(b, "tests.asserts", "false"); - } - - addVmOpt(b, "tests.file.encoding", System.getProperty("file.encoding")); - - return b.toString(); - } - - /** - * Append a VM option (-Dkey=value) to a {@link StringBuilder}. Add quotes if spaces or other - * funky characters are detected. - */ - static void addVmOpt(StringBuilder b, String key, Object value) { - if (value == null) return; - - b.append(" -D").append(key).append("="); - String v = value.toString(); - // Add simplistic quoting. This varies a lot from system to system and between - // shells... ANT should have some code for doing it properly. - if (Pattern.compile("[\\s=']").matcher(v).find()) { - v = '"' + v + '"'; + if (somethingFailed || LuceneTestCase.VERBOSE) { + System.err.println(envInfoJunit4.getDebuggingInformation()); } - b.append(v); } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestEnvInfo.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestEnvInfo.java new file mode 100644 index 000000000000..0d148d7f4f36 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestEnvInfo.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.tests.util; + +import static org.apache.lucene.tests.util.LuceneTestCaseParent.*; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; +import java.util.TimeZone; +import java.util.function.Consumer; +import java.util.regex.Pattern; +import org.apache.lucene.codecs.Codec; +import org.apache.lucene.search.similarities.Similarity; +import org.apache.lucene.util.Constants; + +/** Test environment information. */ +record TestEnvInfo(String codec, String similarity, String locale, String timeZone) { + static final String TEST_ENV_LEAD = "NOTE: test environment is:"; + static final String TEST_REPRO_LEAD = "NOTE: reproduce with:"; + + TestEnvInfo(Codec codec, Similarity similarity, Locale locale, TimeZone timeZone) { + this( + Objects.toString(codec), + Objects.toString(similarity), + Optional.ofNullable(locale).map(Locale::toLanguageTag).orElse(null), + Optional.ofNullable(timeZone).map(TimeZone::getID).orElse(null)); + } + + /** print some useful debugging information about the environment */ + String getDebuggingInformation() { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + pw.println( + (TEST_ENV_LEAD + " codec=" + codec) + + (", sim=" + similarity) + + (", locale=" + locale) + + (", timezone=" + timeZone)); + pw.println( + "NOTE: " + + (System.getProperty("os.name") + " ") + + (System.getProperty("os.version") + " ") + + (System.getProperty("os.arch") + "/" + System.getProperty("java.vendor")) + + (" " + System.getProperty("java.version")) + + (" " + + (Constants.JRE_IS_64BIT ? "(64-bit)" : "(32-bit)") + + "/" + + "cpus=" + + Runtime.getRuntime().availableProcessors() + + ",") + + ("threads=" + Thread.activeCount() + ",") + + ("free=" + Runtime.getRuntime().freeMemory() + ",") + + ("total=" + Runtime.getRuntime().totalMemory())); + pw.flush(); + return sw.toString(); + } + + String getAdditionalFailureInfo(String seed, Consumer extraArguments) { + if (TEST_LINE_DOCS_FILE.endsWith(JENKINS_LARGE_LINE_DOCS_FILE)) { + System.err.println( + "NOTE: large line-docs file was used in this run. You have to download " + + "it manually ('gradlew getEnWikiRandomLines') and use -P" + + TEST_LINE_DOCS_FILE + + "=... property to point to it."); + } + + final StringBuilder b = new StringBuilder(); + b.append(TEST_REPRO_LEAD + " gradlew test "); + + extraArguments.accept(b); + + // Pass the master seed. + addVmOpt(b, "tests.seed", seed); + addVmOpt(b, "tests.jvmargs", System.getProperty("tests.jvmargs")); + + // Test groups and multipliers. + if (RANDOM_MULTIPLIER != defaultRandomMultiplier()) + addVmOpt(b, "tests.multiplier", RANDOM_MULTIPLIER); + if (TEST_NIGHTLY) addVmOpt(b, SYSPROP_NIGHTLY, TEST_NIGHTLY); + if (TEST_WEEKLY) addVmOpt(b, SYSPROP_WEEKLY, TEST_WEEKLY); + if (TEST_MONSTER) addVmOpt(b, SYSPROP_MONSTER, TEST_MONSTER); + if (TEST_AWAITSFIX) addVmOpt(b, SYSPROP_AWAITSFIX, TEST_AWAITSFIX); + + // Codec, postings, directories. + if (!TEST_CODEC.equals("random")) addVmOpt(b, "tests.codec", TEST_CODEC); + if (!TEST_POSTINGSFORMAT.equals("random")) + addVmOpt(b, "tests.postingsformat", TEST_POSTINGSFORMAT); + if (!TEST_DOCVALUESFORMAT.equals("random")) + addVmOpt(b, "tests.docvaluesformat", TEST_DOCVALUESFORMAT); + if (!TEST_DIRECTORY.equals("random")) addVmOpt(b, "tests.directory", TEST_DIRECTORY); + + // Environment. + if (!TEST_LINE_DOCS_FILE.equals(DEFAULT_LINE_DOCS_FILE)) + addVmOpt(b, "tests.linedocsfile", TEST_LINE_DOCS_FILE); + if (locale() != null) { + addVmOpt(b, "tests.locale", locale()); + } + + if (timeZone() != null) { + addVmOpt(b, "tests.timezone", timeZone()); + } + + if (TEST_ASSERTS_ENABLED) { + addVmOpt(b, "tests.asserts", "true"); + } else { + addVmOpt(b, "tests.asserts", "false"); + } + + addVmOpt(b, "tests.file.encoding", System.getProperty("file.encoding")); + + return b.toString(); + } + + /** + * Append a VM option (-Dkey=value) to a {@link StringBuilder}. Add quotes if spaces or other + * funky characters are detected. + */ + static void addVmOpt(StringBuilder b, String key, Object value) { + if (value == null) return; + + b.append(" -D").append(key).append("="); + String v = value.toString(); + // Add simplistic quoting. This varies a lot from system to system and between + // shells... ANT should have some code for doing it properly. + if (Pattern.compile("[\\s=']").matcher(v).find()) { + v = '"' + v + '"'; + } + b.append(v); + } +} diff --git a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java index 6a935985774c..30a6962b5f2d 100644 --- a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java @@ -24,29 +24,105 @@ import com.carrotsearch.randomizedtesting.jupiter.DetectThreadLeaks; import com.carrotsearch.randomizedtesting.jupiter.SysProps; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.function.Supplier; import java.util.stream.Stream; import org.apache.lucene.util.SuppressForbidden; +import org.assertj.core.api.Assertions; import org.junit.Assert; +import org.junit.Assume; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; +import org.junit.jupiter.api.function.Executable; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.junit.platform.testkit.engine.EngineTestKit; /// groups all tests of the junit5/ jupiter parent class and its infrastructure. @Execution(value = ExecutionMode.SAME_THREAD, reason = "single-threaded.") public class TestLuceneTestCaseJupiter { + /** + * A test class that calls the provided callable at a specific pointcut (callback method, test). + * This is used to make unit tests more compact. + */ + static class CallAtPointcut extends LuceneTestCaseJupiter { + enum Pointcut { + BEFORE_ALL, + BEFORE_EACH, + TEST_NORMAL, + TEST_DYNAMIC, + TEST_PARAMETERIZED, + AFTER_EACH, + AFTER_ALL, + } + + static Map pointcuts; + + private static void call(Pointcut pointcut) throws Throwable { + if (pointcuts.containsKey(pointcut)) { + pointcuts.get(pointcut).execute(); + } + } + + @BeforeAll + static void beforeAll() throws Throwable { + call(Pointcut.BEFORE_ALL); + } + + @BeforeEach + void beforeEach() throws Throwable { + call(Pointcut.BEFORE_EACH); + } + + @Test + void normalTestMethod() throws Throwable { + call(Pointcut.TEST_NORMAL); + } + + @TestFactory + Stream dynamicTests() throws Throwable { + return Stream.of( + DynamicTest.dynamicTest( + "dynamicTest", + () -> { + call(Pointcut.TEST_DYNAMIC); + })); + } + + @ParameterizedTest + @ValueSource(strings = {"a"}) + void templateTest(String unused) throws Throwable { + call(Pointcut.TEST_PARAMETERIZED); + } + + @AfterEach + void afterEach() throws Throwable { + call(Pointcut.AFTER_EACH); + } + + @AfterAll + static void afterAll() throws Throwable { + call(Pointcut.AFTER_ALL); + } + } + /// Test cases should use parameter-injected [java.util.Random] or a supplier /// of [java.util.Random]. Avoid using static methods. @Nested @@ -141,21 +217,21 @@ public void testNoFailureLeavesMarkerClear() { Assert.assertTrue(LuceneTestCaseJupiter.suiteFailureTracker.wasSuccessful()); } + static class SuccessfulSuite extends LuceneTestCaseJupiter { + @Test + void testMethod() {} + } + @TestFactory Stream suiteFailureIsTracked() { - return Stream.of( - FailInTestMethod.class, - FailInBeforeEach.class, - FailInAfterEach.class, - FailInBeforeAll.class, - FailInAfterAll.class, - FailBecauseOfLeakedThreads.class) + return Stream.of(CallAtPointcut.Pointcut.values()) .map( - clazz -> + pointcut -> DynamicTest.dynamicTest( - clazz.getSimpleName(), + pointcut.name(), () -> { - testKitBuilder(clazz) + CallAtPointcut.pointcuts = Map.of(pointcut, Assertions::fail); + testKitBuilder(CallAtPointcut.class) .execute() .allEvents() .assertThatEvents() @@ -165,56 +241,50 @@ Stream suiteFailureIsTracked() { })); } - static class SuccessfulSuite extends LuceneTestCaseJupiter { - @Test - void testOk() {} - } - - static class FailInTestMethod extends LuceneTestCaseJupiter { - @Test - void testFails() { - throw new AssertionError(); - } - } - - static class FailInBeforeEach extends LuceneTestCaseJupiter { - @BeforeEach - void beforeEach() { - throw new AssertionError(); - } - - @Test - void testMethod() {} - } - - static class FailInAfterEach extends LuceneTestCaseJupiter { - @AfterEach - void afterEach() { - throw new AssertionError(); - } - - @Test - void testMethod() {} - } - - static class FailInBeforeAll extends LuceneTestCaseJupiter { - @BeforeAll - static void setUpSuite() { - throw new AssertionError(); - } - - @Test - void testMethod() {} + @TestFactory + Stream failedAssumptionsAreNotFailures() { + return Stream.of(CallAtPointcut.Pointcut.values()) + .>mapMulti( + (pointcut, downstream) -> { + downstream.accept( + Map.entry( + pointcut, + () -> { + org.junit.jupiter.api.Assumptions.assumeTrue(false); + })); + downstream.accept( + Map.entry( + pointcut, + () -> { + org.assertj.core.api.Assumptions.assumeThat(true).isFalse(); + })); + downstream.accept( + Map.entry( + pointcut, + () -> { + Assume.assumeTrue(false); + })); + }) + .map( + entry -> { + return DynamicTest.dynamicTest( + entry.getKey().name(), + () -> { + CallAtPointcut.pointcuts = Map.ofEntries(entry); + testKitBuilder(CallAtPointcut.class).execute(); + Assert.assertTrue(LuceneTestCaseJupiter.suiteFailureTracker.wasSuccessful()); + }); + }); } - static class FailInAfterAll extends LuceneTestCaseJupiter { - @AfterAll - static void tearDownSuite() { - throw new AssertionError(); - } - - @Test - void testMethod() {} + @Test + public void testFailBecauseOfLeakedThreads() { + testKitBuilder(FailBecauseOfLeakedThreads.class) + .execute() + .allEvents() + .assertThatEvents() + .haveAtLeast(1, event(finishedWithFailure())); + Assert.assertFalse(LuceneTestCaseJupiter.suiteFailureTracker.wasSuccessful()); } @DetectThreadLeaks.LingerTime(millis = 0) @@ -252,6 +322,70 @@ void testLeaksDirectory() { } } + @Nested + class ReproduceLinePrinter { + @TestFactory + Stream testReproLineIsPrinted() throws Exception { + return Stream.of(CallAtPointcut.Pointcut.values()) + .map( + pointcut -> { + return DynamicTest.dynamicTest( + pointcut.name(), + () -> { + String testOutput = collectOutputFrom(Map.of(pointcut, Assertions::fail)); + + Assertions.assertThat(testOutput) + .contains( + LuceneTestCaseJupiter.PrintReproduceInfoExtension.TEST_REPRO_LEAD) + .contains( + LuceneTestCaseJupiter.PrintReproduceInfoExtension.TEST_ENV_LEAD); + }); + }); + } + + @TestFactory + Stream testReproLineIsNotPrintedForAssumptions() throws Exception { + return Stream.of(CallAtPointcut.Pointcut.values()) + .map( + pointcut -> { + return DynamicTest.dynamicTest( + pointcut.name(), + () -> { + String testOutput = + collectOutputFrom( + Map.of( + pointcut, + () -> { + Assumptions.assumeTrue(false); + })); + + Assertions.assertThat(testOutput) + .doesNotContain( + LuceneTestCaseJupiter.PrintReproduceInfoExtension.TEST_REPRO_LEAD) + .doesNotContain( + LuceneTestCaseJupiter.PrintReproduceInfoExtension.TEST_ENV_LEAD); + }); + }); + } + + private static String collectOutputFrom(Map callables) + throws IOException { + String testOutput; + try (var baos = new ByteArrayOutputStream(); + var pw = new PrintStream(baos, true, StandardCharsets.UTF_8)) { + CallAtPointcut.pointcuts = callables; + LuceneTestCaseJupiter.PrintReproduceInfoExtension.debugStream = pw; + testKitBuilder(CallAtPointcut.class).execute(); + pw.flush(); + testOutput = baos.toString(StandardCharsets.UTF_8); + } finally { + LuceneTestCaseJupiter.PrintReproduceInfoExtension.debugStream = null; + CallAtPointcut.pointcuts = null; + } + return testOutput; + } + } + public static EngineTestKit.Builder testKitBuilder(Class testClass) { return testKitBuilder().selectors(selectClass(testClass)); } From d97873eb1992f3c03801f20a7d578f14ebebfe13 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 30 Apr 2026 14:41:18 +0200 Subject: [PATCH 34/68] Minor cleanups. --- .../gradle/plugins/java/ShowFailedTestsAtEndPlugin.java | 9 ++++++++- .../apache/lucene/tests/util/LuceneTestCaseJupiter.java | 3 +-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ShowFailedTestsAtEndPlugin.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ShowFailedTestsAtEndPlugin.java index ebb044d2339c..0889ddf66586 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ShowFailedTestsAtEndPlugin.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ShowFailedTestsAtEndPlugin.java @@ -104,7 +104,14 @@ public void afterTest(TestDescriptor desc, TestResult result) { if (desc.getName().equals("classMethod")) { qTestName = desc.getClassName(); } else { - qTestName = desc.getClassName() + "." + desc.getName(); + // For junit5/jupiter, gradle support is very limited for now. + // ideally, we should report the repro line using test metadata + // (from within the test). Or use uniqueid on the context that failed + // to reproduce it. + // + // for now, just trim the trailing (). + String name = desc.getName().replaceAll("\\(\\).*$", ""); + qTestName = desc.getClassName() + "." + name; } var randomizationParameters = ""; diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 4d6cedc9b566..9aa7967922cd 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -89,7 +89,7 @@ /// - inserted as a synthetic stack frame in any exceptions. /// /* -// TODO: port these. +// TODO: port these too. - test sysout rule @TestRuleLimitSysouts.Limit( bytes = TestRuleLimitSysouts.DEFAULT_LIMIT, @@ -99,7 +99,6 @@ - add tests of the LuceneTestCaseJupiter infrastructure (if what was previously implemented as rules in LuceneTestCase still provides the same functionality). Nested classes should be perhaps excluded from discovery entirely (unless they're really needed/loaded?). - */ @Randomized @DetectThreadLeaks(scope = DetectThreadLeaks.Scope.SUITE) From 271616d9ded2415e3490fbfc3262120e9a95553c Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 30 Apr 2026 14:43:43 +0200 Subject: [PATCH 35/68] Clean up todos. --- .../lucene/tests/util/LuceneTestCaseJupiter.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 9aa7967922cd..6eeaac0380d7 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -89,17 +89,10 @@ /// - inserted as a synthetic stack frame in any exceptions. /// /* -// TODO: port these too. -- test sysout rule -@TestRuleLimitSysouts.Limit( - bytes = TestRuleLimitSysouts.DEFAULT_LIMIT, - hardLimit = TestRuleLimitSysouts.DEFAULT_HARD_LIMIT) -- pick a smaller module and move (some?) of the tests to jupiter. Ensure both frameworks can coexist (jupiter and -vintage engine running both). -- add tests of the LuceneTestCaseJupiter infrastructure (if what was previously implemented -as rules in LuceneTestCase still provides the same functionality). Nested classes should be perhaps -excluded from discovery entirely (unless they're really needed/loaded?). - */ +TODO: port the remaining infrastructure bits from LuceneTestCase: +- there are class rules and test rules that are still only on junit4 side +- sysout limit annotation/ rule is not ported. +*/ @Randomized @DetectThreadLeaks(scope = DetectThreadLeaks.Scope.SUITE) @DetectThreadLeaks.LingerTime(millis = 20_000) From 60a6c94d38f8e394039294c7e3afaab544aec263 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 30 Apr 2026 15:01:09 +0200 Subject: [PATCH 36/68] Enforce test class name. --- .../lucene/tests/util/LuceneTestCaseJupiter.java | 10 ++++++++++ .../tests/util/VerifyTestClassNamingConvention.java | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 6eeaac0380d7..1094bd5ae3ba 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -31,11 +31,14 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.lucene.util.IOUtils; import org.jspecify.annotations.Nullable; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.extension.AfterAllCallback; @@ -531,6 +534,13 @@ public static Random random() { return LuceneTestCaseParent.random(); } + @BeforeAll + static void testTestClassNameConvention(TestInfo testInfo) { + new VerifyTestClassNamingConvention( + "org.apache.lucene", Pattern.compile("(.+\\.)(Test)([^.]+)")) + .check(testInfo.getTestClass().orElseThrow()); + } + /** * Unfortunately there is no easy way to implement custom test providers in jupiter so we just * enforce annotations on {@code test*} methods (so that they're not silently ignored). diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/VerifyTestClassNamingConvention.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/VerifyTestClassNamingConvention.java index 4926f90a8090..905be5f927ff 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/VerifyTestClassNamingConvention.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/VerifyTestClassNamingConvention.java @@ -37,8 +37,11 @@ protected void before() throws Exception { return; } - String suiteName = RandomizedContext.current().getTargetClass().getName(); + check(RandomizedContext.current().getTargetClass()); + } + public void check(Class clazz) { + String suiteName = clazz.getName(); Matcher matcher = namingConvention.matcher(suiteName); if (suiteName.startsWith(packagePrefix) && !matcher.matches()) { throw new AssertionError( From 2d2171dcf3cffdff4ca1d0c8ebdd8af601ad9d03 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 30 Apr 2026 15:18:21 +0200 Subject: [PATCH 37/68] Cleanups. --- .../tests/util/LuceneTestCaseJupiter.java | 22 +++++++--- .../util/TestRuleAssertionsRequired.java | 43 +++++++++---------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 1094bd5ae3ba..2151c9a0f361 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -35,7 +35,6 @@ import java.util.stream.Collectors; import org.apache.lucene.util.IOUtils; import org.jspecify.annotations.Nullable; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; @@ -94,7 +93,12 @@ /* TODO: port the remaining infrastructure bits from LuceneTestCase: - there are class rules and test rules that are still only on junit4 side -- sysout limit annotation/ rule is not ported. +TestRuleRestoreSystemProperties +TestRuleLimitSysouts +NoInstanceHooksOverridesRule (?) +ignoreAfterMaxFailures +threadAndTestNameRule (?) +TestRuleSetupAndRestoreInstanceEnv */ @Randomized @DetectThreadLeaks(scope = DetectThreadLeaks.Scope.SUITE) @@ -534,8 +538,14 @@ public static Random random() { return LuceneTestCaseParent.random(); } - @BeforeAll - static void testTestClassNameConvention(TestInfo testInfo) { + @Test + void verifyTestAssertionStatus() throws Exception { + TestRuleAssertionsRequired.checkAssertionStatus(); + } + + /** Enforce test class naming convention. */ + @Test + void enforceClassNamingConvention(TestInfo testInfo) { new VerifyTestClassNamingConvention( "org.apache.lucene", Pattern.compile("(.+\\.)(Test)([^.]+)")) .check(testInfo.getTestClass().orElseThrow()); @@ -549,10 +559,10 @@ static void testTestClassNameConvention(TestInfo testInfo) { * before-after hooks so they're not a direct substitute. */ @Test - public void allTestMethodsAreAnnotated() { + void allTestMethodsAreAnnotated(TestInfo testInfo) { var testMethodsWithoutAnnotations = ReflectionSupport.findMethods( - getClass(), + testInfo.getTestClass().orElseThrow(), m -> { return m.getName().startsWith("test") && !ModifierSupport.isStatic(m) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleAssertionsRequired.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleAssertionsRequired.java index 192f2ee8321c..3a8ff2908119 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleAssertionsRequired.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleAssertionsRequired.java @@ -27,30 +27,29 @@ public Statement apply(final Statement base, final Description description) { return new Statement() { @Override public void evaluate() throws Throwable { - try { - // Make sure -ea matches -Dtests.asserts, to catch accidental mis-use: - var assertsEnabled = LuceneTestCase.class.desiredAssertionStatus(); - if (assertsEnabled != LuceneTestCase.TEST_ASSERTS_ENABLED) { - String msg = "Assertions mismatch: "; - if (assertsEnabled) { - msg += "-ea was specified"; - } else { - msg += "-ea was not specified"; - } - if (LuceneTestCase.TEST_ASSERTS_ENABLED) { - msg += " but -Dtests.asserts=true"; - } else { - msg += " but -Dtests.asserts=false"; - } - System.err.println(msg); - throw new Exception(msg); - } - } catch (AssertionError _) { - // Ok, enabled. - } - + checkAssertionStatus(); base.evaluate(); } }; } + + // Make sure -ea matches -Dtests.asserts, to catch accidental mis-use: + static void checkAssertionStatus() throws Exception { + var assertsEnabled = LuceneTestCase.class.desiredAssertionStatus(); + if (assertsEnabled != LuceneTestCase.TEST_ASSERTS_ENABLED) { + String msg = "Assertions mismatch: "; + if (assertsEnabled) { + msg += "-ea was specified"; + } else { + msg += "-ea was not specified"; + } + if (LuceneTestCase.TEST_ASSERTS_ENABLED) { + msg += " but -Dtests.asserts=true"; + } else { + msg += " but -Dtests.asserts=false"; + } + System.err.println(msg); + throw new Exception(msg); + } + } } From 63c9a9c194b3065c9bf0b504ca711d8ddde1e914 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 30 Apr 2026 16:40:01 +0200 Subject: [PATCH 38/68] More cleanups. --- .../lucene/tests/util/LuceneTestCase.java | 2 +- .../tests/util/LuceneTestCaseJupiter.java | 23 +++++++++++-- .../TestRuleSetupAndRestoreInstanceEnv.java | 6 ++-- .../tests/util/TestLuceneTestCaseJupiter.java | 34 +++++++++++++++++++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 1985ad37e67d..9b8f04c9904f 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -486,7 +486,7 @@ public void before() { RuleChain.outerRule(testFailureMarker) .around(ignoreAfterMaxFailures) .around(threadAndTestNameRule) - .around(new TestRuleSetupAndRestoreInstanceEnv()) + .around(new CallbacksToRuleAdapter(new TestRuleSetupAndRestoreInstanceEnv())) .around(parentChainCallRule); /** A counter of calls to {@link #random()} if {@link #SYSPROP_RANDOM_MAXACQUIRES} is defined. */ diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 2151c9a0f361..050a8b6347c2 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -43,6 +43,7 @@ import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.DynamicTestInvocationContext; import org.junit.jupiter.api.extension.ExecutableInvoker; import org.junit.jupiter.api.extension.ExtendWith; @@ -97,8 +98,6 @@ - there are class rules and test rules that are still only on junit4 side TestRuleLimitSysouts NoInstanceHooksOverridesRule (?) ignoreAfterMaxFailures -threadAndTestNameRule (?) -TestRuleSetupAndRestoreInstanceEnv */ @Randomized @DetectThreadLeaks(scope = DetectThreadLeaks.Scope.SUITE) @@ -508,6 +507,22 @@ public RandomizedContext captureParameter(RandomizedContext ctx) { } } + static class TestLevelCallbackChain implements BeforeEachCallback, AfterEachCallback { + private OrderedBeforeAfterCallbacks callbacks; + + @Override + public void beforeEach(ExtensionContext context) throws Exception { + this.callbacks = + new OrderedBeforeAfterCallbacks(List.of(new TestRuleSetupAndRestoreInstanceEnv())); + callbacks.before(); + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + callbacks.after(); + } + } + @RegisterExtension @Order(0) static final SuiteFailureTracker suiteFailureTracker = new SuiteFailureTracker(); @@ -524,6 +539,10 @@ public RandomizedContext captureParameter(RandomizedContext ctx) { Objects.requireNonNull(suiteFailureTracker), Objects.requireNonNull(printReproduceInfoExtension)); + @RegisterExtension + @Order(3) + static final TestLevelCallbackChain testLevelCallbackChain = new TestLevelCallbackChain(); + // // Deprecated or removed methods (LuceneTestCase) and other backward-compatibility // infrastructure. diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreInstanceEnv.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreInstanceEnv.java index 4dff8ce4bf80..65f193e75b71 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreInstanceEnv.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestRuleSetupAndRestoreInstanceEnv.java @@ -22,16 +22,16 @@ * Prepares and restores {@link LuceneTestCase} at instance level (fine grained junk that doesn't * fit anywhere else). */ -final class TestRuleSetupAndRestoreInstanceEnv extends AbstractBeforeAfterRule { +final class TestRuleSetupAndRestoreInstanceEnv implements BeforeAfterCallback { private int savedBoolMaxClauseCount; @Override - protected void before() { + public void before() { savedBoolMaxClauseCount = IndexSearcher.getMaxClauseCount(); } @Override - protected void after() { + public void after() { IndexSearcher.setMaxClauseCount(savedBoolMaxClauseCount); } } diff --git a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java index 30a6962b5f2d..32a9a2e8efcd 100644 --- a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java @@ -35,6 +35,7 @@ import java.util.Random; import java.util.function.Supplier; import java.util.stream.Stream; +import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.util.SuppressForbidden; import org.assertj.core.api.Assertions; import org.junit.Assert; @@ -386,6 +387,39 @@ private static String collectOutputFrom(Map } } + @Nested + class BackCompatBehavior { + @Test + public void testIndexWriterIsRestoredAfterEachTest() throws Exception { + try { + AlterIndexSearcher.expectedValue = IndexSearcher.getMaxClauseCount(); + testKitBuilder(AlterIndexSearcher.class) + .execute() + .allEvents() + .assertThatEvents() + .doNotHave(event(finishedWithFailure())); + } finally { + IndexSearcher.setMaxClauseCount(AlterIndexSearcher.expectedValue); + } + } + + static class AlterIndexSearcher extends LuceneTestCaseJupiter { + static int expectedValue; + + @Test + public void t1() { + Assertions.assertThat(IndexSearcher.getMaxClauseCount()).isEqualTo(expectedValue); + IndexSearcher.setMaxClauseCount(expectedValue + 1); + } + + @Test + public void t2() { + Assertions.assertThat(IndexSearcher.getMaxClauseCount()).isEqualTo(expectedValue); + IndexSearcher.setMaxClauseCount(expectedValue + 1); + } + } + } + public static EngineTestKit.Builder testKitBuilder(Class testClass) { return testKitBuilder().selectors(selectClass(testClass)); } From bcf23790344a1db829e93ef17e39e2cc9cc2c4c3 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 1 May 2026 19:17:43 +0200 Subject: [PATCH 39/68] Changes entry and migration guide. --- lucene/CHANGES.txt | 2 ++ lucene/MIGRATE.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 8ef68343e5fb..c2e66a1f9bd0 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -90,6 +90,8 @@ API Changes Also removed QueryParserBase.setDeterminizeWorkLimit/getDeterminizeWorkLimit, which are no longer needed. (Dimitris Rempapis) +* GITHUB#: Add junit5/jupiter support to the test-framework module. (Dawid Weiss) + New Features --------------------- * GITHUB#15505: Upgrade snowball to 2d2e312df56f2ede014a4ffb3e91e6dea43c24be. New stemmer: PolishStemmer (and diff --git a/lucene/MIGRATE.md b/lucene/MIGRATE.md index e7afaaedabd8..1f473a1fab18 100644 --- a/lucene/MIGRATE.md +++ b/lucene/MIGRATE.md @@ -19,6 +19,35 @@ ## Migration from Lucene 10.x to Lucene 11.0 +### JUnit5/jupiter support in the test-framework + +Lucene 11 brings initial support for writing test cases +using JUnit Jupiter. + +The test-framework module exports both junit4 and junit5/jupiter +modules. `LuceneTestCase` remains the parent abstract class for JUnit4 tests. +`LuceneTestCaseJupiter` is the parent class to extend from for JUnit5 +support. + +#### Key changes + +* All tests must be Jupiter tests, typically this means +methods must be annotated with `@Test`. Method prefix +`test*` is not sufficient. Methods that are named `test*` but are not tests +will cause validation errors. +* You can use parameterized tests, dynamic tests, etc. All these are supported. +* You *must not* call the static `random()` method on the parent +class, even though it is there. Add a `Random` parameter to your test methods +or callbacks - it will +be automatically injected by the test framework. See the `memory` +module tests for examples. +* Use `@BeforeEach`, `@AfterEach` and other junit5-specific callback +annotations instead of `setUp` and `tearDown` methods. +* Static utility methods have been pulled up to a parent class +called `LuceneTestCaseParent` but you should reference them either +without an explicit type or via the type of the parent class +for your test framework. The parent class may be removed in the future. + ### Relaxed Index Upgrade Policy (GITHUB#13797) Starting with Lucene 11.0.0, the index upgrade policy has been relaxed to allow safe upgrades across multiple major version numbers without reindexing when no format breaks occur. From 0e9bc321774b5776a7ff2046c7c491ad712cb6f4 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 09:26:01 +0200 Subject: [PATCH 40/68] Replace junit4-specific expectation on thrown exception with plain code. --- .../TestCapitalizationFilter.java | 72 +++++++++++-------- .../TestCodepointCountFilter.java | 8 ++- .../miscellaneous/TestLengthFilter.java | 8 ++- .../TestLimitTokenCountFilter.java | 8 ++- .../TestLimitTokenOffsetFilter.java | 8 ++- .../TestLimitTokenPositionFilter.java | 8 ++- .../TestTruncateTokenFilter.java | 20 ++++-- .../lucene/monitor/TestDocumentBatch.java | 8 ++- .../lucene/spatial3d/geom/TestGeoPoint.java | 8 ++- 9 files changed, 98 insertions(+), 50 deletions(-) diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilter.java index d7fe12b90f77..8b9339e84199 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilter.java @@ -295,42 +295,54 @@ protected TokenStreamComponents createComponents(String fieldName) { } /** checking the validity of constructor arguments */ - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalArguments() throws Exception { - new CapitalizationFilter( - whitespaceMockTokenizer("accept only valid arguments"), - true, - null, - true, - null, - -1, - DEFAULT_MAX_WORD_COUNT, - DEFAULT_MAX_TOKEN_LENGTH); + expectThrows( + IllegalArgumentException.class, + () -> { + new CapitalizationFilter( + whitespaceMockTokenizer("accept only valid arguments"), + true, + null, + true, + null, + -1, + DEFAULT_MAX_WORD_COUNT, + DEFAULT_MAX_TOKEN_LENGTH); + }); } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalArguments1() throws Exception { - new CapitalizationFilter( - whitespaceMockTokenizer("accept only valid arguments"), - true, - null, - true, - null, - 0, - -10, - DEFAULT_MAX_TOKEN_LENGTH); + expectThrows( + IllegalArgumentException.class, + () -> { + new CapitalizationFilter( + whitespaceMockTokenizer("accept only valid arguments"), + true, + null, + true, + null, + 0, + -10, + DEFAULT_MAX_TOKEN_LENGTH); + }); } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalArguments2() throws Exception { - new CapitalizationFilter( - whitespaceMockTokenizer("accept only valid arguments"), - true, - null, - true, - null, - 0, - DEFAULT_MAX_WORD_COUNT, - -50); + expectThrows( + IllegalArgumentException.class, + () -> { + new CapitalizationFilter( + whitespaceMockTokenizer("accept only valid arguments"), + true, + null, + true, + null, + 0, + DEFAULT_MAX_WORD_COUNT, + -50); + }); } } diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCodepointCountFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCodepointCountFilter.java index e9d319bd9714..b2f204fd02b0 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCodepointCountFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCodepointCountFilter.java @@ -70,8 +70,12 @@ public void testRandomStrings() throws IOException { } /** checking the validity of constructor arguments */ - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalArguments() throws Exception { - new CodepointCountFilter(whitespaceMockTokenizer("accept only valid arguments"), 4, 1); + expectThrows( + IllegalArgumentException.class, + () -> { + new CodepointCountFilter(whitespaceMockTokenizer("accept only valid arguments"), 4, 1); + }); } } diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilter.java index 2121a6f34f17..11a71847baef 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilter.java @@ -47,8 +47,12 @@ protected TokenStreamComponents createComponents(String fieldName) { } /** checking the validity of constructor arguments */ - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalArguments() throws Exception { - new LengthFilter(whitespaceMockTokenizer("accept only valid arguments"), -4, -1); + expectThrows( + IllegalArgumentException.class, + () -> { + new LengthFilter(whitespaceMockTokenizer("accept only valid arguments"), -4, -1); + }); } } diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilter.java index 46b7c654ee94..cae9aef40ce5 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilter.java @@ -32,8 +32,12 @@ public void test() throws Exception { } } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalArguments() throws Exception { - new LimitTokenCountFilter(whitespaceMockTokenizer("A1 B2 C3 D4 E5 F6"), -1); + expectThrows( + IllegalArgumentException.class, + () -> { + new LimitTokenCountFilter(whitespaceMockTokenizer("A1 B2 C3 D4 E5 F6"), -1); + }); } } diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenOffsetFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenOffsetFilter.java index 9bf640b9eea0..02168f52a799 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenOffsetFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenOffsetFilter.java @@ -33,8 +33,12 @@ public void test() throws Exception { } } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalArguments() throws Exception { - new LimitTokenOffsetFilter(whitespaceMockTokenizer("A1 B2 C3 D4 E5 F6"), -1); + expectThrows( + IllegalArgumentException.class, + () -> { + new LimitTokenOffsetFilter(whitespaceMockTokenizer("A1 B2 C3 D4 E5 F6"), -1); + }); } } diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilter.java index 9349d35ff662..e6d8b26798a2 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilter.java @@ -120,8 +120,12 @@ public void testMaxPosition3WithSynomyms() throws IOException { } } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalArguments() throws Exception { - new LimitTokenPositionFilter(whitespaceMockTokenizer("one two three four five"), 0); + expectThrows( + IllegalArgumentException.class, + () -> { + new LimitTokenPositionFilter(whitespaceMockTokenizer("one two three four five"), 0); + }); } } diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTruncateTokenFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTruncateTokenFilter.java index 631e4d3f8b6b..4c8841bc0b50 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTruncateTokenFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTruncateTokenFilter.java @@ -124,15 +124,23 @@ protected TokenStreamComponents createComponents(String fieldName) { checkRandomData(rnd, a, 20 * RANDOM_MULTIPLIER, truncateLength * 2); } - @Test(expected = IllegalArgumentException.class) + @Test public void testLegacyNonPositiveLength() throws Exception { - TruncateTokenFilter.truncateAfterChars( - whitespaceMockTokenizer("param must be a positive number"), -48); + expectThrows( + IllegalArgumentException.class, + () -> { + TruncateTokenFilter.truncateAfterChars( + whitespaceMockTokenizer("param must be a positive number"), -48); + }); } - @Test(expected = IllegalArgumentException.class) + @Test public void testNonPositiveLength() throws Exception { - TruncateTokenFilter.truncateAfterCodePoints( - whitespaceMockTokenizer("param must be a positive number"), -48); + expectThrows( + IllegalArgumentException.class, + () -> { + TruncateTokenFilter.truncateAfterCodePoints( + whitespaceMockTokenizer("param must be a positive number"), -48); + }); } } diff --git a/lucene/monitor/src/test/org/apache/lucene/monitor/TestDocumentBatch.java b/lucene/monitor/src/test/org/apache/lucene/monitor/TestDocumentBatch.java index 35b86dd06cd0..e03af88fb92e 100644 --- a/lucene/monitor/src/test/org/apache/lucene/monitor/TestDocumentBatch.java +++ b/lucene/monitor/src/test/org/apache/lucene/monitor/TestDocumentBatch.java @@ -31,9 +31,13 @@ public class TestDocumentBatch extends LuceneTestCase { public static final Analyzer ANALYZER = new StandardAnalyzer(); - @Test(expected = IllegalArgumentException.class) + @Test public void testDocumentBatchThrowsIllegalArgumentExceptionUponZeroDocument() { - DocumentBatch.of(ANALYZER); + expectThrows( + IllegalArgumentException.class, + () -> { + DocumentBatch.of(ANALYZER); + }); } public void testSingleDocumentAndArrayOfOneDocumentResultInSameDocumentBatch() diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPoint.java index de08b065433f..027f7ae6edb4 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPoint.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPoint.java @@ -118,8 +118,12 @@ public void testBisection() { } } - @Test(expected = IllegalArgumentException.class) + @Test public void testBadLatLon() { - new GeoPoint(PlanetModel.SPHERE, 50.0, 32.2); + expectThrows( + IllegalArgumentException.class, + () -> { + new GeoPoint(PlanetModel.SPHERE, 50.0, 32.2); + }); } } From 3db94b6d66a190797f383a86cb4eb10626a661ee Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 09:52:06 +0200 Subject: [PATCH 41/68] claude written scripts to detect junit test annotations on already test* prefixed methods. Useful for refactorings. --- .../FindAnnotatedTestMethods.java | 63 +++++++++++++ .../RemoveRedundantTestAnnotations.java | 91 +++++++++++++++++++ .../remove-redundant-test-annotations.md | 55 +++++++++++ 3 files changed, 209 insertions(+) create mode 100644 dev-tools/refactorings/FindAnnotatedTestMethods.java create mode 100644 dev-tools/refactorings/RemoveRedundantTestAnnotations.java create mode 100644 dev-tools/refactorings/remove-redundant-test-annotations.md diff --git a/dev-tools/refactorings/FindAnnotatedTestMethods.java b/dev-tools/refactorings/FindAnnotatedTestMethods.java new file mode 100644 index 000000000000..93a70ef799d3 --- /dev/null +++ b/dev-tools/refactorings/FindAnnotatedTestMethods.java @@ -0,0 +1,63 @@ +///usr/bin/env jbang "$0" "$@" ; exit $? +//JAVA 17+ +//DEPS com.github.javaparser:javaparser-core:3.25.10 + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParserConfiguration; +import com.github.javaparser.ast.body.MethodDeclaration; + +import java.io.IOException; +import java.nio.file.*; +import java.util.stream.Stream; + +/** + * Finds all methods whose name starts with "test" and that carry a @Test annotation. + * + * Usage: + * jbang FindAnnotatedTestMethods.java [root-directory] + * + * Docker: + * docker run --rm \ + * -v jbang-cache:/root/.jbang/cache \ + * -v "$(pwd)":/workdir \ + * jbangdev/jbang \ + * jbang /workdir/dev-tools/scripts/FindAnnotatedTestMethods.java /workdir + */ +public class FindAnnotatedTestMethods { + + public static void main(String[] args) throws IOException { + Path root = args.length > 0 ? Paths.get(args[0]) : Paths.get("."); + + var config = new ParserConfiguration() + .setLanguageLevel(ParserConfiguration.LanguageLevel.BLEEDING_EDGE); + var parser = new JavaParser(config); + + try (Stream paths = Files.walk(root)) { + paths.filter(p -> p.toString().endsWith(".java")) + .sorted() + .forEach(file -> { + try { + parser.parse(file).getResult().ifPresent(cu -> + cu.findAll(MethodDeclaration.class).stream() + .filter(m -> m.getNameAsString().startsWith("test")) + .filter(m -> m.getAnnotations().stream() + .anyMatch(a -> a.getNameAsString().equals("Test"))) + .forEach(m -> { + int line = m.getBegin().map(p -> p.line).orElse(-1); + String rel = root.relativize(file).toString(); + String ann = m.getAnnotations().stream() + .filter(a -> a.getNameAsString().equals("Test")) + .findFirst() + .map(Object::toString) + .orElse("@Test"); + System.out.printf("%s:%d: %s %s%n", + rel, line, ann, m.getSignature()); + }) + ); + } catch (IOException e) { + System.err.println("# skip: " + file + " — " + e.getMessage()); + } + }); + } + } +} diff --git a/dev-tools/refactorings/RemoveRedundantTestAnnotations.java b/dev-tools/refactorings/RemoveRedundantTestAnnotations.java new file mode 100644 index 000000000000..e4d5b37f333d --- /dev/null +++ b/dev-tools/refactorings/RemoveRedundantTestAnnotations.java @@ -0,0 +1,91 @@ +///usr/bin/env jbang "$0" "$@" ; exit $? +//JAVA 17+ +//DEPS com.github.javaparser:javaparser-core:3.25.10 + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParserConfiguration; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.AnnotationExpr; +import com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter; + +import java.io.IOException; +import java.nio.file.*; +import java.util.List; +import java.util.stream.Stream; + +/** + * Removes redundant @Test annotations from methods whose names already start with "test". + * Also removes the "import org.junit.Test" line if no other @Test usages remain in the file. + * Uses LexicalPreservingPrinter so only the removed nodes are affected; no reformatting occurs. + * + * Usage: + * jbang RemoveRedundantTestAnnotations.java [root-directory] + * + * Docker: + * docker run --rm \ + * -v jbang-cache:/root/.jbang/cache \ + * -v "$(pwd)":/workdir \ + * jbangdev/jbang \ + * /workdir/dev-tools/scripts/RemoveRedundantTestAnnotations.java /workdir + */ +public class RemoveRedundantTestAnnotations { + + public static void main(String[] args) throws IOException { + Path root = args.length > 0 ? Paths.get(args[0]) : Paths.get("."); + + var config = new ParserConfiguration() + .setLanguageLevel(ParserConfiguration.LanguageLevel.BLEEDING_EDGE); + var parser = new JavaParser(config); + + try (Stream paths = Files.walk(root)) { + paths.filter(p -> p.toString().endsWith(".java")) + .sorted() + .forEach(file -> { + try { + var result = parser.parse(file); + if (!result.getResult().isPresent()) { + System.err.println("# parse error: " + file); + return; + } + + CompilationUnit cu = result.getResult().get(); + LexicalPreservingPrinter.setup(cu); + + boolean modified = false; + + for (MethodDeclaration m : cu.findAll(MethodDeclaration.class)) { + if (!m.getNameAsString().startsWith("test")) continue; + + List toRemove = m.getAnnotations().stream() + .filter(a -> a.getNameAsString().equals("Test")) + .toList(); + + for (AnnotationExpr ann : toRemove) { + m.getAnnotations().remove(ann); + modified = true; + } + } + + if (!modified) return; + + // Remove the import if no @Test annotations remain anywhere in the file. + boolean hasOtherTestAnnotations = cu.findAll(AnnotationExpr.class).stream() + .anyMatch(a -> a.getNameAsString().equals("Test")); + + if (!hasOtherTestAnnotations) { + cu.getImports().removeIf(imp -> + imp.getNameAsString().equals("org.junit.Test")); + } + + String rel = root.relativize(file).toString(); + System.out.println(rel); + Files.writeString(file, LexicalPreservingPrinter.print(cu)); + + } catch (IOException e) { + System.err.println("# error: " + file + " — " + e.getMessage()); + } + }); + } + } +} diff --git a/dev-tools/refactorings/remove-redundant-test-annotations.md b/dev-tools/refactorings/remove-redundant-test-annotations.md new file mode 100644 index 000000000000..d713344635cf --- /dev/null +++ b/dev-tools/refactorings/remove-redundant-test-annotations.md @@ -0,0 +1,55 @@ +# Removing redundant @Test annotations from test* methods + +In Lucene's test framework (RandomizedTesting / LuceneTestCase), any method whose name +starts with `test` is automatically discovered as a test — the `@Test` annotation is +redundant on those methods. These scripts find and remove them. + +## Prerequisites + +Docker (no local Java/Maven needed). The named volume `jbang-cache` persists downloaded +jars so the second run is instant. + +## Step 1 — audit (find, don't touch) + +```bash +docker run --rm \ + -v jbang-cache:/root/.jbang/cache \ + -v "$(pwd)":/workdir \ + jbangdev/jbang \ + /workdir/dev-tools/refactorings/FindAnnotatedTestMethods.java /workdir 2>/dev/null +``` + +Output: one line per match — `path/to/File.java:line: @Test methodSignature(...)`. +Pipe through `grep -v '@Test test'` to surface any non-plain `@Test(...)` survivors. + +## Step 2 — remove + +```bash +docker run --rm \ + -v jbang-cache:/root/.jbang/cache \ + -v "$(pwd)":/workdir \ + jbangdev/jbang \ + /workdir/dev-tools/refactorings/RemoveRedundantTestAnnotations.java /workdir 2>/dev/null +``` + +- Prints each modified file path to stdout. +- Uses `LexicalPreservingPrinter` — only the removed annotation node is touched, + no other reformatting occurs. +- Also removes `import org.junit.Test;` from files where no `@Test` usages remain. +- Run it twice if you see output: the second run should produce nothing (idempotent). + +## Known quirks + +**Parse warnings for `_` catch parameters** — files using the Java 21 unnamed-variable +syntax (`catch (IOException _)`) trigger a JavaParser warning under `BLEEDING_EDGE` +language level. The script uses `getResult().isPresent()` (not `isSuccessful()`) so it +proceeds with the partial AST, which is complete enough for annotation removal. + +**Build-tool sources** — `build-tools/build-infra/**` contains Gradle plugin sources +that use Groovy-interop annotations; several fail to parse. None of them contain test +methods, so the failures are harmless. + +## Re-running after new test files are added + +Just run Step 2 again from the repo root. It is idempotent: files with no redundant +annotations are left untouched. From f6231102ca66bc4cce16be9ba4dbeaf9c2c8838a Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 10:00:17 +0200 Subject: [PATCH 42/68] Ignore local dev scripts editor configs. --- dev-tools/refactorings/.editorconfig | 1 + 1 file changed, 1 insertion(+) create mode 100644 dev-tools/refactorings/.editorconfig diff --git a/dev-tools/refactorings/.editorconfig b/dev-tools/refactorings/.editorconfig new file mode 100644 index 000000000000..78b36ca0838f --- /dev/null +++ b/dev-tools/refactorings/.editorconfig @@ -0,0 +1 @@ +root = true From dee2db6b2294862e701c798ecba846efe820422b Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 10:05:43 +0200 Subject: [PATCH 43/68] Drop @Test annotation on methods that are test* prefixed. --- .../analysis/hunspell/TestDictionary.java | 3 - .../analysis/hunspell/TestHunspell.java | 13 ----- .../TestHunspellRepositoryTestCases.java | 2 - .../analysis/minhash/TestMinHashFilter.java | 13 ----- .../TestCapitalizationFilter.java | 4 -- .../TestCodepointCountFilter.java | 2 - .../TestConcatenateGraphFilter.java | 12 ---- .../TestKeywordMarkerFilter.java | 3 - .../miscellaneous/TestLengthFilter.java | 2 - .../TestLimitTokenCountFilter.java | 2 - .../TestLimitTokenOffsetFilter.java | 2 - .../TestLimitTokenPositionFilter.java | 2 - .../TestTruncateTokenFilter.java | 3 - .../TestWord2VecSynonymFilterFactory.java | 1 - .../word2vec/TestWord2VecSynonymProvider.java | 1 - .../ja/TestJapaneseCompletionAnalyzer.java | 5 -- .../ja/TestJapaneseCompletionFilter.java | 3 - .../TestJapaneseCompletionFilterFactory.java | 3 - .../analysis/ja/TestJapaneseNumberFilter.java | 24 -------- .../ja/completion/TestKatakanaRomanizer.java | 3 - .../ja/dict/TestUnknownDictionary.java | 3 - .../analysis/ja/dict/TestUserDictionary.java | 8 --- .../analysis/ko/TestKoreanNumberFilter.java | 22 -------- .../ko/dict/TestUnknownDictionary.java | 3 - .../analysis/ko/dict/TestUserDictionary.java | 3 - .../opennlp/TestOpenNLPTokenizerFactory.java | 5 -- .../byTask/feeds/TestEnwikiContentSource.java | 4 -- .../benchmark/byTask/utils/TestConfig.java | 2 - .../byTask/utils/TestStreamUtils.java | 7 --- .../Test20NewsgroupsClassification.java | 2 - .../classification/TestBM25NBClassifier.java | 5 -- .../TestBooleanPerceptronClassifier.java | 5 -- .../TestCachingNaiveBayesClassifier.java | 5 -- .../TestKNearestFuzzyClassifier.java | 4 -- .../TestKNearestNeighborClassifier.java | 6 -- .../TestSimpleNaiveBayesClassifier.java | 5 -- ...estKNearestNeighborDocumentClassifier.java | 5 -- ...estSimpleNaiveBayesDocumentClassifier.java | 4 -- .../utils/TestConfusionMatrixGenerator.java | 8 --- .../utils/TestDataSplitter.java | 3 - .../utils/TestDocToDoubleVectorUtils.java | 3 - .../tests/TestRuntimeDependenciesSane.java | 5 -- .../lucene/analysis/TestCharacterUtils.java | 4 -- .../TestPrefetchableFlatVectorScorer.java | 2 - .../perfield/TestPerFieldPostingsFormat2.java | 4 -- .../apache/lucene/index/TestCheckIndex.java | 6 -- .../index/TestClassloadingDeadlock.java | 2 - .../index/TestConsistentFieldNumbers.java | 4 -- .../TestDocInverterPerFieldErrorInfo.java | 3 - .../lucene/index/TestFilterIndexInput.java | 2 - .../apache/lucene/index/TestIndexCommit.java | 2 - .../lucene/index/TestIndexWriterConfig.java | 8 --- .../lucene/index/TestIndexWriterReader.java | 2 - .../apache/lucene/index/TestIsCurrent.java | 3 - .../lucene/index/TestNoDeletionPolicy.java | 5 -- .../lucene/index/TestNoMergePolicy.java | 4 -- .../lucene/index/TestNoMergeScheduler.java | 4 -- .../TestOneMergeWrappingMergePolicy.java | 2 - .../TestPersistentSnapshotDeletionPolicy.java | 6 -- .../lucene/index/TestRollingUpdates.java | 2 - .../index/TestSnapshotDeletionPolicy.java | 8 --- .../lucene/internal/hppc/TestCharHashSet.java | 23 -------- .../internal/hppc/TestCharObjectHashMap.java | 29 ---------- .../internal/hppc/TestFloatArrayList.java | 35 ------------ .../internal/hppc/TestIntArrayList.java | 36 ------------ .../internal/hppc/TestIntDoubleHashMap.java | 30 ---------- .../internal/hppc/TestIntFloatHashMap.java | 30 ---------- .../lucene/internal/hppc/TestIntHashSet.java | 23 -------- .../internal/hppc/TestIntIntHashMap.java | 30 ---------- .../internal/hppc/TestIntLongHashMap.java | 31 ---------- .../internal/hppc/TestIntObjectHashMap.java | 29 ---------- .../internal/hppc/TestLongArrayList.java | 36 ------------ .../internal/hppc/TestLongFloatHashMap.java | 30 ---------- .../lucene/internal/hppc/TestLongHashSet.java | 23 -------- .../internal/hppc/TestLongIntHashMap.java | 30 ---------- .../internal/hppc/TestLongObjectHashMap.java | 29 ---------- .../lucene/search/TestBaseRangeFilter.java | 2 - .../apache/lucene/search/TestBoolean2.java | 11 ---- .../lucene/search/TestFilterWeight.java | 2 - ...sionFloatVectorSimilarityValuesSource.java | 2 - .../search/TestFuzzyTermOnShortTerms.java | 2 - .../TestHnswQueueSaturationCollector.java | 5 -- .../lucene/search/TestMultiCollector.java | 4 -- .../search/TestMultiTermConstantScore.java | 7 --- .../lucene/search/TestSimpleExplanations.java | 2 - .../lucene/store/BaseDataOutputTestCase.java | 2 - .../store/TestByteBuffersDataInput.java | 9 --- .../store/TestByteBuffersDataOutput.java | 11 ---- .../store/TestByteBuffersDirectory.java | 2 - .../lucene/store/TestFilterDirectory.java | 2 - .../lucene/store/TestFilterIndexOutput.java | 2 - .../apache/lucene/util/TestBytesRefHash.java | 2 - .../util/TestRecyclingByteBlockAllocator.java | 4 -- .../util/TestRecyclingIntBlockAllocator.java | 4 -- .../lucene/util/TestSentinelIntSet.java | 3 - .../org/apache/lucene/util/TestSetOnce.java | 6 -- .../lucene/util/automaton/TestIntSet.java | 6 -- .../facet/TestAssociationsFacetsExample.java | 3 - .../demo/facet/TestCustomFacetSetExample.java | 5 -- .../facet/TestDynamicRangeFacetsExample.java | 2 - ...estExpressionAggregationFacetsExample.java | 2 - .../TestMultiCategoryListsFacetsExample.java | 2 - .../demo/facet/TestRangeFacetsExample.java | 3 - .../demo/facet/TestSimpleFacetsExample.java | 5 -- .../TestSimpleSortedSetFacetsExample.java | 4 +- .../lucene/distribution/TestModularLayer.java | 9 --- .../lucene/distribution/TestScripts.java | 2 - .../lucene/facet/TestDrillSideways.java | 2 - .../apache/lucene/facet/TestFacetQuery.java | 3 - .../lucene/facet/TestMultipleIndexFields.java | 6 -- .../lucene/facet/taxonomy/TestFacetLabel.java | 13 ----- .../lucene/facet/taxonomy/TestLRUHashMap.java | 2 - .../TestOrdinalMappingLeafReader.java | 2 - .../facet/taxonomy/TestTaxonomyCombined.java | 21 ------- .../taxonomy/TestTaxonomyFacetCounts2.java | 5 -- .../TestDirectoryTaxonomyReader.java | 17 ------ .../TestDirectoryTaxonomyWriter.java | 15 ----- .../TestLruTaxonomyWriterCache.java | 2 - .../matchhighlight/TestMatchHighlighter.java | 7 --- .../TestMatchRegionRetriever.java | 23 -------- .../matchhighlight/TestPassageSelector.java | 1 - .../TestUnifiedHighlighterReanalysis.java | 3 - .../TestUnifiedHighlighterTermVec.java | 2 - .../TestUnifiedHighlighterExtensibility.java | 5 -- .../search/join/TestBlockJoinSorting.java | 4 -- .../lucene/search/join/TestJoinUtil.java | 3 - .../TestParentsChildrenBlockJoinQuery.java | 9 --- .../luke/app/desktop/util/TestListUtils.java | 2 - .../util/inifile/TestSimpleIniFile.java | 5 -- .../models/analysis/TestAnalysisImpl.java | 9 --- .../luke/models/commits/TestCommitsImpl.java | 17 ------ .../documents/TestDocValuesAdapter.java | 7 --- .../models/documents/TestDocumentsImpl.java | 19 +------ .../documents/TestTermVectorsAdapter.java | 5 -- .../models/overview/TestOverviewImpl.java | 18 ------ .../luke/models/overview/TestTermCounts.java | 6 -- .../luke/models/overview/TestTopTerms.java | 2 - .../luke/models/search/TestSearchImpl.java | 18 ------ .../lucene/monitor/TestDocumentBatch.java | 2 - .../lucene/monitor/TestMonitorReadonly.java | 6 -- .../TestCandidateMatcherVisibility.java | 4 -- .../lucene/queries/TestCommonTermsQuery.java | 2 - .../queries/function/TestFieldScoreQuery.java | 9 --- .../function/TestFunctionRangeQuery.java | 10 ---- .../payloads/TestPayloadScoreQuery.java | 7 --- .../lucene/queries/spans/TestFilterSpans.java | 2 - .../queries/spans/TestSpanCollection.java | 4 -- .../spans/TestSpanMultiTermQueryWrapper.java | 2 - .../queries/spans/TestSpanWithinQuery.java | 2 - .../core/builders/TestQueryTreeBuilder.java | 2 - .../core/util/TestUnescapedCharSequence.java | 5 -- .../standard/TestStandardQPEnhancements.java | 24 -------- .../surround/query/TestSrndQuery.java | 2 - .../lucene/spatial/TestDistanceStrategy.java | 3 - .../lucene/spatial/TestPortedSolr3.java | 2 - .../spatial/TestQueryEqualsHashCode.java | 2 - .../lucene/spatial/TestTestFramework.java | 1 - .../lucene/spatial/bbox/TestBBoxStrategy.java | 11 ---- .../composite/TestCompositeStrategy.java | 2 - .../spatial/prefix/TestDateNRStrategy.java | 8 --- .../prefix/TestHeatmapFacetCounter.java | 5 -- .../lucene/spatial/prefix/TestJtsPolygon.java | 3 - .../spatial/prefix/TestNumberRangeFacets.java | 2 - .../TestRandomSpatialOpFuzzyPrefixTree.java | 10 ---- .../TestRecursivePrefixTreeStrategy.java | 4 -- .../TestTermQueryPrefixGridStrategy.java | 2 - .../spatial/prefix/tree/TestS2PrefixTree.java | 4 -- .../prefix/tree/TestSpatialPrefixTree.java | 3 - .../spatial/query/TestSpatialArgsParser.java | 2 - .../serialized/TestSerializedStrategy.java | 4 -- .../spatial4j/ShapeRectRelationTestCase.java | 5 -- .../lucene/spatial/spatial4j/TestGeo3d.java | 3 - .../spatial/spatial4j/TestGeo3dRpt.java | 5 -- ...TestGeo3dShapeSphereModelRectRelation.java | 2 - .../TestGeo3dShapeWGS84ModelRectRelation.java | 3 - .../vector/TestPointVectorStrategy.java | 5 -- .../TestCompositeGeoPolygonRelationships.java | 17 ------ .../lucene/spatial3d/geom/TestGeoBBox.java | 12 ---- .../lucene/spatial3d/geom/TestGeoCircle.java | 8 --- .../spatial3d/geom/TestGeoConvexPolygon.java | 3 - .../spatial3d/geom/TestGeoExactCircle.java | 9 --- .../lucene/spatial3d/geom/TestGeoModel.java | 3 - .../lucene/spatial3d/geom/TestGeoPath.java | 12 ---- .../lucene/spatial3d/geom/TestGeoPoint.java | 5 -- .../lucene/spatial3d/geom/TestGeoPolygon.java | 56 ------------------- .../lucene/spatial3d/geom/TestPlane.java | 5 -- .../spatial3d/geom/TestRandomBinaryCodec.java | 4 -- .../spatial3d/geom/TestRandomGeoPolygon.java | 5 -- .../geom/TestRandomGeoShapeRelationship.java | 6 -- .../spatial3d/geom/TestRandomPlane.java | 4 -- .../TestSimpleGeoPolygonRelationships.java | 15 ----- .../lucene/spatial3d/geom/TestXYZSolid.java | 4 -- .../suggest/TestDocumentDictionary.java | 9 +-- .../TestDocumentValueSourceDictionary.java | 13 ----- .../search/suggest/TestFileDictionary.java | 6 -- .../TestAnalyzingInfixSuggester.java | 2 - .../suggest/document/TestContextQuery.java | 16 ------ .../document/TestContextSuggestField.java | 7 --- .../document/TestFuzzyCompletionQuery.java | 4 -- .../document/TestPrefixCompletionQuery.java | 2 - .../document/TestRegexCompletionQuery.java | 6 -- .../suggest/document/TestSuggestField.java | 18 ------ .../suggest/fst/TestBytesRefSorters.java | 4 -- 203 files changed, 3 insertions(+), 1543 deletions(-) diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestDictionary.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestDictionary.java index 481a3dc0aae4..3482a0215f36 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestDictionary.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestDictionary.java @@ -37,7 +37,6 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.IntsRef; -import org.junit.Test; public class TestDictionary extends LuceneTestCase { @@ -325,7 +324,6 @@ public void testFlagWithCrazyWhitespace() { assertNotNull(Dictionary.getFlagParsingStrategy("FLAG UTF-8", UTF_8)); } - @Test public void testUtf8Flag() { Dictionary.FlagParsingStrategy strategy = Dictionary.getFlagParsingStrategy("FLAG\tUTF-8", Dictionary.DEFAULT_CHARSET); @@ -336,7 +334,6 @@ public void testUtf8Flag() { assertEquals(src, new String(strategy.parseFlags(asAscii))); } - @Test public void testCustomMorphologicalData() throws IOException, ParseException { Dictionary dic = loadDictionary("morphdata.aff", "morphdata.dic"); assertNull(dic.lookupEntries("nonexistent")); diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspell.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspell.java index cbb876262ebe..9521117bd022 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspell.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspell.java @@ -37,7 +37,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestHunspell extends LuceneTestCase { public void testCheckCanceled() throws Exception { @@ -108,14 +107,12 @@ public void testSuggestionTimeLimit() throws IOException, ParseException { assertEquals(Collections.emptyList(), noLimit.suggest(word.substring(0, 5), timeLimitMs)); } - @Test public void testStemmingApi() throws Exception { Hunspell hunspell = loadNoTimeout("simple"); assertEquals(Collections.singletonList("apach"), hunspell.getRoots("apache")); assertEquals(Collections.singletonList("foo"), hunspell.getRoots("foo")); } - @Test public void testAnalysisApi() throws Exception { Hunspell hunspell = loadNoTimeout("base"); assertEquals(hunspell.analyzeSimpleWord("nonexistent"), List.of()); @@ -123,26 +120,22 @@ public void testAnalysisApi() throws Exception { checkAffixedWord(word, "create", List.of("A"), List.of("D")); } - @Test public void testAnalysisSeveralSuffixes() throws Exception { Hunspell hunspell = loadNoTimeout("needaffix5"); AffixedWord word = hunspell.analyzeSimpleWord("pseudoprefoopseudosufbar").get(0); checkAffixedWord(word, "foo", List.of("C"), List.of("B", "A")); } - @Test public void testAnalysisFlagLong() throws Exception { AffixedWord word = loadNoTimeout("flaglong").analyzeSimpleWord("foos").get(0); checkAffixedWord(word, "foo", List.of(), List.of("Y1")); } - @Test public void testAnalysisFlagNum() throws Exception { AffixedWord word = loadNoTimeout("flagnum").analyzeSimpleWord("foos").get(0); checkAffixedWord(word, "foo", List.of(), List.of("65000")); } - @Test public void testAnalysisMorphData() throws Exception { List words = loadNoTimeout("morphdata").analyzeSimpleWord("works"); assertEquals(2, words.size()); @@ -175,7 +168,6 @@ private static Hunspell loadNoTimeout(Dictionary dictionary) { return new Hunspell(dictionary, TimeoutPolicy.NO_TIMEOUT, () -> {}); } - @Test public void testExpandRootApi() throws Exception { Hunspell h = loadNoTimeout("base"); String[] createFormsBase = { @@ -208,7 +200,6 @@ public void testExpandRootApi() throws Exception { nonExistentRoot.stream().map(w -> w.getWord()).collect(Collectors.toSet())); } - @Test public void testCompressingApi() throws Exception { Hunspell h = loadNoTimeout("base"); String[] createQuery = {"create", "created", "creates", "creating", "creation"}; @@ -222,7 +213,6 @@ public void testCompressingApi() throws Exception { loadNoTimeout("compress"), "toEdit=[], toAdd=[form/X], extra=[forms]", "form", "formx"); } - @Test public void testCompressingIsMinimal() throws Exception { Hunspell h = loadNoTimeout("compress"); checkCompression( @@ -236,14 +226,12 @@ public void testCompressingIsMinimal() throws Exception { assertEquals("toEdit=[], toAdd=[f/abc], extra=[]", fAbc.internalsToString()); } - @Test public void testCompressingIsFastOnLargeUnrelatedWordSets() throws Exception { Hunspell h = loadNoTimeout("compress"); String[] letters = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"}; checkCompression(h, "toEdit=[], toAdd=[a, b, c, d, e, f, g, h, i, j, k, l], extra=[]", letters); } - @Test public void testCompressingWithProhibition() throws Exception { WordFormGenerator gen = new WordFormGenerator(loadNoTimeout("compress").dictionary); assertEquals( @@ -258,7 +246,6 @@ private void checkCompression(Hunspell h, String expected, String... words) { assertEquals(expected, h.compress(List.of(words)).internalsToString()); } - @Test public void testSuggestionOrderStabilityOnDictionaryEditing() throws IOException, ParseException { String original = "some_word"; diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspellRepositoryTestCases.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspellRepositoryTestCases.java index 2ce977bfb7fe..bfa41d739a48 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspellRepositoryTestCases.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspellRepositoryTestCases.java @@ -25,7 +25,6 @@ import java.util.TreeSet; import org.junit.Assert; import org.junit.AssumptionViolatedException; -import org.junit.Test; import org.junit.function.ThrowingRunnable; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -74,7 +73,6 @@ public static Collection data() throws IOException { return names.stream().map(s -> new Object[] {s, tests.resolve(s)}).toList(); } - @Test public void test() throws Throwable { ThrowingRunnable test = () -> TestSpellChecking.checkSpellCheckerExpectations(pathPrefix); if (EXPECTED_FAILURES.contains(testName)) { diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/minhash/TestMinHashFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/minhash/TestMinHashFilter.java index 47d2061f2a9c..37e71dbb2da2 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/minhash/TestMinHashFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/minhash/TestMinHashFilter.java @@ -33,12 +33,10 @@ import org.apache.lucene.util.automaton.CharacterRunAutomaton; import org.apache.lucene.util.automaton.Operations; import org.apache.lucene.util.automaton.RegExp; -import org.junit.Test; /** Tests for {@link MinHashFilter} */ public class TestMinHashFilter extends BaseTokenStreamTestCase { - @Test public void testIntHash() { LongPair hash = new LongPair(); MinHashFilter.murmurhash3_x64_128(MinHashFilter.getBytes(0), 0, 4, 0, hash); @@ -46,7 +44,6 @@ public void testIntHash() { assertEquals(6383328099726337777L, hash.val2); } - @Test public void testStringHash() { LongPair hash = new LongPair(); byte[] bytes = "woof woof woof woof woof".getBytes(StandardCharsets.UTF_16LE); @@ -55,7 +52,6 @@ public void testStringHash() { assertEquals(4378804943379391304L, hash.val2); } - @Test public void testSimpleOrder() { LongPair hash1 = new LongPair(); hash1.val1 = 1; @@ -66,7 +62,6 @@ public void testSimpleOrder() { assert (hash1.compareTo(hash2) > 0); } - @Test public void testHashOrder() { assertTrue(!MinHashFilter.isLessThanUnsigned(0L, 0L)); assertTrue(MinHashFilter.isLessThanUnsigned(0L, -1L)); @@ -137,7 +132,6 @@ public void testCollisions() { } } - @Test public void testHashNotRepeated() { FixedSizeTreeSet minSet = new FixedSizeTreeSet<>(500); HashSet unadded = new HashSet<>(); @@ -170,7 +164,6 @@ public void testHashNotRepeated() { } } - @Test public void testMockShingleTokenizer() throws IOException { Tokenizer mockShingleTokenizer = createMockShingleTokenizer( @@ -180,7 +173,6 @@ public void testMockShingleTokenizer() throws IOException { new String[] {"woof woof woof woof woof", "woof woof woof woof puff"}); } - @Test public void testTokenStreamSingleInput() throws IOException { String[] hashes = new String[] {"℁팽徭聙↝ꇁ홱杯"}; TokenStream ts = createTokenStream(5, "woof woof woof woof woof", 1, 1, 100, false); @@ -217,7 +209,6 @@ public void testTokenStreamSingleInput() throws IOException { null); } - @Test public void testTokenStream1() throws IOException { String[] hashes = new String[] { @@ -258,7 +249,6 @@ private ArrayList getTokens(TokenStream ts) throws IOException { return tokens; } - @Test public void testTokenStream2() throws IOException { TokenStream ts = createTokenStream( @@ -269,7 +259,6 @@ public void testTokenStream2() throws IOException { assertEquals(100, tokens.size()); } - @Test public void testTokenStream3() throws IOException { TokenStream ts = createTokenStream( @@ -280,7 +269,6 @@ public void testTokenStream3() throws IOException { assertEquals(20, tokens.size()); } - @Test public void testTokenStream4() throws IOException { TokenStream ts = createTokenStream( @@ -299,7 +287,6 @@ public void testTokenStream4() throws IOException { assertEquals(100, tokens.size()); } - @Test public void testTokenStream5() throws IOException { TokenStream ts = createTokenStream( diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilter.java index 8b9339e84199..f82950427b0d 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilter.java @@ -31,7 +31,6 @@ import org.apache.lucene.analysis.core.KeywordTokenizer; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.apache.lucene.tests.analysis.MockTokenizer; -import org.junit.Test; /** Tests {@link CapitalizationFilter} */ public class TestCapitalizationFilter extends BaseTokenStreamTestCase { @@ -295,7 +294,6 @@ protected TokenStreamComponents createComponents(String fieldName) { } /** checking the validity of constructor arguments */ - @Test public void testIllegalArguments() throws Exception { expectThrows( IllegalArgumentException.class, @@ -312,7 +310,6 @@ public void testIllegalArguments() throws Exception { }); } - @Test public void testIllegalArguments1() throws Exception { expectThrows( IllegalArgumentException.class, @@ -329,7 +326,6 @@ public void testIllegalArguments1() throws Exception { }); } - @Test public void testIllegalArguments2() throws Exception { expectThrows( IllegalArgumentException.class, diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCodepointCountFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCodepointCountFilter.java index b2f204fd02b0..350b07d1f503 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCodepointCountFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCodepointCountFilter.java @@ -24,7 +24,6 @@ import org.apache.lucene.analysis.core.KeywordTokenizer; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.apache.lucene.tests.util.TestUtil; -import org.junit.Test; public class TestCodepointCountFilter extends BaseTokenStreamTestCase { public void testFilterWithPosIncr() throws Exception { @@ -70,7 +69,6 @@ public void testRandomStrings() throws IOException { } /** checking the validity of constructor arguments */ - @Test public void testIllegalArguments() throws Exception { expectThrows( IllegalArgumentException.class, diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestConcatenateGraphFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestConcatenateGraphFilter.java index 48a331237faf..de06ba50b941 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestConcatenateGraphFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestConcatenateGraphFilter.java @@ -29,13 +29,11 @@ import org.apache.lucene.tests.analysis.MockTokenizer; import org.apache.lucene.util.CharsRef; import org.apache.lucene.util.CharsRefBuilder; -import org.junit.Test; public class TestConcatenateGraphFilter extends BaseTokenStreamTestCase { private static final char SEP_LABEL = (char) ConcatenateGraphFilter.SEP_LABEL; - @Test public void testBasic() throws Exception { Tokenizer tokenStream = new MockTokenizer(MockTokenizer.WHITESPACE, true); String input = "mykeyword"; @@ -44,7 +42,6 @@ public void testBasic() throws Exception { assertTokenStreamContents(stream, new String[] {input}, null, null, new int[] {1}); } - @Test public void testWithNoPreserveSep() throws Exception { Tokenizer tokenStream = new MockTokenizer(MockTokenizer.WHITESPACE, true); String input = "mykeyword another keyword"; @@ -54,7 +51,6 @@ public void testWithNoPreserveSep() throws Exception { stream, new String[] {"mykeywordanotherkeyword"}, null, null, new int[] {1}); } - @Test public void testWithMultipleTokens() throws Exception { Tokenizer tokenStream = new MockTokenizer(MockTokenizer.WHITESPACE, true); String input = "mykeyword another keyword"; @@ -70,7 +66,6 @@ public void testWithMultipleTokens() throws Exception { stream, new String[] {builder.toCharsRef().toString()}, null, null, new int[] {1}); } - @Test public void testWithSynonym() throws Exception { SynonymMap.Builder builder = new SynonymMap.Builder(true); builder.add(new CharsRef("mykeyword"), new CharsRef("mysynonym"), true); @@ -83,7 +78,6 @@ public void testWithSynonym() throws Exception { stream, new String[] {"mykeyword", "mysynonym"}, null, null, new int[] {1, 0}); } - @Test public void testWithSynonyms() throws Exception { SynonymMap.Builder builder = new SynonymMap.Builder(true); builder.add(new CharsRef("mykeyword"), new CharsRef("mysynonym"), true); @@ -111,7 +105,6 @@ public void testWithSynonyms() throws Exception { assertTokenStreamContents(stream, expectedOutputs, null, null, new int[] {1, 0}); } - @Test public void testWithStopword() throws Exception { for (boolean preservePosInc : new boolean[] {true, false}) { Tokenizer tokenStream = new MockTokenizer(MockTokenizer.WHITESPACE, true); @@ -137,7 +130,6 @@ public void testWithStopword() throws Exception { } } - @Test public void testValidNumberOfExpansions() throws IOException { SynonymMap.Builder builder = new SynonymMap.Builder(true); for (int i = 0; i < 256; i++) { @@ -174,7 +166,6 @@ public void testEmpty() throws IOException { assertTokenStreamContents(filter, new String[0]); } - @Test public void testSeparator() throws IOException { Tokenizer tokenStream = new MockTokenizer(MockTokenizer.SIMPLE, true); String input = "...mykeyword.another.keyword."; @@ -185,7 +176,6 @@ public void testSeparator() throws IOException { stream, new String[] {"mykeyword another keyword"}, null, null, new int[] {1}); } - @Test public void testSeparatorWithStopWords() throws IOException { Tokenizer tokenStream = new MockTokenizer(MockTokenizer.WHITESPACE, false); String input = "A B C D E F J H"; @@ -197,7 +187,6 @@ public void testSeparatorWithStopWords() throws IOException { assertTokenStreamContents(stream, new String[] {"B-C-F-H"}, null, null, new int[] {1}); } - @Test public void testSeparatorWithStopWordsAndPreservePositionIncrements() throws IOException { Tokenizer tokenStream = new MockTokenizer(MockTokenizer.WHITESPACE, false); String input = "A B C D E F J H"; @@ -209,7 +198,6 @@ public void testSeparatorWithStopWordsAndPreservePositionIncrements() throws IOE assertTokenStreamContents(stream, new String[] {"-B-C---F--H"}, null, null, new int[] {1}); } - @Test public void testSeparatorWithSynonyms() throws IOException { SynonymMap.Builder builder = new SynonymMap.Builder(true); builder.add(new CharsRef("mykeyword"), new CharsRef("mysynonym"), true); diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeywordMarkerFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeywordMarkerFilter.java index 3652a2b5d14a..6ab2682cdd73 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeywordMarkerFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeywordMarkerFilter.java @@ -25,12 +25,10 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.analysis.tokenattributes.KeywordAttribute; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; -import org.junit.Test; /** Testcase for {@link KeywordMarkerFilter} */ public class TestKeywordMarkerFilter extends BaseTokenStreamTestCase { - @Test public void testSetFilterIncrementToken() throws IOException { CharArraySet set = new CharArraySet(5, true); set.add("lucenefox"); @@ -54,7 +52,6 @@ public void testSetFilterIncrementToken() throws IOException { output); } - @Test public void testPatternFilterIncrementToken() throws IOException { String[] output = new String[] {"the", "quick", "brown", "LuceneFox", "jumps"}; assertTokenStreamContents( diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilter.java index 11a71847baef..7a94ab0f385e 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilter.java @@ -22,7 +22,6 @@ import org.apache.lucene.analysis.Tokenizer; import org.apache.lucene.analysis.core.KeywordTokenizer; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; -import org.junit.Test; public class TestLengthFilter extends BaseTokenStreamTestCase { @@ -47,7 +46,6 @@ protected TokenStreamComponents createComponents(String fieldName) { } /** checking the validity of constructor arguments */ - @Test public void testIllegalArguments() throws Exception { expectThrows( IllegalArgumentException.class, diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilter.java index cae9aef40ce5..c864dbf6130b 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilter.java @@ -19,7 +19,6 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.apache.lucene.tests.analysis.MockTokenizer; -import org.junit.Test; public class TestLimitTokenCountFilter extends BaseTokenStreamTestCase { @@ -32,7 +31,6 @@ public void test() throws Exception { } } - @Test public void testIllegalArguments() throws Exception { expectThrows( IllegalArgumentException.class, diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenOffsetFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenOffsetFilter.java index 02168f52a799..dd678d8cbd1c 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenOffsetFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenOffsetFilter.java @@ -19,7 +19,6 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.apache.lucene.tests.analysis.MockTokenizer; -import org.junit.Test; public class TestLimitTokenOffsetFilter extends BaseTokenStreamTestCase { @@ -33,7 +32,6 @@ public void test() throws Exception { } } - @Test public void testIllegalArguments() throws Exception { expectThrows( IllegalArgumentException.class, diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilter.java index e6d8b26798a2..1b26f2f40bae 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilter.java @@ -26,7 +26,6 @@ import org.apache.lucene.tests.analysis.MockTokenizer; import org.apache.lucene.util.CharsRef; import org.apache.lucene.util.CharsRefBuilder; -import org.junit.Test; public class TestLimitTokenPositionFilter extends BaseTokenStreamTestCase { @@ -120,7 +119,6 @@ public void testMaxPosition3WithSynomyms() throws IOException { } } - @Test public void testIllegalArguments() throws Exception { expectThrows( IllegalArgumentException.class, diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTruncateTokenFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTruncateTokenFilter.java index 4c8841bc0b50..7d7f9ed0a66b 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTruncateTokenFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTruncateTokenFilter.java @@ -23,7 +23,6 @@ import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.apache.lucene.tests.analysis.MockTokenizer; import org.apache.lucene.tests.util.TestUtil; -import org.junit.Test; /** Test the truncate token filter. */ public class TestTruncateTokenFilter extends BaseTokenStreamTestCase { @@ -124,7 +123,6 @@ protected TokenStreamComponents createComponents(String fieldName) { checkRandomData(rnd, a, 20 * RANDOM_MULTIPLIER, truncateLength * 2); } - @Test public void testLegacyNonPositiveLength() throws Exception { expectThrows( IllegalArgumentException.class, @@ -134,7 +132,6 @@ public void testLegacyNonPositiveLength() throws Exception { }); } - @Test public void testNonPositiveLength() throws Exception { expectThrows( IllegalArgumentException.class, diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/word2vec/TestWord2VecSynonymFilterFactory.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/word2vec/TestWord2VecSynonymFilterFactory.java index 007fedf4abed..0a40b53f3e18 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/word2vec/TestWord2VecSynonymFilterFactory.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/word2vec/TestWord2VecSynonymFilterFactory.java @@ -27,7 +27,6 @@ public class TestWord2VecSynonymFilterFactory extends BaseTokenStreamFactoryTest public static final String FACTORY_NAME = "Word2VecSynonym"; private static final String WORD2VEC_MODEL_FILE = "word2vec-model.zip"; - @Test public void testInform() throws Exception { ResourceLoader loader = new ClasspathResourceLoader(getClass()); assertTrue("loader is null and it shouldn't be", loader != null); diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/word2vec/TestWord2VecSynonymProvider.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/word2vec/TestWord2VecSynonymProvider.java index cc64f9fde02d..77b18128e954 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/word2vec/TestWord2VecSynonymProvider.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/word2vec/TestWord2VecSynonymProvider.java @@ -107,7 +107,6 @@ public void noSynonymsWithinAcceptedSimilarity_shouldReturnNoSynonyms() throws E assertEquals(0, actualSynonymsResults.size()); } - @Test public void testModel_shouldReturnNormalizedVectors() { Word2VecModel model = new Word2VecModel(4, 2); model.addTermAndVector(new TermAndVector(new BytesRef("a"), new float[] {10, 10})); diff --git a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionAnalyzer.java b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionAnalyzer.java index 8077ed025509..bf3c3e3f38a5 100644 --- a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionAnalyzer.java +++ b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionAnalyzer.java @@ -20,11 +20,9 @@ import java.util.Random; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; -import org.junit.Test; public class TestJapaneseCompletionAnalyzer extends BaseTokenStreamTestCase { - @Test public void testCompletionDefault() throws IOException { // mode=INDEX (default) Analyzer analyzer = new JapaneseCompletionAnalyzer(); @@ -38,7 +36,6 @@ public void testCompletionDefault() throws IOException { analyzer.close(); } - @Test public void testCompletionQuery() throws IOException { // mode=QUERY Analyzer analyzer = new JapaneseCompletionAnalyzer(null, JapaneseCompletionFilter.Mode.QUERY); @@ -53,7 +50,6 @@ public void testCompletionQuery() throws IOException { } /** blast random strings against the analyzer */ - @Test public void testRandom() throws IOException { Random random = random(); final Analyzer a = new JapaneseCompletionAnalyzer(); @@ -62,7 +58,6 @@ public void testRandom() throws IOException { } /** blast some random large strings through the analyzer */ - @Test public void testRandomHugeStrings() throws Exception { Random random = random(); final Analyzer a = new JapaneseCompletionAnalyzer(); diff --git a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionFilter.java b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionFilter.java index 20f55f7e89bf..b6edc1ca1c88 100644 --- a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionFilter.java +++ b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionFilter.java @@ -24,7 +24,6 @@ import org.apache.lucene.analysis.core.KeywordTokenizer; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.apache.lucene.util.IOUtils; -import org.junit.Test; public class TestJapaneseCompletionFilter extends BaseTokenStreamTestCase { private Analyzer indexAnalyzer; @@ -82,7 +81,6 @@ public void tearDown() throws Exception { super.tearDown(); } - @Test public void testCompletionIndex() throws IOException { assertAnalyzesTo( indexAnalyzer, @@ -144,7 +142,6 @@ public void testCompletionIndex() throws IOException { new int[] {1, 0, 1, 1, 0}); } - @Test public void testCompletionQuery() throws IOException { assertAnalyzesTo( queryAnalyzer, diff --git a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionFilterFactory.java b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionFilterFactory.java index 5f30d8f90cbd..4ed124842d2d 100644 --- a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionFilterFactory.java +++ b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionFilterFactory.java @@ -24,10 +24,8 @@ import org.apache.lucene.analysis.Tokenizer; import org.apache.lucene.analysis.cjk.CJKWidthFilterFactory; import org.apache.lucene.tests.analysis.BaseTokenStreamFactoryTestCase; -import org.junit.Test; public class TestJapaneseCompletionFilterFactory extends BaseTokenStreamFactoryTestCase { - @Test public void testCompletion() throws IOException { JapaneseTokenizerFactory tokenizerFactory = new JapaneseTokenizerFactory(new HashMap<>()); TokenStream tokenStream = tokenizerFactory.create(); @@ -41,7 +39,6 @@ public void testCompletion() throws IOException { } /** Test that bogus arguments result in exception */ - @Test public void testBogusArguments() throws Exception { IllegalArgumentException expected = expectThrows( diff --git a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseNumberFilter.java b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseNumberFilter.java index ced49e2fe74f..962caa7041ec 100644 --- a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseNumberFilter.java +++ b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseNumberFilter.java @@ -31,7 +31,6 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.junit.Ignore; -import org.junit.Test; public class TestJapaneseNumberFilter extends BaseTokenStreamTestCase { private Analyzer analyzer; @@ -57,7 +56,6 @@ public void tearDown() throws Exception { super.tearDown(); } - @Test public void testBasics() throws IOException { assertAnalyzesTo( @@ -82,7 +80,6 @@ public void testBasics() throws IOException { new int[] {5, 6, 8, 9, 10, 14, 15, 17}); } - @Test public void testVariants() throws IOException { // Test variants of three assertAnalyzesTo(analyzer, "3", new String[] {"3"}); @@ -106,7 +103,6 @@ public void testVariants() throws IOException { assertAnalyzesTo(analyzer, "10百", new String[] {"1000"}); // Strange, but supported } - @Test public void testLargeVariants() throws IOException { // Test large numbers assertAnalyzesTo(analyzer, "三五七八九", new String[] {"35789"}); @@ -118,19 +114,16 @@ public void testLargeVariants() throws IOException { assertAnalyzesTo(analyzer, "垓京兆億万千百十一", new String[] {"100010001000100011111"}); } - @Test public void testNegative() throws IOException { assertAnalyzesTo(analyzer, "-100万", new String[] {"-", "1000000"}); } - @Test public void testMixed() throws IOException { // Test mixed numbers assertAnalyzesTo(analyzer, "三千2百2十三", new String[] {"3223"}); assertAnalyzesTo(analyzer, "32二三", new String[] {"3223"}); } - @Test public void testNininsankyaku() throws IOException { // Unstacked tokens assertAnalyzesTo(analyzer, "二", new String[] {"2"}); @@ -140,13 +133,11 @@ public void testNininsankyaku() throws IOException { assertAnalyzesTo(analyzer, "二人三脚", new String[] {"二", "二人三脚", "人", "三", "脚"}); } - @Test public void testFujiyaichinisanu() throws IOException { // Stacked tokens with a numeral partial assertAnalyzesTo(analyzer, "不二家一二三", new String[] {"不", "不二家", "二", "家", "123"}); } - @Test public void testFunny() throws IOException { // Test some oddities for inconsistent input assertAnalyzesTo(analyzer, "十十", new String[] {"20"}); // 100? @@ -154,7 +145,6 @@ public void testFunny() throws IOException { assertAnalyzesTo(analyzer, "千千千千", new String[] {"4000"}); // 1,000,000,000,000? } - @Test public void testKanjiArabic() throws IOException { // Test kanji numerals used as Arabic numbers (with head zero) assertAnalyzesTo(analyzer, "〇一二三四五六七八九九八七六五四三二一〇", new String[] {"1234567899876543210"}); @@ -163,13 +153,11 @@ public void testKanjiArabic() throws IOException { assertAnalyzesTo(analyzer, "〇〇七", new String[] {"7"}); } - @Test public void testDoubleZero() throws IOException { assertAnalyzesTo( analyzer, "〇〇", new String[] {"0"}, new int[] {0}, new int[] {2}, new int[] {1}); } - @Test public void testName() throws IOException { // Test name that normalises to number assertAnalyzesTo( @@ -206,61 +194,50 @@ protected TokenStreamComponents createComponents(String fieldName) { keywordMarkingAnalyzer.close(); } - @Test public void testDecimal() throws IOException { // Test Arabic numbers with punctuation, i.e. 3.2 thousands assertAnalyzesTo(analyzer, "1.2万345.67", new String[] {"12345.67"}); } - @Test public void testDecimalPunctuation() throws IOException { // Test Arabic numbers with punctuation, i.e. 3.2 thousands yen assertAnalyzesTo(analyzer, "3.2千円", new String[] {"3200", "円"}); } - @Test public void testThousandSeparator() throws IOException { assertAnalyzesTo(analyzer, "4,647", new String[] {"4647"}); } - @Test public void testDecimalThousandSeparator() throws IOException { assertAnalyzesTo(analyzer, "4,647.0010", new String[] {"4647.001"}); } - @Test public void testCommaDecimalSeparator() throws IOException { assertAnalyzesTo(analyzer, "15,7", new String[] {"157"}); } - @Test public void testTrailingZeroStripping() throws IOException { assertAnalyzesTo(analyzer, "1000.1000", new String[] {"1000.1"}); assertAnalyzesTo(analyzer, "1000.0000", new String[] {"1000"}); } - @Test public void testEmpty() throws IOException { assertAnalyzesTo(analyzer, "", new String[] {}); } - @Test public void testRandomHugeStrings() throws Exception { checkRandomData(random(), analyzer, RANDOM_MULTIPLIER, 4096); } - @Test @Nightly public void testRandomHugeStringsAtNight() throws Exception { checkRandomData(random(), analyzer, 3 * RANDOM_MULTIPLIER, 8192); } - @Test public void testRandomSmallStrings() throws Exception { checkRandomData(random(), analyzer, 100 * RANDOM_MULTIPLIER, 128); } - @Test public void testFunnyIssue() throws Exception { BaseTokenStreamTestCase.checkAnalysisConsistency( random(), analyzer, true, "〇〇\u302f\u3029\u3039\u3023\u3033\u302bB", true); @@ -268,7 +245,6 @@ public void testFunnyIssue() throws Exception { @Ignore( "This test is used during development when analyze normalizations in large amounts of text") - @Test public void testLargeData() throws IOException { Path input = Paths.get("/tmp/test.txt"); Path tokenizedOutput = Paths.get("/tmp/test.tok.txt"); diff --git a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/completion/TestKatakanaRomanizer.java b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/completion/TestKatakanaRomanizer.java index d6611209a748..a03e9e23f974 100644 --- a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/completion/TestKatakanaRomanizer.java +++ b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/completion/TestKatakanaRomanizer.java @@ -19,12 +19,10 @@ import java.util.List; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.CharsRef; -import org.junit.Test; public class TestKatakanaRomanizer extends LuceneTestCase { private final KatakanaRomanizer romanizer = KatakanaRomanizer.getInstance(); - @Test public void testRomanize() { assertCharsRefListEqualsUnordered( List.of(new CharsRef("hasi"), new CharsRef("hashi")), @@ -47,7 +45,6 @@ public void testRomanize() { romanizer.romanize(new CharsRef("ヴォルテール"))); } - @Test public void testRomanizeWithAlphabets() { assertCharsRefListEqualsUnordered( List.of(new CharsRef("toukyout")), romanizer.romanize(new CharsRef("トウキョウt"))); diff --git a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/dict/TestUnknownDictionary.java b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/dict/TestUnknownDictionary.java index 2d245c7a599c..d5a318c43e27 100644 --- a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/dict/TestUnknownDictionary.java +++ b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/dict/TestUnknownDictionary.java @@ -18,12 +18,10 @@ import org.apache.lucene.analysis.util.CSVUtil; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestUnknownDictionary extends LuceneTestCase { public static final String FILENAME = "unk-tokeninfo-dict.obj"; - @Test public void testPutCharacterCategory() { UnknownDictionaryWriter unkDic = new UnknownDictionaryWriter(10 * 1024 * 1024); @@ -38,7 +36,6 @@ public void testPutCharacterCategory() { unkDic.putCharacterCategory(4, "KANJI"); } - @Test public void testPut() { UnknownDictionaryWriter unkDic = new UnknownDictionaryWriter(10 * 1024 * 1024); expectThrows( diff --git a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/dict/TestUserDictionary.java b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/dict/TestUserDictionary.java index 537d621016e6..af069ad1124c 100644 --- a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/dict/TestUserDictionary.java +++ b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/dict/TestUserDictionary.java @@ -20,11 +20,9 @@ import java.io.StringReader; import org.apache.lucene.analysis.ja.TestJapaneseTokenizer; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestUserDictionary extends LuceneTestCase { - @Test public void testLookup() throws IOException { UserDictionary dictionary = TestJapaneseTokenizer.readDict(); String s = "関西国際空港に行った"; @@ -48,7 +46,6 @@ public void testLookup() throws IOException { assertEquals(6, dictionaryEntryResult2.length); } - @Test public void testReadings() throws IOException { UserDictionary dictionary = TestJapaneseTokenizer.readDict(); int[][] result = dictionary.lookup("日本経済新聞".toCharArray(), 0, 6); @@ -65,7 +62,6 @@ public void testReadings() throws IOException { dictionary.getMorphAttributes().getReading(wordIdAsashoryu, "朝青龍".toCharArray(), 0, 3)); } - @Test public void testPartOfSpeech() throws IOException { UserDictionary dictionary = TestJapaneseTokenizer.readDict(); int[][] result = dictionary.lookup("日本経済新聞".toCharArray(), 0, 6); @@ -74,13 +70,11 @@ public void testPartOfSpeech() throws IOException { assertEquals("カスタム名詞", dictionary.getMorphAttributes().getPartOfSpeech(wordIdKeizai)); } - @Test public void testRead() throws IOException { UserDictionary dictionary = TestJapaneseTokenizer.readDict(); assertNotNull(dictionary); } - @Test public void testReadInvalid1() throws IOException { // the concatenated segment must be the same as the surface form String invalidEntry = "日経新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞"; @@ -92,7 +86,6 @@ public void testReadInvalid1() throws IOException { assertTrue(e.getMessage().contains("does not match the surface form")); } - @Test public void testReadInvalid2() throws IOException { // the concatenated segment must be the same as the surface form String invalidEntry = "日本経済新聞,日経 新聞,ニッケイ シンブン,カスタム名詞"; @@ -104,7 +97,6 @@ public void testReadInvalid2() throws IOException { assertTrue(e.getMessage().contains("does not match the surface form")); } - @Test public void testSharp() throws IOException { String[] inputs = {"テスト#", "テスト#テスト"}; UserDictionary dictionary = TestJapaneseTokenizer.readDict(); diff --git a/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/TestKoreanNumberFilter.java b/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/TestKoreanNumberFilter.java index 02409a692633..2bc26baa9e90 100644 --- a/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/TestKoreanNumberFilter.java +++ b/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/TestKoreanNumberFilter.java @@ -36,7 +36,6 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.junit.Ignore; -import org.junit.Test; public class TestKoreanNumberFilter extends BaseTokenStreamTestCase { private Analyzer analyzer; @@ -86,7 +85,6 @@ public void tearDown() throws Exception { super.tearDown(); } - @Test public void testBasics() throws IOException { assertAnalyzesTo( @@ -113,7 +111,6 @@ public void testBasics() throws IOException { new int[] {2, 3, 8, 10, 11}); } - @Test public void testVariants() throws IOException { // Test variants of three assertAnalyzesTo(analyzer, "3", new String[] {"3"}); @@ -137,7 +134,6 @@ public void testVariants() throws IOException { assertAnalyzesTo(analyzer, "10백", new String[] {"1000"}); // Strange, but supported } - @Test public void testLargeVariants() throws IOException { // Test large numbers assertAnalyzesTo(analyzer, "삼오칠팔구", new String[] {"35789"}); @@ -149,19 +145,16 @@ public void testLargeVariants() throws IOException { assertAnalyzesTo(analyzer, "해경조억만천백십일", new String[] {"100010001000100011111"}); } - @Test public void testNegative() throws IOException { assertAnalyzesTo(analyzer, "-백만", new String[] {"-", "1000000"}); } - @Test public void testMixed() throws IOException { // Test mixed numbers assertAnalyzesTo(analyzer, "삼천2백2십삼", new String[] {"3223"}); assertAnalyzesTo(analyzer, "32이삼", new String[] {"3223"}); } - @Test public void testFunny() throws IOException { // Test some oddities for inconsistent input assertAnalyzesTo(analyzer, "십십", new String[] {"20"}); // 100? @@ -169,7 +162,6 @@ public void testFunny() throws IOException { assertAnalyzesTo(analyzer, "천천천천", new String[] {"4000"}); // 1,000,000,000,000? } - @Test public void testHangulArabic() throws IOException { // Test kanji numerals used as Arabic numbers (with head zero) assertAnalyzesTo(analyzer, "영일이삼사오육칠팔구구팔칠육오사삼이일영", new String[] {"1234567899876543210"}); @@ -178,13 +170,11 @@ public void testHangulArabic() throws IOException { assertAnalyzesTo(analyzer, "영영칠", new String[] {"7"}); } - @Test public void testDoubleZero() throws IOException { assertAnalyzesTo( analyzer, "영영", new String[] {"0"}, new int[] {0}, new int[] {2}, new int[] {1}); } - @Test public void testName() throws IOException { // Test name that normalises to number assertAnalyzesTo( @@ -228,61 +218,50 @@ protected TokenStreamComponents createComponents(String fieldName) { keywordMarkingAnalyzer.close(); } - @Test public void testDecimal() throws IOException { // Test Arabic numbers with punctuation, i.e. 3.2 thousands assertAnalyzesTo(analyzer, "1.2만345.67", new String[] {"12345.67"}); } - @Test public void testDecimalPunctuation() throws IOException { // Test Arabic numbers with punctuation, i.e. 3.2 thousands won assertAnalyzesTo(analyzer, "3.2천 원", new String[] {"3200", "원"}); } - @Test public void testThousandSeparator() throws IOException { assertAnalyzesTo(analyzer, "4,647", new String[] {"4647"}); } - @Test public void testDecimalThousandSeparator() throws IOException { assertAnalyzesTo(analyzer, "4,647.0010", new String[] {"4647.001"}); } - @Test public void testCommaDecimalSeparator() throws IOException { assertAnalyzesTo(analyzer, "15,7", new String[] {"157"}); } - @Test public void testTrailingZeroStripping() throws IOException { assertAnalyzesTo(analyzer, "1000.1000", new String[] {"1000.1"}); assertAnalyzesTo(analyzer, "1000.0000", new String[] {"1000"}); } - @Test public void testEmpty() throws IOException { assertAnalyzesTo(analyzer, "", new String[] {}); } - @Test public void testRandomHugeStrings() throws Exception { checkRandomData(random(), analyzer, RANDOM_MULTIPLIER, 4096); } - @Test @Nightly public void testRandomHugeStringsAtNight() throws Exception { checkRandomData(random(), analyzer, 5 * RANDOM_MULTIPLIER, 8192); } - @Test public void testRandomSmallStrings() throws Exception { checkRandomData(random(), analyzer, 100 * RANDOM_MULTIPLIER, 128); } - @Test public void testFunnyIssue() throws Exception { BaseTokenStreamTestCase.checkAnalysisConsistency( random(), analyzer, true, "영영\u302f\u3029\u3039\u3023\u3033\u302bB", true); @@ -290,7 +269,6 @@ public void testFunnyIssue() throws Exception { @Ignore( "This test is used during development when analyze normalizations in large amounts of text") - @Test public void testLargeData() throws IOException { Path input = Paths.get("/tmp/test.txt"); Path tokenizedOutput = Paths.get("/tmp/test.tok.txt"); diff --git a/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/dict/TestUnknownDictionary.java b/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/dict/TestUnknownDictionary.java index 13190b21a73a..97573fb734ff 100644 --- a/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/dict/TestUnknownDictionary.java +++ b/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/dict/TestUnknownDictionary.java @@ -18,11 +18,9 @@ import org.apache.lucene.analysis.util.CSVUtil; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestUnknownDictionary extends LuceneTestCase { - @Test public void testPutCharacterCategory() { UnknownDictionaryWriter unkDic = new UnknownDictionaryWriter(10 * 1024 * 1024); @@ -37,7 +35,6 @@ public void testPutCharacterCategory() { unkDic.putCharacterCategory(4, "KANJI"); } - @Test public void testPut() { UnknownDictionaryWriter unkDic = new UnknownDictionaryWriter(10 * 1024 * 1024); expectThrows( diff --git a/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/dict/TestUserDictionary.java b/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/dict/TestUserDictionary.java index 7ce5dd805638..b5e3947ed094 100644 --- a/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/dict/TestUserDictionary.java +++ b/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/dict/TestUserDictionary.java @@ -21,10 +21,8 @@ import org.apache.lucene.analysis.ko.POS; import org.apache.lucene.analysis.ko.TestKoreanTokenizer; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestUserDictionary extends LuceneTestCase { - @Test public void testLookup() throws IOException { UserDictionary dictionary = TestKoreanTokenizer.readDict(); String s = "세종"; @@ -55,7 +53,6 @@ public void testLookup() throws IOException { assertNull(dictionary.getMorphAttributes().getMorphemes(wordIds.get(0), sArray, 0, s.length())); } - @Test public void testRead() { UserDictionary dictionary = TestKoreanTokenizer.readDict(); assertNotNull(dictionary); diff --git a/lucene/analysis/opennlp/src/test/org/apache/lucene/analysis/opennlp/TestOpenNLPTokenizerFactory.java b/lucene/analysis/opennlp/src/test/org/apache/lucene/analysis/opennlp/TestOpenNLPTokenizerFactory.java index 39ef7bf98708..45e9a3ac44e6 100644 --- a/lucene/analysis/opennlp/src/test/org/apache/lucene/analysis/opennlp/TestOpenNLPTokenizerFactory.java +++ b/lucene/analysis/opennlp/src/test/org/apache/lucene/analysis/opennlp/TestOpenNLPTokenizerFactory.java @@ -25,7 +25,6 @@ import org.apache.lucene.analysis.custom.CustomAnalyzer; import org.apache.lucene.tests.analysis.BaseTokenStreamTestCase; import org.apache.lucene.util.ClasspathResourceLoader; -import org.junit.Test; /** * Tests the Tokenizer as well- the Tokenizer needs the OpenNLP model files, which this can load @@ -63,7 +62,6 @@ public class TestOpenNLPTokenizerFactory extends BaseTokenStreamTestCase { "Sentence", "number", "1", "has", "6", "words", "." }; - @Test public void testTokenizer() throws IOException { CustomAnalyzer analyzer = CustomAnalyzer.builder(new ClasspathResourceLoader(getClass())) @@ -79,7 +77,6 @@ public void testTokenizer() throws IOException { assertAnalyzesTo(analyzer, SENTENCE1, SENTENCE1_punc); } - @Test public void testTokenizerNoSentenceDetector() throws IOException { IllegalArgumentException expected = expectThrows( @@ -93,7 +90,6 @@ public void testTokenizerNoSentenceDetector() throws IOException { expected.getMessage().contains("Configuration Error: missing parameter 'sentenceModel'")); } - @Test public void testTokenizerNoTokenizer() throws IOException { IllegalArgumentException expected = expectThrows( @@ -108,7 +104,6 @@ public void testTokenizerNoTokenizer() throws IOException { } // test analyzer caching the tokenizer - @Test public void testClose() throws IOException { Map args = new HashMap<>() { diff --git a/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/feeds/TestEnwikiContentSource.java b/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/feeds/TestEnwikiContentSource.java index a2a58bdb5d15..aeaee5a1e241 100644 --- a/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/feeds/TestEnwikiContentSource.java +++ b/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/feeds/TestEnwikiContentSource.java @@ -24,7 +24,6 @@ import java.util.Properties; import org.apache.lucene.benchmark.byTask.utils.Config; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestEnwikiContentSource extends LuceneTestCase { @@ -99,7 +98,6 @@ private void assertNoMoreDataException(EnwikiContentSource stdm) throws Exceptio + " \r\n" + " \r\n"; - @Test public void testOneDocument() throws Exception { String docs = "\r\n" + PAGE1 + ""; @@ -128,7 +126,6 @@ private EnwikiContentSource createContentSource(String docs, boolean forever) th return source; } - @Test public void testTwoDocuments() throws Exception { String docs = "\r\n" + PAGE1 + PAGE2 + ""; @@ -143,7 +140,6 @@ public void testTwoDocuments() throws Exception { assertNoMoreDataException(source); } - @Test public void testForever() throws Exception { String docs = "\r\n" + PAGE1 + PAGE2 + ""; diff --git a/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/utils/TestConfig.java b/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/utils/TestConfig.java index 57c4f5a34f0e..1d6089020ce8 100644 --- a/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/utils/TestConfig.java +++ b/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/utils/TestConfig.java @@ -18,11 +18,9 @@ import java.util.Properties; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestConfig extends LuceneTestCase { - @Test public void testAbsolutePathNamesWindows() throws Exception { Properties props = new Properties(); props.setProperty("work.dir1", "c:\\temp"); diff --git a/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/utils/TestStreamUtils.java b/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/utils/TestStreamUtils.java index a3953f4bbaee..d24c63dd32eb 100644 --- a/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/utils/TestStreamUtils.java +++ b/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/utils/TestStreamUtils.java @@ -29,19 +29,16 @@ import org.apache.commons.compress.compressors.CompressorStreamFactory; import org.apache.lucene.benchmark.BenchmarkTestCase; import org.junit.Before; -import org.junit.Test; public class TestStreamUtils extends BenchmarkTestCase { private static final String TEXT = "Some-Text..."; private Path testDir; - @Test public void testGetInputStreamPlainText() throws Exception { assertReadText(rawTextFile("txt")); assertReadText(rawTextFile("TXT")); } - @Test public void testGetInputStreamGzip() throws Exception { assertReadText(rawGzipFile("gz")); assertReadText(rawGzipFile("gzip")); @@ -49,7 +46,6 @@ public void testGetInputStreamGzip() throws Exception { assertReadText(rawGzipFile("GZIP")); } - @Test public void testGetInputStreamBzip2() throws Exception { assertReadText(rawBzip2File("bz2")); assertReadText(rawBzip2File("bzip")); @@ -57,7 +53,6 @@ public void testGetInputStreamBzip2() throws Exception { assertReadText(rawBzip2File("BZIP")); } - @Test public void testGetOutputStreamBzip2() throws Exception { assertReadText(autoOutFile("bz2")); assertReadText(autoOutFile("bzip")); @@ -65,7 +60,6 @@ public void testGetOutputStreamBzip2() throws Exception { assertReadText(autoOutFile("BZIP")); } - @Test public void testGetOutputStreamGzip() throws Exception { assertReadText(autoOutFile("gz")); assertReadText(autoOutFile("gzip")); @@ -73,7 +67,6 @@ public void testGetOutputStreamGzip() throws Exception { assertReadText(autoOutFile("GZIP")); } - @Test public void testGetOutputStreamPlain() throws Exception { assertReadText(autoOutFile("txt")); assertReadText(autoOutFile("text")); diff --git a/lucene/classification/src/test/org/apache/lucene/classification/Test20NewsgroupsClassification.java b/lucene/classification/src/test/org/apache/lucene/classification/Test20NewsgroupsClassification.java index 3ac54e448ebc..ef7ec45e2e85 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/Test20NewsgroupsClassification.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/Test20NewsgroupsClassification.java @@ -65,7 +65,6 @@ import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.NamedThreadFactory; import org.apache.lucene.util.SuppressForbidden; -import org.junit.Test; @LuceneTestCase.SuppressSysoutChecks(bugUrl = "none") @TimeoutSuite(millis = Integer.MAX_VALUE) // hopefully ~24 days is long enough ;) @@ -81,7 +80,6 @@ public final class Test20NewsgroupsClassification extends LuceneTestCase { private boolean split = true; @SuppressForbidden(reason = "Thread sleep") - @Test public void test20Newsgroups() throws Exception { String indexProperty = System.getProperty("index"); diff --git a/lucene/classification/src/test/org/apache/lucene/classification/TestBM25NBClassifier.java b/lucene/classification/src/test/org/apache/lucene/classification/TestBM25NBClassifier.java index aa9163d4adf3..026962cc8792 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/TestBM25NBClassifier.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/TestBM25NBClassifier.java @@ -31,12 +31,10 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; /** Tests for {@link BM25NBClassifier} */ public class TestBM25NBClassifier extends ClassificationTestBase { - @Test public void testBasicUsage() throws Exception { LeafReader leafReader = null; try { @@ -50,7 +48,6 @@ public void testBasicUsage() throws Exception { } } - @Test public void testBasicUsageWithQuery() throws Exception { LeafReader leafReader = null; try { @@ -65,7 +62,6 @@ public void testBasicUsageWithQuery() throws Exception { } } - @Test public void testNGramUsage() throws Exception { LeafReader leafReader = null; try { @@ -90,7 +86,6 @@ protected TokenStreamComponents createComponents(String fieldName) { } } - @Test public void testPerformance() throws Exception { MockAnalyzer analyzer = new MockAnalyzer(random()); int numDocs = atLeast(10); diff --git a/lucene/classification/src/test/org/apache/lucene/classification/TestBooleanPerceptronClassifier.java b/lucene/classification/src/test/org/apache/lucene/classification/TestBooleanPerceptronClassifier.java index dcec5864f135..e9f18713b586 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/TestBooleanPerceptronClassifier.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/TestBooleanPerceptronClassifier.java @@ -26,12 +26,10 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; /** Testcase for {@link org.apache.lucene.classification.BooleanPerceptronClassifier} */ public class TestBooleanPerceptronClassifier extends ClassificationTestBase { - @Test public void testBasicUsage() throws Exception { LeafReader leafReader = null; try { @@ -47,7 +45,6 @@ public void testBasicUsage() throws Exception { } } - @Test public void testExplicitThreshold() throws Exception { LeafReader leafReader = null; try { @@ -63,7 +60,6 @@ public void testExplicitThreshold() throws Exception { } } - @Test public void testBasicUsageWithQuery() throws Exception { TermQuery query = new TermQuery(new Term(textFieldName, "of")); LeafReader leafReader = null; @@ -80,7 +76,6 @@ public void testBasicUsageWithQuery() throws Exception { } } - @Test public void testPerformance() throws Exception { MockAnalyzer analyzer = new MockAnalyzer(random()); int numDocs = atLeast(10); diff --git a/lucene/classification/src/test/org/apache/lucene/classification/TestCachingNaiveBayesClassifier.java b/lucene/classification/src/test/org/apache/lucene/classification/TestCachingNaiveBayesClassifier.java index e12093a105de..2a1666f18cd9 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/TestCachingNaiveBayesClassifier.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/TestCachingNaiveBayesClassifier.java @@ -31,12 +31,10 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; /** Testcase for {@link org.apache.lucene.classification.CachingNaiveBayesClassifier} */ public class TestCachingNaiveBayesClassifier extends ClassificationTestBase { - @Test public void testBasicUsage() throws Exception { LeafReader leafReader = null; try { @@ -57,7 +55,6 @@ public void testBasicUsage() throws Exception { } } - @Test public void testBasicUsageWithQuery() throws Exception { LeafReader leafReader = null; try { @@ -74,7 +71,6 @@ public void testBasicUsageWithQuery() throws Exception { } } - @Test public void testNGramUsage() throws Exception { LeafReader leafReader = null; try { @@ -101,7 +97,6 @@ protected TokenStreamComponents createComponents(String fieldName) { } } - @Test public void testPerformance() throws Exception { MockAnalyzer analyzer = new MockAnalyzer(random()); int numDocs = atLeast(10); diff --git a/lucene/classification/src/test/org/apache/lucene/classification/TestKNearestFuzzyClassifier.java b/lucene/classification/src/test/org/apache/lucene/classification/TestKNearestFuzzyClassifier.java index 19d614f730c0..15a43aff6367 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/TestKNearestFuzzyClassifier.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/TestKNearestFuzzyClassifier.java @@ -26,12 +26,10 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; /** Tests for {@link KNearestFuzzyClassifier} */ public class TestKNearestFuzzyClassifier extends ClassificationTestBase { - @Test public void testBasicUsage() throws Exception { LeafReader leafReader = null; try { @@ -47,7 +45,6 @@ public void testBasicUsage() throws Exception { } } - @Test public void testBasicUsageWithQuery() throws Exception { LeafReader leafReader = null; try { @@ -63,7 +60,6 @@ public void testBasicUsageWithQuery() throws Exception { } } - @Test public void testPerformance() throws Exception { MockAnalyzer analyzer = new MockAnalyzer(random()); int numDocs = atLeast(10); diff --git a/lucene/classification/src/test/org/apache/lucene/classification/TestKNearestNeighborClassifier.java b/lucene/classification/src/test/org/apache/lucene/classification/TestKNearestNeighborClassifier.java index 073703ae61e9..5713fa91a781 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/TestKNearestNeighborClassifier.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/TestKNearestNeighborClassifier.java @@ -31,12 +31,10 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; /** Testcase for {@link KNearestNeighborClassifier} */ public class TestKNearestNeighborClassifier extends ClassificationTestBase { - @Test public void testBasicUsage() throws Exception { LeafReader leafReader = null; try { @@ -102,7 +100,6 @@ public void testBasicUsage() throws Exception { * * @throws Exception if any error happens */ - @Test public void testRankedClasses() throws Exception { LeafReader leafReader = null; try { @@ -128,7 +125,6 @@ public void testRankedClasses() throws Exception { * * @throws Exception if any error happens */ - @Test public void testUnbalancedClasses() throws Exception { LeafReader leafReader = null; try { @@ -146,7 +142,6 @@ public void testUnbalancedClasses() throws Exception { } } - @Test public void testBasicUsageWithQuery() throws Exception { LeafReader leafReader = null; try { @@ -163,7 +158,6 @@ public void testBasicUsageWithQuery() throws Exception { } } - @Test public void testPerformance() throws Exception { MockAnalyzer analyzer = new MockAnalyzer(random()); int numDocs = atLeast(10); diff --git a/lucene/classification/src/test/org/apache/lucene/classification/TestSimpleNaiveBayesClassifier.java b/lucene/classification/src/test/org/apache/lucene/classification/TestSimpleNaiveBayesClassifier.java index dac15dfca2fb..98598ae8d2ff 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/TestSimpleNaiveBayesClassifier.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/TestSimpleNaiveBayesClassifier.java @@ -31,12 +31,10 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; /** Testcase for {@link SimpleNaiveBayesClassifier} */ public class TestSimpleNaiveBayesClassifier extends ClassificationTestBase { - @Test public void testBasicUsage() throws Exception { LeafReader leafReader = null; try { @@ -52,7 +50,6 @@ public void testBasicUsage() throws Exception { } } - @Test public void testBasicUsageWithQuery() throws Exception { LeafReader leafReader = null; try { @@ -69,7 +66,6 @@ public void testBasicUsageWithQuery() throws Exception { } } - @Test public void testNGramUsage() throws Exception { LeafReader leafReader = null; try { @@ -95,7 +91,6 @@ protected TokenStreamComponents createComponents(String fieldName) { } } - @Test public void testPerformance() throws Exception { MockAnalyzer analyzer = new MockAnalyzer(random()); int numDocs = atLeast(10); diff --git a/lucene/classification/src/test/org/apache/lucene/classification/document/TestKNearestNeighborDocumentClassifier.java b/lucene/classification/src/test/org/apache/lucene/classification/document/TestKNearestNeighborDocumentClassifier.java index 926b831d35c8..75b9b7c1e99a 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/document/TestKNearestNeighborDocumentClassifier.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/document/TestKNearestNeighborDocumentClassifier.java @@ -21,13 +21,11 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; /** Tests for {@link org.apache.lucene.classification.KNearestNeighborClassifier} */ public class TestKNearestNeighborDocumentClassifier extends DocumentClassificationTestBase { - @Test public void testBasicDocumentClassification() throws Exception { try { Document videoGameDocument = getVideoGameDocument(); @@ -79,7 +77,6 @@ public void testBasicDocumentClassification() throws Exception { } } - @Test public void testBasicDocumentClassificationScore() throws Exception { try { Document videoGameDocument = getVideoGameDocument(); @@ -137,7 +134,6 @@ public void testBasicDocumentClassificationScore() throws Exception { } } - @Test public void testBoostedDocumentClassification() throws Exception { try { checkCorrectDocumentClassification( @@ -172,7 +168,6 @@ public void testBoostedDocumentClassification() throws Exception { } } - @Test public void testBasicDocumentClassificationWithQuery() throws Exception { try { TermQuery query = new TermQuery(new Term(authorFieldName, "ign")); diff --git a/lucene/classification/src/test/org/apache/lucene/classification/document/TestSimpleNaiveBayesDocumentClassifier.java b/lucene/classification/src/test/org/apache/lucene/classification/document/TestSimpleNaiveBayesDocumentClassifier.java index 5aa6f2d183de..883d743ae34f 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/document/TestSimpleNaiveBayesDocumentClassifier.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/document/TestSimpleNaiveBayesDocumentClassifier.java @@ -18,13 +18,11 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; /** Tests for {@link org.apache.lucene.classification.SimpleNaiveBayesClassifier} */ public class TestSimpleNaiveBayesDocumentClassifier extends DocumentClassificationTestBase { - @Test public void testBasicDocumentClassification() throws Exception { try { checkCorrectDocumentClassification( @@ -61,7 +59,6 @@ public void testBasicDocumentClassification() throws Exception { } } - @Test public void testBasicDocumentClassificationScore() throws Exception { try { double score1 = @@ -114,7 +111,6 @@ public void testBasicDocumentClassificationScore() throws Exception { } } - @Test public void testBoostedDocumentClassification() throws Exception { try { checkCorrectDocumentClassification( diff --git a/lucene/classification/src/test/org/apache/lucene/classification/utils/TestConfusionMatrixGenerator.java b/lucene/classification/src/test/org/apache/lucene/classification/utils/TestConfusionMatrixGenerator.java index c6281a7f59df..c760c5256595 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/utils/TestConfusionMatrixGenerator.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/utils/TestConfusionMatrixGenerator.java @@ -31,12 +31,10 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; /** Tests for {@link ConfusionMatrixGenerator} */ public class TestConfusionMatrixGenerator extends ClassificationTestBase { - @Test public void testGetConfusionMatrix() throws Exception { LeafReader reader = null; try { @@ -86,7 +84,6 @@ public List> getClasses(String text, int max) } } - @Test public void testGetConfusionMatrixWithSNB() throws Exception { LeafReader reader = null; try { @@ -122,7 +119,6 @@ private void checkCM(ConfusionMatrixGenerator.ConfusionMatrix confusionMatrix) { assertTrue(f1Measure <= 1d); } - @Test public void testGetConfusionMatrixWithBM25NB() throws Exception { LeafReader reader = null; try { @@ -139,7 +135,6 @@ public void testGetConfusionMatrixWithBM25NB() throws Exception { } } - @Test public void testGetConfusionMatrixWithCNB() throws Exception { LeafReader reader = null; try { @@ -156,7 +151,6 @@ public void testGetConfusionMatrixWithCNB() throws Exception { } } - @Test public void testGetConfusionMatrixWithKNN() throws Exception { LeafReader reader = null; try { @@ -174,7 +168,6 @@ public void testGetConfusionMatrixWithKNN() throws Exception { } } - @Test public void testGetConfusionMatrixWithFLTKNN() throws Exception { LeafReader reader = null; try { @@ -192,7 +185,6 @@ public void testGetConfusionMatrixWithFLTKNN() throws Exception { } } - @Test public void testGetConfusionMatrixWithBP() throws Exception { LeafReader reader = null; try { diff --git a/lucene/classification/src/test/org/apache/lucene/classification/utils/TestDataSplitter.java b/lucene/classification/src/test/org/apache/lucene/classification/utils/TestDataSplitter.java index 1e7f2447a8f0..f5e3ebda9551 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/utils/TestDataSplitter.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/utils/TestDataSplitter.java @@ -36,7 +36,6 @@ import org.apache.lucene.util.IOUtils; import org.junit.After; import org.junit.Before; -import org.junit.Test; /** Testcase for {@link org.apache.lucene.classification.utils.DatasetSplitter} */ @LuceneTestCase.SuppressCodecs("SimpleText") @@ -88,12 +87,10 @@ public void tearDown() throws Exception { super.tearDown(); } - @Test public void testSplitOnAllFields() throws Exception { assertSplit(originalIndex, 0.1, 0.1); } - @Test public void testSplitOnSomeFields() throws Exception { assertSplit(originalIndex, 0.2, 0.35, idFieldName, textFieldName); } diff --git a/lucene/classification/src/test/org/apache/lucene/classification/utils/TestDocToDoubleVectorUtils.java b/lucene/classification/src/test/org/apache/lucene/classification/utils/TestDocToDoubleVectorUtils.java index cc1b41262aad..40a962513ca6 100644 --- a/lucene/classification/src/test/org/apache/lucene/classification/utils/TestDocToDoubleVectorUtils.java +++ b/lucene/classification/src/test/org/apache/lucene/classification/utils/TestDocToDoubleVectorUtils.java @@ -33,7 +33,6 @@ import org.apache.lucene.util.IOUtils; import org.junit.After; import org.junit.Before; -import org.junit.Test; /** Testcase for {@link org.apache.lucene.classification.utils.DocToDoubleVectorUtils} */ public class TestDocToDoubleVectorUtils extends LuceneTestCase { @@ -79,7 +78,6 @@ public void tearDown() throws Exception { super.tearDown(); } - @Test public void testDenseFreqDoubleArrayConversion() throws Exception { IndexSearcher indexSearcher = new IndexSearcher(index); TermVectors termVectors = index.termVectors(); @@ -92,7 +90,6 @@ public void testDenseFreqDoubleArrayConversion() throws Exception { } } - @Test public void testSparseFreqDoubleArrayConversion() throws Exception { Terms fieldTerms = MultiTerms.getTerms(index, "text"); if (fieldTerms != null && fieldTerms.size() != -1) { diff --git a/lucene/core.tests/src/test/org/apache/lucene/core/tests/TestRuntimeDependenciesSane.java b/lucene/core.tests/src/test/org/apache/lucene/core/tests/TestRuntimeDependenciesSane.java index 2a07d4b8bac4..bcc9bbb4eb70 100644 --- a/lucene/core.tests/src/test/org/apache/lucene/core/tests/TestRuntimeDependenciesSane.java +++ b/lucene/core.tests/src/test/org/apache/lucene/core/tests/TestRuntimeDependenciesSane.java @@ -18,28 +18,23 @@ import org.apache.lucene.core.tests.main.EmptyReference; import org.apache.lucene.index.IndexWriter; -import org.junit.Test; /** Intentionally not a subclass of {@code LuceneTestCase}. */ public class TestRuntimeDependenciesSane { - @Test public void testExternalDependenciesAreModules() { isModule(org.junit.Test.class); } - @Test public void testInterProjectDependenciesAreModules() { // The core Lucene should be a modular dependency. isModule(IndexWriter.class); } - @Test public void testTestSourceSetIsAModule() { // The test source set itself should be loaded as a module. isModule(getClass()); } - @Test public void testMainSourceSetIsAModule() { // The test source set itself should be loaded as a module. isModule(EmptyReference.class); diff --git a/lucene/core/src/test/org/apache/lucene/analysis/TestCharacterUtils.java b/lucene/core/src/test/org/apache/lucene/analysis/TestCharacterUtils.java index 8d0dcc6ff9d2..43352537d2a9 100644 --- a/lucene/core/src/test/org/apache/lucene/analysis/TestCharacterUtils.java +++ b/lucene/core/src/test/org/apache/lucene/analysis/TestCharacterUtils.java @@ -23,7 +23,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.ArrayUtil; -import org.junit.Test; /** TestCase for the {@link CharacterUtils} class. */ public class TestCharacterUtils extends LuceneTestCase { @@ -54,7 +53,6 @@ public void testConversions() { ArrayUtil.copyOfSubArray(restored, o3, o3 + charCount)); } - @Test public void testNewCharacterBuffer() { CharacterBuffer newCharacterBuffer = CharacterUtils.newCharacterBuffer(1024); assertEquals(1024, newCharacterBuffer.getBuffer().length); @@ -74,7 +72,6 @@ public void testNewCharacterBuffer() { }); } - @Test public void testFillNoHighSurrogate() throws IOException { Reader reader = new StringReader("helloworld"); CharacterBuffer buffer = CharacterUtils.newCharacterBuffer(6); @@ -90,7 +87,6 @@ public void testFillNoHighSurrogate() throws IOException { assertFalse(CharacterUtils.fill(buffer, reader)); } - @Test public void testFill() throws IOException { String input = "1234\ud801\udc1c789123\ud801\ud801\udc1c\ud801"; Reader reader = new StringReader(input); diff --git a/lucene/core/src/test/org/apache/lucene/codecs/hnsw/TestPrefetchableFlatVectorScorer.java b/lucene/core/src/test/org/apache/lucene/codecs/hnsw/TestPrefetchableFlatVectorScorer.java index 04dbed76ecce..bc7bfad726f5 100644 --- a/lucene/core/src/test/org/apache/lucene/codecs/hnsw/TestPrefetchableFlatVectorScorer.java +++ b/lucene/core/src/test/org/apache/lucene/codecs/hnsw/TestPrefetchableFlatVectorScorer.java @@ -20,7 +20,6 @@ import java.lang.reflect.Modifier; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.hnsw.RandomVectorScorerSupplier; -import org.junit.Test; /** * Tests that {@link PrefetchableFlatVectorScorer} overrides all methods from {@link @@ -28,7 +27,6 @@ */ public class TestPrefetchableFlatVectorScorer extends LuceneTestCase { - @Test public void testDeclaredMethodsOverridden() { implTestDeclaredMethodsOverridden(FlatVectorsScorer.class, PrefetchableFlatVectorScorer.class); implTestDeclaredMethodsOverridden( diff --git a/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java b/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java index a782440c952b..977a388f9b52 100644 --- a/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java +++ b/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java @@ -56,7 +56,6 @@ import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.tests.util.TestUtil; -import org.junit.Test; /** */ // TODO: would be better in this test to pull termsenums and instanceof or something? @@ -103,7 +102,6 @@ private void addDocs3(IndexWriter writer, int numDocs) throws IOException { /* * Test that heterogeneous index segments are merge successfully */ - @Test public void testMergeUnusedPerFieldCodec() throws IOException { Directory dir = newDirectory(); IndexWriterConfig iwconf = @@ -130,7 +128,6 @@ public void testMergeUnusedPerFieldCodec() throws IOException { */ // TODO: not sure this test is that great, we should probably peek inside PerFieldPostingsFormat // or something?! - @Test public void testChangeCodecAndMerge() throws IOException { Directory dir = newDirectory(); if (VERBOSE) { @@ -231,7 +228,6 @@ public PostingsFormat getPostingsFormatForField(String field) { /* * Test per field codec support - adding fields with random codecs */ - @Test public void testStressPerFieldCodec() throws IOException { Directory dir = newDirectory(random()); final int docsPerRound = 97; diff --git a/lucene/core/src/test/org/apache/lucene/index/TestCheckIndex.java b/lucene/core/src/test/org/apache/lucene/index/TestCheckIndex.java index 496c1b78ff2b..8e2afb228ddc 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestCheckIndex.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestCheckIndex.java @@ -42,7 +42,6 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.VectorUtil; -import org.junit.Test; public class TestCheckIndex extends BaseTestCheckIndex { private Directory directory; @@ -59,27 +58,22 @@ public void tearDown() throws Exception { super.tearDown(); } - @Test public void testDeletedDocs() throws IOException { testDeletedDocs(directory); } - @Test public void testChecksumsOnly() throws IOException { testChecksumsOnly(directory); } - @Test public void testChecksumsOnlyVerbose() throws IOException { testChecksumsOnlyVerbose(directory); } - @Test public void testObtainsLock() throws IOException { testObtainsLock(directory); } - @Test public void testCheckIndexAllValid() throws Exception { try (Directory dir = newDirectory()) { int liveDocCount = 1 + random().nextInt(10); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java b/lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java index bf99db13b96e..2b7c80b8b156 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java @@ -46,7 +46,6 @@ import org.apache.lucene.util.NamedThreadFactory; import org.apache.lucene.util.SuppressForbidden; import org.junit.Assert; -import org.junit.Test; import org.junit.runner.RunWith; /* WARNING: This test does *not* extend LuceneTestCase to prevent static class @@ -56,7 +55,6 @@ public class TestClassloadingDeadlock extends Assert { private static final int MAX_TIME_SECONDS = 30; - @Test @SuppressForbidden(reason = "Uses Path.toFile because ProcessBuilder requires it.") public void testDeadlock() throws Exception { // pick random codec names for stress test in separate process: diff --git a/lucene/core/src/test/org/apache/lucene/index/TestConsistentFieldNumbers.java b/lucene/core/src/test/org/apache/lucene/index/TestConsistentFieldNumbers.java index c21c6fbbd4dd..db7606bbc3aa 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestConsistentFieldNumbers.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestConsistentFieldNumbers.java @@ -26,11 +26,9 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.util.FailOnNonBulkMergesInfoStream; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestConsistentFieldNumbers extends LuceneTestCase { - @Test public void testSameFieldNumbersAcrossSegments() throws Exception { for (int i = 0; i < 2; i++) { Directory dir = newDirectory(); @@ -96,7 +94,6 @@ public void testSameFieldNumbersAcrossSegments() throws Exception { } } - @Test public void testAddIndexes() throws Exception { Directory dir1 = newDirectory(); Directory dir2 = newDirectory(); @@ -256,7 +253,6 @@ public void testFieldNumberGaps() throws IOException { } } - @Test public void testManyFields() throws Exception { final int NUM_DOCS = atLeast(200); final int MAX_FIELDS = atLeast(50); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestDocInverterPerFieldErrorInfo.java b/lucene/core/src/test/org/apache/lucene/index/TestDocInverterPerFieldErrorInfo.java index 4ae2dacabc78..f56231a1b7d9 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestDocInverterPerFieldErrorInfo.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestDocInverterPerFieldErrorInfo.java @@ -31,7 +31,6 @@ import org.apache.lucene.tests.analysis.MockTokenizer; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.PrintStreamInfoStream; -import org.junit.Test; /** Test adding to the info stream when there's an exception thrown during field analysis. */ public class TestDocInverterPerFieldErrorInfo extends LuceneTestCase { @@ -62,7 +61,6 @@ public boolean incrementToken() throws IOException { } } - @Test public void testInfoStreamGetsFieldName() throws Exception { Directory dir = newDirectory(); IndexWriter writer; @@ -83,7 +81,6 @@ public void testInfoStreamGetsFieldName() throws Exception { dir.close(); } - @Test public void testNoExtraNoise() throws Exception { Directory dir = newDirectory(); IndexWriter writer; diff --git a/lucene/core/src/test/org/apache/lucene/index/TestFilterIndexInput.java b/lucene/core/src/test/org/apache/lucene/index/TestFilterIndexInput.java index d43b580f601e..f0d515c0210a 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestFilterIndexInput.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestFilterIndexInput.java @@ -26,7 +26,6 @@ import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexOutput; -import org.junit.Test; public class TestFilterIndexInput extends TestIndexInput { @@ -59,7 +58,6 @@ public void testRawFilterIndexInputRead() throws IOException { } } - @Test public void testOverrides() { for (Method m : FilterIndexInput.class.getMethods()) { if (m.getName().contains("clone")) { diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexCommit.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexCommit.java index 6ca5c161d5f2..b2fc3b96cee8 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexCommit.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexCommit.java @@ -20,11 +20,9 @@ import java.util.Map; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestIndexCommit extends LuceneTestCase { - @Test public void testEqualsHashCode() throws Exception { // LUCENE-2417: equals and hashCode() impl was inconsistent final Directory dir = newDirectory(); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java index 9119aaff865f..2648d6e72290 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java @@ -32,7 +32,6 @@ import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.InfoStream; -import org.junit.Test; public class TestIndexWriterConfig extends LuceneTestCase { @@ -40,7 +39,6 @@ private static final class MySimilarity extends ClassicSimilarity { // Does not implement anything - used only for type checking on IndexWriterConfig. } - @Test public void testDefaults() throws Exception { IndexWriterConfig conf = new IndexWriterConfig(new MockAnalyzer(random())); assertEquals(MockAnalyzer.class, conf.getAnalyzer().getClass()); @@ -97,7 +95,6 @@ public void testDefaults() throws Exception { } } - @Test public void testSettersChaining() throws Exception { // Ensures that every setter returns IndexWriterConfig to allow chaining. HashSet liveSetters = new HashSet<>(); @@ -126,7 +123,6 @@ public void testSettersChaining() throws Exception { } } - @Test public void testReuse() throws Exception { Directory dir = newDirectory(); // test that IWC cannot be reused across two IWs @@ -143,7 +139,6 @@ public void testReuse() throws Exception { dir.close(); } - @Test public void testOverrideGetters() throws Exception { // Test that IndexWriterConfig overrides all getters, so that javadocs // contain all methods for the users. Also, ensures that IndexWriterConfig @@ -168,7 +163,6 @@ public void testOverrideGetters() throws Exception { } } - @Test public void testConstants() throws Exception { // Tests that the values of the constants does not change assertEquals(-1, IndexWriterConfig.DISABLE_AUTO_FLUSH); @@ -180,7 +174,6 @@ public void testConstants() throws Exception { assertEquals(true, IndexWriterConfig.DEFAULT_USE_COMPOUND_FILE_SYSTEM); } - @Test public void testToString() throws Exception { String str = new IndexWriterConfig(new MockAnalyzer(random())).toString(); for (Field f : IndexWriterConfig.class.getDeclaredFields()) { @@ -200,7 +193,6 @@ public void testToString() throws Exception { } } - @Test public void testInvalidValues() throws Exception { IndexWriterConfig conf = new IndexWriterConfig(new MockAnalyzer(random())); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java index 5f9cac42448e..8ffbf45651d5 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java @@ -51,7 +51,6 @@ import org.apache.lucene.util.InfoStream; import org.apache.lucene.util.ThreadInterruptedException; import org.apache.lucene.util.Version; -import org.junit.Test; @SuppressCodecs("SimpleText") // too slow here public class TestIndexWriterReader extends LuceneTestCase { @@ -1106,7 +1105,6 @@ public void testReopenAfterNoRealChange() throws Exception { d.close(); } - @Test public void testNRTOpenExceptions() throws Exception { // LUCENE-5262: test that several failed attempts to obtain an NRT reader // don't leak file handles. diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIsCurrent.java b/lucene/core/src/test/org/apache/lucene/index/TestIsCurrent.java index 78ba8f44f925..a3f3f89f8cdb 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIsCurrent.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIsCurrent.java @@ -22,7 +22,6 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestIsCurrent extends LuceneTestCase { @@ -53,7 +52,6 @@ public void tearDown() throws Exception { } /** Failing testcase showing the trouble */ - @Test public void testDeleteByTermIsCurrent() throws IOException { // get reader @@ -76,7 +74,6 @@ public void testDeleteByTermIsCurrent() throws IOException { } /** Testcase for example to show that writer.deleteAll() is working as expected */ - @Test public void testDeleteAllIsCurrent() throws IOException { // get reader diff --git a/lucene/core/src/test/org/apache/lucene/index/TestNoDeletionPolicy.java b/lucene/core/src/test/org/apache/lucene/index/TestNoDeletionPolicy.java index 0a349e8d9528..4a11dd7b15e2 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestNoDeletionPolicy.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestNoDeletionPolicy.java @@ -25,18 +25,15 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestNoDeletionPolicy extends LuceneTestCase { - @Test public void testNoDeletionPolicy() throws Exception { IndexDeletionPolicy idp = NoDeletionPolicy.INSTANCE; idp.onInit(null); idp.onCommit(null); } - @Test public void testFinalSingleton() throws Exception { assertTrue(Modifier.isFinal(NoDeletionPolicy.class.getModifiers())); Constructor[] ctors = NoDeletionPolicy.class.getDeclaredConstructors(); @@ -45,7 +42,6 @@ public void testFinalSingleton() throws Exception { "that 1 should be private: " + ctors[0], Modifier.isPrivate(ctors[0].getModifiers())); } - @Test public void testMethodsOverridden() throws Exception { // Ensures that all methods of IndexDeletionPolicy are // overridden/implemented. That's important to ensure that NoDeletionPolicy @@ -65,7 +61,6 @@ public void testMethodsOverridden() throws Exception { } } - @Test public void testAllCommitsRemain() throws Exception { Directory dir = newDirectory(); IndexWriter writer = diff --git a/lucene/core/src/test/org/apache/lucene/index/TestNoMergePolicy.java b/lucene/core/src/test/org/apache/lucene/index/TestNoMergePolicy.java index 360426e29411..58361155cc2e 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestNoMergePolicy.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestNoMergePolicy.java @@ -23,7 +23,6 @@ import java.util.Arrays; import org.apache.lucene.index.MergePolicy.MergeSpecification; import org.apache.lucene.tests.index.BaseMergePolicyTestCase; -import org.junit.Test; public class TestNoMergePolicy extends BaseMergePolicyTestCase { @@ -32,7 +31,6 @@ public MergePolicy mergePolicy() { return NoMergePolicy.INSTANCE; } - @Test public void testNoMergePolicy() throws Exception { MergePolicy mp = mergePolicy(); assertNull(mp.findMerges(null, (SegmentInfos) null, null)); @@ -40,7 +38,6 @@ public void testNoMergePolicy() throws Exception { assertNull(mp.findForcedDeletesMerges(null, null)); } - @Test public void testFinalSingleton() throws Exception { assertTrue(Modifier.isFinal(NoMergePolicy.class.getModifiers())); Constructor[] ctors = NoMergePolicy.class.getDeclaredConstructors(); @@ -49,7 +46,6 @@ public void testFinalSingleton() throws Exception { "that 1 should be private: " + ctors[0], Modifier.isPrivate(ctors[0].getModifiers())); } - @Test public void testMethodsOverridden() throws Exception { // Ensures that all methods of MergePolicy are overridden. That's important // to ensure that NoMergePolicy overrides everything, so that no unexpected diff --git a/lucene/core/src/test/org/apache/lucene/index/TestNoMergeScheduler.java b/lucene/core/src/test/org/apache/lucene/index/TestNoMergeScheduler.java index 3b1bf3549c55..b145a3c7c89c 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestNoMergeScheduler.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestNoMergeScheduler.java @@ -22,18 +22,15 @@ import java.lang.reflect.Modifier; import java.util.Arrays; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestNoMergeScheduler extends LuceneTestCase { - @Test public void testNoMergeScheduler() throws Exception { MergeScheduler ms = NoMergeScheduler.INSTANCE; ms.close(); ms.merge(null, RandomPicks.randomFrom(random(), MergeTrigger.values())); } - @Test public void testFinalSingleton() throws Exception { assertTrue(Modifier.isFinal(NoMergeScheduler.class.getModifiers())); Constructor[] ctors = NoMergeScheduler.class.getDeclaredConstructors(); @@ -42,7 +39,6 @@ public void testFinalSingleton() throws Exception { "that 1 should be private: " + ctors[0], Modifier.isPrivate(ctors[0].getModifiers())); } - @Test public void testMethodsOverridden() throws Exception { // Ensures that all methods of MergeScheduler are overridden. That's // important to ensure that NoMergeScheduler overrides everything, so that diff --git a/lucene/core/src/test/org/apache/lucene/index/TestOneMergeWrappingMergePolicy.java b/lucene/core/src/test/org/apache/lucene/index/TestOneMergeWrappingMergePolicy.java index a501caba197c..3b9c340e2b93 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestOneMergeWrappingMergePolicy.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestOneMergeWrappingMergePolicy.java @@ -27,7 +27,6 @@ import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.Version; -import org.junit.Test; public class TestOneMergeWrappingMergePolicy extends LuceneTestCase { @@ -80,7 +79,6 @@ public WrappedOneMerge(MergePolicy.OneMerge original) { } } - @Test public void testSegmentsAreWrapped() throws IOException { try (final Directory dir = newDirectory()) { // first create random merge specs diff --git a/lucene/core/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java b/lucene/core/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java index fdbd2b166329..0ee4a575df57 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java @@ -23,7 +23,6 @@ import org.apache.lucene.tests.store.MockDirectoryWrapper; import org.junit.After; import org.junit.Before; -import org.junit.Test; public class TestPersistentSnapshotDeletionPolicy extends TestSnapshotDeletionPolicy { @@ -44,7 +43,6 @@ private SnapshotDeletionPolicy getDeletionPolicy(Directory dir) throws IOExcepti new KeepOnlyLastCommitDeletionPolicy(), dir, OpenMode.CREATE); } - @Test public void testExistingSnapshots() throws Exception { int numSnapshots = 3; MockDirectoryWrapper dir = newMockDirectory(); @@ -92,7 +90,6 @@ public void testExistingSnapshots() throws Exception { dir.close(); } - @Test public void testNoSnapshotInfos() throws Exception { Directory dir = newDirectory(); new PersistentSnapshotDeletionPolicy( @@ -100,7 +97,6 @@ public void testNoSnapshotInfos() throws Exception { dir.close(); } - @Test public void testMissingSnapshots() throws Exception { Directory dir = newDirectory(); @@ -152,7 +148,6 @@ public void eval(MockDirectoryWrapper dir) throws IOException { dir.close(); } - @Test public void testSnapshotRelease() throws Exception { Directory dir = newDirectory(); IndexWriter writer = new IndexWriter(dir, getConfig(random(), getDeletionPolicy(dir))); @@ -170,7 +165,6 @@ public void testSnapshotRelease() throws Exception { dir.close(); } - @Test public void testSnapshotReleaseByGeneration() throws Exception { Directory dir = newDirectory(); IndexWriter writer = new IndexWriter(dir, getConfig(random(), getDeletionPolicy(dir))); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java b/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java index 14d09f8d9414..2ceb5422cb55 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java @@ -31,14 +31,12 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRef; -import org.junit.Test; public class TestRollingUpdates extends LuceneTestCase { // Just updates the same set of N docs over and over, to // stress out deletions - @Test public void testRollingUpdates() throws Exception { Random random = new Random(random().nextLong()); final BaseDirectoryWrapper dir = newDirectory(); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java b/lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java index 0a35e17084c5..b98a86ff275f 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java @@ -32,7 +32,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.SuppressForbidden; import org.apache.lucene.util.ThreadInterruptedException; -import org.junit.Test; // // This was developed for Lucene In Action, @@ -98,7 +97,6 @@ protected void assertSnapshotExists( } } - @Test public void testSnapshotDeletionPolicy() throws Exception { Directory fsDir = newDirectory(); runTest(random(), fsDir); @@ -253,7 +251,6 @@ private void readFile(Directory dir, String name) throws Exception { } } - @Test public void testBasicSnapshots() throws Exception { int numSnapshots = 3; @@ -281,7 +278,6 @@ public void testBasicSnapshots() throws Exception { dir.close(); } - @Test public void testMultiThreadedSnapshotting() throws Exception { Directory dir = newDirectory(); @@ -334,7 +330,6 @@ public void run() { dir.close(); } - @Test public void testRollbackToOldSnapshot() throws Exception { int numSnapshots = 2; Directory dir = newDirectory(); @@ -361,7 +356,6 @@ public void testRollbackToOldSnapshot() throws Exception { dir.close(); } - @Test public void testReleaseSnapshot() throws Exception { Directory dir = newDirectory(); IndexWriter writer = new IndexWriter(dir, getConfig(random(), getDeletionPolicy())); @@ -385,7 +379,6 @@ public void testReleaseSnapshot() throws Exception { dir.close(); } - @Test public void testSnapshotLastCommitTwice() throws Exception { Directory dir = newDirectory(); @@ -412,7 +405,6 @@ public void testSnapshotLastCommitTwice() throws Exception { dir.close(); } - @Test public void testMissingCommits() throws Exception { // Tests the behavior of SDP when commits that are given at ctor are missing // on onInit(). diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestCharHashSet.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestCharHashSet.java index 0df4ed1b9467..61986f6a6ea9 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestCharHashSet.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestCharHashSet.java @@ -33,7 +33,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.hamcrest.MatcherAssert; import org.junit.Before; -import org.junit.Test; /** * Tests for {@link CharHashSet}. @@ -64,7 +63,6 @@ public void initialize() { set = new CharHashSet(); } - @Test public void testAddAllViaInterface() { set.addAll(key1, key2); @@ -74,7 +72,6 @@ public void testAddAllViaInterface() { MatcherAssert.assertThat(set(iface.toArray()), is(equalTo(set(key1, key2)))); } - @Test public void testIndexMethods() { set.add(keyE); set.add(key1); @@ -114,7 +111,6 @@ public void testIndexMethods() { MatcherAssert.assertThat(set.indexOf(key2), is(lessThan(0))); } - @Test public void testCursorIndexIsValid() { set.add(keyE); set.add(key1); @@ -126,7 +122,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testEmptyKey() { CharHashSet set = new CharHashSet(); @@ -166,7 +161,6 @@ public void testEmptyKey() { MatcherAssert.assertThat(set.indexGet(index), is(equalTo(EMPTY_KEY))); } - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); CharHashSet set = @@ -193,19 +187,16 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testInitiallyEmpty() { assertEquals(0, set.size()); } - @Test public void testAdd() { assertTrue(set.add(key1)); assertFalse(set.add(key1)); assertEquals(1, set.size()); } - @Test public void testAdd2() { set.addAll(key1, key1); assertEquals(1, set.size()); @@ -213,14 +204,12 @@ public void testAdd2() { assertEquals(2, set.size()); } - @Test public void testAddVarArgs() { set.addAll(asArray(0, 1, 2, 1, 0)); assertEquals(3, set.size()); assertSortedListEquals(set.toArray(), asArray(0, 1, 2)); } - @Test public void testAddAll() { CharHashSet set2 = new CharHashSet(); set2.addAll(asArray(1, 2)); @@ -233,7 +222,6 @@ public void testAddAll() { assertSortedListEquals(set.toArray(), asArray(0, 1, 2)); } - @Test public void testRemove() { set.addAll(asArray(0, 1, 2, 3, 4)); @@ -243,7 +231,6 @@ public void testRemove() { assertSortedListEquals(set.toArray(), asArray(0, 1, 3, 4)); } - @Test public void testInitialCapacityAndGrowth() { for (int i = 0; i < 256; i++) { CharHashSet set = new CharHashSet(i); @@ -256,7 +243,6 @@ public void testInitialCapacityAndGrowth() { } } - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -301,7 +287,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testRemoveAllFromLookupContainer() { set.addAll(asArray(0, 1, 2, 3, 4)); @@ -313,14 +298,12 @@ public void testRemoveAllFromLookupContainer() { assertSortedListEquals(set.toArray(), asArray(0, 2, 4)); } - @Test public void testClear() { set.addAll(asArray(1, 2, 3)); set.clear(); assertEquals(0, set.size()); } - @Test public void testRelease() { set.addAll(asArray(1, 2, 3)); set.release(); @@ -329,7 +312,6 @@ public void testRelease() { assertEquals(3, set.size()); } - @Test public void testIterable() { set.addAll(asArray(1, 2, 2, 3, 4)); set.remove(key2); @@ -347,7 +329,6 @@ public void testIterable() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashSet}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashSet() { final Random rnd = RandomizedTest.getRandom(); @@ -395,7 +376,6 @@ public void testAgainstHashSet() { } } - @Test public void testHashCodeEquals() { CharHashSet l0 = new CharHashSet(); assertEquals(0, l0.hashCode()); @@ -409,7 +389,6 @@ public void testHashCodeEquals() { assertEquals(l1, l2); } - @Test public void testClone() { this.set.addAll(asArray(1, 2, 3)); @@ -420,7 +399,6 @@ public void testClone() { assertSortedListEquals(cloned.toArray(), asArray(2, 3)); } - @Test public void testEqualsSameClass() { CharHashSet l1 = CharHashSet.from(key1, key2, key3); CharHashSet l2 = CharHashSet.from(key1, key2, key3); @@ -431,7 +409,6 @@ public void testEqualsSameClass() { MatcherAssert.assertThat(l1, is(not(equalTo(l3)))); } - @Test public void testEqualsSubClass() { class Sub extends CharHashSet {} ; diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestCharObjectHashMap.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestCharObjectHashMap.java index 2f95ec1c194a..9c0329683b8a 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestCharObjectHashMap.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestCharObjectHashMap.java @@ -29,7 +29,6 @@ import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.After; -import org.junit.Test; /** * Tests for {@link CharObjectHashMap}. @@ -122,7 +121,6 @@ private void assertSameMap( } /* */ - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); CharObjectHashMap map = @@ -149,7 +147,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); @@ -161,7 +158,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); @@ -204,7 +200,6 @@ public void testIndexMethods() { } /* */ - @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); @@ -214,7 +209,6 @@ public void testCloningConstructor() { } /* */ - @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); @@ -226,7 +220,6 @@ public void testFromArrays() { assertSameMap(map, map2); } - @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); @@ -239,7 +232,6 @@ public void testGetOrDefault() { } /* */ - @Test public void testPut() { map.put(key1, value1); @@ -248,7 +240,6 @@ public void testPut() { } /* */ - @Test public void testNullValue() { map.put(key1, null); @@ -256,7 +247,6 @@ public void testNullValue() { assertNull(map.get(key1)); } - @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals(value1, map.put(key1, value3)); @@ -271,7 +261,6 @@ public void testPutOverExistingKey() { } /* */ - @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(random().nextLong()); @@ -290,7 +279,6 @@ public void testPutWithExpansions() { } /* */ - @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); @@ -312,7 +300,6 @@ public void testPutAll() { } /* */ - @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); @@ -320,7 +307,6 @@ public void testPutIfAbsent() { } /* */ - @Test public void testRemove() { map.put(key1, value1); assertEquals(value1, map.remove(key1)); @@ -332,7 +318,6 @@ public void testRemove() { } /* */ - @Test public void testEmptyKey() { final char empty = 0; @@ -369,7 +354,6 @@ public void testEmptyKey() { } /* */ - @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); @@ -379,7 +363,6 @@ public void testMapKeySet() { } /* */ - @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); @@ -394,7 +377,6 @@ public void testMapKeySetIterator() { } /* */ - @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); @@ -414,7 +396,6 @@ public void testClear() { } /* */ - @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); @@ -429,7 +410,6 @@ public void testRelease() { } /* */ - @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); @@ -452,7 +432,6 @@ public void testIterable() { } /* */ - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -497,7 +476,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testHashCodeEquals() { CharObjectHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); @@ -518,7 +496,6 @@ public void testHashCodeEquals() { assertFalse(l2.equals(l3)); } - @Test public void testBug_HPPC37() { CharObjectHashMap l1 = CharObjectHashMap.from(newArray(key1), newvArray(value1)); @@ -529,7 +506,6 @@ public void testBug_HPPC37() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashMap}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashMap() { final Random rnd = RandomizedTest.getRandom(); @@ -583,7 +559,6 @@ public void testAgainstHashMap() { /* * */ - @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); @@ -597,7 +572,6 @@ public void testClone() { } /* */ - @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); @@ -614,7 +588,6 @@ public void testMapValues() { } /* */ - @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); @@ -629,7 +602,6 @@ public void testMapValuesIterator() { } /* */ - @Test public void testEqualsSameClass() { CharObjectHashMap l1 = newInstance(); l1.put(key1, value0); @@ -649,7 +621,6 @@ public void testEqualsSameClass() { } /* */ - @Test public void testEqualsSubClass() { class Sub extends CharObjectHashMap {} diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestFloatArrayList.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestFloatArrayList.java index 3acda63ca6e4..a4a9e98f2b06 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestFloatArrayList.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestFloatArrayList.java @@ -21,7 +21,6 @@ import java.util.Iterator; import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.Before; -import org.junit.Test; /** * Tests for {@link FloatArrayList}. @@ -53,38 +52,32 @@ public void initialize() { list = new FloatArrayList(); } - @Test public void testInitiallyEmpty() { assertEquals(0, list.size()); } - @Test public void testAdd() { list.add(key1, key2); assertListEquals(list.toArray(), 1, 2); } - @Test public void testAddTwoArgs() { list.add(key1, key2); list.add(key3, key4); assertListEquals(list.toArray(), 1, 2, 3, 4); } - @Test public void testAddArray() { list.add(asArray(0, 1, 2, 3), 1, 2); assertListEquals(list.toArray(), 1, 2); } - @Test public void testAddVarArg() { list.add(asArray(0, 1, 2, 3)); list.add(key4, key5, key6, key7); assertListEquals(list.toArray(), 0, 1, 2, 3, 4, 5, 6, 7); } - @Test public void testAddAll() { FloatArrayList list2 = new FloatArrayList(); list2.add(asArray(0, 1, 2)); @@ -95,7 +88,6 @@ public void testAddAll() { assertListEquals(list.toArray(), 0, 1, 2, 0, 1, 2); } - @Test public void testInsert() { list.insert(0, key1); list.insert(0, key2); @@ -105,7 +97,6 @@ public void testInsert() { assertListEquals(list.toArray(), 2, 4, 1, 3); } - @Test public void testSet() { list.add(asArray(0, 1, 2)); @@ -116,7 +107,6 @@ public void testSet() { assertListEquals(list.toArray(), 3, 4, 5); } - @Test public void testRemoveAt() { list.add(asArray(0, 1, 2, 3, 4)); @@ -127,7 +117,6 @@ public void testRemoveAt() { assertListEquals(list.toArray(), 1, 4); } - @Test public void testRemoveLast() { list.add(asArray(0, 1, 2, 3, 4)); @@ -143,7 +132,6 @@ public void testRemoveLast() { assertTrue(list.isEmpty()); } - @Test public void testRemoveElement() { list.add(asArray(0, 1, 2, 3, 3, 4)); @@ -154,7 +142,6 @@ public void testRemoveElement() { assertListEquals(list.toArray(), 0, 1, 3, 4); } - @Test public void testRemoveRange() { list.add(asArray(0, 1, 2, 3, 4)); @@ -171,7 +158,6 @@ public void testRemoveRange() { assertListEquals(list.toArray(), 3); } - @Test public void testRemoveFirstLast() { list.add(asArray(0, 1, 2, 1, 0)); @@ -188,7 +174,6 @@ public void testRemoveFirstLast() { assertEquals(-1, list.removeLast(key0)); } - @Test public void testRemoveAll() { list.add(asArray(0, 1, 0, 1, 0)); @@ -200,7 +185,6 @@ public void testRemoveAll() { assertTrue(list.isEmpty()); } - @Test public void testIndexOf() { list.add(asArray(0, 1, 2, 1, 0)); @@ -209,7 +193,6 @@ public void testIndexOf() { assertEquals(2, list.indexOf(key2)); } - @Test public void testLastIndexOf() { list.add(asArray(0, 1, 2, 1, 0)); @@ -218,7 +201,6 @@ public void testLastIndexOf() { assertEquals(2, list.lastIndexOf(key2)); } - @Test public void testEnsureCapacity() { FloatArrayList list = new FloatArrayList(0); assertEquals(list.size(), list.buffer.length); @@ -227,7 +209,6 @@ public void testEnsureCapacity() { assertNotSame(buffer1, list.buffer); } - @Test public void testResizeAndCleanBuffer() { list.ensureCapacity(20); Arrays.fill(list.buffer, key1); @@ -249,14 +230,12 @@ public void testResizeAndCleanBuffer() { } } - @Test public void testTrimToSize() { list.add(asArray(1, 2)); list.trimToSize(); assertEquals(2, list.buffer.length); } - @Test public void testRelease() { list.add(asArray(1, 2)); list.release(); @@ -265,7 +244,6 @@ public void testRelease() { assertEquals(2, list.size()); } - @Test public void testIterable() { list.add(asArray(0, 1, 2, 3)); int count = 0; @@ -284,7 +262,6 @@ public void testIterable() { assertEquals(0, count); } - @Test public void testIterator() { list.add(asArray(0, 1, 2, 3)); Iterator iterator = list.iterator(); @@ -302,7 +279,6 @@ public void testIterator() { assertFalse(list.iterator().hasNext()); } - @Test public void testClear() { list.add(asArray(1, 2, 3)); list.clear(); @@ -310,7 +286,6 @@ public void testClear() { assertEquals(-1, list.indexOf(cast(1))); } - @Test public void testFrom() { list = FloatArrayList.from(key1, key2, key3); assertEquals(3, list.size()); @@ -318,7 +293,6 @@ public void testFrom() { assertEquals(list.size(), list.buffer.length); } - @Test public void testCopyList() { list.add(asArray(1, 2, 3)); FloatArrayList copy = new FloatArrayList(list); @@ -327,7 +301,6 @@ public void testCopyList() { assertEquals(copy.size(), copy.buffer.length); } - @Test public void testHashCodeEquals() { FloatArrayList l0 = FloatArrayList.from(); assertEquals(1, l0.hashCode()); @@ -341,7 +314,6 @@ public void testHashCodeEquals() { assertEquals(l1, l2); } - @Test public void testEqualElements() { FloatArrayList l1 = FloatArrayList.from(key1, key2, key3); FloatArrayList l2 = FloatArrayList.from(key1, key2); @@ -351,7 +323,6 @@ public void testEqualElements() { assertTrue(l2.equalElements(l1)); } - @Test public void testToArray() { FloatArrayList l1 = FloatArrayList.from(key1, key2, key3); l1.ensureCapacity(100); @@ -359,7 +330,6 @@ public void testToArray() { assertArrayEquals(new float[] {key1, key2, key3}, result); } - @Test public void testClone() { list.add(key1, key2, key3); @@ -370,14 +340,12 @@ public void testClone() { assertSortedListEquals(cloned.toArray(), key2, key3); } - @Test public void testToString() { assertEquals( "[" + key1 + ", " + key2 + ", " + key3 + "]", FloatArrayList.from(key1, key2, key3).toString()); } - @Test public void testEqualsSameClass() { FloatArrayList l1 = FloatArrayList.from(key1, key2, key3); FloatArrayList l2 = FloatArrayList.from(key1, key2, key3); @@ -388,7 +356,6 @@ public void testEqualsSameClass() { assertNotEquals(l1, l3); } - @Test public void testEqualsSubClass() { class Sub extends FloatArrayList {} ; @@ -403,7 +370,6 @@ class Sub extends FloatArrayList {} assertNotEquals(l1, l3); } - @Test public void testSort() { list.add(key3, key1, key3, key2); FloatArrayList list2 = new FloatArrayList(); @@ -413,7 +379,6 @@ public void testSort() { assertEquals(FloatArrayList.from(key1, key2, key3, key3), list2); } - @Test public void testReverse() { for (int i = 0; i < 10; i++) { float[] elements = new float[i]; diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntArrayList.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntArrayList.java index e631f1a2161d..0265853218af 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntArrayList.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntArrayList.java @@ -22,7 +22,6 @@ import java.util.NoSuchElementException; import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.Before; -import org.junit.Test; /** * Tests for {@link IntArrayList}. @@ -54,38 +53,32 @@ public void initialize() { list = new IntArrayList(); } - @Test public void testInitiallyEmpty() { assertEquals(0, list.size()); } - @Test public void testAdd() { list.add(key1, key2); assertListEquals(list.toArray(), 1, 2); } - @Test public void testAddTwoArgs() { list.add(key1, key2); list.add(key3, key4); assertListEquals(list.toArray(), 1, 2, 3, 4); } - @Test public void testAddArray() { list.add(asArray(0, 1, 2, 3), 1, 2); assertListEquals(list.toArray(), 1, 2); } - @Test public void testAddVarArg() { list.add(asArray(0, 1, 2, 3)); list.add(key4, key5, key6, key7); assertListEquals(list.toArray(), 0, 1, 2, 3, 4, 5, 6, 7); } - @Test public void testAddAll() { IntArrayList list2 = new IntArrayList(); list2.add(asArray(0, 1, 2)); @@ -96,7 +89,6 @@ public void testAddAll() { assertListEquals(list.toArray(), 0, 1, 2, 0, 1, 2); } - @Test public void testInsert() { list.insert(0, key1); list.insert(0, key2); @@ -106,7 +98,6 @@ public void testInsert() { assertListEquals(list.toArray(), 2, 4, 1, 3); } - @Test public void testSet() { list.add(asArray(0, 1, 2)); @@ -117,7 +108,6 @@ public void testSet() { assertListEquals(list.toArray(), 3, 4, 5); } - @Test public void testRemoveAt() { list.add(asArray(0, 1, 2, 3, 4)); @@ -128,7 +118,6 @@ public void testRemoveAt() { assertListEquals(list.toArray(), 1, 4); } - @Test public void testRemoveLast() { list.add(asArray(0, 1, 2, 3, 4)); @@ -144,7 +133,6 @@ public void testRemoveLast() { assertTrue(list.isEmpty()); } - @Test public void testRemoveElement() { list.add(asArray(0, 1, 2, 3, 3, 4)); @@ -155,7 +143,6 @@ public void testRemoveElement() { assertListEquals(list.toArray(), 0, 1, 3, 4); } - @Test public void testRemoveRange() { list.add(asArray(0, 1, 2, 3, 4)); @@ -172,7 +159,6 @@ public void testRemoveRange() { assertListEquals(list.toArray(), 3); } - @Test public void testRemoveFirstLast() { list.add(asArray(0, 1, 2, 1, 0)); @@ -189,7 +175,6 @@ public void testRemoveFirstLast() { assertEquals(-1, list.removeLast(key0)); } - @Test public void testRemoveAll() { list.add(asArray(0, 1, 0, 1, 0)); @@ -201,7 +186,6 @@ public void testRemoveAll() { assertTrue(list.isEmpty()); } - @Test public void testIndexOf() { list.add(asArray(0, 1, 2, 1, 0)); @@ -210,7 +194,6 @@ public void testIndexOf() { assertEquals(2, list.indexOf(key2)); } - @Test public void testLastIndexOf() { list.add(asArray(0, 1, 2, 1, 0)); @@ -219,7 +202,6 @@ public void testLastIndexOf() { assertEquals(2, list.lastIndexOf(key2)); } - @Test public void testEnsureCapacity() { IntArrayList list = new IntArrayList(0); assertEquals(list.size(), list.buffer.length); @@ -228,7 +210,6 @@ public void testEnsureCapacity() { assertNotSame(buffer1, list.buffer); } - @Test public void testResizeAndCleanBuffer() { list.ensureCapacity(20); Arrays.fill(list.buffer, key1); @@ -250,14 +231,12 @@ public void testResizeAndCleanBuffer() { } } - @Test public void testTrimToSize() { list.add(asArray(1, 2)); list.trimToSize(); assertEquals(2, list.buffer.length); } - @Test public void testRelease() { list.add(asArray(1, 2)); list.release(); @@ -266,7 +245,6 @@ public void testRelease() { assertEquals(2, list.size()); } - @Test public void testIterable() { list.add(asArray(0, 1, 2, 3)); int count = 0; @@ -285,7 +263,6 @@ public void testIterable() { assertEquals(0, count); } - @Test public void testIterator() { list.add(asArray(0, 1, 2, 3)); Iterator iterator = list.iterator(); @@ -303,7 +280,6 @@ public void testIterator() { assertFalse(list.iterator().hasNext()); } - @Test public void testClear() { list.add(asArray(1, 2, 3)); list.clear(); @@ -311,7 +287,6 @@ public void testClear() { assertEquals(-1, list.indexOf(cast(1))); } - @Test public void testFrom() { list = IntArrayList.from(key1, key2, key3); assertEquals(3, list.size()); @@ -319,7 +294,6 @@ public void testFrom() { assertEquals(list.size(), list.buffer.length); } - @Test public void testCopyList() { list.add(asArray(1, 2, 3)); IntArrayList copy = new IntArrayList(list); @@ -328,7 +302,6 @@ public void testCopyList() { assertEquals(copy.size(), copy.buffer.length); } - @Test public void testHashCodeEquals() { IntArrayList l0 = IntArrayList.from(); assertEquals(1, l0.hashCode()); @@ -342,7 +315,6 @@ public void testHashCodeEquals() { assertEquals(l1, l2); } - @Test public void testEqualElements() { IntArrayList l1 = IntArrayList.from(key1, key2, key3); IntArrayList l2 = IntArrayList.from(key1, key2); @@ -352,7 +324,6 @@ public void testEqualElements() { assertTrue(l2.equalElements(l1)); } - @Test public void testToArray() { IntArrayList l1 = IntArrayList.from(key1, key2, key3); l1.ensureCapacity(100); @@ -360,7 +331,6 @@ public void testToArray() { assertArrayEquals(new int[] {key1, key2, key3}, result); } - @Test public void testClone() { list.add(key1, key2, key3); @@ -371,14 +341,12 @@ public void testClone() { assertSortedListEquals(cloned.toArray(), key2, key3); } - @Test public void testToString() { assertEquals( "[" + key1 + ", " + key2 + ", " + key3 + "]", IntArrayList.from(key1, key2, key3).toString()); } - @Test public void testEqualsSameClass() { IntArrayList l1 = IntArrayList.from(key1, key2, key3); IntArrayList l2 = IntArrayList.from(key1, key2, key3); @@ -389,7 +357,6 @@ public void testEqualsSameClass() { assertNotEquals(l1, l3); } - @Test public void testEqualsSubClass() { class Sub extends IntArrayList {} ; @@ -404,7 +371,6 @@ class Sub extends IntArrayList {} assertNotEquals(l1, l3); } - @Test public void testStream() { assertEquals(key1, IntArrayList.from(key1, key2, key3).stream().min().orElseThrow()); assertEquals(key3, IntArrayList.from(key2, key1, key3).stream().max().orElseThrow()); @@ -416,7 +382,6 @@ public void testStream() { }); } - @Test public void testSort() { list.add(key3, key1, key3, key2); IntArrayList list2 = new IntArrayList(); @@ -426,7 +391,6 @@ public void testSort() { assertEquals(IntArrayList.from(key1, key2, key3, key3), list2); } - @Test public void testReverse() { for (int i = 0; i < 10; i++) { int[] elements = new int[i]; diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntDoubleHashMap.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntDoubleHashMap.java index 55f6cba65489..3695e981f7f6 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntDoubleHashMap.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntDoubleHashMap.java @@ -24,7 +24,6 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** * Tests for {@link IntDoubleHashMap}. @@ -118,7 +117,6 @@ private static void assertArrayEquals(double[] v1, double[] v2) { } /* */ - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); IntDoubleHashMap map = @@ -145,7 +143,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); @@ -157,7 +154,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); @@ -200,7 +196,6 @@ public void testIndexMethods() { } /* */ - @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); @@ -210,7 +205,6 @@ public void testCloningConstructor() { } /* */ - @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); @@ -222,7 +216,6 @@ public void testFromArrays() { assertSameMap(map, map2); } - @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); @@ -235,7 +228,6 @@ public void testGetOrDefault() { } /* */ - @Test public void testPut() { map.put(key1, value1); @@ -244,7 +236,6 @@ public void testPut() { } /* */ - @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals2(value1, map.put(key1, value3)); @@ -252,7 +243,6 @@ public void testPutOverExistingKey() { } /* */ - @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(random().nextInt()); @@ -271,7 +261,6 @@ public void testPutWithExpansions() { } /* */ - @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); @@ -293,27 +282,23 @@ public void testPutAll() { } /* */ - @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); assertEquals2(value1, map.get(key1)); } - @Test public void testPutOrAdd() { assertEquals2(value1, map.putOrAdd(key1, value1, value2)); assertEquals2(value3, map.putOrAdd(key1, value1, value2)); } - @Test public void testAddTo() { assertEquals2(value1, map.addTo(key1, value1)); assertEquals2(value3, map.addTo(key1, value2)); } /* */ - @Test public void testRemove() { map.put(key1, value1); assertEquals2(value1, map.remove(key1)); @@ -325,7 +310,6 @@ public void testRemove() { } /* */ - @Test public void testEmptyKey() { final int empty = 0; @@ -352,7 +336,6 @@ public void testEmptyKey() { } /* */ - @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); @@ -362,7 +345,6 @@ public void testMapKeySet() { } /* */ - @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); @@ -377,7 +359,6 @@ public void testMapKeySetIterator() { } /* */ - @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); @@ -397,7 +378,6 @@ public void testClear() { } /* */ - @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); @@ -412,7 +392,6 @@ public void testRelease() { } /* */ - @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); @@ -435,7 +414,6 @@ public void testIterable() { } /* */ - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -480,7 +458,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testHashCodeEquals() { IntDoubleHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); @@ -501,7 +478,6 @@ public void testHashCodeEquals() { assertNotEquals(l2, l3); } - @Test public void testBug_HPPC37() { IntDoubleHashMap l1 = IntDoubleHashMap.from(newArray(key1), newvArray(value1)); @@ -512,7 +488,6 @@ public void testBug_HPPC37() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashMap}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashMap() { final Random rnd = RandomizedTest.getRandom(); @@ -569,7 +544,6 @@ public void testAgainstHashMap() { /* * */ - @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); @@ -583,7 +557,6 @@ public void testClone() { } /* */ - @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); @@ -598,7 +571,6 @@ public void testMapValues() { } /* */ - @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); @@ -613,7 +585,6 @@ public void testMapValuesIterator() { } /* */ - @Test public void testEqualsSameClass() { IntDoubleHashMap l1 = newInstance(); l1.put(key1, value0); @@ -633,7 +604,6 @@ public void testEqualsSameClass() { } /* */ - @Test public void testEqualsSubClass() { class Sub extends IntDoubleHashMap {} diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntFloatHashMap.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntFloatHashMap.java index 5c81d9e4d909..0d8f938fba77 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntFloatHashMap.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntFloatHashMap.java @@ -24,7 +24,6 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** * Tests for {@link IntFloatHashMap}. @@ -118,7 +117,6 @@ private static void assertArrayEquals(float[] v1, float[] v2) { } /* */ - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); IntFloatHashMap map = @@ -145,7 +143,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); @@ -157,7 +154,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); @@ -200,7 +196,6 @@ public void testIndexMethods() { } /* */ - @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); @@ -210,7 +205,6 @@ public void testCloningConstructor() { } /* */ - @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); @@ -222,7 +216,6 @@ public void testFromArrays() { assertSameMap(map, map2); } - @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); @@ -235,7 +228,6 @@ public void testGetOrDefault() { } /* */ - @Test public void testPut() { map.put(key1, value1); @@ -244,7 +236,6 @@ public void testPut() { } /* */ - @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals2(value1, map.put(key1, value3)); @@ -252,7 +243,6 @@ public void testPutOverExistingKey() { } /* */ - @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(random().nextInt()); @@ -271,7 +261,6 @@ public void testPutWithExpansions() { } /* */ - @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); @@ -293,27 +282,23 @@ public void testPutAll() { } /* */ - @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); assertEquals2(value1, map.get(key1)); } - @Test public void testPutOrAdd() { assertEquals2(value1, map.putOrAdd(key1, value1, value2)); assertEquals2(value3, map.putOrAdd(key1, value1, value2)); } - @Test public void testAddTo() { assertEquals2(value1, map.addTo(key1, value1)); assertEquals2(value3, map.addTo(key1, value2)); } /* */ - @Test public void testRemove() { map.put(key1, value1); assertEquals2(value1, map.remove(key1)); @@ -325,7 +310,6 @@ public void testRemove() { } /* */ - @Test public void testEmptyKey() { final int empty = 0; @@ -352,7 +336,6 @@ public void testEmptyKey() { } /* */ - @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); @@ -362,7 +345,6 @@ public void testMapKeySet() { } /* */ - @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); @@ -377,7 +359,6 @@ public void testMapKeySetIterator() { } /* */ - @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); @@ -397,7 +378,6 @@ public void testClear() { } /* */ - @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); @@ -412,7 +392,6 @@ public void testRelease() { } /* */ - @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); @@ -435,7 +414,6 @@ public void testIterable() { } /* */ - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -480,7 +458,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testHashCodeEquals() { IntFloatHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); @@ -501,7 +478,6 @@ public void testHashCodeEquals() { assertNotEquals(l2, l3); } - @Test public void testBug_HPPC37() { IntFloatHashMap l1 = IntFloatHashMap.from(newArray(key1), newvArray(value1)); @@ -512,7 +488,6 @@ public void testBug_HPPC37() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashMap}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashMap() { final Random rnd = RandomizedTest.getRandom(); @@ -569,7 +544,6 @@ public void testAgainstHashMap() { /* * */ - @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); @@ -583,7 +557,6 @@ public void testClone() { } /* */ - @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); @@ -598,7 +571,6 @@ public void testMapValues() { } /* */ - @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); @@ -613,7 +585,6 @@ public void testMapValuesIterator() { } /* */ - @Test public void testEqualsSameClass() { IntFloatHashMap l1 = newInstance(); l1.put(key1, value0); @@ -633,7 +604,6 @@ public void testEqualsSameClass() { } /* */ - @Test public void testEqualsSubClass() { class Sub extends IntFloatHashMap {} diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntHashSet.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntHashSet.java index 0b8721bbe311..cd234dfaa428 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntHashSet.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntHashSet.java @@ -33,7 +33,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.hamcrest.MatcherAssert; import org.junit.Before; -import org.junit.Test; /** * Tests for {@link IntHashSet}. @@ -64,7 +63,6 @@ public void initialize() { set = new IntHashSet(); } - @Test public void testAddAllViaInterface() { set.addAll(key1, key2); @@ -74,7 +72,6 @@ public void testAddAllViaInterface() { MatcherAssert.assertThat(set(iface.toArray()), is(equalTo(set(key1, key2)))); } - @Test public void testIndexMethods() { set.add(keyE); set.add(key1); @@ -114,7 +111,6 @@ public void testIndexMethods() { MatcherAssert.assertThat(set.indexOf(key2), is(lessThan(0))); } - @Test public void testCursorIndexIsValid() { set.add(keyE); set.add(key1); @@ -126,7 +122,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testEmptyKey() { IntHashSet set = new IntHashSet(); @@ -166,7 +161,6 @@ public void testEmptyKey() { MatcherAssert.assertThat(set.indexGet(index), is(equalTo(EMPTY_KEY))); } - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); IntHashSet set = @@ -193,19 +187,16 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testInitiallyEmpty() { assertEquals(0, set.size()); } - @Test public void testAdd() { assertTrue(set.add(key1)); assertFalse(set.add(key1)); assertEquals(1, set.size()); } - @Test public void testAdd2() { set.addAll(key1, key1); assertEquals(1, set.size()); @@ -213,14 +204,12 @@ public void testAdd2() { assertEquals(2, set.size()); } - @Test public void testAddVarArgs() { set.addAll(asArray(0, 1, 2, 1, 0)); assertEquals(3, set.size()); assertSortedListEquals(set.toArray(), asArray(0, 1, 2)); } - @Test public void testAddAll() { IntHashSet set2 = new IntHashSet(); set2.addAll(asArray(1, 2)); @@ -233,7 +222,6 @@ public void testAddAll() { assertSortedListEquals(set.toArray(), asArray(0, 1, 2)); } - @Test public void testRemove() { set.addAll(asArray(0, 1, 2, 3, 4)); @@ -243,7 +231,6 @@ public void testRemove() { assertSortedListEquals(set.toArray(), asArray(0, 1, 3, 4)); } - @Test public void testInitialCapacityAndGrowth() { for (int i = 0; i < 256; i++) { IntHashSet set = new IntHashSet(i); @@ -256,7 +243,6 @@ public void testInitialCapacityAndGrowth() { } } - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -301,7 +287,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testRemoveAllFromLookupContainer() { set.addAll(asArray(0, 1, 2, 3, 4)); @@ -313,14 +298,12 @@ public void testRemoveAllFromLookupContainer() { assertSortedListEquals(set.toArray(), asArray(0, 2, 4)); } - @Test public void testClear() { set.addAll(asArray(1, 2, 3)); set.clear(); assertEquals(0, set.size()); } - @Test public void testRelease() { set.addAll(asArray(1, 2, 3)); set.release(); @@ -329,7 +312,6 @@ public void testRelease() { assertEquals(3, set.size()); } - @Test public void testIterable() { set.addAll(asArray(1, 2, 2, 3, 4)); set.remove(key2); @@ -347,7 +329,6 @@ public void testIterable() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashSet}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashSet() { final Random rnd = RandomizedTest.getRandom(); @@ -395,7 +376,6 @@ public void testAgainstHashSet() { } } - @Test public void testHashCodeEquals() { IntHashSet l0 = new IntHashSet(); assertEquals(0, l0.hashCode()); @@ -409,7 +389,6 @@ public void testHashCodeEquals() { assertEquals(l1, l2); } - @Test public void testClone() { this.set.addAll(asArray(1, 2, 3)); @@ -420,7 +399,6 @@ public void testClone() { assertSortedListEquals(cloned.toArray(), asArray(2, 3)); } - @Test public void testEqualsSameClass() { IntHashSet l1 = IntHashSet.from(key1, key2, key3); IntHashSet l2 = IntHashSet.from(key1, key2, key3); @@ -431,7 +409,6 @@ public void testEqualsSameClass() { MatcherAssert.assertThat(l1, is(not(equalTo(l3)))); } - @Test public void testEqualsSubClass() { class Sub extends IntHashSet {} ; diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntIntHashMap.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntIntHashMap.java index 0d9e2e725bfc..c87737937d80 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntIntHashMap.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntIntHashMap.java @@ -24,7 +24,6 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** * Tests for {@link IntIntHashMap}. @@ -97,7 +96,6 @@ private void assertSameMap(final IntIntHashMap c1, final IntIntHashMap c2) { } /* */ - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); IntIntHashMap map = @@ -124,7 +122,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); @@ -136,7 +133,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); @@ -179,7 +175,6 @@ public void testIndexMethods() { } /* */ - @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); @@ -189,7 +184,6 @@ public void testCloningConstructor() { } /* */ - @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); @@ -201,7 +195,6 @@ public void testFromArrays() { assertSameMap(map, map2); } - @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); @@ -214,7 +207,6 @@ public void testGetOrDefault() { } /* */ - @Test public void testPut() { map.put(key1, value1); @@ -223,7 +215,6 @@ public void testPut() { } /* */ - @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals(value1, map.put(key1, value3)); @@ -231,7 +222,6 @@ public void testPutOverExistingKey() { } /* */ - @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(random().nextLong()); @@ -250,7 +240,6 @@ public void testPutWithExpansions() { } /* */ - @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); @@ -272,27 +261,23 @@ public void testPutAll() { } /* */ - @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); assertEquals(value1, map.get(key1)); } - @Test public void testPutOrAdd() { assertEquals(value1, map.putOrAdd(key1, value1, value2)); assertEquals(value3, map.putOrAdd(key1, value1, value2)); } - @Test public void testAddTo() { assertEquals(value1, map.addTo(key1, value1)); assertEquals(value3, map.addTo(key1, value2)); } /* */ - @Test public void testRemove() { map.put(key1, value1); assertEquals(value1, map.remove(key1)); @@ -304,7 +289,6 @@ public void testRemove() { } /* */ - @Test public void testEmptyKey() { final int empty = 0; @@ -331,7 +315,6 @@ public void testEmptyKey() { } /* */ - @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); @@ -341,7 +324,6 @@ public void testMapKeySet() { } /* */ - @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); @@ -356,7 +338,6 @@ public void testMapKeySetIterator() { } /* */ - @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); @@ -376,7 +357,6 @@ public void testClear() { } /* */ - @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); @@ -391,7 +371,6 @@ public void testRelease() { } /* */ - @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); @@ -414,7 +393,6 @@ public void testIterable() { } /* */ - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -459,7 +437,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testHashCodeEquals() { IntIntHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); @@ -480,7 +457,6 @@ public void testHashCodeEquals() { assertNotEquals(l2, l3); } - @Test public void testBug_HPPC37() { IntIntHashMap l1 = IntIntHashMap.from(newArray(key1), newvArray(value1)); @@ -491,7 +467,6 @@ public void testBug_HPPC37() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashMap}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashMap() { final Random rnd = RandomizedTest.getRandom(); @@ -548,7 +523,6 @@ public void testAgainstHashMap() { /* * */ - @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); @@ -562,7 +536,6 @@ public void testClone() { } /* */ - @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); @@ -577,7 +550,6 @@ public void testMapValues() { } /* */ - @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); @@ -592,7 +564,6 @@ public void testMapValuesIterator() { } /* */ - @Test public void testEqualsSameClass() { IntIntHashMap l1 = newInstance(); l1.put(key1, value0); @@ -612,7 +583,6 @@ public void testEqualsSameClass() { } /* */ - @Test public void testEqualsSubClass() { class Sub extends IntIntHashMap {} diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntLongHashMap.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntLongHashMap.java index 6bc1cd8b07fd..2b0a64e0c40f 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntLongHashMap.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntLongHashMap.java @@ -25,7 +25,6 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.After; -import org.junit.Test; /** * Tests for {@link IntLongHashMap}. @@ -129,7 +128,6 @@ private void assertSameMap(final IntLongHashMap c1, final IntLongHashMap c2) { } /* */ - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); IntLongHashMap map = @@ -156,7 +154,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); @@ -168,7 +165,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); @@ -211,7 +207,6 @@ public void testIndexMethods() { } /* */ - @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); @@ -221,7 +216,6 @@ public void testCloningConstructor() { } /* */ - @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); @@ -233,7 +227,6 @@ public void testFromArrays() { assertSameMap(map, map2); } - @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); @@ -246,7 +239,6 @@ public void testGetOrDefault() { } /* */ - @Test public void testPut() { map.put(key1, value1); @@ -261,7 +253,6 @@ public void testPut() { } /* */ - @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals(value1, map.put(key1, value3)); @@ -278,7 +269,6 @@ public void testPutOverExistingKey() { } /* */ - @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(random().nextLong()); @@ -297,7 +287,6 @@ public void testPutWithExpansions() { } /* */ - @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); @@ -319,27 +308,23 @@ public void testPutAll() { } /* */ - @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); assertEquals(value1, map.get(key1)); } - @Test public void testPutOrAdd() { assertEquals(value1, map.putOrAdd(key1, value1, value2)); assertEquals(value3, map.putOrAdd(key1, value1, value2)); } - @Test public void testAddTo() { assertEquals(value1, map.addTo(key1, value1)); assertEquals(value3, map.addTo(key1, value2)); } /* */ - @Test public void testRemove() { map.put(key1, value1); assertEquals(value1, map.remove(key1)); @@ -351,7 +336,6 @@ public void testRemove() { } /* */ - @Test public void testEmptyKey() { final int empty = 0; @@ -387,7 +371,6 @@ public void testEmptyKey() { } /* */ - @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); @@ -397,7 +380,6 @@ public void testMapKeySet() { } /* */ - @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); @@ -412,7 +394,6 @@ public void testMapKeySetIterator() { } /* */ - @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); @@ -432,7 +413,6 @@ public void testClear() { } /* */ - @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); @@ -447,7 +427,6 @@ public void testRelease() { } /* */ - @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); @@ -470,7 +449,6 @@ public void testIterable() { } /* */ - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -515,7 +493,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testHashCodeEquals() { IntLongHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); @@ -536,7 +513,6 @@ public void testHashCodeEquals() { assertFalse(l2.equals(l3)); } - @Test public void testBug_HPPC37() { IntLongHashMap l1 = IntLongHashMap.from(newArray(key1), newvArray(value1)); @@ -546,7 +522,6 @@ public void testBug_HPPC37() { assertFalse(l2.equals(l1)); } - @Test public void testEmptyValue() { assertEquals(0L, map.put(key1, 0L)); assertEquals(0L, map.get(key1)); @@ -557,7 +532,6 @@ public void testEmptyValue() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashMap}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashMap() { final Random rnd = RandomizedTest.getRandom(); @@ -613,7 +587,6 @@ public void testAgainstHashMap() { /* * */ - @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); @@ -627,7 +600,6 @@ public void testClone() { } /* */ - @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); @@ -642,7 +614,6 @@ public void testMapValues() { } /* */ - @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); @@ -657,7 +628,6 @@ public void testMapValuesIterator() { } /* */ - @Test public void testEqualsSameClass() { IntLongHashMap l1 = newInstance(); l1.put(k1, value0); @@ -677,7 +647,6 @@ public void testEqualsSameClass() { } /* */ - @Test public void testEqualsSubClass() { class Sub extends IntLongHashMap {} ; diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntObjectHashMap.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntObjectHashMap.java index 9e73beb20977..5ca58a041a0f 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntObjectHashMap.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestIntObjectHashMap.java @@ -27,7 +27,6 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.Assert; -import org.junit.Test; /** * Tests for {@link IntObjectHashMap}. @@ -107,7 +106,6 @@ private void assertSameMap(final IntObjectHashMap c1, final IntObjectHas } /* */ - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); IntObjectHashMap map = @@ -134,7 +132,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); @@ -146,7 +143,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); @@ -189,7 +185,6 @@ public void testIndexMethods() { } /* */ - @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); @@ -199,7 +194,6 @@ public void testCloningConstructor() { } /* */ - @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); @@ -211,7 +205,6 @@ public void testFromArrays() { assertSameMap(map, map2); } - @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); @@ -224,7 +217,6 @@ public void testGetOrDefault() { } /* */ - @Test public void testPut() { map.put(key1, value1); @@ -233,7 +225,6 @@ public void testPut() { } /* */ - @Test public void testNullValue() { map.put(key1, null); @@ -241,7 +232,6 @@ public void testNullValue() { assertNull(map.get(key1)); } - @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals(value1, map.put(key1, value3)); @@ -256,7 +246,6 @@ public void testPutOverExistingKey() { } /* */ - @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(random().nextLong()); @@ -275,7 +264,6 @@ public void testPutWithExpansions() { } /* */ - @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); @@ -297,7 +285,6 @@ public void testPutAll() { } /* */ - @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); @@ -305,7 +292,6 @@ public void testPutIfAbsent() { } /* */ - @Test public void testRemove() { map.put(key1, value1); assertEquals(value1, map.remove(key1)); @@ -317,7 +303,6 @@ public void testRemove() { } /* */ - @Test public void testEmptyKey() { final int empty = 0; @@ -354,7 +339,6 @@ public void testEmptyKey() { } /* */ - @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); @@ -364,7 +348,6 @@ public void testMapKeySet() { } /* */ - @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); @@ -379,7 +362,6 @@ public void testMapKeySetIterator() { } /* */ - @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); @@ -399,7 +381,6 @@ public void testClear() { } /* */ - @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); @@ -414,7 +395,6 @@ public void testRelease() { } /* */ - @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); @@ -437,7 +417,6 @@ public void testIterable() { } /* */ - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -482,7 +461,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testHashCodeEquals() { IntObjectHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); @@ -503,7 +481,6 @@ public void testHashCodeEquals() { assertNotEquals(l2, l3); } - @Test public void testBug_HPPC37() { IntObjectHashMap l1 = IntObjectHashMap.from(newArray(key1), newvArray(value1)); @@ -514,7 +491,6 @@ public void testBug_HPPC37() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashMap}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashMap() { final Random rnd = RandomizedTest.getRandom(); @@ -568,7 +544,6 @@ public void testAgainstHashMap() { /* * */ - @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); @@ -582,7 +557,6 @@ public void testClone() { } /* */ - @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); @@ -605,7 +579,6 @@ static List toList(Iterable> values) { } /* */ - @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); @@ -620,7 +593,6 @@ public void testMapValuesIterator() { } /* */ - @Test public void testEqualsSameClass() { IntObjectHashMap l1 = newInstance(); l1.put(key1, value0); @@ -640,7 +612,6 @@ public void testEqualsSameClass() { } /* */ - @Test public void testEqualsSubClass() { class Sub extends IntObjectHashMap {} diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongArrayList.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongArrayList.java index fafd9cc03250..49f72f60ddac 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongArrayList.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongArrayList.java @@ -22,7 +22,6 @@ import java.util.NoSuchElementException; import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.Before; -import org.junit.Test; /** * Tests for {@link LongArrayList}. @@ -54,38 +53,32 @@ public void initialize() { list = new LongArrayList(); } - @Test public void testInitiallyEmpty() { assertEquals(0, list.size()); } - @Test public void testAdd() { list.add(key1, key2); assertListEquals(list.toArray(), 1, 2); } - @Test public void testAddTwoArgs() { list.add(key1, key2); list.add(key3, key4); assertListEquals(list.toArray(), 1, 2, 3, 4); } - @Test public void testAddArray() { list.add(asArray(0, 1, 2, 3), 1, 2); assertListEquals(list.toArray(), 1, 2); } - @Test public void testAddVarArg() { list.add(asArray(0, 1, 2, 3)); list.add(key4, key5, key6, key7); assertListEquals(list.toArray(), 0, 1, 2, 3, 4, 5, 6, 7); } - @Test public void testAddAll() { LongArrayList list2 = new LongArrayList(); list2.add(asArray(0, 1, 2)); @@ -96,7 +89,6 @@ public void testAddAll() { assertListEquals(list.toArray(), 0, 1, 2, 0, 1, 2); } - @Test public void testInsert() { list.insert(0, key1); list.insert(0, key2); @@ -106,7 +98,6 @@ public void testInsert() { assertListEquals(list.toArray(), 2, 4, 1, 3); } - @Test public void testSet() { list.add(asArray(0, 1, 2)); @@ -117,7 +108,6 @@ public void testSet() { assertListEquals(list.toArray(), 3, 4, 5); } - @Test public void testRemoveAt() { list.add(asArray(0, 1, 2, 3, 4)); @@ -128,7 +118,6 @@ public void testRemoveAt() { assertListEquals(list.toArray(), 1, 4); } - @Test public void testRemoveLast() { list.add(asArray(0, 1, 2, 3, 4)); @@ -144,7 +133,6 @@ public void testRemoveLast() { assertTrue(list.isEmpty()); } - @Test public void testRemoveElement() { list.add(asArray(0, 1, 2, 3, 3, 4)); @@ -155,7 +143,6 @@ public void testRemoveElement() { assertListEquals(list.toArray(), 0, 1, 3, 4); } - @Test public void testRemoveRange() { list.add(asArray(0, 1, 2, 3, 4)); @@ -172,7 +159,6 @@ public void testRemoveRange() { assertListEquals(list.toArray(), 3); } - @Test public void testRemoveFirstLast() { list.add(asArray(0, 1, 2, 1, 0)); @@ -189,7 +175,6 @@ public void testRemoveFirstLast() { assertEquals(-1, list.removeLast(key0)); } - @Test public void testRemoveAll() { list.add(asArray(0, 1, 0, 1, 0)); @@ -201,7 +186,6 @@ public void testRemoveAll() { assertTrue(list.isEmpty()); } - @Test public void testIndexOf() { list.add(asArray(0, 1, 2, 1, 0)); @@ -210,7 +194,6 @@ public void testIndexOf() { assertEquals(2, list.indexOf(key2)); } - @Test public void testLastIndexOf() { list.add(asArray(0, 1, 2, 1, 0)); @@ -219,7 +202,6 @@ public void testLastIndexOf() { assertEquals(2, list.lastIndexOf(key2)); } - @Test public void testEnsureCapacity() { LongArrayList list = new LongArrayList(0); assertEquals(list.size(), list.buffer.length); @@ -228,7 +210,6 @@ public void testEnsureCapacity() { assertNotSame(buffer1, list.buffer); } - @Test public void testResizeAndCleanBuffer() { list.ensureCapacity(20); Arrays.fill(list.buffer, key1); @@ -250,14 +231,12 @@ public void testResizeAndCleanBuffer() { } } - @Test public void testTrimToSize() { list.add(asArray(1, 2)); list.trimToSize(); assertEquals(2, list.buffer.length); } - @Test public void testRelease() { list.add(asArray(1, 2)); list.release(); @@ -266,7 +245,6 @@ public void testRelease() { assertEquals(2, list.size()); } - @Test public void testIterable() { list.add(asArray(0, 1, 2, 3)); int count = 0; @@ -285,7 +263,6 @@ public void testIterable() { assertEquals(0, count); } - @Test public void testIterator() { list.add(asArray(0, 1, 2, 3)); Iterator iterator = list.iterator(); @@ -303,7 +280,6 @@ public void testIterator() { assertFalse(list.iterator().hasNext()); } - @Test public void testClear() { list.add(asArray(1, 2, 3)); list.clear(); @@ -311,7 +287,6 @@ public void testClear() { assertEquals(-1, list.indexOf(cast(1))); } - @Test public void testFrom() { list = LongArrayList.from(key1, key2, key3); assertEquals(3, list.size()); @@ -319,7 +294,6 @@ public void testFrom() { assertEquals(list.size(), list.buffer.length); } - @Test public void testCopyList() { list.add(asArray(1, 2, 3)); LongArrayList copy = new LongArrayList(list); @@ -328,7 +302,6 @@ public void testCopyList() { assertEquals(copy.size(), copy.buffer.length); } - @Test public void testHashCodeEquals() { LongArrayList l0 = LongArrayList.from(); assertEquals(1, l0.hashCode()); @@ -342,7 +315,6 @@ public void testHashCodeEquals() { assertEquals(l1, l2); } - @Test public void testEqualElements() { LongArrayList l1 = LongArrayList.from(key1, key2, key3); LongArrayList l2 = LongArrayList.from(key1, key2); @@ -352,7 +324,6 @@ public void testEqualElements() { assertTrue(l2.equalElements(l1)); } - @Test public void testToArray() { LongArrayList l1 = LongArrayList.from(key1, key2, key3); l1.ensureCapacity(100); @@ -360,7 +331,6 @@ public void testToArray() { assertArrayEquals(new long[] {key1, key2, key3}, result); } - @Test public void testClone() { list.add(key1, key2, key3); @@ -371,14 +341,12 @@ public void testClone() { assertSortedListEquals(cloned.toArray(), key2, key3); } - @Test public void testToString() { assertEquals( "[" + key1 + ", " + key2 + ", " + key3 + "]", LongArrayList.from(key1, key2, key3).toString()); } - @Test public void testEqualsSameClass() { LongArrayList l1 = LongArrayList.from(key1, key2, key3); LongArrayList l2 = LongArrayList.from(key1, key2, key3); @@ -389,7 +357,6 @@ public void testEqualsSameClass() { assertNotEquals(l1, l3); } - @Test public void testEqualsSubClass() { class Sub extends LongArrayList {} ; @@ -404,7 +371,6 @@ class Sub extends LongArrayList {} assertNotEquals(l1, l3); } - @Test public void testStream() { assertEquals(key1, LongArrayList.from(key1, key2, key3).stream().min().orElseThrow()); assertEquals(key3, LongArrayList.from(key2, key1, key3).stream().max().orElseThrow()); @@ -416,7 +382,6 @@ public void testStream() { }); } - @Test public void testSort() { list.add(key3, key1, key3, key2); LongArrayList list2 = new LongArrayList(); @@ -426,7 +391,6 @@ public void testSort() { assertEquals(LongArrayList.from(key1, key2, key3, key3), list2); } - @Test public void testReverse() { for (int i = 0; i < 10; i++) { long[] elements = new long[i]; diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongFloatHashMap.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongFloatHashMap.java index 600c0ff03c76..841a3d9eb834 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongFloatHashMap.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongFloatHashMap.java @@ -24,7 +24,6 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** * Tests for {@link LongFloatHashMap}. @@ -118,7 +117,6 @@ private static void assertArrayEquals(float[] v1, float[] v2) { } /* */ - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); LongFloatHashMap map = @@ -145,7 +143,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); @@ -157,7 +154,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); @@ -200,7 +196,6 @@ public void testIndexMethods() { } /* */ - @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); @@ -210,7 +205,6 @@ public void testCloningConstructor() { } /* */ - @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); @@ -222,7 +216,6 @@ public void testFromArrays() { assertSameMap(map, map2); } - @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); @@ -235,7 +228,6 @@ public void testGetOrDefault() { } /* */ - @Test public void testPut() { map.put(key1, value1); @@ -244,7 +236,6 @@ public void testPut() { } /* */ - @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals2(value1, map.put(key1, value3)); @@ -252,7 +243,6 @@ public void testPutOverExistingKey() { } /* */ - @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(random().nextLong()); @@ -271,7 +261,6 @@ public void testPutWithExpansions() { } /* */ - @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); @@ -293,27 +282,23 @@ public void testPutAll() { } /* */ - @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); assertEquals2(value1, map.get(key1)); } - @Test public void testPutOrAdd() { assertEquals2(value1, map.putOrAdd(key1, value1, value2)); assertEquals2(value3, map.putOrAdd(key1, value1, value2)); } - @Test public void testAddTo() { assertEquals2(value1, map.addTo(key1, value1)); assertEquals2(value3, map.addTo(key1, value2)); } /* */ - @Test public void testRemove() { map.put(key1, value1); assertEquals2(value1, map.remove(key1)); @@ -325,7 +310,6 @@ public void testRemove() { } /* */ - @Test public void testEmptyKey() { final int empty = 0; @@ -352,7 +336,6 @@ public void testEmptyKey() { } /* */ - @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); @@ -362,7 +345,6 @@ public void testMapKeySet() { } /* */ - @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); @@ -377,7 +359,6 @@ public void testMapKeySetIterator() { } /* */ - @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); @@ -397,7 +378,6 @@ public void testClear() { } /* */ - @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); @@ -412,7 +392,6 @@ public void testRelease() { } /* */ - @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); @@ -435,7 +414,6 @@ public void testIterable() { } /* */ - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -480,7 +458,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testHashCodeEquals() { LongFloatHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); @@ -501,7 +478,6 @@ public void testHashCodeEquals() { assertNotEquals(l2, l3); } - @Test public void testBug_HPPC37() { LongFloatHashMap l1 = LongFloatHashMap.from(newArray(key1), newvArray(value1)); @@ -512,7 +488,6 @@ public void testBug_HPPC37() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashMap}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashMap() { final Random rnd = RandomizedTest.getRandom(); @@ -569,7 +544,6 @@ public void testAgainstHashMap() { /* * */ - @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); @@ -583,7 +557,6 @@ public void testClone() { } /* */ - @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); @@ -598,7 +571,6 @@ public void testMapValues() { } /* */ - @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); @@ -613,7 +585,6 @@ public void testMapValuesIterator() { } /* */ - @Test public void testEqualsSameClass() { LongFloatHashMap l1 = newInstance(); l1.put(key1, value0); @@ -633,7 +604,6 @@ public void testEqualsSameClass() { } /* */ - @Test public void testEqualsSubClass() { class Sub extends LongFloatHashMap {} diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongHashSet.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongHashSet.java index 0de1971d6090..50fe18b80507 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongHashSet.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongHashSet.java @@ -33,7 +33,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.hamcrest.MatcherAssert; import org.junit.Before; -import org.junit.Test; /** * Tests for {@link LongHashSet}. @@ -64,7 +63,6 @@ public void initialize() { set = new LongHashSet(); } - @Test public void testAddAllViaInterface() { set.addAll(key1, key2); @@ -74,7 +72,6 @@ public void testAddAllViaInterface() { MatcherAssert.assertThat(set(iface.toArray()), is(equalTo(set(key1, key2)))); } - @Test public void testIndexMethods() { set.add(keyE); set.add(key1); @@ -114,7 +111,6 @@ public void testIndexMethods() { MatcherAssert.assertThat(set.indexOf(key2), is(lessThan(0))); } - @Test public void testCursorIndexIsValid() { set.add(keyE); set.add(key1); @@ -126,7 +122,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testEmptyKey() { LongHashSet set = new LongHashSet(); @@ -166,7 +161,6 @@ public void testEmptyKey() { MatcherAssert.assertThat(set.indexGet(index), is(equalTo(EMPTY_KEY))); } - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); LongHashSet set = @@ -193,19 +187,16 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testInitiallyEmpty() { assertEquals(0, set.size()); } - @Test public void testAdd() { assertTrue(set.add(key1)); assertFalse(set.add(key1)); assertEquals(1, set.size()); } - @Test public void testAdd2() { set.addAll(key1, key1); assertEquals(1, set.size()); @@ -213,14 +204,12 @@ public void testAdd2() { assertEquals(2, set.size()); } - @Test public void testAddVarArgs() { set.addAll(asArray(0, 1, 2, 1, 0)); assertEquals(3, set.size()); assertSortedListEquals(set.toArray(), asArray(0, 1, 2)); } - @Test public void testAddAll() { LongHashSet set2 = new LongHashSet(); set2.addAll(asArray(1, 2)); @@ -233,7 +222,6 @@ public void testAddAll() { assertSortedListEquals(set.toArray(), asArray(0, 1, 2)); } - @Test public void testRemove() { set.addAll(asArray(0, 1, 2, 3, 4)); @@ -243,7 +231,6 @@ public void testRemove() { assertSortedListEquals(set.toArray(), asArray(0, 1, 3, 4)); } - @Test public void testInitialCapacityAndGrowth() { for (int i = 0; i < 256; i++) { LongHashSet set = new LongHashSet(i); @@ -256,7 +243,6 @@ public void testInitialCapacityAndGrowth() { } } - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -301,7 +287,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testRemoveAllFromLookupContainer() { set.addAll(asArray(0, 1, 2, 3, 4)); @@ -313,14 +298,12 @@ public void testRemoveAllFromLookupContainer() { assertSortedListEquals(set.toArray(), asArray(0, 2, 4)); } - @Test public void testClear() { set.addAll(asArray(1, 2, 3)); set.clear(); assertEquals(0, set.size()); } - @Test public void testRelease() { set.addAll(asArray(1, 2, 3)); set.release(); @@ -329,7 +312,6 @@ public void testRelease() { assertEquals(3, set.size()); } - @Test public void testIterable() { set.addAll(asArray(1, 2, 2, 3, 4)); set.remove(key2); @@ -347,7 +329,6 @@ public void testIterable() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashSet}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashSet() { final Random rnd = RandomizedTest.getRandom(); @@ -395,7 +376,6 @@ public void testAgainstHashSet() { } } - @Test public void testHashCodeEquals() { LongHashSet l0 = new LongHashSet(); assertEquals(0, l0.hashCode()); @@ -409,7 +389,6 @@ public void testHashCodeEquals() { assertEquals(l1, l2); } - @Test public void testClone() { this.set.addAll(asArray(1, 2, 3)); @@ -420,7 +399,6 @@ public void testClone() { assertSortedListEquals(cloned.toArray(), asArray(2, 3)); } - @Test public void testEqualsSameClass() { LongHashSet l1 = LongHashSet.from(key1, key2, key3); LongHashSet l2 = LongHashSet.from(key1, key2, key3); @@ -431,7 +409,6 @@ public void testEqualsSameClass() { MatcherAssert.assertThat(l1, is(not(equalTo(l3)))); } - @Test public void testEqualsSubClass() { class Sub extends LongHashSet {} ; diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongIntHashMap.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongIntHashMap.java index ddf11a5dd6fb..1cee597eaa0d 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongIntHashMap.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongIntHashMap.java @@ -24,7 +24,6 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** * Tests for {@link LongIntHashMap}. @@ -106,7 +105,6 @@ private void assertSameMap(final LongIntHashMap c1, final LongIntHashMap c2) { } /* */ - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); LongIntHashMap map = @@ -133,7 +131,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); @@ -145,7 +142,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); @@ -188,7 +184,6 @@ public void testIndexMethods() { } /* */ - @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); @@ -198,7 +193,6 @@ public void testCloningConstructor() { } /* */ - @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); @@ -210,7 +204,6 @@ public void testFromArrays() { assertSameMap(map, map2); } - @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); @@ -223,7 +216,6 @@ public void testGetOrDefault() { } /* */ - @Test public void testPut() { map.put(key1, value1); @@ -232,7 +224,6 @@ public void testPut() { } /* */ - @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals(value1, map.put(key1, value3)); @@ -240,7 +231,6 @@ public void testPutOverExistingKey() { } /* */ - @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(random().nextLong()); @@ -259,7 +249,6 @@ public void testPutWithExpansions() { } /* */ - @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); @@ -281,27 +270,23 @@ public void testPutAll() { } /* */ - @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); assertEquals(value1, map.get(key1)); } - @Test public void testPutOrAdd() { assertEquals(value1, map.putOrAdd(key1, value1, value2)); assertEquals(value3, map.putOrAdd(key1, value1, value2)); } - @Test public void testAddTo() { assertEquals(value1, map.addTo(key1, value1)); assertEquals(value3, map.addTo(key1, value2)); } /* */ - @Test public void testRemove() { map.put(key1, value1); assertEquals(value1, map.remove(key1)); @@ -313,7 +298,6 @@ public void testRemove() { } /* */ - @Test public void testEmptyKey() { final long empty = 0; @@ -340,7 +324,6 @@ public void testEmptyKey() { } /* */ - @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); @@ -350,7 +333,6 @@ public void testMapKeySet() { } /* */ - @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); @@ -365,7 +347,6 @@ public void testMapKeySetIterator() { } /* */ - @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); @@ -385,7 +366,6 @@ public void testClear() { } /* */ - @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); @@ -400,7 +380,6 @@ public void testRelease() { } /* */ - @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); @@ -423,7 +402,6 @@ public void testIterable() { } /* */ - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -468,7 +446,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testHashCodeEquals() { LongIntHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); @@ -489,7 +466,6 @@ public void testHashCodeEquals() { assertNotEquals(l2, l3); } - @Test public void testBug_HPPC37() { LongIntHashMap l1 = LongIntHashMap.from(newArray(key1), newvArray(value1)); @@ -500,7 +476,6 @@ public void testBug_HPPC37() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashMap}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashMap() { final Random rnd = RandomizedTest.getRandom(); @@ -557,7 +532,6 @@ public void testAgainstHashMap() { /* * */ - @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); @@ -571,7 +545,6 @@ public void testClone() { } /* */ - @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); @@ -586,7 +559,6 @@ public void testMapValues() { } /* */ - @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); @@ -601,7 +573,6 @@ public void testMapValuesIterator() { } /* */ - @Test public void testEqualsSameClass() { LongIntHashMap l1 = newInstance(); l1.put(key1, value0); @@ -621,7 +592,6 @@ public void testEqualsSameClass() { } /* */ - @Test public void testEqualsSubClass() { class Sub extends LongIntHashMap {} diff --git a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongObjectHashMap.java b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongObjectHashMap.java index 40669a26cd87..394efbe0ad8e 100644 --- a/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongObjectHashMap.java +++ b/lucene/core/src/test/org/apache/lucene/internal/hppc/TestLongObjectHashMap.java @@ -28,7 +28,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; -import org.junit.Test; /** * Tests for {@link LongObjectHashMap}. @@ -104,7 +103,6 @@ private void assertSameMap( } /* */ - @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); LongObjectHashMap map = @@ -131,7 +129,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(before, expands.get()); } - @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); @@ -143,7 +140,6 @@ public void testCursorIndexIsValid() { } } - @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); @@ -186,7 +182,6 @@ public void testIndexMethods() { } /* */ - @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); @@ -196,7 +191,6 @@ public void testCloningConstructor() { } /* */ - @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); @@ -208,7 +202,6 @@ public void testFromArrays() { assertSameMap(map, map2); } - @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); @@ -221,7 +214,6 @@ public void testGetOrDefault() { } /* */ - @Test public void testPut() { map.put(key1, value1); @@ -230,7 +222,6 @@ public void testPut() { } /* */ - @Test public void testNullValue() { map.put(key1, null); @@ -238,7 +229,6 @@ public void testNullValue() { assertNull(map.get(key1)); } - @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals(value1, map.put(key1, value3)); @@ -253,7 +243,6 @@ public void testPutOverExistingKey() { } /* */ - @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(random().nextLong()); @@ -272,7 +261,6 @@ public void testPutWithExpansions() { } /* */ - @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); @@ -294,7 +282,6 @@ public void testPutAll() { } /* */ - @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); @@ -302,7 +289,6 @@ public void testPutIfAbsent() { } /* */ - @Test public void testRemove() { map.put(key1, value1); assertEquals(value1, map.remove(key1)); @@ -314,7 +300,6 @@ public void testRemove() { } /* */ - @Test public void testEmptyKey() { final long empty = 0; @@ -351,7 +336,6 @@ public void testEmptyKey() { } /* */ - @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); @@ -361,7 +345,6 @@ public void testMapKeySet() { } /* */ - @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); @@ -376,7 +359,6 @@ public void testMapKeySetIterator() { } /* */ - @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); @@ -396,7 +378,6 @@ public void testClear() { } /* */ - @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); @@ -411,7 +392,6 @@ public void testRelease() { } /* */ - @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); @@ -434,7 +414,6 @@ public void testIterable() { } /* */ - @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; @@ -479,7 +458,6 @@ protected void allocateBuffers(int arraySize) { assertEquals(reallocationsBefore + 1, reallocations.get()); } - @Test public void testHashCodeEquals() { LongObjectHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); @@ -500,7 +478,6 @@ public void testHashCodeEquals() { assertNotEquals(l2, l3); } - @Test public void testBug_HPPC37() { LongObjectHashMap l1 = LongObjectHashMap.from(newArray(key1), newvArray(value1)); @@ -511,7 +488,6 @@ public void testBug_HPPC37() { } /** Runs random insertions/deletions/clearing and compares the results against {@link HashMap}. */ - @Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAgainstHashMap() { final Random rnd = RandomizedTest.getRandom(); @@ -565,7 +541,6 @@ public void testAgainstHashMap() { /* * */ - @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); @@ -579,7 +554,6 @@ public void testClone() { } /* */ - @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); @@ -596,7 +570,6 @@ public void testMapValues() { } /* */ - @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); @@ -611,7 +584,6 @@ public void testMapValuesIterator() { } /* */ - @Test public void testEqualsSameClass() { LongObjectHashMap l1 = newInstance(); l1.put(key1, value0); @@ -631,7 +603,6 @@ public void testEqualsSameClass() { } /* */ - @Test public void testEqualsSubClass() { class Sub extends LongObjectHashMap {} diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBaseRangeFilter.java b/lucene/core/src/test/org/apache/lucene/search/TestBaseRangeFilter.java index ecc26d4aaf67..60e45b43f5fc 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestBaseRangeFilter.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestBaseRangeFilter.java @@ -36,7 +36,6 @@ import org.apache.lucene.util.BytesRef; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Test; public class TestBaseRangeFilter extends LuceneTestCase { @@ -209,7 +208,6 @@ private static IndexReader build(Random random, TestIndex index) throws IOExcept } } - @Test public void testPad() { int[] tests = new int[] {-9999999, -99560, -100, -3, -1, 0, 3, 9, 10, 1000, 999999999}; diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java b/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java index 70fb8077011e..59fda8f8e21a 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java @@ -40,7 +40,6 @@ import org.apache.lucene.util.ArrayUtil; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Test; /** * Test BooleanQuery2 against BooleanQuery by overriding the standard query parser. This also tests @@ -268,7 +267,6 @@ public void queriesTest(Query query, int[] expDocNrs) throws Exception { CheckHits.checkEqual(query, hits1, hits2); } - @Test public void testQueries01() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST); @@ -277,7 +275,6 @@ public void testQueries01() throws Exception { queriesTest(query.build(), expDocNrs); } - @Test public void testQueries02() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST); @@ -286,7 +283,6 @@ public void testQueries02() throws Exception { queriesTest(query.build(), expDocNrs); } - @Test public void testQueries03() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.SHOULD); @@ -295,7 +291,6 @@ public void testQueries03() throws Exception { queriesTest(query.build(), expDocNrs); } - @Test public void testQueries04() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.SHOULD); @@ -304,7 +299,6 @@ public void testQueries04() throws Exception { queriesTest(query.build(), expDocNrs); } - @Test public void testQueries05() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST); @@ -313,7 +307,6 @@ public void testQueries05() throws Exception { queriesTest(query.build(), expDocNrs); } - @Test public void testQueries06() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST); @@ -323,7 +316,6 @@ public void testQueries06() throws Exception { queriesTest(query.build(), expDocNrs); } - @Test public void testQueries07() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST_NOT); @@ -333,7 +325,6 @@ public void testQueries07() throws Exception { queriesTest(query.build(), expDocNrs); } - @Test public void testQueries08() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST); @@ -343,7 +334,6 @@ public void testQueries08() throws Exception { queriesTest(query.build(), expDocNrs); } - @Test public void testQueries09() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST); @@ -354,7 +344,6 @@ public void testQueries09() throws Exception { queriesTest(query.build(), expDocNrs); } - @Test public void testRandomQueries() throws Exception { String[] vals = {"w1", "w2", "w3", "w4", "w5", "xx", "yy", "zzz"}; diff --git a/lucene/core/src/test/org/apache/lucene/search/TestFilterWeight.java b/lucene/core/src/test/org/apache/lucene/search/TestFilterWeight.java index 64fc5bb057ac..33120a6ef3b1 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestFilterWeight.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestFilterWeight.java @@ -19,11 +19,9 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestFilterWeight extends LuceneTestCase { - @Test public void testDeclaredMethodsOverridden() throws Exception { final Class subClass = FilterWeight.class; implTestDeclaredMethodsOverridden(subClass.getSuperclass(), subClass); diff --git a/lucene/core/src/test/org/apache/lucene/search/TestFullPrecisionFloatVectorSimilarityValuesSource.java b/lucene/core/src/test/org/apache/lucene/search/TestFullPrecisionFloatVectorSimilarityValuesSource.java index 7779f9f23fd2..962c04fefcb8 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestFullPrecisionFloatVectorSimilarityValuesSource.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestFullPrecisionFloatVectorSimilarityValuesSource.java @@ -40,7 +40,6 @@ import org.apache.lucene.util.TestVectorUtil; import org.apache.lucene.util.quantization.QuantizedByteVectorValues.ScalarEncoding; import org.junit.Before; -import org.junit.Test; public class TestFullPrecisionFloatVectorSimilarityValuesSource extends LuceneTestCase { @@ -84,7 +83,6 @@ private KnnVectorsFormat getKnnFormat(int bits) { // TODO: incredibly slow @Nightly - @Test public void testFullPrecisionVectorSimilarityDVS() throws Exception { List vectors = new ArrayList<>(); int numVectors = atLeast(NUM_VECTORS); diff --git a/lucene/core/src/test/org/apache/lucene/search/TestFuzzyTermOnShortTerms.java b/lucene/core/src/test/org/apache/lucene/search/TestFuzzyTermOnShortTerms.java index c2261acfd699..465e2f879a88 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestFuzzyTermOnShortTerms.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestFuzzyTermOnShortTerms.java @@ -29,12 +29,10 @@ import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.tests.util.TestUtil; -import org.junit.Test; public class TestFuzzyTermOnShortTerms extends LuceneTestCase { private static final String FIELD = "field"; - @Test public void test() throws Exception { // proves rule that edit distance between the two terms // must be > smaller term for there to be a match diff --git a/lucene/core/src/test/org/apache/lucene/search/TestHnswQueueSaturationCollector.java b/lucene/core/src/test/org/apache/lucene/search/TestHnswQueueSaturationCollector.java index 37d019034130..571d8c438f59 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestHnswQueueSaturationCollector.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestHnswQueueSaturationCollector.java @@ -18,12 +18,10 @@ import java.util.Random; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** Tests for {@link HnswQueueSaturationCollector} */ public class TestHnswQueueSaturationCollector extends LuceneTestCase { - @Test public void testDelegate() { Random random = random(); int numDocs = 100; @@ -43,7 +41,6 @@ public void testDelegate() { 1e-3); } - @Test public void testEarlyExpectedExit() { int numDocs = 1000; int k = 10; @@ -62,7 +59,6 @@ public void testEarlyExpectedExit() { } } - @Test public void testDelegateVsSaturateEarlyExit() { Random random = random(); int numDocs = 10000; @@ -81,7 +77,6 @@ public void testDelegateVsSaturateEarlyExit() { } } - @Test public void testEarlyExitRelation() { Random random = random(); int numDocs = 10000; diff --git a/lucene/core/src/test/org/apache/lucene/search/TestMultiCollector.java b/lucene/core/src/test/org/apache/lucene/search/TestMultiCollector.java index a65970de6b0c..8abc94aab407 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestMultiCollector.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestMultiCollector.java @@ -35,7 +35,6 @@ import org.apache.lucene.tests.search.DummyTotalHitCountCollector; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.tests.util.TestUtil; -import org.junit.Test; public class TestMultiCollector extends LuceneTestCase { @@ -317,7 +316,6 @@ public ScoreMode scoreMode() { } } - @Test public void testNullCollectors() throws Exception { // Tests that the collector rejects all null collectors. expectThrows( @@ -336,7 +334,6 @@ public void testNullCollectors() throws Exception { c.getLeafCollector(null).setScorer(new SimpleScorable()); } - @Test public void testSingleCollector() throws Exception { // Tests that if a single Collector is input, it is returned (and not MultiCollector). DummyCollector dc = new DummyCollector(); @@ -344,7 +341,6 @@ public void testSingleCollector() throws Exception { assertSame(dc, MultiCollector.wrap(dc, null)); } - @Test public void testCollector() throws Exception { // Tests that the collector delegates calls to input collectors properly. diff --git a/lucene/core/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java b/lucene/core/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java index be8175f6da84..427804ee21c1 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java @@ -32,7 +32,6 @@ import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Test; public class TestMultiTermConstantScore extends TestBaseRangeFilter { @@ -116,7 +115,6 @@ public static Query cswcq(Term wild, MultiTermQuery.RewriteMethod method) { return new WildcardQuery(wild, method); } - @Test public void testBasics() throws IOException { for (MultiTermQuery.RewriteMethod rw : CONSTANT_SCORE_REWRITES) { QueryUtils.check(csrq("data", "1", "6", T, T, rw)); @@ -133,7 +131,6 @@ public void testBasics() throws IOException { } } - @Test public void testEqualScores() throws IOException { // NOTE: uses index build in *this* setUp @@ -177,7 +174,6 @@ public void testEqualScores() throws IOException { } } - @Test // Test for LUCENE-5245: Empty MTQ rewrites should have a consistent norm, so always need to // return a CSQ! public void testEqualScoresWhenNoHits() throws IOException { // NOTE: uses index build in *this* setUp @@ -229,7 +225,6 @@ public void testEqualScoresWhenNoHits() throws IOException { } } - @Test public void testBooleanOrderUnAffected() throws IOException { // NOTE: uses index build in *this* setUp @@ -261,7 +256,6 @@ public void testBooleanOrderUnAffected() throws IOException { } } - @Test public void testRangeQueryId() throws IOException { // NOTE: uses index build in *super* setUp @@ -354,7 +348,6 @@ public void testRangeQueryId() throws IOException { } } - @Test public void testRangeQueryRand() throws IOException { // NOTE: uses index build in *super* setUp diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java b/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java index 64a4b630f971..da60424e2630 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java @@ -19,7 +19,6 @@ import java.util.Arrays; import org.apache.lucene.index.Term; import org.apache.lucene.tests.search.BaseExplanationTestCase; -import org.junit.Test; /** TestExplanations subclass focusing on basic query types */ public class TestSimpleExplanations extends BaseExplanationTestCase { @@ -747,7 +746,6 @@ public void testSynonymQuery() throws Exception { qtest(query, new int[] {0, 1, 2, 3}); } - @Test public void testEquality() { Explanation e1 = Explanation.match(1f, "an explanation"); diff --git a/lucene/core/src/test/org/apache/lucene/store/BaseDataOutputTestCase.java b/lucene/core/src/test/org/apache/lucene/store/BaseDataOutputTestCase.java index bb7483f32f18..49e133ccb5c1 100644 --- a/lucene/core/src/test/org/apache/lucene/store/BaseDataOutputTestCase.java +++ b/lucene/core/src/test/org/apache/lucene/store/BaseDataOutputTestCase.java @@ -30,7 +30,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.IOConsumer; -import org.junit.Test; public abstract class BaseDataOutputTestCase extends LuceneTestCase { protected abstract T newInstance(); @@ -42,7 +41,6 @@ private interface IOBiFunction { R apply(T t, U u) throws IOException; } - @Test public void testRandomizedWrites() throws IOException { T dst = newInstance(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); diff --git a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataInput.java b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataInput.java index d29b9a19092e..458546efaac7 100644 --- a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataInput.java +++ b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataInput.java @@ -30,10 +30,8 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.IOConsumer; -import org.junit.Test; public final class TestByteBuffersDataInput extends LuceneTestCase { - @Test public void testSanity() throws IOException { ByteBuffersDataOutput out = new ByteBuffersDataOutput(); ByteBuffersDataInput o1 = out.toDataInput(); @@ -65,7 +63,6 @@ public void testSanity() throws IOException { assertEquals(1, o2.position()); } - @Test public void testRandomReads() throws Exception { ByteBuffersDataOutput dst = new ByteBuffersDataOutput(); @@ -85,7 +82,6 @@ public void testRandomReads() throws Exception { }); } - @Test public void testRandomReadsOnSlices() throws Exception { for (int reps = randomIntBetween(1, 20); --reps > 0; ) { ByteBuffersDataOutput dst = new ByteBuffersDataOutput(); @@ -117,7 +113,6 @@ public void testRandomReadsOnSlices() throws Exception { } } - @Test public void testSeekEmpty() throws Exception { ByteBuffersDataOutput dst = new ByteBuffersDataOutput(); ByteBuffersDataInput in = dst.toDataInput(); @@ -137,7 +132,6 @@ public void testSeekEmpty() throws Exception { }); } - @Test public void testSeekAndSkip() throws Exception { for (int reps = randomIntBetween(1, 200); --reps > 0; ) { ByteBuffersDataOutput dst = new ByteBuffersDataOutput(); @@ -197,7 +191,6 @@ public void testSeekAndSkip() throws Exception { } } - @Test public void testSlicingWindow() throws Exception { ByteBuffersDataOutput dst = new ByteBuffersDataOutput(); assertEquals(0, dst.toDataInput().slice(0, 0).length()); @@ -214,7 +207,6 @@ public void testSlicingWindow() throws Exception { assertEquals(0, in.slice((int) dst.size(), 0).length()); } - @Test @Timeout(millis = 5000) public void testEofOnArrayReadPastBufferSize() throws Exception { ByteBuffersDataOutput dst = new ByteBuffersDataOutput(); @@ -236,7 +228,6 @@ public void testEofOnArrayReadPastBufferSize() throws Exception { } // https://issues.apache.org/jira/browse/LUCENE-8625 - @Test public void testSlicingLargeBuffers() throws IOException { // Simulate a "large" (> 4GB) input by duplicating // buffers with the same content. diff --git a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataOutput.java b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataOutput.java index 50eefc3f3bfa..cffaa8d1076f 100644 --- a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataOutput.java +++ b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataOutput.java @@ -26,7 +26,6 @@ import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.RamUsageEstimator; import org.junit.Assert; -import org.junit.Test; public final class TestByteBuffersDataOutput extends BaseDataOutputTestCase { @Override @@ -39,7 +38,6 @@ protected byte[] toBytes(ByteBuffersDataOutput instance) { return instance.toArrayCopy(); } - @Test public void testReuse() throws IOException { AtomicInteger allocations = new AtomicInteger(0); ByteBuffersDataOutput.ByteBufferRecycler reuser = @@ -71,7 +69,6 @@ public void testReuse() throws IOException { assertArrayEquals(data, o.toArrayCopy()); } - @Test public void testConstructorWithExpectedSize() { { ByteBuffersDataOutput o = new ByteBuffersDataOutput(0); @@ -152,7 +149,6 @@ public void testNullRecycler() { }); } - @Test public void testSanity() { ByteBuffersDataOutput o = newInstance(); assertEquals(0, o.size()); @@ -169,7 +165,6 @@ public void testSanity() { assertArrayEquals(new byte[] {1, 2, 3, 4}, o.toArrayCopy()); } - @Test public void testWriteByteBuffer() { ByteBuffersDataOutput o = new ByteBuffersDataOutput(); byte[] bytes = new byte[1024 * 8 + 10]; @@ -185,7 +180,6 @@ public void testWriteByteBuffer() { ArrayUtil.copyOfSubArray(bytes, offset, offset + len), o.toArrayCopy()); } - @Test public void testLargeArrayAdd() { ByteBuffersDataOutput o = new ByteBuffersDataOutput(); int MB = 1024 * 1024; @@ -204,7 +198,6 @@ public void testLargeArrayAdd() { ArrayUtil.copyOfSubArray(bytes, offset, offset + len), o.toArrayCopy()); } - @Test public void testCopyBytesOnHeap() throws IOException { byte[] bytes = new byte[1024 * 8 + 10]; random().nextBytes(bytes); @@ -222,7 +215,6 @@ public void testCopyBytesOnHeap() throws IOException { o.toArrayCopy(), ArrayUtil.copyOfSubArray(bytes, offset, offset + len)); } - @Test public void testCopyBytesOnDirectByteBuffer() throws IOException { byte[] bytes = new byte[1024 * 8 + 10]; random().nextBytes(bytes); @@ -240,7 +232,6 @@ public void testCopyBytesOnDirectByteBuffer() throws IOException { o.toArrayCopy(), ArrayUtil.copyOfSubArray(bytes, offset, offset + len)); } - @Test public void testToBufferListReturnsReadOnlyBuffers() throws Exception { ByteBuffersDataOutput dst = new ByteBuffersDataOutput(); dst.writeBytes(new byte[100]); @@ -249,7 +240,6 @@ public void testToBufferListReturnsReadOnlyBuffers() throws Exception { } } - @Test public void testToWriteableBufferListReturnsOriginalBuffers() throws Exception { ByteBuffersDataOutput dst = new ByteBuffersDataOutput(); for (ByteBuffer bb : dst.toWriteableBufferList()) { @@ -264,7 +254,6 @@ public void testToWriteableBufferListReturnsOriginalBuffers() throws Exception { } } - @Test public void testRamBytesUsed() { ByteBuffersDataOutput out = new ByteBuffersDataOutput(); // Empty output requires no RAM diff --git a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDirectory.java b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDirectory.java index 3717f490cfd3..3c83c88e02ef 100644 --- a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDirectory.java +++ b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDirectory.java @@ -30,7 +30,6 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.store.BaseDirectoryTestCase; import org.apache.lucene.tests.util.English; -import org.junit.Test; public class TestByteBuffersDirectory extends BaseDirectoryTestCase { private Supplier implSupplier; @@ -44,7 +43,6 @@ protected Directory getDirectory(Path path) throws IOException { return implSupplier.get(); } - @Test public void testBuildIndex() throws IOException { try (Directory dir = getDirectory(null); IndexWriter writer = diff --git a/lucene/core/src/test/org/apache/lucene/store/TestFilterDirectory.java b/lucene/core/src/test/org/apache/lucene/store/TestFilterDirectory.java index 6109115c885a..bec89bb5cd20 100644 --- a/lucene/core/src/test/org/apache/lucene/store/TestFilterDirectory.java +++ b/lucene/core/src/test/org/apache/lucene/store/TestFilterDirectory.java @@ -22,7 +22,6 @@ import java.util.HashSet; import java.util.Set; import org.apache.lucene.tests.store.BaseDirectoryTestCase; -import org.junit.Test; public class TestFilterDirectory extends BaseDirectoryTestCase { @@ -31,7 +30,6 @@ protected Directory getDirectory(Path path) { return new FilterDirectory(new ByteBuffersDirectory()) {}; } - @Test public void testOverrides() throws Exception { // verify that all methods of Directory are overridden by FilterDirectory, // except those under the 'exclude' list diff --git a/lucene/core/src/test/org/apache/lucene/store/TestFilterIndexOutput.java b/lucene/core/src/test/org/apache/lucene/store/TestFilterIndexOutput.java index 2abdf754d596..825e5660be46 100644 --- a/lucene/core/src/test/org/apache/lucene/store/TestFilterIndexOutput.java +++ b/lucene/core/src/test/org/apache/lucene/store/TestFilterIndexOutput.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import org.junit.Test; public class TestFilterIndexOutput extends BaseDataOutputTestCase { @@ -36,7 +35,6 @@ protected byte[] toBytes(FilterIndexOutput instance) { return ((ByteBuffersIndexOutput) instance.out).toArrayCopy(); } - @Test public void testOverrides() { for (Method m : FilterIndexOutput.class.getMethods()) { if (m.getDeclaringClass() == FilterIndexOutput.class) { diff --git a/lucene/core/src/test/org/apache/lucene/util/TestBytesRefHash.java b/lucene/core/src/test/org/apache/lucene/util/TestBytesRefHash.java index 9d2fd94ebe00..14e00a9386a2 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestBytesRefHash.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestBytesRefHash.java @@ -32,7 +32,6 @@ import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRefHash.MaxBytesLengthExceededException; import org.junit.Before; -import org.junit.Test; public class TestBytesRefHash extends LuceneTestCase { @@ -332,7 +331,6 @@ public void testConcurrentAccessToBytesRefHash() throws Exception { } } - @Test public void testLargeValue() { int[] sizes = new int[] {random().nextInt(5), ByteBlockPool.BYTE_BLOCK_SIZE - 33 + random().nextInt(31)}; diff --git a/lucene/core/src/test/org/apache/lucene/util/TestRecyclingByteBlockAllocator.java b/lucene/core/src/test/org/apache/lucene/util/TestRecyclingByteBlockAllocator.java index 91cb7e27052c..c043e5b6015a 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestRecyclingByteBlockAllocator.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestRecyclingByteBlockAllocator.java @@ -21,7 +21,6 @@ import java.util.List; import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.Before; -import org.junit.Test; /** Testcase for {@link RecyclingByteBlockAllocator} */ public class TestRecyclingByteBlockAllocator extends LuceneTestCase { @@ -37,7 +36,6 @@ private RecyclingByteBlockAllocator newAllocator() { return new RecyclingByteBlockAllocator(random().nextInt(97), Counter.newCounter()); } - @Test public void testAllocate() { RecyclingByteBlockAllocator allocator = newAllocator(); HashSet set = new HashSet<>(); @@ -57,7 +55,6 @@ public void testAllocate() { } } - @Test public void testAllocateAndRecycle() { RecyclingByteBlockAllocator allocator = newAllocator(); HashSet allocated = new HashSet<>(); @@ -94,7 +91,6 @@ public void testAllocateAndRecycle() { } } - @Test public void testAllocateAndFree() { RecyclingByteBlockAllocator allocator = newAllocator(); HashSet allocated = new HashSet<>(); diff --git a/lucene/core/src/test/org/apache/lucene/util/TestRecyclingIntBlockAllocator.java b/lucene/core/src/test/org/apache/lucene/util/TestRecyclingIntBlockAllocator.java index bb9bc8792b5c..67dd13e58cec 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestRecyclingIntBlockAllocator.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestRecyclingIntBlockAllocator.java @@ -21,7 +21,6 @@ import java.util.List; import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.Before; -import org.junit.Test; /** Testcase for {@link RecyclingIntBlockAllocator} */ public class TestRecyclingIntBlockAllocator extends LuceneTestCase { @@ -38,7 +37,6 @@ private RecyclingIntBlockAllocator newAllocator() { 1 << (2 + random().nextInt(15)), random().nextInt(97), Counter.newCounter()); } - @Test public void testAllocate() { RecyclingIntBlockAllocator allocator = newAllocator(); HashSet set = new HashSet<>(); @@ -58,7 +56,6 @@ public void testAllocate() { } } - @Test public void testAllocateAndRecycle() { RecyclingIntBlockAllocator allocator = newAllocator(); HashSet allocated = new HashSet<>(); @@ -95,7 +92,6 @@ public void testAllocateAndRecycle() { } } - @Test public void testAllocateAndFree() { RecyclingIntBlockAllocator allocator = newAllocator(); HashSet allocated = new HashSet<>(); diff --git a/lucene/core/src/test/org/apache/lucene/util/TestSentinelIntSet.java b/lucene/core/src/test/org/apache/lucene/util/TestSentinelIntSet.java index c73bcfe7e408..c5a0b792a4c2 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestSentinelIntSet.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestSentinelIntSet.java @@ -18,12 +18,10 @@ import java.util.HashSet; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** */ public class TestSentinelIntSet extends LuceneTestCase { - @Test public void test() throws Exception { SentinelIntSet set = new SentinelIntSet(10, -1); assertFalse(set.exists(50)); @@ -43,7 +41,6 @@ public void test() throws Exception { assertEquals(24, set.rehashCount); } - @Test public void testRandom() throws Exception { for (int i = 0; i < 10000; i++) { int initSz = random().nextInt(20); diff --git a/lucene/core/src/test/org/apache/lucene/util/TestSetOnce.java b/lucene/core/src/test/org/apache/lucene/util/TestSetOnce.java index eb25186b3bf7..cacaaed59aaf 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestSetOnce.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestSetOnce.java @@ -19,7 +19,6 @@ import java.util.Random; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.SetOnce.AlreadySetException; -import org.junit.Test; public class TestSetOnce extends LuceneTestCase { @@ -49,20 +48,17 @@ public void run() { } } - @Test public void testEmptyCtor() throws Exception { SetOnce set = new SetOnce<>(); assertNull(set.get()); } - @Test public void testSettingCtor() throws Exception { SetOnce set = new SetOnce<>(5); assertEquals(5, set.get().intValue()); expectThrows(AlreadySetException.class, () -> set.set(7)); } - @Test public void testSetOnce() throws Exception { SetOnce set = new SetOnce<>(); set.set(5); @@ -70,7 +66,6 @@ public void testSetOnce() throws Exception { expectThrows(AlreadySetException.class, () -> set.set(7)); } - @Test public void testTrySet() { SetOnce set = new SetOnce<>(); assertTrue(set.trySet(5)); @@ -79,7 +74,6 @@ public void testTrySet() { assertEquals(5, set.get().intValue()); } - @Test public void testSetMultiThreaded() throws Exception { final SetOnce set = new SetOnce<>(); SetOnceThread[] threads = new SetOnceThread[10]; diff --git a/lucene/core/src/test/org/apache/lucene/util/automaton/TestIntSet.java b/lucene/core/src/test/org/apache/lucene/util/automaton/TestIntSet.java index 271240c3fc44..73c945096b9a 100644 --- a/lucene/core/src/test/org/apache/lucene/util/automaton/TestIntSet.java +++ b/lucene/core/src/test/org/apache/lucene/util/automaton/TestIntSet.java @@ -20,15 +20,12 @@ import static org.hamcrest.Matchers.greaterThan; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestIntSet extends LuceneTestCase { - @Test public void testFreezeEqualitySmallSet() { testFreezeEquality(10); } - @Test public void testFreezeEqualityLargeSet() { testFreezeEquality(100); } @@ -51,7 +48,6 @@ private void testFreezeEquality(int size) { assertEquals("Frozen sets were not equal", frozen0, frozen1); } - @Test public void testMapCutover() { StateSet set = new StateSet(10); for (int i = 0; i < 35; i++) { @@ -69,7 +65,6 @@ public void testMapCutover() { assertThat(set.size(), equalTo(0)); } - @Test public void testModify() { StateSet set = new StateSet(2); set.incr(1); @@ -88,7 +83,6 @@ public void testModify() { assertNotEquals(set, set2); } - @Test public void testHashCode() { StateSet set = new StateSet(1000); StateSet set2 = new StateSet(100); diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java index ddb8e8f4c817..be4eebffea2b 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java @@ -19,11 +19,9 @@ import java.util.List; import org.apache.lucene.facet.FacetResult; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestAssociationsFacetsExample extends LuceneTestCase { - @Test public void testExamples() throws Exception { List res = new AssociationsFacetsExample().runSumAssociations(); assertEquals("Wrong number of results", 2, res.size()); @@ -35,7 +33,6 @@ public void testExamples() throws Exception { res.get(1).toString()); } - @Test public void testDrillDown() throws Exception { FacetResult result = new AssociationsFacetsExample().runDrillDown(); assertEquals( diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestCustomFacetSetExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestCustomFacetSetExample.java index eee950ec4826..0aec7ae7414f 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestCustomFacetSetExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestCustomFacetSetExample.java @@ -19,11 +19,9 @@ import org.apache.lucene.facet.FacetResult; import org.apache.lucene.facet.LabelAndValue; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestCustomFacetSetExample extends LuceneTestCase { - @Test public void testExactMatching() throws Exception { FacetResult result = new CustomFacetSetExample().runExactMatching(); @@ -36,7 +34,6 @@ public void testExactMatching() throws Exception { assertEquals(new LabelAndValue("July 2022 (120f)", 2), result.labelValues[1]); } - @Test public void testExactMatchingWithFastMatchQuery() throws Exception { FacetResult result = new CustomFacetSetExample().runExactMatchingWithFastMatchQuery(); @@ -49,7 +46,6 @@ public void testExactMatchingWithFastMatchQuery() throws Exception { assertEquals(new LabelAndValue("July 2022 (120f)", 2), result.labelValues[1]); } - @Test public void testRangeMatching() throws Exception { FacetResult result = new CustomFacetSetExample().runRangeMatching(); @@ -61,7 +57,6 @@ public void testRangeMatching() throws Exception { assertEquals(new LabelAndValue("Eighty to Hundred Degrees", 4), result.labelValues[0]); } - @Test public void testCustomRangeMatching() throws Exception { FacetResult result = new CustomFacetSetExample().runCustomRangeMatching(); diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestDynamicRangeFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestDynamicRangeFacetsExample.java index 8724f2dcf273..d9c539f8a2f4 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestDynamicRangeFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestDynamicRangeFacetsExample.java @@ -19,10 +19,8 @@ import java.util.List; import org.apache.lucene.facet.range.DynamicRangeUtil; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestDynamicRangeFacetsExample extends LuceneTestCase { - @Test public void testExample() throws Exception { List res = new DynamicRangeFacetsExample().runSearch(); assertEquals( diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java index 5f40f22d0230..684ee33c3b8b 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java @@ -18,11 +18,9 @@ import org.apache.lucene.facet.FacetResult; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestExpressionAggregationFacetsExample extends LuceneTestCase { - @Test public void testSimple() throws Exception { FacetResult result = new ExpressionAggregationFacetsExample().runSearch(); assertEquals( diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java index 1e4e401687c8..fff558b76741 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java @@ -19,11 +19,9 @@ import java.util.List; import org.apache.lucene.facet.FacetResult; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestMultiCategoryListsFacetsExample extends LuceneTestCase { - @Test public void testExample() throws Exception { List results = new MultiCategoryListsFacetsExample().runSearch(); assertEquals(2, results.size()); diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java index f7fde4c974c5..49d748aa88ec 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java @@ -19,11 +19,9 @@ import org.apache.lucene.facet.FacetResult; import org.apache.lucene.search.TopDocs; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestRangeFacetsExample extends LuceneTestCase { - @Test public void testSimple() throws Exception { RangeFacetsExample example = new RangeFacetsExample(); example.index(); @@ -49,7 +47,6 @@ public void testSimple() throws Exception { example.close(); } - @Test @SuppressWarnings("unchecked") public void testDrillDown() throws Exception { RangeFacetsExample example = new RangeFacetsExample(); diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java index 30af60cc6776..fd1a1d5d5c95 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java @@ -19,11 +19,9 @@ import java.util.List; import org.apache.lucene.facet.FacetResult; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestSimpleFacetsExample extends LuceneTestCase { - @Test public void testFacetOnly() throws Exception { List results = new SimpleFacetsExample().runFacetOnly(); assertEquals(2, results.size()); @@ -35,7 +33,6 @@ public void testFacetOnly() throws Exception { results.get(1).toString()); } - @Test public void testSimple() throws Exception { List results = new SimpleFacetsExample().runSearch(); assertEquals(2, results.size()); @@ -47,14 +44,12 @@ public void testSimple() throws Exception { results.get(1).toString()); } - @Test public void testDrillDown() throws Exception { FacetResult result = new SimpleFacetsExample().runDrillDown(); assertEquals( "dim=Author path=[] value=2 childCount=2\n Bob (1)\n Lisa (1)\n", result.toString()); } - @Test public void testDrillSideways() throws Exception { List result = new SimpleFacetsExample().runDrillSideways(); assertEquals( diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java index 2f97b86834d6..58be15da221b 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java @@ -19,12 +19,11 @@ import java.util.List; import org.apache.lucene.facet.FacetResult; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; // We require sorted set DVs: + public class TestSimpleSortedSetFacetsExample extends LuceneTestCase { - @Test public void testSimple() throws Exception { List results = new SimpleSortedSetFacetsExample().runSearch(); assertEquals(2, results.size()); @@ -36,7 +35,6 @@ public void testSimple() throws Exception { results.get(1).toString()); } - @Test public void testDrillDown() throws Exception { FacetResult result = new SimpleSortedSetFacetsExample().runDrillDown(); assertEquals( diff --git a/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestModularLayer.java b/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestModularLayer.java index 4531f870c1cf..45f41097c7f9 100644 --- a/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestModularLayer.java +++ b/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestModularLayer.java @@ -42,7 +42,6 @@ import org.assertj.core.api.Assumptions; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Test; /** * Sanity checks concerning the distribution's binary artifacts (modules). @@ -112,7 +111,6 @@ public static void cleanup() { } /** Make sure all published module names remain constant, even if we reorganize the build. */ - @Test public void testExpectedDistributionModuleNames() { Assertions.assertThat( allLuceneModules.stream().map(module -> module.descriptor().name()).sorted()) @@ -153,7 +151,6 @@ public void testExpectedDistributionModuleNames() { } /** Try to instantiate the demo classes so that we make sure their module layer is complete. */ - @Test public void testDemoClassesCanBeLoaded() { ModuleLayer bootLayer = ModuleLayer.boot(); Assertions.assertThatNoException() @@ -185,7 +182,6 @@ public void testDemoClassesCanBeLoaded() { } /** Checks that Lucene Core is a MR-JAR and has Panama foreign classes */ - @Test public void testMultiReleaseJar() { ModuleLayer bootLayer = ModuleLayer.boot(); Assertions.assertThatNoException() @@ -228,7 +224,6 @@ public void testMultiReleaseJar() { } /** Make sure we don't publish automatic modules. */ - @Test public void testAllCoreModulesAreNamedModules() { Assertions.assertThat(allLuceneModules) .allSatisfy( @@ -239,7 +234,6 @@ public void testAllCoreModulesAreNamedModules() { } /** Ensure all modules have the same (expected) version. */ - @Test public void testAllModulesHaveExpectedVersion() { String luceneBuildVersion = System.getProperty(VERSION_PROPERTY); Assumptions.assumeThat(luceneBuildVersion).isNotNull(); @@ -251,7 +245,6 @@ public void testAllModulesHaveExpectedVersion() { } /** Ensure SPIs are equal for the module and classpath layer. */ - @Test public void testModularAndClasspathProvidersAreConsistent() throws IOException { for (var module : allLuceneModules) { TreeMap> modularProviders = getModularServiceProviders(module); @@ -326,7 +319,6 @@ private static TreeMap> getModularServiceProviders( *

This test should be progressively tuned so that certain internal packages are hidden in the * module layer. */ - @Test public void testAllExportedPackagesInSync() throws IOException { for (var module : allLuceneModules) { Set jarPackages = getJarPackages(module, _ -> true); @@ -377,7 +369,6 @@ public void testAllExportedPackagesInSync() throws IOException { } /** This test ensures that all analysis modules open their resources files to core. */ - @Test public void testAllOpenAnalysisPackagesInSync() throws IOException { for (var module : allLuceneModules) { if (false == module.descriptor().name().startsWith("org.apache.lucene.analysis.")) { diff --git a/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestScripts.java b/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestScripts.java index 472aaebf5cf4..df859fb528c9 100644 --- a/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestScripts.java +++ b/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestScripts.java @@ -33,11 +33,9 @@ import java.util.function.Supplier; import org.assertj.core.api.Assertions; import org.assertj.core.api.ThrowingConsumer; -import org.junit.Test; /** Verify that scripts included in the distribution work. */ public class TestScripts extends AbstractLuceneDistributionTest { - @Test @RequiresGUI public void testLukeCanBeLaunched() throws Exception { Path distributionPath; diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java b/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java index 1d36b409a21f..e1652df76a7b 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java @@ -90,7 +90,6 @@ import org.apache.lucene.util.InPlaceMergeSorter; import org.apache.lucene.util.InfoStream; import org.apache.lucene.util.NamedThreadFactory; -import org.junit.Test; public class TestDrillSideways extends FacetTestCase { @@ -2231,7 +2230,6 @@ public void testExtendedDrillSidewaysResult() throws Exception { IOUtils.close(searcher.getIndexReader(), taxoReader, taxoWriter, dir, taxoDir); } - @Test public void testDrillSidewaysSearchUseCorrectIterator() throws Exception { // This test reproduces an issue (see GitHub #12211) where DrillSidewaysScorer would ultimately // cause multiple consecutive calls to TwoPhaseIterator::matches, which results in a failed diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestFacetQuery.java b/lucene/facet/src/test/org/apache/lucene/facet/TestFacetQuery.java index 16ecfd09719f..73dcf202e8e9 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/TestFacetQuery.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/TestFacetQuery.java @@ -32,7 +32,6 @@ import org.apache.lucene.util.IOUtils; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Test; public class TestFacetQuery extends FacetTestCase { @@ -92,13 +91,11 @@ public static void closeTestIndex() throws IOException { config = null; } - @Test public void testSingleValued() throws Exception { TopDocs topDocs = searcher.search(new FacetQuery("Author", "Mark Twain"), 10); assertEquals(1, topDocs.totalHits.value()); } - @Test public void testMultiValued() throws Exception { TopDocs topDocs = searcher.search( diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java b/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java index 5cd0c11905e2..18402a63207f 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java @@ -37,7 +37,6 @@ import org.apache.lucene.tests.analysis.MockTokenizer; import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.util.IOUtils; -import org.junit.Test; public class TestMultipleIndexFields extends FacetTestCase { @@ -60,7 +59,6 @@ private FacetsConfig getConfig() { return config; } - @Test public void testDefault() throws Exception { Directory indexDir = newDirectory(); Directory taxoDir = newDirectory(); @@ -97,7 +95,6 @@ public void testDefault() throws Exception { IOUtils.close(tr, ir, tw, indexDir, taxoDir); } - @Test public void testCustom() throws Exception { Directory indexDir = newDirectory(); Directory taxoDir = newDirectory(); @@ -140,7 +137,6 @@ public void testCustom() throws Exception { IOUtils.close(tr, ir, tw, indexDir, taxoDir); } - @Test public void testTwoCustomsSameField() throws Exception { Directory indexDir = newDirectory(); Directory taxoDir = newDirectory(); @@ -197,7 +193,6 @@ private void assertOrdinalsExist(String field, IndexReader ir) throws IOExceptio fail("no ordinals found for " + field); } - @Test public void testDifferentFieldsAndText() throws Exception { Directory indexDir = newDirectory(); Directory taxoDir = newDirectory(); @@ -242,7 +237,6 @@ public void testDifferentFieldsAndText() throws Exception { IOUtils.close(tr, ir, tw, indexDir, taxoDir); } - @Test public void testSomeSameSomeDifferent() throws Exception { Directory indexDir = newDirectory(); Directory taxoDir = newDirectory(); diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestFacetLabel.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestFacetLabel.java index 3f24691d2525..439faceec8c4 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestFacetLabel.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestFacetLabel.java @@ -21,18 +21,15 @@ import org.apache.lucene.facet.sortedset.SortedSetDocValuesFacetField; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRef; -import org.junit.Test; public class TestFacetLabel extends FacetTestCase { - @Test public void testBasic() { assertEquals(0, new FacetLabel().length); assertEquals(1, new FacetLabel("hello").length); assertEquals(2, new FacetLabel("hello", "world").length); } - @Test public void testToString() { // When the category is empty, we expect an empty string assertEquals("FacetLabel: []", new FacetLabel().toString()); @@ -42,7 +39,6 @@ public void testToString() { assertEquals("FacetLabel: [hello, world]", new FacetLabel("hello", "world").toString()); } - @Test public void testGetComponent() { String[] components = new String[atLeast(10)]; for (int i = 0; i < components.length; i++) { @@ -54,7 +50,6 @@ public void testGetComponent() { } } - @Test public void testDefaultConstructor() { // test that the default constructor (no parameters) currently // defaults to creating an object with a 0 initial capacity. @@ -65,7 +60,6 @@ public void testDefaultConstructor() { assertEquals("FacetLabel: []", p.toString()); } - @Test public void testSubPath() { final FacetLabel p = new FacetLabel("hi", "there", "man"); assertEquals(p.length, 3); @@ -93,7 +87,6 @@ public void testSubPath() { } @SuppressWarnings("unlikely-arg-type") - @Test public void testEquals() { assertEquals(new FacetLabel(), new FacetLabel()); assertFalse(new FacetLabel().equals(new FacetLabel("hi"))); @@ -101,7 +94,6 @@ public void testEquals() { assertEquals(new FacetLabel("hello", "world"), new FacetLabel("hello", "world")); } - @Test public void testHashCode() { assertEquals(new FacetLabel().hashCode(), new FacetLabel().hashCode()); assertFalse(new FacetLabel().hashCode() == new FacetLabel("hi").hashCode()); @@ -109,7 +101,6 @@ public void testHashCode() { new FacetLabel("hello", "world").hashCode(), new FacetLabel("hello", "world").hashCode()); } - @Test public void testLongHashCode() { assertEquals(new FacetLabel().longHashCode(), new FacetLabel().longHashCode()); assertFalse(new FacetLabel().longHashCode() == new FacetLabel("hi").longHashCode()); @@ -118,14 +109,12 @@ public void testLongHashCode() { new FacetLabel("hello", "world").longHashCode()); } - @Test public void testArrayConstructor() { FacetLabel p = new FacetLabel("hello", "world", "yo"); assertEquals(3, p.length); assertEquals("FacetLabel: [hello, world, yo]", p.toString()); } - @Test public void testCompareTo() { FacetLabel p = new FacetLabel("a", "b", "c", "d"); FacetLabel pother = new FacetLabel("a", "b", "c", "d"); @@ -145,7 +134,6 @@ public void testCompareTo() { assertTrue(p.compareTo(pother) < 0); } - @Test public void testEmptyNullComponents() throws Exception { // LUCENE-4724: CategoryPath should not allow empty or null components String[][] components_tests = @@ -199,7 +187,6 @@ public void testEmptyNullComponents() throws Exception { expectThrows(IllegalArgumentException.class, () -> new SortedSetDocValuesFacetField("dim", "")); } - @Test public void testLongPath() throws Exception { String bigComp = null; while (true) { diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestLRUHashMap.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestLRUHashMap.java index b23278d679f1..7b7c34564170 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestLRUHashMap.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestLRUHashMap.java @@ -17,13 +17,11 @@ package org.apache.lucene.facet.taxonomy; import org.apache.lucene.facet.FacetTestCase; -import org.junit.Test; public class TestLRUHashMap extends FacetTestCase { // testLRU() tests that the specified size limit is indeed honored, and // the remaining objects in the map are indeed those that have been most // recently used - @Test public void testLRU() throws Exception { LRUHashMap lru = new LRUHashMap<>(3); assertEquals(0, lru.size()); diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestOrdinalMappingLeafReader.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestOrdinalMappingLeafReader.java index afcb9c8aab3e..578d7263761e 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestOrdinalMappingLeafReader.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestOrdinalMappingLeafReader.java @@ -42,7 +42,6 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; import org.junit.Before; -import org.junit.Test; public class TestOrdinalMappingLeafReader extends FacetTestCase { @@ -57,7 +56,6 @@ public void setUp() throws Exception { facetConfig.setIndexFieldName("tag", "$tags"); // add custom index field name } - @Test public void testTaxonomyMergeUtils() throws Exception { Directory srcIndexDir = newDirectory(); Directory srcTaxoDir = newDirectory(); diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyCombined.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyCombined.java index d3acb6015e03..0a4caefe454d 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyCombined.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyCombined.java @@ -30,7 +30,6 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.tests.util.LuceneTestCase.SuppressCodecs; import org.apache.lucene.util.SuppressForbidden; -import org.junit.Test; @SuppressCodecs("SimpleText") public class TestTaxonomyCombined extends FacetTestCase { @@ -159,7 +158,6 @@ private String showcat(FacetLabel path) { * do not test here that after writing the index can be read - this will be done in more tests * below. */ - @Test public void testWriter() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -175,7 +173,6 @@ public void testWriter() throws Exception { * testWriterTwice is exactly like testWriter, except that after adding all the categories, we add * them again, and see that we get the same old ids again - not new categories. */ - @Test public void testWriterTwice() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -197,7 +194,6 @@ public void testWriterTwice() throws Exception { * with writing and reading correctly just to the cache, testWriterTwice2 checks also the actual * disk read part of the writer: */ - @Test public void testWriterTwice2() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -219,7 +215,6 @@ public void testWriterTwice2() throws Exception { * sessions. This test used to fail because of a bug involving commit(), explained below, and now * should succeed. */ - @Test public void testWriterTwice3() throws Exception { Directory indexDir = newDirectory(); // First, create and fill the taxonomy @@ -251,7 +246,6 @@ public void testWriterTwice3() throws Exception { * cases, and therefore may be more helpful for debugging a problem than testWriter() which is * hard to know why or where it failed. */ - @Test public void testWriterSimpler() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -295,7 +289,6 @@ public void testWriterSimpler() throws Exception { * Test writing an empty index, and seeing that a reader finds in it the root category, and only * it. We check all the methods on that root category return the expected results. */ - @Test public void testRootOnly() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -317,7 +310,6 @@ public void testRootOnly() throws Exception { * before opening the reader. We want to see that the root is visible to the reader not only after * the writer is closed, but immediately after it is created. */ - @Test public void testRootOnly2() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -337,7 +329,6 @@ public void testRootOnly2() throws Exception { * getCategory() and getOrdinal()). We test that after writing the index, it can be read and all * the categories and ordinals are there just as we expected them to be. */ - @Test public void testReaderBasic() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -405,7 +396,6 @@ public void testReaderBasic() throws Exception { * they should not be tested! Until they are removed (*if* they are removed), these tests should * remain to see that they still work correctly. */ - @Test public void testReaderParent() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -460,7 +450,6 @@ public void testReaderParent() throws Exception { * *

This test code is virtually identical to that of testReaderParent(). */ - @Test public void testWriterParent1() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -476,7 +465,6 @@ public void testWriterParent1() throws Exception { indexDir.close(); } - @Test public void testWriterParent2() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -535,7 +523,6 @@ private void checkWriterParent(TaxonomyReader tr, TaxonomyWriter tw) throws Exce * Test TaxonomyReader's child browsing method, getChildrenArrays() This only tests for * correctness of the data on one example - we have below further tests on data refresh etc. */ - @Test public void testChildrenArrays() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -596,7 +583,6 @@ public void testChildrenArrays() throws Exception { * taxonomies, because we do not need to build the expected list of categories like we did in the * above test. */ - @Test public void testChildrenArraysInvariants() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -681,7 +667,6 @@ private static void assertArrayEquals(int[] expected, ParallelTaxonomyArrays.Int } /** Test how getChildrenArrays() deals with the taxonomy's growth: */ - @Test public void testChildrenArraysGrowth() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -720,7 +705,6 @@ public void testChildrenArraysGrowth() throws Exception { } // Test that getParentArrays is valid when retrieved during refresh - @Test public void testTaxonomyReaderRefreshRaces() throws Exception { // compute base child arrays - after first chunk, and after the other Directory indexDirBase = newDirectory(); @@ -879,7 +863,6 @@ private String stackTraceStr(final Throwable error) { * happens when the two processes do their actual work at exactly the same time. It also doesn't * test multi-threading. */ - @Test public void testSeparateReaderAndWriter() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -934,7 +917,6 @@ public void testSeparateReaderAndWriter() throws Exception { indexDir.close(); } - @Test public void testSeparateReaderAndWriter2() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -1038,7 +1020,6 @@ public static void checkPaths(TaxonomyWriter tw) throws IOException { * Basic test for TaxonomyWriter.getParent(). This is similar to testWriter above, except we also * check the parents of the added categories, not just the categories themselves. */ - @Test public void testWriterCheckPaths() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -1056,7 +1037,6 @@ public void testWriterCheckPaths() throws Exception { * paths. We repeat the path checking yet again after closing and opening the index for writing * again - to see that the reading of existing data from disk works as well. */ - @Test public void testWriterCheckPaths2() throws Exception { Directory indexDir = newDirectory(); TaxonomyWriter tw = new DirectoryTaxonomyWriter(indexDir); @@ -1074,7 +1054,6 @@ public void testWriterCheckPaths2() throws Exception { indexDir.close(); } - @Test public void testNRT() throws Exception { Directory dir = newDirectory(); DirectoryTaxonomyWriter writer = new DirectoryTaxonomyWriter(dir); diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts2.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts2.java index dcb5df665cea..6aae8a9986d1 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts2.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts2.java @@ -50,7 +50,6 @@ import org.apache.lucene.util.IOUtils; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Test; public class TestTaxonomyFacetCounts2 extends FacetTestCase { @@ -264,7 +263,6 @@ public static void beforeClassCountingFacetsAggregatorTest() throws Exception { IOUtils.close(taxoWriter); } - @Test public void testDifferentNumResults() throws Exception { // test the collector w/ FacetRequests and different numResults DirectoryReader indexReader = DirectoryReader.open(indexDir); @@ -288,7 +286,6 @@ public void testDifferentNumResults() throws Exception { IOUtils.close(indexReader, taxoReader); } - @Test public void testAllCounts() throws Exception { DirectoryReader indexReader = DirectoryReader.open(indexDir); TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); @@ -329,7 +326,6 @@ public void testAllCounts() throws Exception { IOUtils.close(indexReader, taxoReader); } - @Test public void testBigNumResults() throws Exception { DirectoryReader indexReader = DirectoryReader.open(indexDir); TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); @@ -353,7 +349,6 @@ public void testBigNumResults() throws Exception { IOUtils.close(indexReader, taxoReader); } - @Test public void testNoParents() throws Exception { DirectoryReader indexReader = DirectoryReader.open(indexDir); TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyReader.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyReader.java index 16b1875d4ad6..453d4830bad6 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyReader.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyReader.java @@ -45,14 +45,12 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.util.IOUtils; -import org.junit.Test; public class TestDirectoryTaxonomyReader extends FacetTestCase { private static final FacetLabel ILLEGAL_PATH = new FacetLabel("PATH_THAT_CAUSED_IllegalArgumentException"); - @Test public void testCloseAfterIncRef() throws Exception { Directory dir = newDirectory(); DirectoryTaxonomyWriter ltw = new DirectoryTaxonomyWriter(dir); @@ -70,7 +68,6 @@ public void testCloseAfterIncRef() throws Exception { dir.close(); } - @Test public void testCloseTwice() throws Exception { Directory dir = newDirectory(); DirectoryTaxonomyWriter ltw = new DirectoryTaxonomyWriter(dir); @@ -84,7 +81,6 @@ public void testCloseTwice() throws Exception { dir.close(); } - @Test public void testOpenIfChangedResult() throws Exception { Directory dir = null; DirectoryTaxonomyWriter ltw = null; @@ -112,7 +108,6 @@ public void testOpenIfChangedResult() throws Exception { } } - @Test public void testAlreadyClosed() throws Exception { Directory dir = newDirectory(); DirectoryTaxonomyWriter ltw = new DirectoryTaxonomyWriter(dir); @@ -127,12 +122,10 @@ public void testAlreadyClosed() throws Exception { } /** recreating a taxonomy should work well with a freshly opened taxonomy reader */ - @Test public void testFreshReadRecreatedTaxonomy() throws Exception { doTestReadRecreatedTaxonomy(random(), true); } - @Test public void testOpenIfChangedReadRecreatedTaxonomy() throws Exception { doTestReadRecreatedTaxonomy(random(), false); } @@ -185,7 +178,6 @@ private void doTestReadRecreatedTaxonomy(Random random, boolean closeReader) thr } } - @Test public void testOpenIfChangedAndRefCount() throws Exception { Directory dir = new ByteBuffersDirectory(); // no need for random directories here @@ -212,7 +204,6 @@ public void testOpenIfChangedAndRefCount() throws Exception { dir.close(); } - @Test public void testOpenIfChangedManySegments() throws Exception { // test openIfChanged() when the taxonomy contains many segments Directory dir = newDirectory(); @@ -258,7 +249,6 @@ protected IndexWriterConfig createIndexWriterConfig(OpenMode openMode) { dir.close(); } - @Test public void testOpenIfChangedMergedSegment() throws Exception { // test openIfChanged() when all index segments were merged - used to be // a bug in ParentArray, caught by testOpenIfChangedManySegments - only @@ -303,7 +293,6 @@ protected IndexWriter openIndexWriter(Directory directory, IndexWriterConfig con dir.close(); } - @Test public void testOpenIfChangedNoChangesButSegmentMerges() throws Exception { // test openIfChanged() when the taxonomy hasn't really changed, but segments // were merged. The NRT reader will be reopened, and ParentArray used to assert @@ -351,7 +340,6 @@ protected IndexWriter openIndexWriter(Directory directory, IndexWriterConfig con dir.close(); } - @Test public void testOpenIfChangedReuseAfterRecreate() throws Exception { // tests that if the taxonomy is recreated, no data is reused from the previous taxonomy Directory dir = newDirectory(); @@ -389,7 +377,6 @@ public void testOpenIfChangedReuseAfterRecreate() throws Exception { dir.close(); } - @Test public void testOpenIfChangedReuse() throws Exception { // test the reuse of data from the old DTR instance for (boolean nrt : new boolean[] {false, true}) { @@ -426,7 +413,6 @@ public void testOpenIfChangedReuse() throws Exception { } } - @Test public void testOpenIfChangedReplaceTaxonomy() throws Exception { // test openIfChanged when replaceTaxonomy is called, which is equivalent to recreate // only can work with NRT as well @@ -556,7 +542,6 @@ private void assertPathsAndOrdinals( assertGettingOrdinals(reader, ords, paths); } - @Test public void testGetChildren() throws Exception { Directory dir = newDirectory(); DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(dir); @@ -623,7 +608,6 @@ public void testGetChildren() throws Exception { dir.close(); } - @Test public void testAccountable() throws Exception { Directory dir = newDirectory(); DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(dir); @@ -651,7 +635,6 @@ public void testAccountable() throws Exception { dir.close(); } - @Test public void testGetPathAndOrdinalsRandomMultithreading() throws Exception { Directory src = newDirectory(); DirectoryTaxonomyWriter w = new DirectoryTaxonomyWriter(src); diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyWriter.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyWriter.java index 2e1465b727fb..026d5c4a46db 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyWriter.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyWriter.java @@ -46,7 +46,6 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.IOUtils; -import org.junit.Test; public class TestDirectoryTaxonomyWriter extends FacetTestCase { @@ -82,7 +81,6 @@ public int size() { } }; - @Test public void testCommit() throws Exception { // Verifies that nothing is committed to the underlying Directory, if // commit() wasn't called. @@ -101,7 +99,6 @@ public void testCommit() throws Exception { dir.close(); } - @Test public void testCommitUserData() throws Exception { // Verifies taxonomy commit data Directory dir = newDirectory(); @@ -165,7 +162,6 @@ public void testCommitUserData() throws Exception { dir.close(); } - @Test public void testRollback() throws Exception { // Verifies that if rollback is called, DTW is closed. Directory dir = newDirectory(); @@ -183,7 +179,6 @@ public void testRollback() throws Exception { dir.close(); } - @Test public void testRecreateRollback() throws Exception { // Tests rollback with OpenMode.CREATE Directory dir = newDirectory(); @@ -195,7 +190,6 @@ public void testRecreateRollback() throws Exception { dir.close(); } - @Test public void testEnsureOpen() throws Exception { // verifies that an exception is thrown if DTW was closed Directory dir = newDirectory(); @@ -222,7 +216,6 @@ private void touchTaxo(DirectoryTaxonomyWriter taxoWriter, FacetLabel cp) throws taxoWriter.commit(); } - @Test public void testRecreateAndRefresh() throws Exception { // DirTaxoWriter lost the INDEX_EPOCH property if it was opened in // CREATE_OR_APPEND (or commit(userData) called twice), which could lead to @@ -267,7 +260,6 @@ public void testRecreateAndRefresh() throws Exception { } } - @Test public void testBackwardsCompatibility() throws Exception { // tests that if the taxonomy index doesn't have the INDEX_EPOCH // property (supports pre-3.6 indexes), all still works. @@ -388,7 +380,6 @@ private long getEpoch(Directory taxoDir) throws IOException { return Long.parseLong(infos.getUserData().get(DirectoryTaxonomyWriter.INDEX_EPOCH)); } - @Test public void testReplaceTaxonomy() throws Exception { Directory input = newDirectory(); DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(input); @@ -429,7 +420,6 @@ public void testReplaceTaxonomy() throws Exception { input.close(); } - @Test public void testReaderFreshness() throws Exception { // ensures that the internal index reader is always kept fresh. Previously, // this simple scenario failed, if the cache just evicted the category that @@ -444,7 +434,6 @@ public void testReaderFreshness() throws Exception { dir.close(); } - @Test public void testCommitNoEmptyCommits() throws Exception { // LUCENE-4972: DTW used to create empty commits even if no changes were made Directory dir = newDirectory(); @@ -461,7 +450,6 @@ public void testCommitNoEmptyCommits() throws Exception { dir.close(); } - @Test public void testCloseNoEmptyCommits() throws Exception { // LUCENE-4972: DTW used to create empty commits even if no changes were made Directory dir = newDirectory(); @@ -478,7 +466,6 @@ public void testCloseNoEmptyCommits() throws Exception { dir.close(); } - @Test public void testPrepareCommitNoEmptyCommits() throws Exception { // LUCENE-4972: DTW used to create empty commits even if no changes were made Directory dir = newDirectory(); @@ -498,7 +485,6 @@ public void testPrepareCommitNoEmptyCommits() throws Exception { } // TODO: this test can hit pathological cases: it adds only a few docs, what is going on? - @Test @Nightly public void testHugeLabel() throws Exception { Directory indexDir = newDirectory(), taxoDir = newDirectory(); @@ -545,7 +531,6 @@ public void testHugeLabel() throws Exception { IOUtils.close(indexReader, taxoReader, indexDir, taxoDir); } - @Test public void testReplaceTaxoWithLargeTaxonomy() throws Exception { Directory srcTaxoDir = newDirectory(), targetTaxoDir = newDirectory(); diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/writercache/TestLruTaxonomyWriterCache.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/writercache/TestLruTaxonomyWriterCache.java index af129d8a317f..0b1faf1cdefa 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/writercache/TestLruTaxonomyWriterCache.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/writercache/TestLruTaxonomyWriterCache.java @@ -19,11 +19,9 @@ import org.apache.lucene.facet.FacetTestCase; import org.apache.lucene.facet.taxonomy.FacetLabel; -import org.junit.Test; public class TestLruTaxonomyWriterCache extends FacetTestCase { - @Test public void testDefaultLRUTypeIsCollisionSafe() { // These labels are clearly different, but have identical longHashCodes. // Note that these labels are clearly contrived. We did encounter diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestMatchHighlighter.java b/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestMatchHighlighter.java index 1251c069376d..542ccde0d16c 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestMatchHighlighter.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestMatchHighlighter.java @@ -63,7 +63,6 @@ import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Before; -import org.junit.Test; public class TestMatchHighlighter extends LuceneTestCase { private static final String FLD_ID = "id"; @@ -126,7 +125,6 @@ static SynonymMap buildSynonymMap(String[][] synonyms) throws IOException { return builder.build(); } - @Test public void testBasicUsage() throws Exception { new IndexBuilder(this::toField) .doc(FLD_TEXT1, "foo bar baz") @@ -236,7 +234,6 @@ public void testBasicUsage() throws Exception { }); } - @Test public void testSynonymHighlight() throws Exception { // There is nothing special needed to highlight or process complex queries, synonyms, etc. // Synonyms defined in the constructor of this class. @@ -267,7 +264,6 @@ public void testSynonymHighlight() throws Exception { }); } - @Test public void testAnalyzedTextIntervals() throws Exception { SynonymMap synonymMap = buildSynonymMap( @@ -318,7 +314,6 @@ protected TokenStreamComponents createComponents(String fieldName) { }); } - @Test public void testStandardQueryParserIntervalFunctions() throws Exception { Analyzer analyzer = new Analyzer() { @@ -534,7 +529,6 @@ protected TokenStreamComponents createComponents(String fieldName) { } } - @Test public void testCustomFieldHighlightHandling() throws Exception { // Match highlighter is a showcase of individual components in this package, suitable // to create any kind of field-display designs. @@ -641,7 +635,6 @@ public Collection alwaysFetchedFields() { }); } - @Test public void testHighlightMoreQueriesAtOnceShowoff() throws Exception { // Match highlighter underlying components are powerful enough to build interesting, // if not always super-practical, things. In this case, we would like to highlight diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestMatchRegionRetriever.java b/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestMatchRegionRetriever.java index 71b00ecdc249..bad081422cd2 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestMatchRegionRetriever.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestMatchRegionRetriever.java @@ -69,7 +69,6 @@ import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Before; -import org.junit.Test; public class TestMatchRegionRetriever extends LuceneTestCase { private static final String FLD_ID = IndexBuilder.FLD_ID; @@ -160,12 +159,10 @@ protected TokenStreamComponents createComponents(String fieldName) { } }; - @Test public void testTermQueryWithOffsets() throws Exception { checkTermQuery(FLD_TEXT_POS_OFFS); } - @Test public void testTermQueryWithPositions() throws Exception { checkTermQuery(FLD_TEXT_POS); } @@ -188,12 +185,10 @@ private void checkTermQuery(String field) throws Exception { }); } - @Test public void testBooleanMultifieldQueryWithOffsets() throws Exception { checkBooleanMultifieldQuery(FLD_TEXT_POS_OFFS); } - @Test public void testBooleanMultifieldQueryWithPositions() throws Exception { checkBooleanMultifieldQuery(FLD_TEXT_POS); } @@ -221,12 +216,10 @@ private void checkBooleanMultifieldQuery(String field) throws Exception { }); } - @Test public void testVariousQueryTypesWithOffsets() throws Exception { checkVariousQueryTypes(FLD_TEXT_POS_OFFS); } - @Test public void testVariousQueryTypesWithPositions() throws Exception { checkVariousQueryTypes(FLD_TEXT_POS); } @@ -313,7 +306,6 @@ private void checkVariousQueryTypes(String field) throws Exception { }); } - @Test public void testIntervalQueryHighlightCrossingMultivalueBoundary() throws Exception { String field = FLD_TEXT_POS; new IndexBuilder(this::toField) @@ -331,7 +323,6 @@ public void testIntervalQueryHighlightCrossingMultivalueBoundary() throws Except }); } - @Test public void testIntervalQueries() throws Exception { String field = FLD_TEXT_POS_OFFS; @@ -395,12 +386,10 @@ public void testIntervalQueries() throws Exception { }); } - @Test public void testDegenerateIntervalsWithPositions() throws Exception { testDegenerateIntervals(FLD_TEXT_POS); } - @Test public void testDegenerateIntervalsWithOffsets() throws Exception { testDegenerateIntervals(FLD_TEXT_POS_OFFS); } @@ -425,12 +414,10 @@ public void testDegenerateIntervals(String field) throws Exception { }); } - @Test public void testMultivaluedFieldsWithOffsets() throws Exception { checkMultivaluedFields(FLD_TEXT_POS_OFFS); } - @Test public void testMultivaluedFieldsWithPositions() throws Exception { checkMultivaluedFields(FLD_TEXT_POS); } @@ -452,7 +439,6 @@ public void checkMultivaluedFields(String field) throws Exception { }); } - @Test public void testMultiFieldHighlights() throws Exception { for (String[] fieldPairs : new String[][] { @@ -490,7 +476,6 @@ public void testMultiFieldHighlights() throws Exception { * Rewritten Boolean queries may omit matches from {@link * org.apache.lucene.search.BooleanClause.Occur#SHOULD} clauses. Check that this isn't the case. */ - @Test public void testNoRewrite() throws Exception { String field1 = FLD_TEXT_POS_OFFS1; String field2 = FLD_TEXT_POS_OFFS2; @@ -524,12 +509,10 @@ public void testNoRewrite() throws Exception { }); } - @Test public void testNestedQueryHitsWithOffsets() throws Exception { checkNestedQueryHits(FLD_TEXT_POS_OFFS); } - @Test public void testNestedQueryHitsWithPositions() throws Exception { checkNestedQueryHits(FLD_TEXT_POS); } @@ -561,12 +544,10 @@ public void checkNestedQueryHits(String field) throws Exception { }); } - @Test public void testGraphQueryWithOffsets() throws Exception { checkGraphQuery(FLD_TEXT_SYNONYMS_POS_OFFS); } - @Test public void testGraphQueryWithPositions() throws Exception { checkGraphQuery(FLD_TEXT_SYNONYMS_POS); } @@ -604,12 +585,10 @@ private void checkGraphQuery(String field) throws Exception { }); } - @Test public void testSpanQueryWithOffsets() throws Exception { checkSpanQueries(FLD_TEXT_POS_OFFS); } - @Test public void testSpanQueryWithPositions() throws Exception { checkSpanQueries(FLD_TEXT_POS); } @@ -673,7 +652,6 @@ private void checkSpanQueries(String field) throws Exception { * checks the {@link OffsetsFromValues} strategy that returns highlights over entire indexed * values. */ - @Test public void testTextFieldNoPositionsOffsetFromValues() throws Exception { String field = FLD_TEXT_NOPOS; @@ -707,7 +685,6 @@ public void testTextFieldNoPositionsOffsetFromValues() throws Exception { * *

Such field structure is often useful for multivalued "keyword-like" fields. */ - @Test public void testTextFieldNoPositionsOffsetsFromTokens() throws Exception { String field = FLD_TEXT_NOPOS; diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestPassageSelector.java b/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestPassageSelector.java index 0fb9830f5bb7..93e0801f44ad 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestPassageSelector.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/matchhighlight/TestPassageSelector.java @@ -283,7 +283,6 @@ public void rangeWindows() { new OffsetRange(18, Integer.MAX_VALUE))); } - @Test public void testHighlightAcrossAllowedValueRange() { checkPassages( "012>34<|>56<789", diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterReanalysis.java b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterReanalysis.java index 0ad299eb4ccc..6bac38b7ba12 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterReanalysis.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterReanalysis.java @@ -26,14 +26,12 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; -import org.junit.Test; public class TestUnifiedHighlighterReanalysis extends UnifiedHighlighterTestBase { public TestUnifiedHighlighterReanalysis() { super(randomFieldType(random())); } - @Test public void testWithoutIndexSearcher() throws IOException { String text = "This is a test. Just a test highlighting without a searcher. Feel free to ignore."; @@ -55,7 +53,6 @@ public void testWithoutIndexSearcher() throws IOException { assertEquals("Hello", highlighter.highlightWithoutSearcher("nonexistent", query, "Hello", 1)); } - @Test public void testIndexSearcherNullness() throws IOException { String text = "This is a test. Just a test highlighting without a searcher. Feel free to ignore."; diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterTermVec.java b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterTermVec.java index 1517d517b482..9ba89f3d98bb 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterTermVec.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterTermVec.java @@ -43,7 +43,6 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.tests.index.RandomIndexWriter; -import org.junit.Test; /** * Tests highlighting for matters *expressly* relating to term vectors. @@ -205,7 +204,6 @@ public CacheHelper getReaderCacheHelper() { } } - @Test public void testUserFailedToIndexOffsets() throws IOException { FieldType fieldType = new FieldType(tvType); // note: it's indexed too fieldType.setStoreTermVectorPositions(random().nextBoolean()); diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/visibility/TestUnifiedHighlighterExtensibility.java b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/visibility/TestUnifiedHighlighterExtensibility.java index 65b1ad35785a..d40fb6878135 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/visibility/TestUnifiedHighlighterExtensibility.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/visibility/TestUnifiedHighlighterExtensibility.java @@ -47,7 +47,6 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.BytesRef; -import org.junit.Test; /** Helps us be aware of visibility/extensibility concerns. */ public class TestUnifiedHighlighterExtensibility extends LuceneTestCase { @@ -56,7 +55,6 @@ public class TestUnifiedHighlighterExtensibility extends LuceneTestCase { * This test is for maintaining the extensibility of the FieldOffsetStrategy for customizations * out of package. */ - @Test public void testFieldOffsetStrategyExtensibility() { final UnifiedHighlighter.OffsetSource offsetSource = UnifiedHighlighter.OffsetSource.NONE_NEEDED; @@ -95,7 +93,6 @@ protected OffsetsEnum createOffsetsEnumFromReader(LeafReader leafReader, int doc * This test is for maintaining the extensibility of the UnifiedHighlighter for customizations out * of package. */ - @Test public void testUnifiedHighlighterExtensibility() { final int maxLength = 1000; UnifiedHighlighter.Builder uhBuilder = @@ -230,7 +227,6 @@ public int getMaxLength() { assertEquals(uh.getMaxLength(), maxLength); } - @Test public void testPassageFormatterExtensibility() { final Object formattedResponse = new Object(); PassageFormatter formatter = @@ -243,7 +239,6 @@ public Object format(Passage[] passages, String content) { assertEquals(formattedResponse, formatter.format(new Passage[0], "")); } - @Test public void testFieldHiglighterExtensibility() { final String fieldName = "fieldName"; FieldHighlighter fieldHighlighter = diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoinSorting.java b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoinSorting.java index 52dd08f780d0..598c59e2e218 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoinSorting.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoinSorting.java @@ -38,12 +38,10 @@ import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.BytesRef; -import org.junit.Test; /** */ public class TestBlockJoinSorting extends LuceneTestCase { - @Test public void testNestedSorting() throws Exception { final Directory dir = newDirectory(); final RandomIndexWriter w = @@ -327,7 +325,6 @@ public void testNestedSorting() throws Exception { dir.close(); } - @Test public void testParentMissingValueNestedSorting() throws Exception { final Directory dir = newDirectory(); final RandomIndexWriter w = @@ -451,7 +448,6 @@ public void testParentMissingValueNestedSorting() throws Exception { dir.close(); } - @Test public void testChildMissingValueNestedSorting() throws Exception { final Directory dir = newDirectory(); final RandomIndexWriter w = diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java index 4a564ff07ac3..2f815a8357fd 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java @@ -98,7 +98,6 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.packed.PackedInts; -import org.junit.Test; public class TestJoinUtil extends LuceneTestCase { @@ -1466,14 +1465,12 @@ public void testEquals_numericJoin() throws Exception { } } - @Test public void testSingleValueRandomJoin() throws Exception { int maxIndexIter = atLeast(1); int maxSearchIter = atLeast(1); executeRandomJoin(false, maxIndexIter, maxSearchIter, TestUtil.nextInt(random(), 87, 764)); } - @Test // This test really takes more time, that is why the number of iterations are smaller. public void testMultiValueRandomJoin() throws Exception { int maxIndexIter = atLeast(1); diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestParentsChildrenBlockJoinQuery.java b/lucene/join/src/test/org/apache/lucene/search/join/TestParentsChildrenBlockJoinQuery.java index 82c6705ceed9..c3da870ade24 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestParentsChildrenBlockJoinQuery.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestParentsChildrenBlockJoinQuery.java @@ -44,7 +44,6 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestParentsChildrenBlockJoinQuery extends LuceneTestCase { @@ -57,13 +56,11 @@ private static RandomIndexWriter createIndexWriter(Directory dir) throws IOExcep random(), dir, newIndexWriterConfig().setMergePolicy(newLogMergePolicy())); } - @Test public void testEmptyIndex() throws Exception { // No documents to index, just test the query execution test(new TestDoc[0][0], new int[0], 10); } - @Test public void testOnlyParentDocs() throws Exception { // Only parent documents, no children TestDoc[][] blocks = { @@ -75,7 +72,6 @@ public void testOnlyParentDocs() throws Exception { test(blocks, expectedDocIds, 10); } - @Test public void testFirstParentWithoutChild() throws Exception { // First parent has no children, but the second parent has two children TestDoc[][] blocks = { @@ -86,7 +82,6 @@ public void testFirstParentWithoutChild() throws Exception { test(blocks, expectedDocIds, 10); } - @Test public void testWithRandomizedIndex() throws Exception { for (int i = 0; i < 10; i++) { // Run multiple iterations to ensure randomness @@ -146,7 +141,6 @@ private void runRandomizedTest() throws Exception { test(testDocs, expectedMatchArray, childLimitPerParent); } - @Test public void testAdvance() throws Exception { // Create test blocks with specific structure to test advance() TestDoc[][] blocks = new TestDoc[3][]; @@ -325,7 +319,6 @@ private void test(TestDoc[][] blocks, int[] expectedDocIds, int childLimitPerPar dir.close(); } - @Test public void testInvalidChildLimit() { BitSetProducer parentFilter = new QueryBitSetProducer(new TermQuery(new Term("type", "parent"))); @@ -339,7 +332,6 @@ public void testInvalidChildLimit() { assertTrue(e.getMessage().contains("childLimitPerParent must be > 0")); } - @Test public void testExplain() throws Exception { // Create test blocks with specific structure to test explain() TestDoc[][] blocks = new TestDoc[2][]; @@ -411,7 +403,6 @@ public void testExplain() throws Exception { dir.close(); } - @Test public void testIntraSegmentConcurrencyNotSupported() throws Exception { // Create test blocks with specific structure - using a larger number of documents final int numParents = atLeast(1000); // Create at least 1000 parents to ensure large segment diff --git a/lucene/luke/src/test/org/apache/lucene/luke/app/desktop/util/TestListUtils.java b/lucene/luke/src/test/org/apache/lucene/luke/app/desktop/util/TestListUtils.java index 112e6c77a051..0724f1bfe63e 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/app/desktop/util/TestListUtils.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/app/desktop/util/TestListUtils.java @@ -21,11 +21,9 @@ import java.util.List; import javax.swing.JList; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestListUtils extends LuceneTestCase { - @Test public void testGetAllItems() { JList list = new JList<>(new String[] {"Item 1", "Item 2"}); List items = ListUtils.getAllItems(list); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/app/desktop/util/inifile/TestSimpleIniFile.java b/lucene/luke/src/test/org/apache/lucene/luke/app/desktop/util/inifile/TestSimpleIniFile.java index 6952539013e3..e29b8b902a27 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/app/desktop/util/inifile/TestSimpleIniFile.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/app/desktop/util/inifile/TestSimpleIniFile.java @@ -25,11 +25,9 @@ import java.util.List; import java.util.Map; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestSimpleIniFile extends LuceneTestCase { - @Test public void testStore() throws IOException { Path path = saveTestIni(); assertTrue(Files.exists(path)); @@ -49,7 +47,6 @@ public void testStore() throws IOException { } } - @Test public void testLoad() throws IOException { Path path = saveTestIni(); @@ -62,7 +59,6 @@ public void testLoad() throws IOException { assertEquals(2, sections.get("section2").size()); } - @Test public void testPut() { SimpleIniFile iniFile = new SimpleIniFile(); iniFile.put("section1", "s1", "aaa"); @@ -76,7 +72,6 @@ public void testPut() { assertNull(sections.get("section2").get("b2")); } - @Test public void testGet() throws IOException { Path path = saveTestIni(); SimpleIniFile iniFile = new SimpleIniFile(); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/TestAnalysisImpl.java b/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/TestAnalysisImpl.java index cdf0f9213a88..ee750ac20560 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/TestAnalysisImpl.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/TestAnalysisImpl.java @@ -30,32 +30,27 @@ import org.apache.lucene.analysis.custom.CustomAnalyzer; import org.apache.lucene.luke.models.LukeException; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestAnalysisImpl extends LuceneTestCase { - @Test public void testGetAvailableCharFilters() { AnalysisImpl analysis = new AnalysisImpl(); Collection charFilters = analysis.getAvailableCharFilters(); assertNotNull(charFilters); } - @Test public void testGetAvailableTokenizers() { AnalysisImpl analysis = new AnalysisImpl(); Collection tokenizers = analysis.getAvailableTokenizers(); assertNotNull(tokenizers); } - @Test public void testGetAvailableTokenFilters() { AnalysisImpl analysis = new AnalysisImpl(); Collection tokenFilters = analysis.getAvailableTokenFilters(); assertNotNull(tokenFilters); } - @Test public void testAnalyze_preset() { AnalysisImpl analysis = new AnalysisImpl(); String analyzerType = "org.apache.lucene.analysis.standard.StandardAnalyzer"; @@ -68,7 +63,6 @@ public void testAnalyze_preset() { assertNotNull(tokens); } - @Test public void testAnalyze_custom() { AnalysisImpl analysis = new AnalysisImpl(); Map tkParams = new HashMap<>(); @@ -90,7 +84,6 @@ public void testAnalyze_custom() { assertNotNull(tokens); } - @Test public void testAnalyzer_custom_with_confdir() throws Exception { Path confDir = createTempDir("conf"); Path stopFile = Files.createFile(Paths.get(confDir.toString(), "stop.txt")); @@ -132,7 +125,6 @@ public void testAnalyze_default() { assertNotNull(tokens); } - @Test public void testAnalyzeStepByStep_preset() { AnalysisImpl analysis = new AnalysisImpl(); String analyzerType = "org.apache.lucene.analysis.standard.StandardAnalyzer"; @@ -143,7 +135,6 @@ public void testAnalyzeStepByStep_preset() { expectThrows(LukeException.class, () -> analysis.analyzeStepByStep(text)); } - @Test public void testAnalyzeStepByStep_custom() { AnalysisImpl analysis = new AnalysisImpl(); Map tkParams = new HashMap<>(); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/commits/TestCommitsImpl.java b/lucene/luke/src/test/org/apache/lucene/luke/models/commits/TestCommitsImpl.java index 695db48185fa..e6230c923c6d 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/commits/TestCommitsImpl.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/commits/TestCommitsImpl.java @@ -35,7 +35,6 @@ import org.apache.lucene.tests.util.TestUtil; import org.junit.After; import org.junit.Before; -import org.junit.Test; public class TestCommitsImpl extends LuceneTestCase { @@ -94,7 +93,6 @@ public void tearDown() throws Exception { dir.close(); } - @Test public void testListCommits() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); List commitList = commits.listCommits(); @@ -104,7 +102,6 @@ public void testListCommits() { assertEquals(1, commitList.get(commitList.size() - 1).getGeneration()); } - @Test public void testGetCommit() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); Optional commit = commits.getCommit(1); @@ -112,13 +109,11 @@ public void testGetCommit() { assertEquals(1, commit.get().getGeneration()); } - @Test public void testGetCommit_generation_notfound() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); assertFalse(commits.getCommit(10).isPresent()); } - @Test public void testGetFiles() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); List files = commits.getFiles(1); @@ -126,81 +121,69 @@ public void testGetFiles() { assertTrue(files.stream().anyMatch(file -> file.getFileName().equals("segments_1"))); } - @Test public void testGetFiles_generation_notfound() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); assertTrue(commits.getFiles(10).isEmpty()); } - @Test public void testGetSegments() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); List segments = commits.getSegments(1); assertTrue(segments.size() > 0); } - @Test public void testGetSegments_generation_notfound() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); assertTrue(commits.getSegments(10).isEmpty()); } - @Test public void testGetSegmentAttributes() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); Map attributes = commits.getSegmentAttributes(1, "_0"); assertTrue(attributes.size() > 0); } - @Test public void testGetSegmentAttributes_generation_notfound() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); Map attributes = commits.getSegmentAttributes(3, "_0"); assertTrue(attributes.isEmpty()); } - @Test public void testGetSegmentAttributes_invalid_name() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); Map attributes = commits.getSegmentAttributes(1, "xxx"); assertTrue(attributes.isEmpty()); } - @Test public void testGetSegmentDiagnostics() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); Map diagnostics = commits.getSegmentDiagnostics(1, "_0"); assertTrue(diagnostics.size() > 0); } - @Test public void testGetSegmentDiagnostics_generation_notfound() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); assertTrue(commits.getSegmentDiagnostics(10, "_0").isEmpty()); } - @Test public void testGetSegmentDiagnostics_invalid_name() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); Map diagnostics = commits.getSegmentDiagnostics(1, "xxx"); assertTrue(diagnostics.isEmpty()); } - @Test public void testSegmentCodec() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); Optional codec = commits.getSegmentCodec(1, "_0"); assertTrue(codec.isPresent()); } - @Test public void testSegmentCodec_generation_notfound() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); Optional codec = commits.getSegmentCodec(10, "_0"); assertFalse(codec.isPresent()); } - @Test public void testSegmentCodec_invalid_name() { CommitsImpl commits = new CommitsImpl(reader, indexDir.toString()); Optional codec = commits.getSegmentCodec(1, "xxx"); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestDocValuesAdapter.java b/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestDocValuesAdapter.java index 516180c51ae4..2c3671f4e0f7 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestDocValuesAdapter.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestDocValuesAdapter.java @@ -31,7 +31,6 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.util.BytesRef; -import org.junit.Test; public class TestDocValuesAdapter extends DocumentsTestBase { @@ -58,7 +57,6 @@ protected void createIndex() throws IOException { dir.close(); } - @Test public void testGetDocValues_binary() throws Exception { DocValuesAdapter adapterImpl = new DocValuesAdapter(reader); DocValues values = @@ -68,7 +66,6 @@ public void testGetDocValues_binary() throws Exception { assertEquals(Collections.emptyList(), values.getNumericValues()); } - @Test public void testGetDocValues_sorted() throws Exception { DocValuesAdapter adapterImpl = new DocValuesAdapter(reader); DocValues values = @@ -78,7 +75,6 @@ public void testGetDocValues_sorted() throws Exception { assertEquals(Collections.emptyList(), values.getNumericValues()); } - @Test public void testGetDocValues_sorted_set() throws Exception { DocValuesAdapter adapterImpl = new DocValuesAdapter(reader); DocValues values = @@ -89,7 +85,6 @@ public void testGetDocValues_sorted_set() throws Exception { assertEquals(Collections.emptyList(), values.getNumericValues()); } - @Test public void testGetDocValues_numeric() throws Exception { DocValuesAdapter adapterImpl = new DocValuesAdapter(reader); DocValues values = @@ -99,7 +94,6 @@ public void testGetDocValues_numeric() throws Exception { assertEquals(42L, values.getNumericValues().get(0).longValue()); } - @Test public void testGetDocValues_sorted_numeric() throws Exception { DocValuesAdapter adapterImpl = new DocValuesAdapter(reader); DocValues values = @@ -110,7 +104,6 @@ public void testGetDocValues_sorted_numeric() throws Exception { assertEquals(22L, values.getNumericValues().get(1).longValue()); } - @Test public void testGetDocValues_notAvailable() throws Exception { DocValuesAdapter adapterImpl = new DocValuesAdapter(reader); assertFalse(adapterImpl.getDocValues(0, "no_dv").isPresent()); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestDocumentsImpl.java b/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestDocumentsImpl.java index d9c5bca2cc79..aefa3907be07 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestDocumentsImpl.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestDocumentsImpl.java @@ -25,9 +25,9 @@ import org.apache.lucene.store.AlreadyClosedException; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.NumericUtils; -import org.junit.Test; // See: https://github.com/DmitryKey/luke/issues/133 + @LuceneTestCase.SuppressCodecs({ "DummyCompressingStoredFieldsData", "HighCompressionCompressingStoredFieldsData", @@ -36,19 +36,16 @@ }) public class TestDocumentsImpl extends DocumentsTestBase { - @Test public void testGetMaxDoc() { DocumentsImpl documents = new DocumentsImpl(reader); assertEquals(5, documents.getMaxDoc()); } - @Test public void testIsLive() { DocumentsImpl documents = new DocumentsImpl(reader); assertTrue(documents.isLive(0)); } - @Test public void testGetDocumentFields() { DocumentsImpl documents = new DocumentsImpl(reader); List fields = documents.getDocumentFields(0); @@ -131,7 +128,6 @@ public void testGetDocumentFields() { assertNull(f5.getNumericValue()); } - @Test public void testFirstTerm() { DocumentsImpl documents = new DocumentsImpl(reader); Term term = documents.firstTerm("title").orElseThrow(IllegalStateException::new); @@ -139,14 +135,12 @@ public void testFirstTerm() { assertEquals("a", term.text()); } - @Test public void testFirstTerm_notAvailable() { DocumentsImpl documents = new DocumentsImpl(reader); assertFalse(documents.firstTerm("subject").isPresent()); assertNull(documents.getCurrentField()); } - @Test public void testNextTerm() { DocumentsImpl documents = new DocumentsImpl(reader); documents.firstTerm("title").orElseThrow(IllegalStateException::new); @@ -158,13 +152,11 @@ public void testNextTerm() { } } - @Test public void testNextTerm_unPositioned() { DocumentsImpl documents = new DocumentsImpl(reader); assertFalse(documents.nextTerm().isPresent()); } - @Test public void testSeekTerm() { DocumentsImpl documents = new DocumentsImpl(reader); documents.firstTerm("title").orElseThrow(IllegalStateException::new); @@ -174,13 +166,11 @@ public void testSeekTerm() { assertFalse(documents.seekTerm("x").isPresent()); } - @Test public void testSeekTerm_unPositioned() { DocumentsImpl documents = new DocumentsImpl(reader); assertFalse(documents.seekTerm("a").isPresent()); } - @Test public void testFirstTermDoc() { DocumentsImpl documents = new DocumentsImpl(reader); documents.firstTerm("title").orElseThrow(IllegalStateException::new); @@ -189,13 +179,11 @@ public void testFirstTermDoc() { assertTrue(documents.firstTermDoc().isPresent()); } - @Test public void testFirstTermDoc_unPositioned() { DocumentsImpl documents = new DocumentsImpl(reader); assertFalse(documents.firstTermDoc().isPresent()); } - @Test public void testNextTermDoc() { DocumentsImpl documents = new DocumentsImpl(reader); Term term = documents.firstTerm("title").orElseThrow(IllegalStateException::new); @@ -208,14 +196,12 @@ public void testNextTermDoc() { assertFalse(documents.nextTermDoc().isPresent()); } - @Test public void testNextTermDoc_unPositioned() { DocumentsImpl documents = new DocumentsImpl(reader); documents.firstTerm("title").orElseThrow(IllegalStateException::new); assertFalse(documents.nextTermDoc().isPresent()); } - @Test public void testTermPositions() { DocumentsImpl documents = new DocumentsImpl(reader); documents.firstTerm("author").orElseThrow(IllegalStateException::new); @@ -228,14 +214,12 @@ public void testTermPositions() { assertEquals(13, postings.get(0).getEndOffset()); } - @Test public void testTermPositions_unPositioned() { DocumentsImpl documents = new DocumentsImpl(reader); documents.firstTerm("author").orElseThrow(IllegalStateException::new); assertEquals(0, documents.getTermPositions().size()); } - @Test public void testTermPositions_noPositions() { DocumentsImpl documents = new DocumentsImpl(reader); documents.firstTerm("title").orElseThrow(IllegalStateException::new); @@ -243,7 +227,6 @@ public void testTermPositions_noPositions() { assertEquals(0, documents.getTermPositions().size()); } - @Test public void testClose() throws Exception { new DocumentsImpl(reader); reader.close(); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestTermVectorsAdapter.java b/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestTermVectorsAdapter.java index bfc2456d90c6..4aff0718f8af 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestTermVectorsAdapter.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/documents/TestTermVectorsAdapter.java @@ -25,7 +25,6 @@ import org.apache.lucene.index.IndexOptions; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; -import org.junit.Test; public class TestTermVectorsAdapter extends DocumentsTestBase { @@ -67,7 +66,6 @@ protected void createIndex() throws IOException { dir.close(); } - @Test public void testGetTermVector() throws Exception { TermVectorsAdapter adapterImpl = new TermVectorsAdapter(reader); List tvEntries = adapterImpl.getTermVector(0, "text1"); @@ -129,7 +127,6 @@ public void testGetTermVector() throws Exception { assertEquals(1, tvEntries.get(17).getFreq()); } - @Test public void testGetTermVector_with_positions() throws Exception { TermVectorsAdapter adapterImpl = new TermVectorsAdapter(reader); List tvEntries = adapterImpl.getTermVector(0, "text2"); @@ -143,7 +140,6 @@ public void testGetTermVector_with_positions() throws Exception { assertFalse(tvEntries.get(1).getPositions().get(0).getEndOffset().isPresent()); } - @Test public void testGetTermVector_with_positions_offsets() throws Exception { TermVectorsAdapter adapterImpl = new TermVectorsAdapter(reader); List tvEntries = adapterImpl.getTermVector(0, "text3"); @@ -157,7 +153,6 @@ public void testGetTermVector_with_positions_offsets() throws Exception { assertEquals(38, tvEntries.get(1).getPositions().get(0).getEndOffset().orElse(-1)); } - @Test public void testGetTermVectors_notAvailable() throws Exception { TermVectorsAdapter adapterImpl = new TermVectorsAdapter(reader); assertEquals(0, adapterImpl.getTermVector(0, "title").size()); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestOverviewImpl.java b/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestOverviewImpl.java index bab9acef1973..dc954aeeb117 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestOverviewImpl.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestOverviewImpl.java @@ -23,96 +23,80 @@ import java.util.List; import java.util.Map; import org.apache.lucene.store.AlreadyClosedException; -import org.junit.Test; public class TestOverviewImpl extends OverviewTestBase { - @Test public void testGetIndexPath() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertEquals(indexDir.toString(), overview.getIndexPath()); } - @Test public void testGetNumFields() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertEquals(2, (long) overview.getNumFields()); } - @Test public void testGetFieldNames() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertEquals(new HashSet<>(Arrays.asList("f1", "f2")), new HashSet<>(overview.getFieldNames())); } - @Test public void testGetNumDocuments() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertEquals(3, (long) overview.getNumDocuments()); } - @Test public void testGetNumTerms() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertEquals(9, overview.getNumTerms()); } - @Test public void testHasDeletions() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertFalse(overview.hasDeletions()); } - @Test public void testGetNumDeletedDocs() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertEquals(0, (long) overview.getNumDeletedDocs()); } - @Test public void testIsOptimized() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertTrue(overview.isOptimized().isPresent()); } - @Test public void testGetIndexVersion() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertTrue(overview.getIndexVersion().orElseThrow(IllegalStateException::new) > 0); } - @Test public void testGetIndexFormat() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertEquals("Lucene 8.6 or later", overview.getIndexFormat().get()); } - @Test public void testGetDirImpl() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertEquals(dir.getClass().getName(), overview.getDirImpl().get()); } - @Test public void testGetCommitDescription() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertTrue(overview.getCommitDescription().isPresent()); } - @Test public void testGetCommitUserData() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); assertTrue(overview.getCommitUserData().isPresent()); } - @Test public void testGetSortedTermCounts() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); Map countsMap = overview.getSortedTermCounts(TermCountsOrder.COUNT_DESC); assertEquals(Arrays.asList("f2", "f1"), new ArrayList<>(countsMap.keySet())); } - @Test public void testGetTopTerms() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); List result = overview.getTopTerms("f2", 2); @@ -121,13 +105,11 @@ public void testGetTopTerms() { assertEquals("f2", result.get(0).getField()); } - @Test public void testGetTopTerms_illegal_numterms() { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); expectThrows(IllegalArgumentException.class, () -> overview.getTopTerms("f2", -1)); } - @Test public void testClose() throws Exception { OverviewImpl overview = new OverviewImpl(reader, indexDir.toString()); reader.close(); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestTermCounts.java b/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestTermCounts.java index cb7a03476cda..ffb31db86dab 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestTermCounts.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestTermCounts.java @@ -20,17 +20,14 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Map; -import org.junit.Test; public class TestTermCounts extends OverviewTestBase { - @Test public void testNumTerms() throws Exception { TermCounts termCounts = new TermCounts(reader); assertEquals(9, termCounts.numTerms()); } - @Test @SuppressWarnings("unchecked") public void testSortedTermCounts_count_asc() throws Exception { TermCounts termCounts = new TermCounts(reader); @@ -42,7 +39,6 @@ public void testSortedTermCounts_count_asc() throws Exception { assertEquals(6, (long) countsMap.get("f2")); } - @Test @SuppressWarnings("unchecked") public void testSortedTermCounts_count_desc() throws Exception { TermCounts termCounts = new TermCounts(reader); @@ -54,7 +50,6 @@ public void testSortedTermCounts_count_desc() throws Exception { assertEquals(6, (long) countsMap.get("f2")); } - @Test @SuppressWarnings("unchecked") public void testSortedTermCounts_name_asc() throws Exception { TermCounts termCounts = new TermCounts(reader); @@ -66,7 +61,6 @@ public void testSortedTermCounts_name_asc() throws Exception { assertEquals(6, (long) countsMap.get("f2")); } - @Test @SuppressWarnings("unchecked") public void testSortedTermCounts_name_desc() throws Exception { TermCounts termCounts = new TermCounts(reader); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestTopTerms.java b/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestTopTerms.java index dab4a6afef5d..298fcf88702a 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestTopTerms.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/overview/TestTopTerms.java @@ -18,11 +18,9 @@ package org.apache.lucene.luke.models.overview; import java.util.List; -import org.junit.Test; public class TestTopTerms extends OverviewTestBase { - @Test public void testGetTopTerms() throws Exception { TopTerms topTerms = new TopTerms(reader); List result = topTerms.getTopTerms("f2", 2); diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/search/TestSearchImpl.java b/lucene/luke/src/test/org/apache/lucene/luke/models/search/TestSearchImpl.java index a2ba76b2c1a6..c3e17ec3fb5c 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/search/TestSearchImpl.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/search/TestSearchImpl.java @@ -49,7 +49,6 @@ import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.BytesRef; -import org.junit.Test; public class TestSearchImpl extends LuceneTestCase { @@ -154,7 +153,6 @@ public void tearDown() throws Exception { dir.close(); } - @Test public void testGetSortableFieldNames() { SearchImpl search = new SearchImpl(reader); assertArrayEquals( @@ -162,20 +160,17 @@ public void testGetSortableFieldNames() { search.getSortableFieldNames().toArray()); } - @Test public void testGetSearchableFieldNames() { SearchImpl search = new SearchImpl(reader); assertArrayEquals(new String[] {"f1"}, search.getSearchableFieldNames().toArray()); } - @Test public void testGetRangeSearchableFieldNames() { SearchImpl search = new SearchImpl(reader); assertArrayEquals( new String[] {"f8", "f9", "f10", "f11"}, search.getRangeSearchableFieldNames().toArray()); } - @Test public void testParseClassic() { SearchImpl search = new SearchImpl(reader); QueryParserConfig config = @@ -188,7 +183,6 @@ public void testParseClassic() { assertEquals("+f1:app~1 +f2:*ie", q.toString()); } - @Test public void testParsePointRange() { SearchImpl search = new SearchImpl(reader); Map> types = new HashMap<>(); @@ -201,7 +195,6 @@ public void testParsePointRange() { assertTrue(q instanceof PointRangeQuery); } - @Test public void testGuessSortTypes() { SearchImpl search = new SearchImpl(reader); @@ -254,13 +247,11 @@ public void testGuessSortTypes() { search.guessSortTypes("f7").toArray()); } - @Test public void testGuessSortTypesNoSuchField() { SearchImpl search = new SearchImpl(reader); expectThrows(LukeException.class, () -> search.guessSortTypes("unknown")); } - @Test public void testGetSortType() { SearchImpl search = new SearchImpl(reader); @@ -295,13 +286,11 @@ public void testGetSortType() { assertFalse(search.getSortType("f7", "STRING", false).isPresent()); } - @Test public void testGetSortTypeNoSuchField() { SearchImpl search = new SearchImpl(reader); expectThrows(LukeException.class, () -> search.getSortType("unknown", "STRING", false)); } - @Test public void testSearch() throws Exception { SearchImpl search = new SearchImpl(reader); Query query = new QueryParser("f1", new StandardAnalyzer()).parse("apple"); @@ -313,7 +302,6 @@ public void testSearch() throws Exception { assertEquals(0, res.getOffset()); } - @Test public void testSearchWithSort() throws Exception { SearchImpl search = new SearchImpl(reader); Query query = new QueryParser("f1", new StandardAnalyzer()).parse("apple"); @@ -326,7 +314,6 @@ public void testSearchWithSort() throws Exception { assertEquals(0, res.getOffset()); } - @Test public void testNextPage() throws Exception { SearchImpl search = new SearchImpl(reader); Query query = new QueryParser("f1", new StandardAnalyzer()).parse("pie"); @@ -340,13 +327,11 @@ public void testNextPage() throws Exception { assertEquals(10, res.getOffset()); } - @Test public void testNextPageSearchNotStarted() { SearchImpl search = new SearchImpl(reader); expectThrows(LukeException.class, () -> search.nextPage()); } - @Test public void testNextPageNoMoreResults() throws Exception { SearchImpl search = new SearchImpl(reader); Query query = new QueryParser("f1", new StandardAnalyzer()).parse("pie"); @@ -355,7 +340,6 @@ public void testNextPageNoMoreResults() throws Exception { assertFalse(search.nextPage().isPresent()); } - @Test public void testPrevPage() throws Exception { SearchImpl search = new SearchImpl(reader); Query query = new QueryParser("f1", new StandardAnalyzer()).parse("pie"); @@ -370,13 +354,11 @@ public void testPrevPage() throws Exception { assertEquals(0, res.getOffset()); } - @Test public void testPrevPageSearchNotStarted() { SearchImpl search = new SearchImpl(reader); expectThrows(LukeException.class, () -> search.prevPage()); } - @Test public void testPrevPageNoMoreResults() throws Exception { SearchImpl search = new SearchImpl(reader); Query query = new QueryParser("f1", new StandardAnalyzer()).parse("pie"); diff --git a/lucene/monitor/src/test/org/apache/lucene/monitor/TestDocumentBatch.java b/lucene/monitor/src/test/org/apache/lucene/monitor/TestDocumentBatch.java index e03af88fb92e..77248c1a44c6 100644 --- a/lucene/monitor/src/test/org/apache/lucene/monitor/TestDocumentBatch.java +++ b/lucene/monitor/src/test/org/apache/lucene/monitor/TestDocumentBatch.java @@ -25,13 +25,11 @@ import org.apache.lucene.document.Document; import org.apache.lucene.tests.util.LuceneTestCase; import org.hamcrest.MatcherAssert; -import org.junit.Test; public class TestDocumentBatch extends LuceneTestCase { public static final Analyzer ANALYZER = new StandardAnalyzer(); - @Test public void testDocumentBatchThrowsIllegalArgumentExceptionUponZeroDocument() { expectThrows( IllegalArgumentException.class, diff --git a/lucene/monitor/src/test/org/apache/lucene/monitor/TestMonitorReadonly.java b/lucene/monitor/src/test/org/apache/lucene/monitor/TestMonitorReadonly.java index db316ba080dd..43cd28867c3f 100644 --- a/lucene/monitor/src/test/org/apache/lucene/monitor/TestMonitorReadonly.java +++ b/lucene/monitor/src/test/org/apache/lucene/monitor/TestMonitorReadonly.java @@ -30,12 +30,10 @@ import org.apache.lucene.index.Term; import org.apache.lucene.search.TermQuery; import org.apache.lucene.store.FSDirectory; -import org.junit.Test; public class TestMonitorReadonly extends MonitorTestBase { private static final Analyzer ANALYZER = new WhitespaceAnalyzer(); - @Test public void testReadonlyMonitorThrowsOnInexistentIndex() { Path indexDirectory = createTempDir(); MonitorConfiguration config = @@ -51,7 +49,6 @@ public void testReadonlyMonitorThrowsOnInexistentIndex() { }); } - @Test public void testReadonlyMonitorThrowsWhenCallingWriteRequests() throws IOException { Path indexDirectory = createTempDir(); MonitorConfiguration writeConfig = @@ -92,7 +89,6 @@ public void testReadonlyMonitorThrowsWhenCallingWriteRequests() throws IOExcepti } } - @Test public void testSettingCustomDirectory() throws IOException { Path indexDirectory = createTempDir(); Document doc = new Document(); @@ -118,7 +114,6 @@ public void testSettingCustomDirectory() throws IOException { } } - @Test public void testMonitorReadOnlyCouldReadOnTheSameIndex() throws IOException { Path indexDirectory = createTempDir(); Document doc = new Document(); @@ -166,7 +161,6 @@ public void testMonitorReadOnlyCouldReadOnTheSameIndex() throws IOException { } } - @Test public void testReadonlyMonitorGetsRefreshed() throws IOException, InterruptedException { Path indexDirectory = createTempDir(); Document doc = new Document(); diff --git a/lucene/monitor/src/test/org/apache/lucene/monitor/outsidepackage/TestCandidateMatcherVisibility.java b/lucene/monitor/src/test/org/apache/lucene/monitor/outsidepackage/TestCandidateMatcherVisibility.java index 73e84112e387..bab314134b07 100644 --- a/lucene/monitor/src/test/org/apache/lucene/monitor/outsidepackage/TestCandidateMatcherVisibility.java +++ b/lucene/monitor/src/test/org/apache/lucene/monitor/outsidepackage/TestCandidateMatcherVisibility.java @@ -25,7 +25,6 @@ import org.apache.lucene.monitor.QueryMatch; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.TermQuery; -import org.junit.Test; public class TestCandidateMatcherVisibility { @@ -36,7 +35,6 @@ private CandidateMatcher newCandidateMatcher() { return QueryMatch.SIMPLE_MATCHER.createMatcher(searcher); } - @Test public void testMatchQueryVisibleOutsidePackage() throws IOException { CandidateMatcher matcher = newCandidateMatcher(); // This should compile from outside org.apache.lucene.monitor package @@ -45,7 +43,6 @@ public void testMatchQueryVisibleOutsidePackage() throws IOException { matcher.matchQuery("test", new TermQuery(new Term("test_field")), Collections.emptyMap()); } - @Test public void testReportErrorVisibleOutsidePackage() { CandidateMatcher matcher = newCandidateMatcher(); // This should compile from outside org.apache.lucene.monitor package @@ -54,7 +51,6 @@ public void testReportErrorVisibleOutsidePackage() { matcher.reportError("test", new RuntimeException("test exception")); } - @Test public void testFinishVisibleOutsidePackage() { CandidateMatcher matcher = newCandidateMatcher(); // This should compile from outside org.apache.lucene.monitor package diff --git a/lucene/queries/src/test/org/apache/lucene/queries/TestCommonTermsQuery.java b/lucene/queries/src/test/org/apache/lucene/queries/TestCommonTermsQuery.java index abaf31d75b1a..f897895ffe0c 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/TestCommonTermsQuery.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/TestCommonTermsQuery.java @@ -54,7 +54,6 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.PriorityQueue; -import org.junit.Test; public class TestCommonTermsQuery extends LuceneTestCase { @@ -356,7 +355,6 @@ public void testIllegalOccur() { }); } - @Test public void testExtend() throws IOException { Directory dir = newDirectory(); MockAnalyzer analyzer = new MockAnalyzer(random()); diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFieldScoreQuery.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFieldScoreQuery.java index 44ef9ed03514..0e168138ce14 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFieldScoreQuery.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFieldScoreQuery.java @@ -24,7 +24,6 @@ import org.apache.lucene.search.TopDocs; import org.apache.lucene.tests.search.QueryUtils; import org.junit.BeforeClass; -import org.junit.Test; /** * Test FieldScoreQuery search. @@ -44,25 +43,21 @@ public static void beforeClass() throws Exception { } /** Test that FieldScoreQuery of Type.INT returns docs in expected order. */ - @Test public void testRankInt() throws Exception { doTestRank(INT_VALUESOURCE); } - @Test public void testRankIntMultiValued() throws Exception { doTestRank(INT_MV_MAX_VALUESOURCE); doTestRank(INT_MV_MIN_VALUESOURCE); } /** Test that FieldScoreQuery of Type.FLOAT returns docs in expected order. */ - @Test public void testRankFloat() throws Exception { // same values, but in flot format doTestRank(FLOAT_VALUESOURCE); } - @Test public void testRankFloatMultiValued() throws Exception { // same values, but in flot format doTestRank(FLOAT_MV_MAX_VALUESOURCE); @@ -91,25 +86,21 @@ private void doTestRank(ValueSource valueSource) throws Exception { } /** Test that FieldScoreQuery of Type.INT returns the expected scores. */ - @Test public void testExactScoreInt() throws Exception { doTestExactScore(INT_VALUESOURCE); } - @Test public void testExactScoreIntMultiValued() throws Exception { doTestExactScore(INT_MV_MAX_VALUESOURCE); doTestExactScore(INT_MV_MIN_VALUESOURCE); } /** Test that FieldScoreQuery of Type.FLOAT returns the expected scores. */ - @Test public void testExactScoreFloat() throws Exception { // same values, but in flot format doTestExactScore(FLOAT_VALUESOURCE); } - @Test public void testExactScoreFloatMultiValued() throws Exception { // same values, but in flot format doTestExactScore(FLOAT_MV_MAX_VALUESOURCE); diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionRangeQuery.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionRangeQuery.java index 4f6844c4b9b5..251bbd634c89 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionRangeQuery.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionRangeQuery.java @@ -31,7 +31,6 @@ import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Test; public class TestFunctionRangeQuery extends FunctionTestSetup { @@ -54,23 +53,19 @@ public void after() throws IOException { indexReader.close(); } - @Test public void testRangeInt() throws IOException { doTestRange(INT_VALUESOURCE); } - @Test public void testRangeIntMultiValued() throws IOException { doTestRange(INT_MV_MAX_VALUESOURCE); doTestRange(INT_MV_MIN_VALUESOURCE); } - @Test public void testRangeFloat() throws IOException { doTestRange(FLOAT_VALUESOURCE); } - @Test public void testRangeFloatMultiValued() throws IOException { doTestRange(FLOAT_MV_MAX_VALUESOURCE); doTestRange(FLOAT_MV_MIN_VALUESOURCE); @@ -86,12 +81,10 @@ private void doTestRange(ValueSource valueSource) throws IOException { expectScores(scoreDocs, 4, 3); } - @Test public void testDeleted() throws IOException { doTestDeleted(INT_VALUESOURCE); } - @Test public void testDeletedMultiValued() throws IOException { doTestDeleted(INT_MV_MAX_VALUESOURCE); doTestDeleted(INT_MV_MIN_VALUESOURCE); @@ -117,7 +110,6 @@ private void doTestDeleted(ValueSource valueSource) throws IOException { } } - @Test public void testExplain() throws IOException { Query rangeQuery = new FunctionRangeQuery(INT_VALUESOURCE, 2, 2, true, true); ScoreDoc[] scoreDocs = indexSearcher.search(rangeQuery, N_DOCS).scoreDocs; @@ -128,7 +120,6 @@ public void testExplain() throws IOException { explain.toString()); } - @Test public void testExplainMultiValued() throws IOException { Query rangeQuery = new FunctionRangeQuery(INT_MV_MIN_VALUESOURCE, 2, 2, true, true); ScoreDoc[] scoreDocs = indexSearcher.search(rangeQuery, N_DOCS).scoreDocs; @@ -144,7 +135,6 @@ public void testExplainMultiValued() throws IOException { explain.toString()); } - @Test public void testTwoRangeQueries() throws IOException { Query rq1 = new FunctionRangeQuery(INT_VALUESOURCE, 2, 4, true, true); Query rq2 = new FunctionRangeQuery(INT_VALUESOURCE, 8, 10, true, true); diff --git a/lucene/queries/src/test/org/apache/lucene/queries/payloads/TestPayloadScoreQuery.java b/lucene/queries/src/test/org/apache/lucene/queries/payloads/TestPayloadScoreQuery.java index 76f120bed678..e7e93a0fde65 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/payloads/TestPayloadScoreQuery.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/payloads/TestPayloadScoreQuery.java @@ -49,7 +49,6 @@ import org.apache.lucene.util.BytesRef; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Test; public class TestPayloadScoreQuery extends LuceneTestCase { @@ -94,7 +93,6 @@ private static void checkQuery( QueryUtils.check(random(), psq, searcher); } - @Test public void testTermQuery() throws IOException { SpanTermQuery q = new SpanTermQuery(new Term("field", "eighteen")); @@ -106,7 +104,6 @@ public void testTermQuery() throws IOException { } } - @Test public void testOrQuery() throws IOException { SpanOrQuery q = @@ -125,7 +122,6 @@ public void testOrQuery() throws IOException { } } - @Test public void testNearQuery() throws IOException { // 2 4 @@ -152,7 +148,6 @@ public void testNearQuery() throws IOException { // TODO: incredibly slow @Nightly - @Test public void testNestedNearQuery() throws Exception { // (one OR hundred) NEAR (twenty two) ~ 1 @@ -212,7 +207,6 @@ public void testNestedNearQuery() throws Exception { // TODO: incredibly slow @Nightly - @Test public void testSpanContainingQuery() throws Exception { // twenty WITHIN ((one OR hundred) NEAR two)~2 @@ -235,7 +229,6 @@ public void testSpanContainingQuery() throws Exception { checkQuery(q, new MinPayloadFunction(), new int[] {222, 122}, new float[] {4.0f, 2.0f}); } - @Test public void testEquality() { SpanQuery sq1 = new SpanTermQuery(new Term("field", "one")); SpanQuery sq2 = new SpanTermQuery(new Term("field", "two")); diff --git a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestFilterSpans.java b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestFilterSpans.java index 565885777a64..3e70385c4ca5 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestFilterSpans.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestFilterSpans.java @@ -18,11 +18,9 @@ import java.lang.reflect.Method; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestFilterSpans extends LuceneTestCase { - @Test public void testOverrides() throws Exception { // verify that all methods of Spans are overridden by FilterSpans, for (Method m : FilterSpans.class.getMethods()) { diff --git a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanCollection.java b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanCollection.java index 8c3f4bb84773..8f248f1e6356 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanCollection.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanCollection.java @@ -32,7 +32,6 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestSpanCollection extends LuceneTestCase { @@ -104,7 +103,6 @@ private void checkCollectedTerms(Spans spans, TermCollector collector, Term... e assertEquals("Unexpected terms found", expectedTerms.length, collector.terms.size()); } - @Test public void testNestedNearQuery() throws IOException { // near(w1, near(w2, or(w3, w4))) @@ -136,7 +134,6 @@ public void testNestedNearQuery() throws IOException { spans, collector, new Term(FIELD, "w1"), new Term(FIELD, "w2"), new Term(FIELD, "w3")); } - @Test public void testOrQuery() throws IOException { SpanTermQuery q2 = new SpanTermQuery(new Term(FIELD, "w2")); SpanTermQuery q3 = new SpanTermQuery(new Term(FIELD, "w3")); @@ -165,7 +162,6 @@ public void testOrQuery() throws IOException { checkCollectedTerms(spans, collector, new Term(FIELD, "w3")); } - @Test public void testSpanNotQuery() throws IOException { SpanTermQuery q1 = new SpanTermQuery(new Term(FIELD, "w1")); diff --git a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanMultiTermQueryWrapper.java b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanMultiTermQueryWrapper.java index f0dbaebac90f..58b79f697e6b 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanMultiTermQueryWrapper.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanMultiTermQueryWrapper.java @@ -30,7 +30,6 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** Tests for {@link SpanMultiTermQueryWrapper}, wrapping a few MultiTermQueries. */ public class TestSpanMultiTermQueryWrapper extends LuceneTestCase { @@ -223,7 +222,6 @@ public void testNoSuchMultiTermsInSpanFirst() throws Exception { assertEquals(0, searcher.count(spanFirst)); } - @Test public void testWrappedQueryIsNotModified() { final PrefixQuery pq = new PrefixQuery(new Term("field", "test")); int pqHash = pq.hashCode(); diff --git a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanWithinQuery.java b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanWithinQuery.java index 026081e02233..933afcd34e5c 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanWithinQuery.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestSpanWithinQuery.java @@ -29,7 +29,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Test; /** Basic tests for SpanWithinQuery */ public class TestSpanWithinQuery extends LuceneTestCase { @@ -118,7 +117,6 @@ public void testNoMatches() throws Exception { check(query, expectedDocs); } - @Test public void testDifferentFieldsThrowsIllegalArgumentException() { SpanQuery big = new SpanTermQuery(new Term("field1", "one")); SpanQuery little = new SpanTermQuery(new Term("field2", "two")); diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/core/builders/TestQueryTreeBuilder.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/core/builders/TestQueryTreeBuilder.java index e8e5fc5998dc..47bb7d2f381a 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/core/builders/TestQueryTreeBuilder.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/core/builders/TestQueryTreeBuilder.java @@ -23,11 +23,9 @@ import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax; import org.apache.lucene.queryparser.flexible.core.util.UnescapedCharSequence; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestQueryTreeBuilder extends LuceneTestCase { - @Test public void testSetFieldBuilder() throws QueryNodeException { QueryTreeBuilder qtb = new QueryTreeBuilder(); qtb.setBuilder("field", new DummyBuilder()); diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/core/util/TestUnescapedCharSequence.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/core/util/TestUnescapedCharSequence.java index 65f20415aa8b..346ea68eee3c 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/core/util/TestUnescapedCharSequence.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/core/util/TestUnescapedCharSequence.java @@ -18,12 +18,10 @@ import java.util.Locale; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestUnescapedCharSequence extends LuceneTestCase { private static final char[] wildcardChars = {'*', '?'}; - @Test public void testToStringEscaped() { char[] chars = {'a', 'b', 'c', '\\', 'e'}; boolean[] wasEscaped = {false, true, true, false, false}; @@ -33,7 +31,6 @@ public void testToStringEscaped() { assertTrue(sequence.wasEscaped(1)); } - @Test public void testToStringEscapedWithEnabledChars() { char[] chars = {'a', 'b', 'c', '?', '*'}; boolean[] wasEscaped = {true, true, true, true, true}; @@ -41,13 +38,11 @@ public void testToStringEscapedWithEnabledChars() { assertEquals("abc\\?\\*", sequence.toStringEscaped(wildcardChars)); } - @Test public void testSubSequence() { UnescapedCharSequence sequence = new UnescapedCharSequence("abcdef"); assertEquals("bc", sequence.subSequence(1, 3).toString()); } - @Test public void testToLowerCase() { UnescapedCharSequence sequence = new UnescapedCharSequence("ABC"); assertEquals( diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestStandardQPEnhancements.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestStandardQPEnhancements.java index 5bc09a89bb28..4c435cace412 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestStandardQPEnhancements.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestStandardQPEnhancements.java @@ -31,7 +31,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; -import org.junit.Test; /** Test interval sub-query support in {@link StandardQueryParser}. */ public class TestStandardQPEnhancements extends LuceneTestCase { @@ -53,7 +52,6 @@ protected TokenStreamComponents createComponents(String fieldName) { return qp; } - @Test public void testMinShouldMatchOperator() throws Exception { Query parsed = parsedQuery( @@ -68,42 +66,34 @@ public void testMinShouldMatchOperator() throws Exception { ((BooleanQuery) parsed).getMinimumNumberShouldMatch(), Matchers.equalTo(2)); } - @Test public void testAtLeast() throws Exception { checkIntervalQueryNode("fn:atleast(3 FOO BAR baz)"); } - @Test public void testMaxWidth() throws Exception { checkIntervalQueryNode("fn:maxwidth(3 fn:atleast(2 foo bar baz))"); } - @Test public void testQuotedTerm() throws Exception { checkIntervalQueryNode("fn:atleast(2 \"foo\" \"BAR baz\")"); } - @Test public void testMaxGaps() throws Exception { checkIntervalQueryNode("fn:maxgaps(2 fn:unordered(foo BAR baz))"); } - @Test public void testOrdered() throws Exception { checkIntervalQueryNode("fn:ordered(foo BAR baz)"); } - @Test public void testUnordered() throws Exception { checkIntervalQueryNode("fn:unordered(foo BAR baz)"); } - @Test public void testOr() throws Exception { checkIntervalQueryNode("fn:or(foo baz)"); } - @Test public void testWildcard() throws Exception { checkIntervalQueryNode("fn:wildcard(foo*)"); @@ -111,72 +101,58 @@ public void testWildcard() throws Exception { checkIntervalQueryNode("fn:wildcard(foo* 128)"); } - @Test public void testPhrase() throws Exception { checkIntervalQueryNode("fn:phrase(abc def fn:or(baz boo))"); } - @Test public void testBefore() throws Exception { checkIntervalQueryNode("fn:before(abc fn:ordered(foo bar))"); } - @Test public void testAfter() throws Exception { checkIntervalQueryNode("fn:after(abc fn:ordered(foo bar))"); } - @Test public void testContaining() throws Exception { checkIntervalQueryNode("fn:containing(big small)"); } - @Test public void testContainedBy() throws Exception { checkIntervalQueryNode("fn:containedBy(small big)"); } - @Test public void testNotContaining() throws Exception { checkIntervalQueryNode("fn:notContaining(minuend subtrahend)"); } - @Test public void testNotContainedBy() throws Exception { checkIntervalQueryNode("fn:notContainedBy(small big)"); } - @Test public void testWithin() throws Exception { checkIntervalQueryNode("fn:within(small 2 fn:ordered(big foo))"); } - @Test public void testNotWithin() throws Exception { checkIntervalQueryNode("fn:notWithin(small 2 fn:ordered(big foo))"); } - @Test public void testOverlapping() throws Exception { checkIntervalQueryNode("fn:overlapping(fn:ordered(big foo) small)"); } - @Test public void testNonOverlapping() throws Exception { checkIntervalQueryNode("fn:nonOverlapping(fn:ordered(big foo) small)"); } - @Test public void testUnorderedNoOverlaps() throws Exception { checkIntervalQueryNode("fn:unorderedNoOverlaps(fn:ordered(big foo) small)"); } - @Test public void testExtend() throws Exception { checkIntervalQueryNode("fn:extend(fn:ordered(big foo) 2 5)"); } - @Test public void testFuzzy() throws Exception { checkIntervalQueryNode("fn:fuzzyTerm(dfe)"); // Explicit maxEdits diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/surround/query/TestSrndQuery.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/surround/query/TestSrndQuery.java index 1dd8419bc93e..b2795262062f 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/surround/query/TestSrndQuery.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/surround/query/TestSrndQuery.java @@ -20,7 +20,6 @@ import org.apache.lucene.search.Query; import org.apache.lucene.tests.search.QueryUtils; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** */ public class TestSrndQuery extends LuceneTestCase { @@ -34,7 +33,6 @@ void checkEqualParsings(String s1, String s2) throws Exception { QueryUtils.checkEqual(lq1, lq2); } - @Test public void testHashEquals() throws Exception { // grab some sample queries from Test02Boolean and Test03Distance and // check there hashes and equals diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestDistanceStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestDistanceStrategy.java index 31212621e4a6..651648aa882f 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestDistanceStrategy.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestDistanceStrategy.java @@ -30,7 +30,6 @@ import org.apache.lucene.spatial.serialized.SerializedDVStrategy; import org.apache.lucene.spatial.vector.PointVectorStrategy; import org.apache.lucene.util.ArrayUtil; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Point; import org.locationtech.spatial4j.shape.Shape; @@ -79,7 +78,6 @@ public TestDistanceStrategy(String suiteName, SpatialStrategy strategy) { this.strategy = strategy; } - @Test public void testDistanceOrder() throws IOException { ShapeFactory shapeFactory = ctx.getShapeFactory(); adoc("100", shapeFactory.pointXY(2, 1)); @@ -91,7 +89,6 @@ public void testDistanceOrder() throws IOException { checkDistValueSource(shapeFactory.pointXY(0, 4), 3.6043684f, 0.9975641f, 180f); } - @Test public void testRecipScore() throws IOException { Point p100 = ctx.getShapeFactory().pointXY(2.02, 0.98); adoc("100", p100); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestPortedSolr3.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestPortedSolr3.java index b2fad42d385a..0f4dc4f85475 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestPortedSolr3.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestPortedSolr3.java @@ -30,7 +30,6 @@ import org.apache.lucene.spatial.query.SpatialArgs; import org.apache.lucene.spatial.query.SpatialOperation; import org.apache.lucene.spatial.vector.PointVectorStrategy; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.distance.DistanceUtils; import org.locationtech.spatial4j.shape.Point; @@ -95,7 +94,6 @@ private void setupDocs() throws Exception { commit(); } - @Test public void testIntersections() throws Exception { setupDocs(); // Try some edge cases diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestQueryEqualsHashCode.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestQueryEqualsHashCode.java index 3f140ec26f01..59196de0ec41 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestQueryEqualsHashCode.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestQueryEqualsHashCode.java @@ -30,7 +30,6 @@ import org.apache.lucene.spatial.serialized.SerializedDVStrategy; import org.apache.lucene.spatial.vector.PointVectorStrategy; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Shape; @@ -40,7 +39,6 @@ public class TestQueryEqualsHashCode extends LuceneTestCase { private SpatialOperation predicate; - @Test public void testEqualsHashCode() { switch (random().nextInt(4)) { // 0-3 diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestTestFramework.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestTestFramework.java index 5cf491870e46..1b4c38354d73 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestTestFramework.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestTestFramework.java @@ -32,7 +32,6 @@ /** Make sure we are reading the tests as expected */ public class TestTestFramework extends LuceneTestCase { - @Test public void testQueries() throws IOException { String name = StrategyTestCase.QTEST_Cities_Intersects_BBox; diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java index b9d33847a96f..75f8326acda4 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java @@ -26,7 +26,6 @@ import org.apache.lucene.spatial.query.SpatialOperation; import org.apache.lucene.spatial.util.ShapeAreaValueSource; import org.junit.Ignore; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.context.SpatialContextFactory; import org.locationtech.spatial4j.distance.DistanceUtils; @@ -80,7 +79,6 @@ protected Shape randomQueryShape() { return randomIndexedShape(); } - @Test public void testOperations() throws IOException { // setup if (random().nextInt(4) > 0) { // 75% of the time choose geo (more interesting to test) @@ -107,7 +105,6 @@ public void testOperations() throws IOException { } } - @Test public void testIntersectsBugDatelineEdge() throws IOException { setupGeo(); testOperation( @@ -117,7 +114,6 @@ public void testIntersectsBugDatelineEdge() throws IOException { true); } - @Test public void testIntersectsWorldDatelineEdge() throws IOException { setupGeo(); testOperation( @@ -127,7 +123,6 @@ public void testIntersectsWorldDatelineEdge() throws IOException { true); } - @Test public void testWithinBugDatelineEdge() throws IOException { setupGeo(); testOperation( @@ -137,7 +132,6 @@ public void testWithinBugDatelineEdge() throws IOException { true); } - @Test public void testContainsBugDatelineEdge() throws IOException { setupGeo(); testOperation( @@ -147,7 +141,6 @@ public void testContainsBugDatelineEdge() throws IOException { true); } - @Test public void testWorldContainsXDL() throws IOException { setupGeo(); testOperation( @@ -158,7 +151,6 @@ public void testWorldContainsXDL() throws IOException { } /** See https://github.com/spatial4j/spatial4j/issues/85 */ - @Test public void testAlongDatelineOppositeSign() throws IOException { // Due to Spatial4j bug #85, we can't simply do: // testOperation(indexedShape, @@ -189,7 +181,6 @@ private void setupGeo() { // OLD STATIC TESTS (worthless?) - @Test @Ignore("Overlaps not supported") public void testBasicOperaions() throws IOException { setupGeo(); @@ -198,7 +189,6 @@ public void testBasicOperaions() throws IOException { executeQueries(SpatialMatchConcern.EXACT, QTEST_Simple_Queries_BBox); } - @Test public void testStatesBBox() throws IOException { setupGeo(); getAddAndVerifyIndexedDocuments(DATA_STATES_BBOX); @@ -207,7 +197,6 @@ public void testStatesBBox() throws IOException { executeQueries(SpatialMatchConcern.FILTER, QTEST_States_Intersects_BBox); } - @Test public void testCitiesIntersectsBBox() throws IOException { setupGeo(); getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/TestCompositeStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/TestCompositeStrategy.java index 19abb86f7e4e..b4aaef8eef64 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/TestCompositeStrategy.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/TestCompositeStrategy.java @@ -28,7 +28,6 @@ import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree; import org.apache.lucene.spatial.query.SpatialOperation; import org.apache.lucene.spatial.serialized.SerializedDVStrategy; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.context.SpatialContextFactory; import org.locationtech.spatial4j.shape.Point; @@ -71,7 +70,6 @@ protected RecursivePrefixTreeStrategy newRPT() { return rpt; } - @Test public void testOperations() throws IOException { // setup if (randomBoolean()) { diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestDateNRStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestDateNRStrategy.java index ad6e36dc42ed..1133895d3bde 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestDateNRStrategy.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestDateNRStrategy.java @@ -26,7 +26,6 @@ import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape; import org.apache.lucene.spatial.query.SpatialOperation; import org.junit.Before; -import org.junit.Test; import org.locationtech.spatial4j.shape.Shape; public class TestDateNRStrategy extends RandomSpatialOpStrategyTestCase { @@ -50,31 +49,26 @@ public void setUp() throws Exception { randomCalWindowMs = Math.max(2000L, tmpCal.getTimeInMillis()); } - @Test @Repeat(iterations = ITERATIONS) public void testIntersects() throws IOException { testOperationRandomShapes(SpatialOperation.Intersects); } - @Test @Repeat(iterations = ITERATIONS) public void testWithin() throws IOException { testOperationRandomShapes(SpatialOperation.IsWithin); } - @Test @Repeat(iterations = ITERATIONS) public void testContains() throws IOException { testOperationRandomShapes(SpatialOperation.Contains); } - @Test public void testWithinSame() throws IOException { Shape shape = randomIndexedShape(); testOperation(shape, SpatialOperation.IsWithin, shape, true); // is within itself } - @Test public void testWorld() throws IOException { ((NumberRangePrefixTreeStrategy) strategy).setPointsOnly(false); testOperation( @@ -84,7 +78,6 @@ public void testWorld() throws IOException { true); } - @Test public void testBugInitIterOptimization() throws Exception { ((NumberRangePrefixTreeStrategy) strategy).setPointsOnly(false); // bug due to fast path initIter() optimization @@ -95,7 +88,6 @@ public void testBugInitIterOptimization() throws Exception { true); } - @Test public void testLastMillionYearPeriod() throws Exception { testOperation( tree.parseShape( diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestHeatmapFacetCounter.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestHeatmapFacetCounter.java index edebc495df8c..6ba025d321c9 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestHeatmapFacetCounter.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestHeatmapFacetCounter.java @@ -30,7 +30,6 @@ import org.apache.lucene.util.Bits; import org.junit.After; import org.junit.Before; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.context.SpatialContextFactory; import org.locationtech.spatial4j.distance.DistanceUtils; @@ -70,7 +69,6 @@ public void after() { "Validated " + cellsValidated + " cells, " + cellValidatedNonZero + " non-zero"); } - @Test public void testStatic() throws IOException { // Some specific tests (static, not random). adoc("0", shapeFactory.rect(179.8, -170, -90, -80)); // barely crosses equator @@ -86,7 +84,6 @@ public void testStatic() throws IOException { // add specific tests if we find a bug. } - @Test public void testLucene7291Dateline() throws IOException { grid = new QuadPrefixTree(ctx, 2); // only 2, and we wind up with some big leaf cells strategy = new RecursivePrefixTreeStrategy(grid, getTestClass().getSimpleName()); @@ -95,7 +92,6 @@ public void testLucene7291Dateline() throws IOException { validateHeatmapResultLoop(shapeFactory.rect(179, -179, 62, 63), 2, 100); // HM crosses dateline } - @Test public void testQueryCircle() throws IOException { // overwrite setUp; non-geo bounds is more straight-forward; otherwise 88,88 would actually be // practically north, @@ -162,7 +158,6 @@ private void validateHeatmapResultLoop( } } - @Test @Repeat(iterations = 20) public void testRandom() throws IOException { // Tests using random index shapes & query shapes. This has found all sorts of edge case bugs diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestJtsPolygon.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestJtsPolygon.java index 62099e905455..0b54141b8679 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestJtsPolygon.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestJtsPolygon.java @@ -31,7 +31,6 @@ import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree; import org.apache.lucene.spatial.query.SpatialArgs; import org.apache.lucene.spatial.query.SpatialOperation; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContextFactory; import org.locationtech.spatial4j.shape.Point; import org.locationtech.spatial4j.shape.Shape; @@ -58,7 +57,6 @@ public TestJtsPolygon() { .setDistErrPct(LUCENE_4464_distErrPct); // 1% radius (small!) } - @Test /* LUCENE-4464 */ public void testCloseButNoMatch() throws Exception { getAddAndVerifyIndexedDocuments("LUCENE-4464.txt"); @@ -86,7 +84,6 @@ private SpatialArgs q(String shapeStr, double distErrPct) throws ParseException * A PrefixTree pruning optimization gone bad. See LUCENE-4770. */ - @Test public void testBadPrefixTreePrune() throws Exception { Shape area = diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestNumberRangeFacets.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestNumberRangeFacets.java index 168319f0f33c..5512b49a0d8f 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestNumberRangeFacets.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestNumberRangeFacets.java @@ -37,7 +37,6 @@ import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.junit.Before; -import org.junit.Test; import org.locationtech.spatial4j.shape.Shape; public class TestNumberRangeFacets extends StrategyTestCase { @@ -61,7 +60,6 @@ public void setUp() throws Exception { } @Repeat(iterations = 20) - @Test public void test() throws IOException { // generate test data List indexedShapes = new ArrayList<>(); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRandomSpatialOpFuzzyPrefixTree.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRandomSpatialOpFuzzyPrefixTree.java index d9d65ac60cda..c9d7e0dbe329 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRandomSpatialOpFuzzyPrefixTree.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRandomSpatialOpFuzzyPrefixTree.java @@ -50,7 +50,6 @@ import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree; import org.apache.lucene.spatial.query.SpatialArgs; import org.apache.lucene.spatial.query.SpatialOperation; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.context.SpatialContextFactory; import org.locationtech.spatial4j.shape.Point; @@ -127,28 +126,24 @@ protected RecursivePrefixTreeStrategy newRPT() { return new RecursivePrefixTreeStrategy(this.grid, getClass().getSimpleName()); } - @Test @Repeat(iterations = ITERATIONS) public void testIntersects() throws IOException { setupGrid(-1); doTest(SpatialOperation.Intersects); } - @Test @Repeat(iterations = ITERATIONS) public void testWithin() throws IOException { setupGrid(-1); doTest(SpatialOperation.IsWithin); } - @Test @Repeat(iterations = ITERATIONS) public void testContains() throws IOException { setupGrid(-1); doTest(SpatialOperation.Contains); } - @Test public void testPackedQuadPointsOnlyBug() throws IOException { setupQuadGrid(1, true); // packed quad. maxLevels doesn't matter. setupCtx2D(ctx); @@ -160,7 +155,6 @@ public void testPackedQuadPointsOnlyBug() throws IOException { assertEquals(1, executeQuery(query, 1).numFound); } - @Test public void testPointsOnlyOptBug() throws IOException { setupQuadGrid(8, false); setupCtx2D(ctx); @@ -175,7 +169,6 @@ public void testPointsOnlyOptBug() throws IOException { } /** See LUCENE-5062, {@link ContainsPrefixTreeQuery#multiOverlappingIndexedShapes}. */ - @Test public void testContainsPairOverlap() throws IOException { setupQuadGrid(3, randomBoolean()); adoc( @@ -190,7 +183,6 @@ public void testContainsPairOverlap() throws IOException { assertEquals(1, searchResults.numFound); } - @Test public void testWithinDisjointParts() throws IOException { setupQuadGrid(7, randomBoolean()); // one shape comprised of two parts, quite separated apart @@ -208,7 +200,6 @@ public void testWithinDisjointParts() throws IOException { assertTrue(searchResults.numFound == 0); } - @Test /* LUCENE-4916 */ public void testWithinLeafApproxRule() throws IOException { setupQuadGrid(2, randomBoolean()); // 4x4 grid @@ -242,7 +233,6 @@ public void testWithinLeafApproxRule() throws IOException { == 1); // match } - @Test public void testShapePair() { ctx = SpatialContext.GEO; setupCtx2D(ctx); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java index c9ac5fccef63..956806b57f62 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java @@ -25,7 +25,6 @@ import org.apache.lucene.spatial.query.SpatialArgs; import org.apache.lucene.spatial.query.SpatialOperation; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.distance.DistanceUtils; import org.locationtech.spatial4j.shape.Point; @@ -44,7 +43,6 @@ private void init(int maxLength) { this.strategy = new RecursivePrefixTreeStrategy(grid, getClass().getSimpleName()); } - @Test public void testFilterWithVariableScanLevel() throws IOException { init(GeohashPrefixTree.getMaxLevelsPossible()); getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS); @@ -56,7 +54,6 @@ public void testFilterWithVariableScanLevel() throws IOException { } } - @Test public void testOneMeterPrecision() { init(GeohashPrefixTree.getMaxLevelsPossible()); GeohashPrefixTree grid = (GeohashPrefixTree) ((RecursivePrefixTreeStrategy) strategy).getGrid(); @@ -65,7 +62,6 @@ public void testOneMeterPrecision() { assertEquals(11, grid.getLevelForDistance(degrees)); } - @Test public void testPrecision() throws IOException { init(GeohashPrefixTree.getMaxLevelsPossible()); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java index 5f0d8b30bbbc..b07fbfb62876 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java @@ -24,13 +24,11 @@ import org.apache.lucene.document.StringField; import org.apache.lucene.spatial.SpatialTestCase; import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Shape; public class TestTermQueryPrefixGridStrategy extends SpatialTestCase { - @Test public void testNGramPrefixGridLosAngeles() throws IOException { SpatialContext ctx = SpatialContext.GEO; TermQueryPrefixTreeStrategy prefixGridStrategy = diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestS2PrefixTree.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestS2PrefixTree.java index 97d50884e331..c5fe3d7cb2c5 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestS2PrefixTree.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestS2PrefixTree.java @@ -23,14 +23,12 @@ import org.apache.lucene.spatial.spatial4j.Geo3dSpatialContextFactory; import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.BytesRef; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Point; /** Test for S2 Spatial prefix tree. */ public class TestS2PrefixTree extends LuceneTestCase { - @Test @Repeat(iterations = 10) public void testCells() { int face = random().nextInt(6); @@ -69,7 +67,6 @@ public void testCells() { assertEquals(cell, cell2); } - @Test @Repeat(iterations = 10) public void testDistanceAndLevels() { S2PrefixTree tree = @@ -98,7 +95,6 @@ public void testDistanceAndLevels() { assertTrue(randomDist > distanceLevel); } - @Test @Repeat(iterations = 10) public void testPrecision() { int arity = random().nextInt(3) + 1; diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestSpatialPrefixTree.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestSpatialPrefixTree.java index 9fcd5df0b977..46ae258fa741 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestSpatialPrefixTree.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestSpatialPrefixTree.java @@ -30,7 +30,6 @@ import org.apache.lucene.spatial.query.SpatialArgs; import org.apache.lucene.spatial.query.SpatialOperation; import org.junit.Before; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Point; import org.locationtech.spatial4j.shape.Rectangle; @@ -49,7 +48,6 @@ public void setUp() throws Exception { ctx = SpatialContext.GEO; } - @Test public void testCellTraverse() { trie = new GeohashPrefixTree(ctx, 4); @@ -79,7 +77,6 @@ public void testCellTraverse() { * A PrefixTree pruning optimization gone bad, applicable when optimize=true. See LUCENE-4770. */ - @Test public void testBadPrefixTreePrune() throws Exception { trie = new QuadPrefixTree(ctx, 12); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/query/TestSpatialArgsParser.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/query/TestSpatialArgsParser.java index 23e8e6a3877c..a6239a8965eb 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/query/TestSpatialArgsParser.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/query/TestSpatialArgsParser.java @@ -18,7 +18,6 @@ import java.text.ParseException; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Rectangle; @@ -30,7 +29,6 @@ public class TestSpatialArgsParser extends LuceneTestCase { // The args parser is only dependent on the ctx for IO so I don't care to test // with other implementations. - @Test public void testArgsParser() throws Exception { SpatialArgsParser parser = new SpatialArgsParser(); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/TestSerializedStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/TestSerializedStrategy.java index b1ea3adbb57c..439eef751b52 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/TestSerializedStrategy.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/TestSerializedStrategy.java @@ -20,7 +20,6 @@ import org.apache.lucene.spatial.SpatialMatchConcern; import org.apache.lucene.spatial.StrategyTestCase; import org.junit.Before; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; public class TestSerializedStrategy extends StrategyTestCase { @@ -33,14 +32,12 @@ public void setUp() throws Exception { this.strategy = new SerializedDVStrategy(ctx, "serialized"); } - @Test public void testBasicOperaions() throws IOException { getAddAndVerifyIndexedDocuments(DATA_SIMPLE_BBOX); executeQueries(SpatialMatchConcern.EXACT, QTEST_Simple_Queries_BBox); } - @Test public void testStatesBBox() throws IOException { getAddAndVerifyIndexedDocuments(DATA_STATES_BBOX); @@ -48,7 +45,6 @@ public void testStatesBBox() throws IOException { executeQueries(SpatialMatchConcern.FILTER, QTEST_States_Intersects_BBox); } - @Test public void testCitiesIntersectsBBox() throws IOException { getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/ShapeRectRelationTestCase.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/ShapeRectRelationTestCase.java index d5b5942ae80f..992f228e8f73 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/ShapeRectRelationTestCase.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/ShapeRectRelationTestCase.java @@ -19,7 +19,6 @@ import static org.locationtech.spatial4j.distance.DistanceUtils.DEGREES_TO_RADIANS; import org.junit.Rule; -import org.junit.Test; import org.locationtech.spatial4j.TestLog; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Circle; @@ -76,7 +75,6 @@ protected int getBoundingMinimum(int laps) { } } - @Test public void testGeoCircleRect() { new AbstractRectIntersectionTestHelper(ctx) { @@ -93,7 +91,6 @@ protected Point randomPointInEmptyShape(Shape shape) { }.testRelateWithRectangle(); } - @Test public void testGeoBBoxRect() { new AbstractRectIntersectionTestHelper(ctx) { @@ -123,7 +120,6 @@ protected Point randomPointInEmptyShape(Shape shape) { } // very slow, and test sources are not here, so no clue how to fix - @Test public void testGeoPolygonRect() { new AbstractRectIntersectionTestHelper(ctx) { @@ -164,7 +160,6 @@ protected int getWithinMinimum(int laps) { }.testRelateWithRectangle(); } - @Test public void testGeoPathRect() { new AbstractRectIntersectionTestHelper(ctx) { diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3d.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3d.java index aaab077fc543..942f51dca929 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3d.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3d.java @@ -18,14 +18,12 @@ package org.apache.lucene.spatial.spatial4j; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.exception.InvalidShapeException; import org.locationtech.spatial4j.shape.Shape; public class TestGeo3d extends LuceneTestCase { - @Test public void testWKT() throws Exception { Geo3dSpatialContextFactory factory = new Geo3dSpatialContextFactory(); SpatialContext ctx = factory.newSpatialContext(); @@ -65,7 +63,6 @@ public void testWKT() throws Exception { // assertTrue(s instanceof Geo3dShape); } - @Test public void testPolygonWithCoplanarPoints() { Geo3dSpatialContextFactory factory = new Geo3dSpatialContextFactory(); SpatialContext ctx = factory.newSpatialContext(); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dRpt.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dRpt.java index e7b06e10cd60..18b752672401 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dRpt.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dRpt.java @@ -42,7 +42,6 @@ import org.apache.lucene.spatial3d.geom.GeoPointShape; import org.apache.lucene.spatial3d.geom.GeoPolygonFactory; import org.apache.lucene.spatial3d.geom.PlanetModel; -import org.junit.Test; import org.locationtech.spatial4j.shape.Rectangle; import org.locationtech.spatial4j.shape.Shape; @@ -88,7 +87,6 @@ private void setupStrategy() { "composite_" + getClass().getSimpleName(), rptStrategy, serializedDVStrategy); } - @Test public void testFailure1() throws IOException { setupStrategy(); final List points = new ArrayList<>(); @@ -103,7 +101,6 @@ public void testFailure1() throws IOException { testOperation(rect, SpatialOperation.Intersects, triangle, false); } - @Test public void testFailureLucene6535() throws IOException { setupStrategy(); @@ -126,7 +123,6 @@ public void testFailureLucene6535() throws IOException { testOperation(rect, SpatialOperation.Intersects, shape, true); } - @Test public void testOperations() throws IOException { setupStrategy(); @@ -152,7 +148,6 @@ protected Shape randomQueryShape() { // TODO: incredibly slow @Nightly - @Test public void testOperationsFromFile() throws IOException { setupStrategy(); final Iterator indexedSpatialData = getSampleData("states-poly.txt"); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dShapeSphereModelRectRelation.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dShapeSphereModelRectRelation.java index 82d47117bb86..7c1e3fb28fb2 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dShapeSphereModelRectRelation.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dShapeSphereModelRectRelation.java @@ -43,7 +43,6 @@ public TestGeo3dShapeSphereModelRectRelation() { this.ctx = factory.newSpatialContext(); } - @Test public void testFailure1() { final GeoBBox rect = GeoBBoxFactory.makeGeoBBox( @@ -81,7 +80,6 @@ public void testFailure1() { assertFalse(rect.isWithin(point)); } - @Test public void testFailure2_LUCENE6475() { GeoCircle geo3dCircle = GeoCircleFactory.makeGeoCircle( diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dShapeWGS84ModelRectRelation.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dShapeWGS84ModelRectRelation.java index 096d4b715a98..7540c85f2387 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dShapeWGS84ModelRectRelation.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/TestGeo3dShapeWGS84ModelRectRelation.java @@ -45,7 +45,6 @@ public TestGeo3dShapeWGS84ModelRectRelation() { ((Geo3dShapeFactory) ctx.getShapeFactory()).setCircleAccuracy(1e-12); } - @Test public void testFailure1() { final GeoBBox rect = GeoBBoxFactory.makeGeoBBox( @@ -68,7 +67,6 @@ public void testFailure1() { // assertFalse(GeoArea.DISJOINT == rect.getRelationship(bbox)); } - @Test public void testFailure2() { final GeoBBox rect = GeoBBoxFactory.makeGeoBBox( @@ -90,7 +88,6 @@ public void testFailure2() { // assertFalse(GeoArea.DISJOINT == rect.getRelationship(bbox)); } - @Test public void testFailure3() { /* * [junit4] 1> S-R Rel: {}, Shape {}, Rectangle {} lap# {} [CONTAINS, Geo3dShape{planetmodel=PlanetModel: {xyScaling=1.0011188180710464, zScaling=0.9977622539852008}, shape=GeoPath: {planetmodel=PlanetModel: {xyScaling=1.0011188180710464, zScaling=0.9977622539852008}, width=1.53588974175501(87.99999999999999), diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java index 0e6ef3f16f22..6a0ecda96faf 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java @@ -27,7 +27,6 @@ import org.apache.lucene.spatial.query.SpatialArgs; import org.apache.lucene.spatial.query.SpatialOperation; import org.junit.Before; -import org.junit.Test; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Circle; import org.locationtech.spatial4j.shape.Point; @@ -41,7 +40,6 @@ public void setUp() throws Exception { this.ctx = SpatialContext.GEO; } - @Test public void testCircleShapeSupport() { this.strategy = PointVectorStrategy.newInstance(ctx, getClass().getSimpleName()); Circle circle = ctx.makeCircle(ctx.makePoint(0, 0), 10); @@ -51,7 +49,6 @@ public void testCircleShapeSupport() { assertNotNull(query); } - @Test public void testInvalidQueryShape() { this.strategy = PointVectorStrategy.newInstance(ctx, getClass().getSimpleName()); Point point = ctx.makePoint(0, 0); @@ -59,7 +56,6 @@ public void testInvalidQueryShape() { expectThrows(UnsupportedOperationException.class, () -> this.strategy.makeQuery(args)); } - @Test public void testCitiesIntersectsBBox() throws IOException { // note: does not require docValues this.strategy = PointVectorStrategy.newInstance(ctx, getClass().getSimpleName()); @@ -67,7 +63,6 @@ public void testCitiesIntersectsBBox() throws IOException { executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox); } - @Test public void testFieldOptions() throws IOException, ParseException { // It's not stored; test it isn't. this.strategy = PointVectorStrategy.newInstance(ctx, getClass().getSimpleName()); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestCompositeGeoPolygonRelationships.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestCompositeGeoPolygonRelationships.java index 5e8b9846646c..d743cb73a7f0 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestCompositeGeoPolygonRelationships.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestCompositeGeoPolygonRelationships.java @@ -21,7 +21,6 @@ import java.util.Collections; import java.util.List; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** * Check relationship between polygon and GeoShapes of composite polygons. Normally we construct the @@ -29,7 +28,6 @@ */ public class TestCompositeGeoPolygonRelationships extends LuceneTestCase { - @Test public void testGeoCompositePolygon1() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -91,7 +89,6 @@ public void testGeoCompositePolygon1() { assertEquals(GeoArea.OVERLAPS, rel); } - @Test public void testGeoCompositePolygon2() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -154,7 +151,6 @@ public void testGeoCompositePolygon2() { assertEquals(GeoArea.OVERLAPS, rel); } - @Test public void testGeoCompositePolygon3() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -217,7 +213,6 @@ public void testGeoCompositePolygon3() { assertEquals(GeoArea.OVERLAPS, rel); } - @Test public void testGeoCompositePolygon4() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -280,7 +275,6 @@ public void testGeoCompositePolygon4() { assertEquals(GeoArea.WITHIN, rel); } - @Test public void testGeoCompositePolygon5() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -341,7 +335,6 @@ public void testGeoCompositePolygon5() { assertEquals(GeoArea.OVERLAPS, rel); } - @Test public void testGeoCompositePolygon6() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -402,7 +395,6 @@ public void testGeoCompositePolygon6() { assertEquals(GeoArea.CONTAINS, rel); } - @Test public void testGeoCompositePolygon7() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -465,7 +457,6 @@ public void testGeoCompositePolygon7() { assertEquals(GeoArea.OVERLAPS, rel); } - @Test public void testGeoCompositePolygon8() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -489,7 +480,6 @@ public void testGeoCompositePolygon8() { assertEquals(GeoArea.WITHIN, rel); } - @Test public void testGeoPolygonPole1() { // POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80)) GeoPolygon compositePol = getCompositePolygon(); @@ -523,7 +513,6 @@ public void testGeoPolygonPole1() { assertEquals(GeoArea.WITHIN, rel); } - @Test public void testGeoPolygonPole2() { // POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80)) GeoPolygon compositePol = getCompositePolygon(); @@ -555,7 +544,6 @@ public void testGeoPolygonPole2() { assertEquals(GeoArea.OVERLAPS, rel); } - @Test public void testGeoPolygonPole3() { // POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80)) GeoPolygon compositePol = getCompositePolygon(); @@ -587,7 +575,6 @@ public void testGeoPolygonPole3() { assertEquals(GeoArea.OVERLAPS, rel); } - @Test public void testMultiPolygon1() { // MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 // -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)), @@ -621,7 +608,6 @@ public void testMultiPolygon1() { assertEquals(false, polConcave.intersects(multiPol)); } - @Test public void testMultiPolygon2() { // MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 // -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)), @@ -652,7 +638,6 @@ public void testMultiPolygon2() { assertEquals(true, polConcave.intersects(multiPol)); } - @Test public void testMultiPolygon3() { // MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 // -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)), @@ -683,7 +668,6 @@ public void testMultiPolygon3() { assertEquals(false, polConcave.intersects(multiPol)); } - @Test public void testMultiPolygon4() { // MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 // -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)), @@ -714,7 +698,6 @@ public void testMultiPolygon4() { assertEquals(false, polConcave.intersects(multiPol)); } - @Test public void testMultiPolygon5() { // MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 // -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)), diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoBBox.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoBBox.java index 016d41a0aedb..0687aa66dd7b 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoBBox.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoBBox.java @@ -20,13 +20,11 @@ import java.util.List; import org.apache.lucene.tests.geo.GeoTestUtil; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestGeoBBox extends LuceneTestCase { protected static final double DEGREES_TO_RADIANS = Math.PI / 180.0; - @Test public void testBBoxDegenerate() { GeoBBox box; int relationship; @@ -58,7 +56,6 @@ public void testBBoxDegenerate() { assertEquals(GeoArea.CONTAINS, relationship); } - @Test public void testBBoxPointWithin() { GeoBBox box; GeoPoint gp; @@ -123,7 +120,6 @@ public void testBBoxPointWithin() { assertTrue(box.isWithin(gp)); } - @Test public void testBBoxExpand() { GeoBBox box; GeoPoint gp; @@ -148,7 +144,6 @@ public void testBBoxExpand() { assertFalse(box.isWithin(gp)); } - @Test public void testBBoxBounds() { GeoBBox c; LatLonBounds b; @@ -427,7 +422,6 @@ public void testBBoxBounds() { } - @Test public void testFailureCase1() { final GeoPoint point = new GeoPoint(-0.017413370801260174, -2.132522881412925E-18, 0.9976113450663769); @@ -449,7 +443,6 @@ public void testFailureCase1() { assertTrue(box.isWithin(point) ? solid.isWithin(point) : true); } - @Test public void testFailureCase2() { // final GeoPoint point = new GeoPoint(-0.7375647084975573, -2.3309121299774915E-10, // 0.6746626163258577); @@ -482,7 +475,6 @@ public void testFailureCase2() { assertTrue(box.isWithin(point) == solid.isWithin(point)); } - @Test public void testLUCENE10508() { double minX = Geo3DUtil.fromDegrees(GeoTestUtil.nextLongitude()); double maxX = Geo3DUtil.fromDegrees(GeoTestUtil.nextLongitude()); @@ -491,7 +483,6 @@ public void testLUCENE10508() { assertNotNull(GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, maxY, minY, minX, maxX)); } - @Test public void testBBoxRandomDegenerate() { for (int i = 0; i < 100; i++) { double minX = Geo3DUtil.fromDegrees(GeoTestUtil.nextLongitude()); @@ -502,7 +493,6 @@ public void testBBoxRandomDegenerate() { } } - @Test public void testBBoxLatDegenerate() { double minX = Geo3DUtil.fromDegrees(-180.0); double maxX = Geo3DUtil.fromDegrees(-174.37500008381903); @@ -511,7 +501,6 @@ public void testBBoxLatDegenerate() { assertNotNull(GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, maxY, minY, minX, maxX)); } - @Test public void testBBoxRandomLatDegenerate() { for (int i = 0; i < 100; i++) { double minX = Geo3DUtil.fromDegrees(GeoTestUtil.nextLongitude()); @@ -522,7 +511,6 @@ public void testBBoxRandomLatDegenerate() { } } - @Test public void testBBoxRandomLonDegenerate() { for (int i = 0; i < 100; i++) { double minX = Geo3DUtil.fromDegrees(GeoTestUtil.nextLongitude()); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoCircle.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoCircle.java index a29b6c37c7b1..f930df183701 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoCircle.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoCircle.java @@ -17,11 +17,9 @@ package org.apache.lucene.spatial3d.geom; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestGeoCircle extends LuceneTestCase { - @Test public void testCircleDistance() { GeoCircle c; GeoPoint gp; @@ -40,7 +38,6 @@ public void testCircleDistance() { assertEquals(0.049979, c.computeDistance(DistanceStyle.NORMAL, gp), 0.000001); } - @Test public void testCircleFullWorld() { GeoCircle c; GeoPoint gp; @@ -64,7 +61,6 @@ public void testCircleFullWorld() { assertTrue(b.checkNoBottomLatitudeBound()); } - @Test public void testCirclePointWithin() { GeoCircle c; GeoPoint gp; @@ -86,7 +82,6 @@ public void testCirclePointWithin() { assertFalse(c.isWithin(gp)); } - @Test public void testCircleBounds() { GeoCircle c; LatLonBounds b; @@ -510,7 +505,6 @@ public void testCircleBounds() { assertEquals(-0.4, b.getRightLongitude(), 0.00001); } - @Test public void testBoundsFailureCase1() { // lat=2.7399499693409367E-13, lon=-3.141592653589793([X=-1.0011188539924791, // Y=-1.226017000107956E-16, Z=2.743015573303327E-13])], radius=2.1814042682464985 @@ -539,7 +533,6 @@ public void testBoundsFailureCase1() { assertTrue(solid.isWithin(gp)); } - @Test public void testBoundsFailureCase2() { final GeoCircle gc = GeoCircleFactory.makeGeoCircle( @@ -562,7 +555,6 @@ public void testBoundsFailureCase2() { assert gc.isWithin(gp) ? solid.isWithin(gp) : true; } - @Test public void testWholeWorld() { final GeoCircle circle1 = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, 0.0, 3.1415926535897913); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoConvexPolygon.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoConvexPolygon.java index b03c7a1ad011..c3afc8fc73dc 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoConvexPolygon.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoConvexPolygon.java @@ -17,11 +17,9 @@ package org.apache.lucene.spatial3d.geom; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestGeoConvexPolygon extends LuceneTestCase { - @Test public void testPolygonPointWithin() { GeoConvexPolygon c; GeoPoint gp; @@ -62,7 +60,6 @@ public void testPolygonPointWithin() { assertFalse(c.isWithin(gp)); } - @Test public void testPolygonBounds() { GeoConvexPolygon c; LatLonBounds b; diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoExactCircle.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoExactCircle.java index ced5ed0ca23e..804d47e02cb1 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoExactCircle.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoExactCircle.java @@ -29,7 +29,6 @@ /** Tests for GeoExactCircle. */ public class TestGeoExactCircle extends LuceneTestCase { - @Test public void testExactCircle() { GeoCircle c; GeoPoint gp; @@ -56,7 +55,6 @@ public void testExactCircle() { assertTrue(c.isWithin(gp)); } - @Test public void testSurfacePointOnBearingScale() { PlanetModel p1 = PlanetModel.WGS84; PlanetModel p2 = @@ -128,7 +126,6 @@ private void checkBearingPoint( surfaceDistance - radius < Vector.MINIMUM_ANGULAR_RESOLUTION); } - @Test public void testExactCircleBounds() { GeoPoint center = new GeoPoint(PlanetModel.WGS84, 0, 0); @@ -161,7 +158,6 @@ public void exactCircleLargeTest() { }); } - @Test public void testExactCircleDoesNotFit() { expectThrows( IllegalArgumentException.class, @@ -194,7 +190,6 @@ public void testBigCircleInSphere() { * in LUCENE-8054 we have problems with exact circles that have edges that are close together. * This test creates those circles with the same center and slightly different radius. */ - @Test @Repeat(iterations = 100) public void testRandomLUCENE8054() { PlanetModel planetModel = randomPlanetModel(); @@ -217,7 +212,6 @@ public void testRandomLUCENE8054() { assertTrue(b.toString(), circle1.getRelationship(circle2) != GeoArea.DISJOINT); } - @Test public void testLUCENE8054() { GeoCircle circle1 = GeoCircleFactory.makeExactGeoCircle( @@ -239,7 +233,6 @@ public void testLUCENE8054() { assertTrue(rel != GeoArea.DISJOINT); } - @Test public void testLUCENE8056() { GeoCircle circle = GeoCircleFactory.makeExactGeoCircle( @@ -263,7 +256,6 @@ public void testLUCENE8056() { assertTrue(bBox.getRelationship(circle) == GeoArea.OVERLAPS); } - @Test public void testExactCircleLUCENE8054() { // [junit4] > Throwable #1: java.lang.AssertionError: circle1: GeoExactCircle: // {planetmodel=PlanetModel.WGS84, center=[lat=-1.2097332228999564, @@ -286,7 +278,6 @@ public void testExactCircleLUCENE8054() { assertTrue("cannot be disjoint", c1.getRelationship(c2) != GeoArea.DISJOINT); } - @Test public void testLUCENE8065() { // Circle planes are convex GeoCircle circle1 = diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoModel.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoModel.java index 3c3a02c3dda6..e128aeed079e 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoModel.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoModel.java @@ -17,14 +17,12 @@ package org.apache.lucene.spatial3d.geom; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** Test basic plane functionality. */ public class TestGeoModel extends LuceneTestCase { protected static final PlanetModel scaledModel = new PlanetModel(1.2, 1.5); - @Test public void testBasicCircle() { // The point of this test is just to make sure nothing blows up doing normal things with a quite // non-spherical model @@ -76,7 +74,6 @@ public void testBasicCircle() { assertEquals(0.0089, bounds.getRightLongitude(), 0.0001); } - @Test public void testBasicRectangle() { final GeoBBox bbox = GeoBBoxFactory.makeGeoBBox(scaledModel, 1.0, 0.0, 0.0, 1.0); final GeoPoint insidePoint = new GeoPoint(scaledModel, 0.5, 0.5); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPath.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPath.java index d3eec25bb02b..e14b3dce29fc 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPath.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPath.java @@ -17,11 +17,9 @@ package org.apache.lucene.spatial3d.geom; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestGeoPath extends LuceneTestCase { - @Test public void testPathDistance() { // Start with a really simple case GeoStandardPath p; @@ -74,7 +72,6 @@ public void testPathDistance() { assertEquals(0.0 + 0.05, p.computeDistance(DistanceStyle.ARC, gp), 0.000001); } - @Test public void test11956() { // Geo3D:GeoStandardPath: {planetmodel=PlanetModel.SPHERE, width=1.1344640137963142(65.0), // points={[[lat=-1.289777264488089, lon=3.0020962766211765([X=-0.2746408902222561, @@ -124,7 +121,6 @@ public void test11956() { // assertTrue(bounds.isWithin(gp)); } - @Test public void testPathPointWithin() { // Tests whether we can properly detect whether a point is within a path or not GeoStandardPath p; @@ -174,7 +170,6 @@ public void testPathPointWithin() { assertFalse(p.isWithin(gp)); } - @Test public void testGetRelationship() { GeoArea rect; GeoStandardPath p; @@ -228,7 +223,6 @@ public void testGetRelationship() { assertEquals(GeoArea.DISJOINT, rect.getRelationship(p)); } - @Test public void testPathBounds() { GeoStandardPath c; LatLonBounds b; @@ -332,7 +326,6 @@ public void testPathBounds() { assertEquals(0.3999999, b.getMaxLatitude(), 0.000001); } - @Test public void testCoLinear() { // p1: (12,-90), p2: (11, -55), (129, -90) GeoStandardPath p = new GeoStandardPath(PlanetModel.SPHERE, 0.1); @@ -342,7 +335,6 @@ public void testCoLinear() { p.done(); // at least test this doesn't bomb like it used too -- LUCENE-6520 } - @Test public void testFailure1() { /* GeoStandardPath: {planetmodel=PlanetModel.WGS84, width=1.117010721276371(64.0), points={[ @@ -384,7 +376,6 @@ public void testFailure1() { assertTrue(solid.isWithin(point)); } - @Test public void testInterpolation() { final double lat = 52.51607; final double lon = 13.37698; @@ -435,7 +426,6 @@ public void testInterpolation() { } - @Test public void testInterpolation2() { final double lat = 52.5665; final double lon = 13.3076; @@ -481,7 +471,6 @@ public void testInterpolation2() { assertEquals(oldFormulaDistance, distance, 1e-12); } - @Test public void testIdenticalPoints() { PlanetModel planetModel = PlanetModel.WGS84; GeoPoint point1 = new GeoPoint(planetModel, 1.5707963267948963, -2.4818290647609542E-148); @@ -504,7 +493,6 @@ public void testIdenticalPoints() { path = GeoPathFactory.makeGeoPath(planetModel, 0.5, new GeoPoint[] {point4, point5, point6}); } - @Test public void testLUCENE8696() { GeoPoint[] points = new GeoPoint[4]; points[0] = new GeoPoint(PlanetModel.WGS84, 2.4457272005608357E-47, 0.017453291479645996); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPoint.java index 027f7ae6edb4..1042784eb71a 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPoint.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPoint.java @@ -19,13 +19,11 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.randomFloat; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** Test basic GeoPoint functionality. */ public class TestGeoPoint extends LuceneTestCase { static final double DEGREES_TO_RADIANS = Math.PI / 180; - @Test public void testConversion() { testPointRoundTrip(PlanetModel.SPHERE, 90 * DEGREES_TO_RADIANS, 0, 1e-6); testPointRoundTrip(PlanetModel.SPHERE, -90 * DEGREES_TO_RADIANS, 0, 1e-6); @@ -56,7 +54,6 @@ protected void testPointRoundTrip( assertEquals(0, dist, epsilon); } - @Test public void testSurfaceDistance() { final int times = atLeast(100); for (int i = 0; i < times; i++) { @@ -99,7 +96,6 @@ public void testSurfaceDistance() { 1e-6); } - @Test public void testBisection() { final int times = atLeast(100); for (int i = 0; i < times; i++) { @@ -118,7 +114,6 @@ public void testBisection() { } } - @Test public void testBadLatLon() { expectThrows( IllegalArgumentException.class, diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPolygon.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPolygon.java index 8be2acb51ef4..bd51d342c1cf 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPolygon.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPolygon.java @@ -21,11 +21,9 @@ import java.util.Collections; import java.util.List; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestGeoPolygon extends LuceneTestCase { - @Test public void testH3CellsWrongIntersection() { final List points1 = new ArrayList<>(); addToList(points1, PlanetModel.SPHERE, -64.2102198418716, -39.14233318389477); @@ -52,7 +50,6 @@ private static void addToList( points.add(new GeoPoint(planetModel, Geo3DUtil.fromDegrees(lat), Geo3DUtil.fromDegrees(lon))); } - @Test public void testPolygonPointFiltering() { final GeoPoint point1 = new GeoPoint(PlanetModel.WGS84, 1.0, 2.0); final GeoPoint point2 = new GeoPoint(PlanetModel.WGS84, 0.5, 2.5); @@ -119,7 +116,6 @@ public void testPolygonPointFiltering() { } } - @Test public void testPolygonPointFiltering2() { // all coplanar GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, 1.1264101919629863, -0.9108307879480759); @@ -134,7 +130,6 @@ public void testPolygonPointFiltering2() { assertEquals(null, filteredPoints); } - @Test public void testPolygonClockwise() { GeoPolygon c; GeoPoint gp; @@ -184,7 +179,6 @@ public void testPolygonClockwise() { assertTrue(c.isWithin(gp)); } - @Test public void testPolygonIntersects() { GeoPolygon c; List points; @@ -277,7 +271,6 @@ public void testPolygonIntersects() { assertEquals(GeoArea.DISJOINT, xyzSolid.getRelationship(c)); } - @Test public void testPolygonPointWithin() { GeoPolygon c; GeoPoint gp; @@ -437,7 +430,6 @@ public void testPolygonPointWithin() { assertFalse(c.isWithin(gp)); } - @Test public void testPolygonBounds() { GeoMembershipShape c; LatLonBounds b; @@ -489,7 +481,6 @@ public void testPolygonBounds() { assertEquals(0.1, b.getMaxLatitude(), 0.000001); } - @Test public void testPolygonBoundsCase1() { GeoPolygon c; List points; @@ -536,7 +527,6 @@ public void testPolygonBoundsCase1() { assertTrue(area.isWithin(point2)); } - @Test public void testGeoPolygonBoundsCase2() { // [junit4] 1> TEST: iter=23 shape=GeoCompositeMembershipShape: {[GeoConvexPolygon: // {planetmodel=PlanetModel(xyScaling=0.7563871189161702 zScaling=1.2436128810838298), points= @@ -593,7 +583,6 @@ public void testGeoPolygonBoundsCase2() { assertTrue(area.isWithin(pointQuantized)); } - @Test public void testGeoConcaveRelationshipCase1() { /* * [junit4] 1> doc=906 matched but should not @@ -647,7 +636,6 @@ public void testGeoConcaveRelationshipCase1() { assertTrue(xyzSolid.getRelationship(c) == GeoArea.OVERLAPS); } - @Test public void testPolygonFactoryCase1() { /* * [junit4] 1> Initial points: @@ -693,7 +681,6 @@ public void testPolygonFactoryCase1() { }); } - @Test public void testPolygonFactoryCase2() { /* [[lat=-0.48522750470337056, lon=-1.7370471071224087([X=-0.14644023172524287, Y=-0.8727091042681705, Z=-0.4665895520487907])], @@ -724,7 +711,6 @@ public void testPolygonFactoryCase2() { }); } - @Test public void testPolygonFactoryCase3() throws Exception { /* * This one failed to be detected as convex: @@ -762,7 +748,6 @@ public void testPolygonFactoryCase3() throws Exception { assertFalse(mutableBoolean.value); } - @Test public void testPolygonFactoryCase4() { // [[lat=0.897812132711355, lon=0.0025364171887532795([X=0.6227358672251874, // Y=0.0015795213449218714, Z=0.7812318690127594])], @@ -789,7 +774,6 @@ public void testPolygonFactoryCase4() { GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.WGS84, shapeList); } - @Test public void testPolygonFactoryCase5() { /* * [junit4] 1> points=[[lat=0.0425265613312593, lon=0.0([X=1.0002076326868337, Y=0.0, Z=0.042561051669501374])], @@ -874,7 +858,6 @@ public void testPolygonFactoryCase5() { assertTrue(p.isWithin(point) ? solid.isWithin(point) : true); } - @Test public void testLargePolygonFailureCase1() { /* * [junit4] > shape=GeoComplexPolygon: {planetmodel=PlanetModel.WGS84, number of shapes=1, address=65f193fc, @@ -942,7 +925,6 @@ public void testLargePolygonFailureCase1() { assertEquals(referenceBounds.getMaximumZ(), actualBounds.getMaximumZ(), 0.0000001); } - @Test public void testLargePolygonFailureCase2() { /* * [junit4] > Throwable #1: java.lang.AssertionError: FAIL: id=2 should have matched but did not @@ -1042,7 +1024,6 @@ public void testLargePolygonFailureCase2() { assertTrue(solid.isWithin(checkPoint)); } - @Test public void testPolygonFailureCase1() { final List poly2List = new ArrayList<>(); poly2List.add(new GeoPoint(PlanetModel.WGS84, -0.6370451769779303, 2.5318373679431616)); @@ -1059,7 +1040,6 @@ public void testPolygonFailureCase1() { }); } - @Test public void testPolygonFailureCase2() { /* [junit4] 1> shape=GeoCompositeMembershipShape: {[GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=[ @@ -1096,7 +1076,6 @@ public void testPolygonFailureCase2() { assertTrue(poly1.isWithin(point) ? solid.isWithin(point) : true); } - @Test public void testConcavePolygon() { ArrayList points = new ArrayList<>(); points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5)); @@ -1110,7 +1089,6 @@ public void testConcavePolygon() { assertEquals(polygon, polygonConcave); } - @Test public void testPolygonWithHole() { ArrayList points = new ArrayList<>(); points.add(new GeoPoint(PlanetModel.SPHERE, -1.1, -1.5)); @@ -1158,7 +1136,6 @@ public void testPolygonWithHole() { assertEquals(holeSimplePolygon.isWithin(gp), holeComplexPolygon.isWithin(gp)); } - @Test public void testConvexPolygon() { ArrayList points = new ArrayList<>(); points.add(new GeoPoint(PlanetModel.SPHERE, 0, 0)); @@ -1172,7 +1149,6 @@ public void testConvexPolygon() { assertEquals(polygon, polygon2); } - @Test public void testConvexPolygonWithHole() { ArrayList points = new ArrayList<>(); points.add(new GeoPoint(PlanetModel.SPHERE, -1, -1)); @@ -1197,7 +1173,6 @@ public void testConvexPolygonWithHole() { assertEquals(polygon, polygon2); } - @Test public void testLUCENE8133() { GeoPoint point1 = new GeoPoint( @@ -1244,7 +1219,6 @@ public void testLUCENE8133() { } } - @Test public void testLUCENE8140() throws Exception { // POINT(15.426026 68.35078) is coplanar // "POLYGON((15.426411 68.35069,15.4261 68.35078,15.426026 68.35078,15.425868 68.35078,15.425745 @@ -1270,7 +1244,6 @@ public void testLUCENE8140() throws Exception { assertTrue(GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points) != null); } - @Test public void testLUCENE8211() { // We need to handle the situation where the check point is parallel to // the test point. @@ -1301,7 +1274,6 @@ public void testLUCENE8211() { PlanetModel.SPHERE.createSurfacePoint(-testPoint.x, -testPoint.y, testPoint.z))); } - @Test public void testCoplanarityTileConvex() throws Exception { // This test has been disabled because it is possible that the polygon specified actually // intersects itself. @@ -1364,7 +1336,6 @@ public void testCoplanarityTileConvex() throws Exception { assertTrue(polygon != null); } - @Test public void testCoplanarityConcave() throws Exception { // POLYGON((-52.18851 64.53777,-52.18853 64.53828,-52.18675 64.53829,-52.18676 // 64.53855,-52.18736 64.53855,-52.18737 64.53881,-52.18677 64.53881,-52.18683 @@ -1412,7 +1383,6 @@ public void testCoplanarityConcave() throws Exception { GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points); } - @Test public void testCoplanarityConvex2() throws Exception { // POLYGON((-3.488658 50.45564,-3.4898987 50.455627,-3.489865 50.455585,-3.489833 // 50.45551,-3.489808 50.455433,-3.489806 50.455406,-3.4898643 50.45525,-3.4892037 @@ -1520,7 +1490,6 @@ public void testCoplanarityConvex2() throws Exception { * [junit4] 1> unquantized=[lat=-3.1780051348770987E-74, lon=-3.032608859187692([X=-0.9951793580358298, Y=-0.1088898762907205, Z=-3.181560858610375E-74])] * [junit4] 1> quantized=[X=-0.9951793580415914, Y=-0.10888987641797832, Z=-2.3309121299774915E-10] */ - @Test public void testLUCENE8227() throws Exception { List points = new ArrayList<>(); points.add(new GeoPoint(PlanetModel.WGS84, -0.63542308910253, 0.9853722928232957)); @@ -1574,7 +1543,6 @@ public void testLUCENE8227() throws Exception { * [lat=0.0, lon=0.0([X=1.0011188539924791, Y=0.0, Z=0.0])], * [lat=0.2839194570254642, lon=-1.2434404554202965([X=0.30893121415043073, Y=-0.9097632721627391, Z=0.2803596238536593])]}} */ - @Test public void testLUCENE8227_case2() { List points = new ArrayList<>(); points.add(new GeoPoint(PlanetModel.WGS84, -1.5707963267948966, -1.0755217966112058)); @@ -1620,7 +1588,6 @@ public void testLUCENE8227_case2() { assertTrue(standard.isWithin(quantized) ? standardSolid.isWithin(quantized) : true); } - @Test public void testLUCENE7642() { // Construct XYZ solid final XYZSolid solid = @@ -1755,7 +1722,6 @@ public void testLUCENE7642() { assertTrue(intersection == largeIntersection); } - @Test public void testComplexPolygonPlaneOutsideWorld() { List points = new ArrayList<>(); points.add(new GeoPoint(PlanetModel.SPHERE, -0.5, -0.5)); @@ -1781,7 +1747,6 @@ public void testComplexPolygonPlaneOutsideWorld() { assertTrue(polygon.isWithin(point1) == largePolygon.isWithin(point1)); } - @Test public void testComplexPolygonDegeneratedVector() { List points = new ArrayList<>(); points.add(new GeoPoint(PlanetModel.SPHERE, -0.5, -0.5)); @@ -1807,7 +1772,6 @@ public void testComplexPolygonDegeneratedVector() { assertTrue(polygon.isWithin(point3) == largePolygon.isWithin(point3)); } - @Test public void testAboveBelowCrossingDifferentEdges() { // POLYGON((130.846821906638 -5.066128831305991,134.5635278421427 // 21.75703481126756,156.31803093908155 44.5755831677161,0.0 @@ -1848,7 +1812,6 @@ public void testAboveBelowCrossingDifferentEdges() { assertTrue(polygon.isWithin(point1) == largePolygon.isWithin(point1)); } - @Test public void testBelowCrossingTwiceEdgePoint() { // POLYGON((162.9024012378976 -0.17652184258966092,162.56882659034474 // -0.009075185910497524,162.52932263918404 1.6235907240799453E-189,162.17731099253956 @@ -1889,7 +1852,6 @@ public void testBelowCrossingTwiceEdgePoint() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8245() { // POLYGON((-70.19447784626787 -83.117346007187,0.0 2.8E-322,-139.99870438810106 // 7.994601469571884,-143.14292702670522 -18.500141088122664,-158.7373186858464 @@ -1933,7 +1895,6 @@ public void testLUCENE8245() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8245_case2() { // POLYGON((5.512285089810178 -26.833721534785912,12.13983320542565 // -16.085163683089583,4.868755337835201 -9.167423203860656,0.0 @@ -1980,7 +1941,6 @@ public void testLUCENE8245_case2() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8245_case3() { // POLYGON((144.76249846857021 8.828705232593283,166.00162989841027 -8.5E-322,157.03429484830787 // 64.92565566857392,108.64696979831984 39.10241638996957,102.54234512410089 @@ -2026,7 +1986,6 @@ public void testLUCENE8245_case3() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8245_case4() { // POLYGON((-3.728795716978514 -10.354090605548162,-137.97868338527985 // 0.05602723926521642,-113.87317441507611 -76.2471400450585,-162.64032677742279 @@ -2073,7 +2032,6 @@ public void testLUCENE8245_case4() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8251() { // POLYGON((135.63207358036593 -51.43541696593334,113.00782694696038 -58.984559858566556,0.0 // -3.68E-321,-66.33598777585381 -7.382056816201731,135.63207358036593 -51.43541696593334)) @@ -2117,7 +2075,6 @@ public void testLUCENE8251() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8257() { // POLYGON((12.9610296281349 -8.35317290232106,15.448601008878832 // -3.990004427754539,22.375905319231205 0.2308875600810982,-13.473550791109867 @@ -2175,7 +2132,6 @@ public void testLUCENE8257() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8258() { // POLYGON((0.004541088101890366 2.457524007073783E-4,0.003771467014711204 // 0.0011493732122651466,0.003975546116981415 0.002208372357731988,0.0010780690991920934 @@ -2232,7 +2188,6 @@ public void testLUCENE8258() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8266_case1() { // POLYGON((-6.35093158794635E-11 -4.965517818537545E-11,0.0 3.113E-321,-60.23538585411111 // 18.46706692248612, 162.37100340450482 -25.988383239097754,-6.35093158794635E-11 @@ -2273,7 +2228,6 @@ public void testLUCENE8266_case1() { assertFalse(largePolygon.isWithin(point)); } - @Test public void testLUCENE8266_case2() { // POLYGON((7.885596306952593 -42.25131029665893,1.5412637897085604 // -6.829581354691802,34.03338913004999 27.583811665797796,0.0 5.7E-322,-8.854664233194431E-12 @@ -2325,7 +2279,6 @@ public void testLUCENE8266_case2() { assertFalse(largePolygon.isWithin(point)); } - @Test public void testLUCENE8266_case3() { // POLYGON((-98.38897266664411 7.286530349760722,-169.07259176302364 // -7.410435277740526,8E-123,-179.9999999999438 -1.298973436027626E-10,66.2759716901292 @@ -2373,7 +2326,6 @@ public void testLUCENE8266_case3() { assertFalse(largePolygon.isWithin(point)); } - @Test public void testLUCENE8276_case1() { // POLYGON((1.0517792672527197E-4 -1.592702733911458E-5,1.0324192726355287E-4 // 2.5741558803919037E-5,7.879018764391666E-5 7.192932029677136E-5,0.0 @@ -2421,7 +2373,6 @@ public void testLUCENE8276_case1() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8276_case2() { // POLYGON((0.05925400271049228 -0.08922986460239596,0.07309863706879852 // -0.07813330646578831,0.07411491387725304 -0.07715685640120272,0.0 @@ -2478,7 +2429,6 @@ public void testLUCENE8276_case2() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8276_case3() { // POLYGON((2.693381024483753E-4 -0.001073608118084019,1.5848404608659423E-4 // -2.6378130512803985E-4,8.981079660799132E-4 -6.4697719116416E-4,-7.934854852157693E-5 @@ -2531,7 +2481,6 @@ public void testLUCENE8276_case3() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8281() { /* * [junit4] > Standard polygon: GeoCompositePolygon: {[GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=[[lat=-3.89514302068452E-6, lon=6.597839410815709E-6([X=1.0011188539630433, Y=6.605221429683868E-6, Z=-3.89950111699443E-6])], [lat=-2.8213942160840002E-6, lon=1.608008770581648E-5([X=1.0011188538590383, Y=1.60980789753873E-5, Z=-2.8245509442632E-6])], [lat=3.8977187534179774E-6, lon=1.9713406091526053E-5([X=1.0011188537902969, Y=1.973546251320774E-5, Z=3.902079731596721E-6])], [lat=1.980614928404974E-5, lon=4.069266235973146E-6([X=1.0011188537865057, Y=4.07381914993205E-6, Z=1.982830947192924E-5])], [lat=7.4E-323, lon=0.0([X=1.0011188539924791, Y=0.0, Z=7.4E-323])]], internalEdges={4}}, GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=[[lat=-3.89514302068452E-6, lon=6.597839410815709E-6([X=1.0011188539630433, Y=6.605221429683868E-6, Z=-3.89950111699443E-6])], [lat=7.4E-323, lon=0.0([X=1.0011188539924791, Y=0.0, Z=7.4E-323])], [lat=-1.261719663233924E-5, lon=-1.5701544210600105E-5([X=1.001118853788849, Y=-1.5719111944122703E-5, Z=-1.2631313432823314E-5])]], internalEdges={0}}]} @@ -2597,7 +2546,6 @@ public void testLUCENE8281() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8280() { /* * [junit4] 1> unquantized=[lat=0.16367268756896675, lon=-3.141592653589793([X=-0.9876510422569805, Y=-1.2095236875745584E-16, Z=0.16311061810965483])] @@ -2644,7 +2592,6 @@ public void testLUCENE8280() { } - @Test public void testLUCENE8337() { /* * {planetmodel=PlanetModel.WGS84, number of shapes=1, address=c865f21d, @@ -2681,7 +2628,6 @@ public void testLUCENE8337() { assertTrue(largePolygon.isWithin(thePoint) == smallPolygon.isWithin(thePoint)); } - @Test public void testLUCENE8444() { // POLYGON((0.0 -67.68132244526963,-1.2477695347678826E-95 -88.11137674490907, // 1.7059188343238906E-9 7.009654350320916,0.0 -67.68132244526963)) @@ -2718,7 +2664,6 @@ public void testLUCENE8444() { assertTrue(false == largePolygon.isWithin(point)); } - @Test public void testLUCENE8445() { // POLYGON((32.18017946378854 -17.397683785381247,49.51018758330871 // -9.870219317504647,58.77903721991479 33.90553510354402,2.640604559432277 @@ -2775,7 +2720,6 @@ public void testLUCENE8445() { assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point)); } - @Test public void testLUCENE8451() { // POLYGON((-2.5185339401969213 -24.093993739745027,0.0 // 8.828539494442529E-27,5.495998489568957E-11 -8.321407453133E-11,2.7174659198424288E-11 diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestPlane.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestPlane.java index 33ac50391748..97d072e6e65a 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestPlane.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestPlane.java @@ -17,12 +17,10 @@ package org.apache.lucene.spatial3d.geom; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** Test basic plane functionality. */ public class TestPlane extends LuceneTestCase { - @Test public void testIdenticalPlanes() { final GeoPoint p = new GeoPoint(PlanetModel.SPHERE, 0.123, -0.456); final Plane plane1 = new Plane(p, 0.0); @@ -38,7 +36,6 @@ public void testIdenticalPlanes() { assertTrue(p1.isNumericallyIdentical(p2)); } - @Test public void testIdenticalVector() { final Vector v1 = new Vector(1, 0, 0); final Vector v2 = new Vector(1, 0, 0); @@ -47,7 +44,6 @@ public void testIdenticalVector() { assertFalse(v1.isNumericallyIdentical(v3)); } - @Test public void testInterpolation() { // [X=0.35168818443386646, Y=-0.19637966197066342, Z=0.9152870857244183], // [X=0.5003343189532654, Y=0.522128543226148, Z=0.6906861469771293], @@ -68,7 +64,6 @@ public void testInterpolation() { } } - @Test public void testFindArcPoints() { // Create two points final GeoPoint p1 = new GeoPoint(PlanetModel.WGS84, 0.123, -0.456); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomBinaryCodec.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomBinaryCodec.java index eb0cbdf0c77f..c571036f505e 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomBinaryCodec.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomBinaryCodec.java @@ -27,11 +27,9 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** Test to check Serialization */ public class TestRandomBinaryCodec extends LuceneTestCase { - @Test @Repeat(iterations = 10) public void testRandomPointCodec() throws IOException { PlanetModel planetModel = randomPlanetModel(); @@ -43,7 +41,6 @@ public void testRandomPointCodec() throws IOException { assertEquals(shape.toString(), shape, shapeCopy); } - @Test @Repeat(iterations = 100) public void testRandomPlanetObjectCodec() throws IOException { PlanetModel planetModel = randomPlanetModel(); @@ -56,7 +53,6 @@ public void testRandomPlanetObjectCodec() throws IOException { assertEquals(shape.toString(), shape, shapeCopy); } - @Test @Repeat(iterations = 100) public void testRandomShapeCodec() throws IOException { PlanetModel planetModel = randomPlanetModel(); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomGeoPolygon.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomGeoPolygon.java index 712c5c411fc6..e97c4928fc4f 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomGeoPolygon.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomGeoPolygon.java @@ -25,11 +25,9 @@ import java.util.Collections; import java.util.List; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** Random test for polygons. */ public class TestRandomGeoPolygon extends LuceneTestCase { - @Test public void testRandomLUCENE8157() { final PlanetModel planetModel = randomPlanetModel(); final GeoPoint startPoint = randomGeoPoint(planetModel); @@ -71,7 +69,6 @@ public void testLUCENE8157() { } } - @Test public void testCoplanarityTilePolygon() { // POLYGON((-90.55764 -0.34907,-90.55751 -0.34868,-90.55777 -0.34842,-90.55815 // -0.34766,-90.55943 -0.34842, -90.55918 -0.34842,-90.55764 -0.34907)) @@ -100,13 +97,11 @@ public void testCoplanarityTilePolygon() { } /** Test comparing different polygon (Big) technologies using random biased doubles. */ - @Test public void testCompareBigPolygons() { testComparePolygons(Math.PI); } /** Test comparing different polygon (Small) technologies using random biased doubles. */ - @Test public void testCompareSmallPolygons() { testComparePolygons(1e-4 * Math.PI); } diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomGeoShapeRelationship.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomGeoShapeRelationship.java index 773f7ee06ad6..a2dfbae6a71c 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomGeoShapeRelationship.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomGeoShapeRelationship.java @@ -36,7 +36,6 @@ import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.randomShapeType; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** Random test to check relationship between GeoAreaShapes and GeoShapes. */ public class TestRandomGeoShapeRelationship extends LuceneTestCase { @@ -44,7 +43,6 @@ public class TestRandomGeoShapeRelationship extends LuceneTestCase { * Test for WITHIN points. We build a WITHIN shape with respect the geoAreaShape and create a * point WITHIN the shape. The resulting shape should be WITHIN the original shape. */ - @Test public void testRandomPointWithin() { int referenceShapeType = CONVEX_POLYGON; PlanetModel planetModel = randomPlanetModel(); @@ -104,7 +102,6 @@ public void testRandomPointNotWithin() { * *

Note that both shapes cannot be concave. */ - @Test public void testRandomDisjoint() { int referenceShapeType = CONVEX_SIMPLE_POLYGON; PlanetModel planetModel = randomPlanetModel(); @@ -141,7 +138,6 @@ public void testRandomDisjoint() { * *

Note that if the geoAreaShape is not concave the other shape must be not concave. */ - @Test public void testRandomWithIn() { PlanetModel planetModel = randomPlanetModel(); int geoAreaShapeType = randomGeoAreaShapeType(); @@ -189,7 +185,6 @@ public void testRandomWithIn() { * concave, the shape for reference should be concave as well. */ // TODO: this test seems to hit pathological cases that cause it to run for many minutes?! - @Test @Nightly public void testRandomContains() { int referenceShapeType = CONVEX_SIMPLE_POLYGON; @@ -238,7 +233,6 @@ public void testRandomContains() { * disjoint to other part and contains a disjoint shape. We create shapes according the criteria. * The resulting shape should OVERLAP the geoAreaShape. */ - @Test public void testRandomOverlaps() { PlanetModel planetModel = randomPlanetModel(); int geoAreaShapeType = randomGeoAreaShapeType(); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomPlane.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomPlane.java index c3c65a150edf..360670ad7b70 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomPlane.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomPlane.java @@ -24,12 +24,10 @@ import java.util.ArrayList; import java.util.List; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** Random test for planes. */ public class TestRandomPlane extends LuceneTestCase { - @Test @Repeat(iterations = 10) public void testPlaneAccuracy() { PlanetModel planetModel = randomPlanetModel(); @@ -53,7 +51,6 @@ public void testPlaneAccuracy() { } } - @Test @Repeat(iterations = 10) public void testPlaneThreePointsAccuracy() { PlanetModel planetModel = randomPlanetModel(); @@ -91,7 +88,6 @@ public void testPlaneThreePointsAccuracy() { } } - @Test @Repeat(iterations = 10) public void testPolygonAccuracy() { PlanetModel planetModel = randomPlanetModel(); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestSimpleGeoPolygonRelationships.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestSimpleGeoPolygonRelationships.java index 32ee5cea1697..cc842af86b8d 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestSimpleGeoPolygonRelationships.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestSimpleGeoPolygonRelationships.java @@ -21,7 +21,6 @@ import java.util.Collections; import java.util.List; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; /** * Check relationship between polygon and GeoShapes of basic polygons. Normally we construct the @@ -30,7 +29,6 @@ public class TestSimpleGeoPolygonRelationships extends LuceneTestCase { /** Test with two shapes with no crossing edges and no points in common in convex case. */ - @Test public void testGeoSimplePolygon1() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -109,7 +107,6 @@ public void testGeoSimplePolygon1() { } /** Test with two shapes with crossing edges and some points inside in convex case. */ - @Test public void testGeoSimplePolygon2() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -189,7 +186,6 @@ public void testGeoSimplePolygon2() { } /** Test with two shapes with no crossing edges and all points inside in convex case. */ - @Test public void testGeoSimplePolygon3() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 @@ -269,7 +265,6 @@ public void testGeoSimplePolygon3() { } /** Test with two shapes with crossing edges and no points inside in convex case. */ - @Test public void testGeoSimplePolygon4() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 // -60.257713, 19.845091 -60.452631)) disjoint @@ -349,7 +344,6 @@ public void testGeoSimplePolygon4() { } /** Test with two shapes with no crossing edges and polygon in hole in convex case. */ - @Test public void testGeoSimplePolygonWithHole1() { // POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, // -136.5 -30.4, -136.5 -30.7, -135.5 -30.7)) @@ -393,7 +387,6 @@ public void testGeoSimplePolygonWithHole1() { } /** Test with two shapes with crossing edges in hole and some points inside in convex case. */ - @Test public void testGeoSimplePolygonWithHole2() { // POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, // -136.5 -30.4, -136.5 -30.7, -135.5 -30.7)) @@ -438,7 +431,6 @@ public void testGeoSimplePolygonWithHole2() { } /** Test with two shapes with crossing edges and some points inside in convex case. */ - @Test public void testGeoSimplePolygonWithHole3() { // POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, // -136.5 -30.4, -136.5 -30.7, -135.5 -30.7)) @@ -483,7 +475,6 @@ public void testGeoSimplePolygonWithHole3() { } /** Test with two shapes with no crossing edges and all points inside in convex case. */ - @Test public void testGeoSimplePolygonWithHole4() { // POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, // -136.5 -30.4, -136.5 -30.7, -135.5 -30.7)) @@ -526,7 +517,6 @@ public void testGeoSimplePolygonWithHole4() { assertEquals(GeoArea.OVERLAPS, rel); } - @Test public void testGeoSimplePolygonWithCircle() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 // -60.257713, 19.845091 -60.452631)) disjoint @@ -616,7 +606,6 @@ public void testGeoSimplePolygonWithCircle() { assertEquals(GeoArea.CONTAINS, rel); } - @Test public void testGeoSimplePolygonWithBBox() { // POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 // -60.257713, 19.845091 -60.452631)) disjoint @@ -718,7 +707,6 @@ public void testGeoSimplePolygonWithBBox() { assertEquals(GeoArea.CONTAINS, rel); } - @Test public void testGeoSimplePolygonWithComposite() { GeoShape shape = getCompositeShape(); @@ -773,7 +761,6 @@ public void testGeoSimplePolygonWithComposite() { assertEquals(GeoArea.OVERLAPS, rel); } - @Test public void testDegeneratedPointIntersectShape() { GeoBBox bBox1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 1, 0, 0, 1); GeoBBox bBox2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 1, 1, 1, 1); @@ -787,7 +774,6 @@ public void testDegeneratedPointIntersectShape() { assertEquals(GeoArea.CONTAINS, rel); } - @Test public void testDegeneratedPointInPole() { GeoBBox bBox1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, Math.PI * 0.5, 0, 0); @@ -796,7 +782,6 @@ public void testDegeneratedPointInPole() { assertTrue(bBox1.isWithin(point)); } - @Test public void testDegeneratePathShape() { GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, 0, 0); GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, 0, 1); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestXYZSolid.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestXYZSolid.java index e252744a6143..c71299210a8e 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestXYZSolid.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestXYZSolid.java @@ -17,11 +17,9 @@ package org.apache.lucene.spatial3d.geom; import org.apache.lucene.tests.util.LuceneTestCase; -import org.junit.Test; public class TestXYZSolid extends LuceneTestCase { - @Test public void testNonDegenerateRelationships() { XYZSolid s; GeoShape shape; @@ -60,7 +58,6 @@ public void testNonDegenerateRelationships() { assertEquals(GeoArea.DISJOINT, s.getRelationship(shape)); } - @Test public void testDegenerateRelationships() { GeoArea solid; GeoShape shape; @@ -217,7 +214,6 @@ public void testDegenerateRelationships() { } - @Test public void testLUCENE8457() { GeoShape shape = GeoBBoxFactory.makeGeoBBox( diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestDocumentDictionary.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestDocumentDictionary.java index a529141c15e5..93d2590725b4 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestDocumentDictionary.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestDocumentDictionary.java @@ -44,10 +44,10 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; // See: https://issues.apache.org/jira/browse/SOLR-12028 Tests cannot remove files on Windows // machines occasionally + public class TestDocumentDictionary extends LuceneTestCase { static final String FIELD_NAME = "f1"; @@ -55,7 +55,6 @@ public class TestDocumentDictionary extends LuceneTestCase { static final String PAYLOAD_FIELD_NAME = "p1"; static final String CONTEXT_FIELD_NAME = "c1"; - @Test public void testEmptyReader() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -77,7 +76,6 @@ public void testEmptyReader() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testBasic() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -118,7 +116,6 @@ public void testBasic() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testWithOptionalPayload() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -154,7 +151,6 @@ public void testWithOptionalPayload() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testWithoutPayload() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -193,7 +189,6 @@ public void testWithoutPayload() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testWithContexts() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -241,7 +236,6 @@ public void testWithContexts() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testWithDeletions() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -301,7 +295,6 @@ public void testWithDeletions() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testMultiValuedField() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestDocumentValueSourceDictionary.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestDocumentValueSourceDictionary.java index 8a3690ffa746..e6358aed190d 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestDocumentValueSourceDictionary.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestDocumentValueSourceDictionary.java @@ -47,7 +47,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; public class TestDocumentValueSourceDictionary extends LuceneTestCase { @@ -58,7 +57,6 @@ public class TestDocumentValueSourceDictionary extends LuceneTestCase { static final String PAYLOAD_FIELD_NAME = "p1"; static final String CONTEXTS_FIELD_NAME = "c1"; - @Test public void testValueSourceEmptyReader() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -81,7 +79,6 @@ public void testValueSourceEmptyReader() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testLongValuesSourceEmptyReader() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -104,7 +101,6 @@ public void testLongValuesSourceEmptyReader() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testValueSourceBasic() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -204,7 +200,6 @@ public LongValuesSource rewrite(IndexSearcher searcher) throws IOException { }; } - @Test public void testLongValuesSourceBasic() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -240,7 +235,6 @@ public void testLongValuesSourceBasic() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testValueSourceWithContext() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -281,7 +275,6 @@ public void testValueSourceWithContext() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testLongValuesSourceWithContext() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -322,7 +315,6 @@ public void testLongValuesSourceWithContext() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testValueSourceWithoutPayload() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -354,7 +346,6 @@ public void testValueSourceWithoutPayload() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testLongValuesSourceWithoutPayload() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -386,7 +377,6 @@ public void testLongValuesSourceWithoutPayload() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testValueSourceWithDeletions() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -441,7 +431,6 @@ public void testValueSourceWithDeletions() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testLongValuesSourceWithDeletions() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -496,7 +485,6 @@ public void testLongValuesSourceWithDeletions() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testWithValueSource() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); @@ -528,7 +516,6 @@ public void testWithValueSource() throws IOException { IOUtils.close(ir, analyzer, dir); } - @Test public void testWithLongValuesSource() throws IOException { Directory dir = newDirectory(); Analyzer analyzer = new MockAnalyzer(random()); diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestFileDictionary.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestFileDictionary.java index 15803f1657f8..f57fbe7b41bc 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestFileDictionary.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/TestFileDictionary.java @@ -27,7 +27,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRef; -import org.junit.Test; public class TestFileDictionary extends LuceneTestCase { @@ -74,7 +73,6 @@ private Map.Entry>, String> generateFileInput( return new SimpleEntry<>(entries, sb.toString()); } - @Test public void testFileWithTerm() throws IOException { Map.Entry>, String> fileInput = generateFileInput(atLeast(100), FileDictionary.DEFAULT_FIELD_DELIMITER, false, false); @@ -98,7 +96,6 @@ public void testFileWithTerm() throws IOException { assertEquals(count, entries.size()); } - @Test public void testFileWithWeight() throws IOException { Map.Entry>, String> fileInput = generateFileInput(atLeast(100), FileDictionary.DEFAULT_FIELD_DELIMITER, true, false); @@ -122,7 +119,6 @@ public void testFileWithWeight() throws IOException { assertEquals(count, entries.size()); } - @Test public void testFileWithWeightAndPayload() throws IOException { Map.Entry>, String> fileInput = generateFileInput(atLeast(100), FileDictionary.DEFAULT_FIELD_DELIMITER, true, true); @@ -150,7 +146,6 @@ public void testFileWithWeightAndPayload() throws IOException { assertEquals(count, entries.size()); } - @Test public void testFileWithOneEntry() throws IOException { Map.Entry>, String> fileInput = generateFileInput(1, FileDictionary.DEFAULT_FIELD_DELIMITER, true, true); @@ -178,7 +173,6 @@ public void testFileWithOneEntry() throws IOException { assertEquals(count, entries.size()); } - @Test public void testFileWithDifferentDelimiter() throws IOException { Map.Entry>, String> fileInput = generateFileInput(atLeast(100), " , ", true, true); diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/TestAnalyzingInfixSuggester.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/TestAnalyzingInfixSuggester.java index 3ea17ee146b5..35a9d0790067 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/TestAnalyzingInfixSuggester.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/TestAnalyzingInfixSuggester.java @@ -50,7 +50,6 @@ import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.junit.Test; public class TestAnalyzingInfixSuggester extends LuceneTestCase { @@ -1332,7 +1331,6 @@ public void testBasicContext() throws Exception { } } - @Test public void testAddPrefixMatch() throws IOException { Analyzer a = new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false); Directory dir = newDirectory(); diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestContextQuery.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestContextQuery.java index cf7d5f8e745b..057317687b90 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestContextQuery.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestContextQuery.java @@ -37,7 +37,6 @@ import org.apache.lucene.util.ArrayUtil; import org.junit.After; import org.junit.Before; -import org.junit.Test; public class TestContextQuery extends LuceneTestCase { public Directory dir; @@ -52,7 +51,6 @@ public void after() throws Exception { dir.close(); } - @Test public void testIllegalInnerQuery() throws Exception { IllegalArgumentException expected = expectThrows( @@ -66,7 +64,6 @@ public void testIllegalInnerQuery() throws Exception { assertTrue(expected.getMessage().contains(ContextQuery.class.getSimpleName())); } - @Test public void testSimpleContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -106,7 +103,6 @@ public void testSimpleContextQuery() throws Exception { iw.close(); } - @Test public void testContextQueryOnSuggestField() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -142,7 +138,6 @@ public void testContextQueryOnSuggestField() throws Exception { iw.close(); } - @Test public void testNonExactContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -179,7 +174,6 @@ public void testNonExactContextQuery() throws Exception { iw.close(); } - @Test public void testContextPrecedenceBoost() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -210,7 +204,6 @@ public void testContextPrecedenceBoost() throws Exception { iw.close(); } - @Test public void testEmptyContext() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -240,7 +233,6 @@ public void testEmptyContext() throws Exception { iw.close(); } - @Test public void testEmptyContextWithBoosts() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -278,7 +270,6 @@ public void testEmptyContextWithBoosts() throws Exception { iw.close(); } - @Test public void testSameSuggestionMultipleContext() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -317,7 +308,6 @@ public void testSameSuggestionMultipleContext() throws Exception { iw.close(); } - @Test public void testMixedContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -356,7 +346,6 @@ public void testMixedContextQuery() throws Exception { iw.close(); } - @Test public void testFilteringContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -392,7 +381,6 @@ public void testFilteringContextQuery() throws Exception { iw.close(); } - @Test public void testContextQueryRewrite() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -427,7 +415,6 @@ public void testContextQueryRewrite() throws Exception { iw.close(); } - @Test public void testMultiContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -468,7 +455,6 @@ public void testMultiContextQuery() throws Exception { iw.close(); } - @Test public void testBigNumberOfContextsQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -500,7 +486,6 @@ public void testBigNumberOfContextsQuery() throws Exception { iw.close(); } - @Test public void testAllContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -536,7 +521,6 @@ public void testAllContextQuery() throws Exception { iw.close(); } - @Test public void testRandomContextQueryScoring() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); try (RandomIndexWriter iw = diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestContextSuggestField.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestContextSuggestField.java index dc6eda184d19..ec713b078379 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestContextSuggestField.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestContextSuggestField.java @@ -38,7 +38,6 @@ import org.apache.lucene.util.CharsRefBuilder; import org.junit.After; import org.junit.Before; -import org.junit.Test; public class TestContextSuggestField extends LuceneTestCase { @@ -54,7 +53,6 @@ public void after() throws Exception { dir.close(); } - @Test public void testEmptySuggestion() throws Exception { IllegalArgumentException expected = expectThrows( @@ -65,7 +63,6 @@ public void testEmptySuggestion() throws Exception { assertTrue(expected.getMessage().contains("value")); } - @Test public void testReservedChars() throws Exception { CharsRefBuilder charsRefBuilder = new CharsRefBuilder(); charsRefBuilder.append("sugg"); @@ -105,7 +102,6 @@ public void testReservedChars() throws Exception { } } - @Test public void testTokenStream() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); ContextSuggestField field = @@ -159,7 +155,6 @@ public void testTokenStream() throws Exception { null); } - @Test public void testMixedSuggestFields() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); Document document = new Document(); @@ -180,7 +175,6 @@ public void testMixedSuggestFields() throws Exception { } } - @Test public void testWithSuggestFields() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -230,7 +224,6 @@ public void testWithSuggestFields() throws Exception { iw.close(); } - @Test public void testCompletionAnalyzer() throws Exception { CompletionAnalyzer completionAnalyzer = new CompletionAnalyzer(new StandardAnalyzer(), true, true); diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestFuzzyCompletionQuery.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestFuzzyCompletionQuery.java index d0480a0380cb..089b60bfe8dc 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestFuzzyCompletionQuery.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestFuzzyCompletionQuery.java @@ -30,7 +30,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.After; import org.junit.Before; -import org.junit.Test; public class TestFuzzyCompletionQuery extends LuceneTestCase { public Directory dir; @@ -45,7 +44,6 @@ public void after() throws Exception { dir.close(); } - @Test public void testFuzzyQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -79,7 +77,6 @@ public void testFuzzyQuery() throws Exception { iw.close(); } - @Test public void testFuzzyContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -117,7 +114,6 @@ public void testFuzzyContextQuery() throws Exception { iw.close(); } - @Test public void testFuzzyFilteredContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestPrefixCompletionQuery.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestPrefixCompletionQuery.java index 6670a0b78538..f9b2c743bcf1 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestPrefixCompletionQuery.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestPrefixCompletionQuery.java @@ -46,7 +46,6 @@ import org.apache.lucene.util.FixedBitSet; import org.junit.After; import org.junit.Before; -import org.junit.Test; public class TestPrefixCompletionQuery extends LuceneTestCase { @@ -142,7 +141,6 @@ public void testSimple() throws Exception { iw.close(); } - @Test public void testEmptyPrefixQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestRegexCompletionQuery.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestRegexCompletionQuery.java index 57a858bd3007..3a4288cf81d6 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestRegexCompletionQuery.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestRegexCompletionQuery.java @@ -31,7 +31,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.After; import org.junit.Before; -import org.junit.Test; public class TestRegexCompletionQuery extends LuceneTestCase { public Directory dir; @@ -46,7 +45,6 @@ public void after() throws Exception { dir.close(); } - @Test public void testRegexQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -82,7 +80,6 @@ public void testRegexQuery() throws Exception { iw.close(); } - @Test public void testEmptyRegexQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -106,7 +103,6 @@ public void testEmptyRegexQuery() throws Exception { iw.close(); } - @Test public void testSimpleRegexContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -144,7 +140,6 @@ public void testSimpleRegexContextQuery() throws Exception { iw.close(); } - @Test public void testRegexContextQueryWithBoost() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -185,7 +180,6 @@ public void testRegexContextQueryWithBoost() throws Exception { iw.close(); } - @Test public void testEmptyRegexContextQuery() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestSuggestField.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestSuggestField.java index 1548972c8149..581e070add24 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestSuggestField.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/TestSuggestField.java @@ -69,7 +69,6 @@ import org.hamcrest.MatcherAssert; import org.junit.After; import org.junit.Before; -import org.junit.Test; public class TestSuggestField extends LuceneTestCase { @@ -85,7 +84,6 @@ public void after() throws Exception { dir.close(); } - @Test public void testEmptySuggestion() throws Exception { IllegalArgumentException expected = expectThrows( @@ -93,7 +91,6 @@ public void testEmptySuggestion() throws Exception { MatcherAssert.assertThat(expected.getMessage(), containsString("value")); } - @Test public void testNegativeWeight() throws Exception { IllegalArgumentException expected = expectThrows( @@ -101,7 +98,6 @@ public void testNegativeWeight() throws Exception { MatcherAssert.assertThat(expected.getMessage(), containsString("weight")); } - @Test public void testReservedChars() throws Exception { CharsRefBuilder charsRefBuilder = new CharsRefBuilder(); charsRefBuilder.append("sugg"); @@ -127,7 +123,6 @@ public void testReservedChars() throws Exception { MatcherAssert.assertThat(expected.getMessage(), containsString("[0x0]")); } - @Test public void testEmpty() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -142,7 +137,6 @@ public void testEmpty() throws Exception { iw.close(); } - @Test public void testTokenStream() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); SuggestField suggestField = new SuggestField("field", "input", 1); @@ -179,7 +173,6 @@ public void testTokenStream() throws Exception { null); } - @Test public void testDupSuggestFieldValues() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -438,7 +431,6 @@ public void testRandom() throws Exception { iw.close(); } - @Test public void testNRTDeletedDocFiltering() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); // using IndexWriter instead of RandomIndexWriter @@ -478,7 +470,6 @@ public void testNRTDeletedDocFiltering() throws Exception { iw.close(); } - @Test public void testSuggestOnAllFilteredDocuments() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -514,7 +505,6 @@ public Bits getBits(LeafReaderContext context) throws IOException { iw.close(); } - @Test public void testSuggestOnAllDeletedDocuments() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); // using IndexWriter instead of RandomIndexWriter @@ -544,7 +534,6 @@ public void testSuggestOnAllDeletedDocuments() throws Exception { iw.close(); } - @Test public void testSuggestOnMostlyDeletedDocuments() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); // using IndexWriter instead of RandomIndexWriter @@ -575,7 +564,6 @@ public void testSuggestOnMostlyDeletedDocuments() throws Exception { iw.close(); } - @Test public void testMultipleSuggestFieldsPerDoc() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -615,7 +603,6 @@ public void testMultipleSuggestFieldsPerDoc() throws Exception { iw.close(); } - @Test public void testEarlyTermination() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -645,7 +632,6 @@ public void testEarlyTermination() throws Exception { iw.close(); } - @Test public void testMultipleSegments() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -678,7 +664,6 @@ public void testMultipleSegments() throws Exception { iw.close(); } - @Test public void testReturnedDocID() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -716,7 +701,6 @@ public void testReturnedDocID() throws Exception { iw.close(); } - @Test public void testScoring() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -761,7 +745,6 @@ public void testScoring() throws Exception { iw.close(); } - @Test public void testRealisticKeys() throws Exception { Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = @@ -812,7 +795,6 @@ public void testRealisticKeys() throws Exception { iw.close(); } - @Test public void testThreads() throws Exception { final Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/TestBytesRefSorters.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/TestBytesRefSorters.java index 4a1939342877..96286e3cb539 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/TestBytesRefSorters.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/fst/TestBytesRefSorters.java @@ -28,10 +28,8 @@ import org.apache.lucene.util.BytesRefIterator; import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.OfflineSorter; -import org.junit.Test; public class TestBytesRefSorters extends LuceneTestCase { - @Test public void testExternalRefSorter() throws Exception { Directory tempDir = newDirectory(); ExternalRefSorter s = new ExternalRefSorter(new OfflineSorter(tempDir, "temp")); @@ -39,7 +37,6 @@ public void testExternalRefSorter() throws Exception { IOUtils.close(s, tempDir); } - @Test public void testExternalRefSortersIteratorIsCloseable() throws Exception { try (Directory tempDir = newDirectory(); ExternalRefSorter s = new ExternalRefSorter(new OfflineSorter(tempDir, "temp"))) { @@ -55,7 +52,6 @@ public void testExternalRefSortersIteratorIsCloseable() throws Exception { } } - @Test public void testInMemorySorter() throws Exception { check(new InMemorySorter(Comparator.naturalOrder())); } From 5c072a4f6df9183a1d7cae24d1255eb474b5f9d5 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 11:31:32 +0200 Subject: [PATCH 44/68] More utility scripts. --- ...TestClassesNotExtendingLuceneTestCase.java | 112 ++++++++++++++++++ ...t-classes-not-extending-LuceneTestCase.txt | 51 ++++++++ 2 files changed, 163 insertions(+) create mode 100644 dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java create mode 100644 dev-tools/refactorings/test-classes-not-extending-LuceneTestCase.txt diff --git a/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java b/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java new file mode 100644 index 000000000000..3ff63c79c950 --- /dev/null +++ b/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java @@ -0,0 +1,112 @@ +///usr/bin/env jbang "$0" "$@" ; exit $? +//JAVA 17+ +//DEPS com.github.javaparser:javaparser-core:3.25.10 + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParserConfiguration; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; + +import java.io.IOException; +import java.nio.file.*; +import java.util.*; +import java.util.stream.*; + +/** + * Finds test classes (in src/test trees) that do not descend from LuceneTestCase. + * + * A "test class" is any non-abstract class in a src/test source tree that has at + * least one method whose name starts with "test". + * + * The superclass graph is built from ALL .java files under the given root (both + * src/main and src/test), so abstract base classes defined inside the project are + * resolved transitively. Classes whose superclass cannot be resolved within the + * project are flagged with "(unresolved)" — those are the ones most worth reviewing. + * + * Usage / Docker: + * docker run --rm \ + * -v jbang-cache:/root/.jbang/cache \ + * -v "$(pwd)":/workdir \ + * jbangdev/jbang \ + * /workdir/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java /workdir + */ +public class FindTestClassesNotExtendingLuceneTestCase { + + public static void main(String[] args) throws IOException { + Path root = args.length > 0 ? Paths.get(args[0]) : Paths.get("."); + + var config = new ParserConfiguration() + .setLanguageLevel(ParserConfiguration.LanguageLevel.BLEEDING_EDGE); + var parser = new JavaParser(config); + + // simple class name -> simple superclass name (first declared, ignoring generics) + Map superOf = new HashMap<>(); + // simple class name -> relative file path, for test classes with test* methods + Map testClasses = new LinkedHashMap<>(); + + try (Stream paths = Files.walk(root)) { + paths.filter(p -> p.toString().endsWith(".java")) + .sorted() + .forEach(file -> { + try { + var result = parser.parse(file); + if (!result.getResult().isPresent()) return; + + String rel = root.relativize(file).toString(); + boolean isTestTree = rel.contains("/src/test/"); + + result.getResult().get() + .findAll(ClassOrInterfaceDeclaration.class).forEach(cls -> { + if (cls.isInterface()) return; + + String name = cls.getNameAsString(); + + // Record superclass (simple name, strip generics) + cls.getExtendedTypes().stream().findFirst().ifPresent(t -> + superOf.put(name, t.getNameAsString())); + + // A test class: non-abstract, in a test tree, has test* methods + if (isTestTree && !cls.isAbstract()) { + boolean hasTestMethods = cls.findAll(MethodDeclaration.class) + .stream() + .anyMatch(m -> m.getNameAsString().startsWith("test")); + if (hasTestMethods) { + testClasses.put(name, rel); + } + } + }); + } catch (IOException e) { + System.err.println("# skip: " + file); + } + }); + } + + // Transitive closure: all classes that are descendants of LuceneTestCase + Set descendants = new HashSet<>(); + descendants.add("LuceneTestCase"); + boolean changed = true; + while (changed) { + changed = false; + for (var entry : superOf.entrySet()) { + if (descendants.contains(entry.getValue()) && descendants.add(entry.getKey())) { + changed = true; + } + } + } + + // Report test classes outside the LuceneTestCase hierarchy + long count = testClasses.entrySet().stream() + .filter(e -> !descendants.contains(e.getKey())) + .peek(e -> { + String sup = superOf.containsKey(e.getKey()) + ? superOf.get(e.getKey()) + : "(no superclass)"; + boolean resolved = descendants.contains(sup) || superOf.containsKey(sup); + String tag = resolved ? "" : " *** unresolved superclass"; + System.out.printf("%s [extends %s]%s%n", e.getValue(), sup, tag); + }) + .count(); + + System.err.printf("%n# %d test class(es) not descending from LuceneTestCase%n", count); + } +} diff --git a/dev-tools/refactorings/test-classes-not-extending-LuceneTestCase.txt b/dev-tools/refactorings/test-classes-not-extending-LuceneTestCase.txt new file mode 100644 index 000000000000..e2a882cd82c7 --- /dev/null +++ b/dev-tools/refactorings/test-classes-not-extending-LuceneTestCase.txt @@ -0,0 +1,51 @@ +lucene/analysis/common + lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspellRepositoryTestCases.java [extends (no superclass)] *** unresolved superclass + +lucene/core + lucene/core/src/test/org/apache/lucene/document/TestXYLineShapeQueries.java [extends Validator] *** unresolved superclass + lucene/core/src/test/org/apache/lucene/document/TestXYMultiLineShapeQueries.java [extends Validator] *** unresolved superclass + lucene/core/src/test/org/apache/lucene/document/TestXYMultiPointShapeQueries.java [extends Validator] *** unresolved superclass + lucene/core/src/test/org/apache/lucene/document/TestXYMultiPolygonShapeQueries.java [extends Validator] *** unresolved superclass + lucene/core/src/test/org/apache/lucene/document/TestXYPointShapeQueries.java [extends Validator] *** unresolved superclass + lucene/core/src/test/org/apache/lucene/document/TestXYPolygonShapeQueries.java [extends Validator] *** unresolved superclass + lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java [extends Assert] *** unresolved superclass + lucene/core/src/test/org/apache/lucene/search/TestMultiThreadTermVectors.java [extends Thread] *** unresolved superclass + +lucene/core.tests + lucene/core.tests/src/test/org/apache/lucene/core/tests/TestRuntimeDependenciesSane.java [extends (no superclass)] *** unresolved superclass + +lucene/distribution.tests + lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestModularLayer.java [extends AbstractLuceneDistributionTest] + lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestScripts.java [extends AbstractLuceneDistributionTest] + +lucene/memory + lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java [extends LuceneTestCaseJupiter] + lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java [extends LuceneTestCaseJupiter] + lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java [extends LuceneTestCaseJupiter] + +lucene/monitor + lucene/monitor/src/test/org/apache/lucene/monitor/outsidepackage/TestCandidateMatcherVisibility.java [extends (no superclass)] *** unresolved superclass + +lucene/queryparser + lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java [extends LuceneTestCaseJupiter] + +lucene/suggest + lucene/suggest/src/test/org/apache/lucene/search/suggest/SuggestRebuildTestUtil.java [extends (no superclass)] *** unresolved superclass + +lucene/test-framework + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestBeforeAfterOverrides.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestCodecReported.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestExceptionInBeforeClassHooks.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestFailIfDirectoryNotClosed.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestFailIfUnreferencedFiles.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestJUnitRuleOrder.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestJvmInfo.java [extends RandomizedTest] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestMaxFailuresRule.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestReproduceMessage.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestReproduceMessageWithRepeated.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSeedFromUncaught.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSetupTeardownChaining.java [extends WithNestedTests] *** unresolved superclass + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSysoutsLimits.java [extends ParentNestedTest] + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSysoutsLimits.java [extends ParentNestedTest] + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSysoutsLimits.java [extends ParentNestedTest] + lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSysoutsLimits.java [extends WithNestedTests] *** unresolved superclass From 92ada094a42a781884652b90dc1859a0bfd58ae8 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 11:33:46 +0200 Subject: [PATCH 45/68] Update javaparser, revert the hack. --- dev-tools/refactorings/FindAnnotatedTestMethods.java | 2 +- .../FindTestClassesNotExtendingLuceneTestCase.java | 2 +- dev-tools/refactorings/RemoveRedundantTestAnnotations.java | 4 ++-- dev-tools/refactorings/remove-redundant-test-annotations.md | 5 ----- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/dev-tools/refactorings/FindAnnotatedTestMethods.java b/dev-tools/refactorings/FindAnnotatedTestMethods.java index 93a70ef799d3..d116979d4c4a 100644 --- a/dev-tools/refactorings/FindAnnotatedTestMethods.java +++ b/dev-tools/refactorings/FindAnnotatedTestMethods.java @@ -1,6 +1,6 @@ ///usr/bin/env jbang "$0" "$@" ; exit $? //JAVA 17+ -//DEPS com.github.javaparser:javaparser-core:3.25.10 +//DEPS com.github.javaparser:javaparser-core:3.28.0 import com.github.javaparser.JavaParser; import com.github.javaparser.ParserConfiguration; diff --git a/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java b/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java index 3ff63c79c950..e6847cdabd7c 100644 --- a/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java +++ b/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java @@ -1,6 +1,6 @@ ///usr/bin/env jbang "$0" "$@" ; exit $? //JAVA 17+ -//DEPS com.github.javaparser:javaparser-core:3.25.10 +//DEPS com.github.javaparser:javaparser-core:3.28.0 import com.github.javaparser.JavaParser; import com.github.javaparser.ParserConfiguration; diff --git a/dev-tools/refactorings/RemoveRedundantTestAnnotations.java b/dev-tools/refactorings/RemoveRedundantTestAnnotations.java index e4d5b37f333d..9295f36b83e6 100644 --- a/dev-tools/refactorings/RemoveRedundantTestAnnotations.java +++ b/dev-tools/refactorings/RemoveRedundantTestAnnotations.java @@ -1,6 +1,6 @@ ///usr/bin/env jbang "$0" "$@" ; exit $? //JAVA 17+ -//DEPS com.github.javaparser:javaparser-core:3.25.10 +//DEPS com.github.javaparser:javaparser-core:3.28.0 import com.github.javaparser.JavaParser; import com.github.javaparser.ParserConfiguration; @@ -44,7 +44,7 @@ public static void main(String[] args) throws IOException { .forEach(file -> { try { var result = parser.parse(file); - if (!result.getResult().isPresent()) { + if (!result.isSuccessful()) { System.err.println("# parse error: " + file); return; } diff --git a/dev-tools/refactorings/remove-redundant-test-annotations.md b/dev-tools/refactorings/remove-redundant-test-annotations.md index d713344635cf..201c2bffb4d1 100644 --- a/dev-tools/refactorings/remove-redundant-test-annotations.md +++ b/dev-tools/refactorings/remove-redundant-test-annotations.md @@ -40,11 +40,6 @@ docker run --rm \ ## Known quirks -**Parse warnings for `_` catch parameters** — files using the Java 21 unnamed-variable -syntax (`catch (IOException _)`) trigger a JavaParser warning under `BLEEDING_EDGE` -language level. The script uses `getResult().isPresent()` (not `isSuccessful()`) so it -proceeds with the partial AST, which is complete enough for annotation removal. - **Build-tool sources** — `build-tools/build-infra/**` contains Gradle plugin sources that use Groovy-interop annotations; several fail to parse. None of them contain test methods, so the failures are harmless. From f9a1ccc18a940cc15a99b501ddd4c6dae7d39032 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 11:46:32 +0200 Subject: [PATCH 46/68] Add setUp, tearDown support, unfortunately. --- dev-tools/refactorings/.editorconfig | 4 ++++ .../complexPhrase/TestComplexPhraseQuery.java | 17 +++++++++-------- .../tests/util/LuceneTestCaseJupiter.java | 10 ++++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/dev-tools/refactorings/.editorconfig b/dev-tools/refactorings/.editorconfig index 78b36ca0838f..87f877b2844b 100644 --- a/dev-tools/refactorings/.editorconfig +++ b/dev-tools/refactorings/.editorconfig @@ -1 +1,5 @@ root = true + +[*] +charset = utf-8 +end_of_line = lf diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java index 9173ce8955eb..260d9df9d65c 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java @@ -38,8 +38,7 @@ import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.analysis.MockSynonymAnalyzer; import org.apache.lucene.tests.util.LuceneTestCaseJupiter; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; +import org.apache.lucene.util.IOUtils; import org.junit.jupiter.api.Test; public class TestComplexPhraseQuery extends LuceneTestCaseJupiter { @@ -245,8 +244,10 @@ public void testBoosts() throws Exception { assertEquals(expected, actual); } - @BeforeEach - void setUp() throws Exception { + @Override + public void setUp() throws Exception { + super.setUp(); + analyzer = new MockAnalyzer(random()); rd = newDirectory(); IndexWriter w = new IndexWriter(rd, newIndexWriterConfig(analyzer)); @@ -262,10 +263,10 @@ void setUp() throws Exception { searcher = newSearcher(reader); } - @AfterEach - void tearDown() throws Exception { - reader.close(); - rd.close(); + @Override + public void tearDown() throws Exception { + IOUtils.close(reader, rd); + super.tearDown(); } static class DocData { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 050a8b6347c2..bbfcd2d21069 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -35,6 +35,8 @@ import java.util.stream.Collectors; import org.apache.lucene.util.IOUtils; import org.jspecify.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; @@ -548,6 +550,14 @@ public void afterEach(ExtensionContext context) throws Exception { // infrastructure. // + /// a [BeforeEach] callback. In subclasses, if you override, you must call `super.setUp` too. + @BeforeEach + public void setUp() throws Exception {} + + /// a [AfterEach] callback. In subclasses, if you override, you must call `super.setUp` too. + @AfterEach + public void tearDown() throws Exception {} + /** * Use explicit, injected {@link Random} or {@code Supplier} parameters on junit jupiter * test methods (or callbacks). From 3ec98a5a94e1a64bd6e340b1ec93c2b8795222cf Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 19:42:08 +0200 Subject: [PATCH 47/68] Remove junit4 repeat annotations. --- .../org/apache/lucene/util/TestMergedIterator.java | 14 -------------- .../lucene/search/highlight/TestTokenSources.java | 3 --- .../lucene/spatial/prefix/TestDateNRStrategy.java | 7 ------- .../spatial/prefix/TestHeatmapFacetCounter.java | 2 -- .../spatial/prefix/TestNumberRangeFacets.java | 2 -- .../prefix/TestRandomSpatialOpFuzzyPrefixTree.java | 4 ---- .../spatial/prefix/tree/TestS2PrefixTree.java | 4 ---- .../lucene/spatial3d/geom/TestGeoExactCircle.java | 4 ---- .../spatial3d/geom/TestRandomBinaryCodec.java | 5 +---- .../lucene/spatial3d/geom/TestRandomPlane.java | 4 ---- 10 files changed, 1 insertion(+), 48 deletions(-) diff --git a/lucene/core/src/test/org/apache/lucene/util/TestMergedIterator.java b/lucene/core/src/test/org/apache/lucene/util/TestMergedIterator.java index 36e03278314e..86f0b56d5b4a 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestMergedIterator.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestMergedIterator.java @@ -16,7 +16,6 @@ */ package org.apache.lucene.util; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -24,7 +23,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; public class TestMergedIterator extends LuceneTestCase { - private static final int REPEATS = 2; private static final int VALS_TO_MERGE = 15000; @SuppressWarnings({"rawtypes", "unchecked"}) @@ -43,62 +41,50 @@ public void testMergeEmpty() { assertFalse(merged.hasNext()); } - @Repeat(iterations = REPEATS) public void testNoDupsRemoveDups() { testCase(1, 1, true); } - @Repeat(iterations = REPEATS) public void testOffItrDupsRemoveDups() { testCase(3, 1, true); } - @Repeat(iterations = REPEATS) public void testOnItrDupsRemoveDups() { testCase(1, 3, true); } - @Repeat(iterations = REPEATS) public void testOnItrRandomDupsRemoveDups() { testCase(1, -3, true); } - @Repeat(iterations = REPEATS) public void testBothDupsRemoveDups() { testCase(3, 3, true); } - @Repeat(iterations = REPEATS) public void testBothDupsWithRandomDupsRemoveDups() { testCase(3, -3, true); } - @Repeat(iterations = REPEATS) public void testNoDupsKeepDups() { testCase(1, 1, false); } - @Repeat(iterations = REPEATS) public void testOffItrDupsKeepDups() { testCase(3, 1, false); } - @Repeat(iterations = REPEATS) public void testOnItrDupsKeepDups() { testCase(1, 3, false); } - @Repeat(iterations = REPEATS) public void testOnItrRandomDupsKeepDups() { testCase(1, -3, false); } - @Repeat(iterations = REPEATS) public void testBothDupsKeepDups() { testCase(3, 3, false); } - @Repeat(iterations = REPEATS) public void testBothDupsWithRandomDupsKeepDups() { testCase(3, -3, false); } diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/highlight/TestTokenSources.java b/lucene/highlighter/src/test/org/apache/lucene/search/highlight/TestTokenSources.java index 6a466822b40a..9a88d011f1b4 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/highlight/TestTokenSources.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/highlight/TestTokenSources.java @@ -16,7 +16,6 @@ */ package org.apache.lucene.search.highlight; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import java.io.IOException; import java.util.Arrays; import org.apache.lucene.analysis.TokenStream; @@ -360,8 +359,6 @@ public void testPayloads() throws Exception { dir.close(); } - @Repeat(iterations = 10) - // @Seed("947083AB20AB2D4F") public void testRandomizedRoundTrip() throws Exception { final int distinct = TestUtil.nextInt(random(), 1, 10); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestDateNRStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestDateNRStrategy.java index 1133895d3bde..cfb60b916622 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestDateNRStrategy.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestDateNRStrategy.java @@ -19,7 +19,6 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt; import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import java.io.IOException; import java.util.Calendar; import org.apache.lucene.spatial.prefix.tree.DateRangePrefixTree; @@ -29,9 +28,6 @@ import org.locationtech.spatial4j.shape.Shape; public class TestDateNRStrategy extends RandomSpatialOpStrategyTestCase { - - static final int ITERATIONS = 10; - DateRangePrefixTree tree; long randomCalWindowMs; @@ -49,17 +45,14 @@ public void setUp() throws Exception { randomCalWindowMs = Math.max(2000L, tmpCal.getTimeInMillis()); } - @Repeat(iterations = ITERATIONS) public void testIntersects() throws IOException { testOperationRandomShapes(SpatialOperation.Intersects); } - @Repeat(iterations = ITERATIONS) public void testWithin() throws IOException { testOperationRandomShapes(SpatialOperation.IsWithin); } - @Repeat(iterations = ITERATIONS) public void testContains() throws IOException { testOperationRandomShapes(SpatialOperation.Contains); } diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestHeatmapFacetCounter.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestHeatmapFacetCounter.java index 6ba025d321c9..8afe91822c76 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestHeatmapFacetCounter.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestHeatmapFacetCounter.java @@ -19,7 +19,6 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.atMost; import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -158,7 +157,6 @@ private void validateHeatmapResultLoop( } } - @Repeat(iterations = 20) public void testRandom() throws IOException { // Tests using random index shapes & query shapes. This has found all sorts of edge case bugs // (e.g. dateline, diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestNumberRangeFacets.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestNumberRangeFacets.java index 5512b49a0d8f..970609ca9d26 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestNumberRangeFacets.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestNumberRangeFacets.java @@ -18,7 +18,6 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; @@ -59,7 +58,6 @@ public void setUp() throws Exception { randomCalWindowMs = Math.max(2000L, tmpCal.getTimeInMillis()); } - @Repeat(iterations = 20) public void test() throws IOException { // generate test data List indexedShapes = new ArrayList<>(); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRandomSpatialOpFuzzyPrefixTree.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRandomSpatialOpFuzzyPrefixTree.java index c9d7e0dbe329..99f171d6ab70 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRandomSpatialOpFuzzyPrefixTree.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRandomSpatialOpFuzzyPrefixTree.java @@ -24,7 +24,6 @@ import static org.locationtech.spatial4j.shape.SpatialRelation.INTERSECTS; import static org.locationtech.spatial4j.shape.SpatialRelation.WITHIN; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -126,19 +125,16 @@ protected RecursivePrefixTreeStrategy newRPT() { return new RecursivePrefixTreeStrategy(this.grid, getClass().getSimpleName()); } - @Repeat(iterations = ITERATIONS) public void testIntersects() throws IOException { setupGrid(-1); doTest(SpatialOperation.Intersects); } - @Repeat(iterations = ITERATIONS) public void testWithin() throws IOException { setupGrid(-1); doTest(SpatialOperation.IsWithin); } - @Repeat(iterations = ITERATIONS) public void testContains() throws IOException { setupGrid(-1); doTest(SpatialOperation.Contains); diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestS2PrefixTree.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestS2PrefixTree.java index c5fe3d7cb2c5..5b2f72d119bb 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestS2PrefixTree.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/TestS2PrefixTree.java @@ -17,7 +17,6 @@ package org.apache.lucene.spatial.prefix.tree; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import com.google.common.geometry.S2CellId; import com.google.common.geometry.S2Projections; import org.apache.lucene.spatial.spatial4j.Geo3dSpatialContextFactory; @@ -29,7 +28,6 @@ /** Test for S2 Spatial prefix tree. */ public class TestS2PrefixTree extends LuceneTestCase { - @Repeat(iterations = 10) public void testCells() { int face = random().nextInt(6); S2CellId id = S2CellId.fromFacePosLevel(face, 0, 0); @@ -67,7 +65,6 @@ public void testCells() { assertEquals(cell, cell2); } - @Repeat(iterations = 10) public void testDistanceAndLevels() { S2PrefixTree tree = new S2PrefixTree( @@ -95,7 +92,6 @@ public void testDistanceAndLevels() { assertTrue(randomDist > distanceLevel); } - @Repeat(iterations = 10) public void testPrecision() { int arity = random().nextInt(3) + 1; SpatialContext context = new Geo3dSpatialContextFactory().newSpatialContext(); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoExactCircle.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoExactCircle.java index 804d47e02cb1..8bc9def80ac5 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoExactCircle.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoExactCircle.java @@ -21,7 +21,6 @@ import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.randomGeoPoint; import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.randomPlanetModel; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator; import org.apache.lucene.tests.util.LuceneTestCase; import org.junit.Test; @@ -79,7 +78,6 @@ public void testSurfacePointOnBearingScale() { } @Test - @Repeat(iterations = 100) public void RandomPointBearingWGS84Test() { PlanetModel planetModel = PlanetModel.WGS84; GeoPoint center = randomGeoPoint(planetModel); @@ -91,7 +89,6 @@ public void RandomPointBearingWGS84Test() { } @Test - @Repeat(iterations = 100) public void RandomPointBearingCardinalTest() { // surface distance calculations methods start not converging when // planet scaledFlattening > 0.4 @@ -190,7 +187,6 @@ public void testBigCircleInSphere() { * in LUCENE-8054 we have problems with exact circles that have edges that are close together. * This test creates those circles with the same center and slightly different radius. */ - @Repeat(iterations = 100) public void testRandomLUCENE8054() { PlanetModel planetModel = randomPlanetModel(); GeoCircle circle1 = diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomBinaryCodec.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomBinaryCodec.java index c571036f505e..53062203d950 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomBinaryCodec.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomBinaryCodec.java @@ -22,7 +22,6 @@ import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.randomPlanetModel; import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.randomShapeType; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -30,7 +29,7 @@ /** Test to check Serialization */ public class TestRandomBinaryCodec extends LuceneTestCase { - @Repeat(iterations = 10) + public void testRandomPointCodec() throws IOException { PlanetModel planetModel = randomPlanetModel(); GeoPoint shape = randomGeoPoint(planetModel); @@ -41,7 +40,6 @@ public void testRandomPointCodec() throws IOException { assertEquals(shape.toString(), shape, shapeCopy); } - @Repeat(iterations = 100) public void testRandomPlanetObjectCodec() throws IOException { PlanetModel planetModel = randomPlanetModel(); int type = randomShapeType(); @@ -53,7 +51,6 @@ public void testRandomPlanetObjectCodec() throws IOException { assertEquals(shape.toString(), shape, shapeCopy); } - @Repeat(iterations = 100) public void testRandomShapeCodec() throws IOException { PlanetModel planetModel = randomPlanetModel(); int type = randomShapeType(); diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomPlane.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomPlane.java index 360670ad7b70..687abb84bea8 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomPlane.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestRandomPlane.java @@ -20,7 +20,6 @@ import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.randomGeoPoint; import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.randomPlanetModel; -import com.carrotsearch.randomizedtesting.annotations.Repeat; import java.util.ArrayList; import java.util.List; import org.apache.lucene.tests.util.LuceneTestCase; @@ -28,7 +27,6 @@ /** Random test for planes. */ public class TestRandomPlane extends LuceneTestCase { - @Repeat(iterations = 10) public void testPlaneAccuracy() { PlanetModel planetModel = randomPlanetModel(); GeoPoint point1 = randomGeoPoint(planetModel); @@ -51,7 +49,6 @@ public void testPlaneAccuracy() { } } - @Repeat(iterations = 10) public void testPlaneThreePointsAccuracy() { PlanetModel planetModel = randomPlanetModel(); for (int i = 0; i < 1000; i++) { @@ -88,7 +85,6 @@ public void testPlaneThreePointsAccuracy() { } } - @Repeat(iterations = 10) public void testPolygonAccuracy() { PlanetModel planetModel = randomPlanetModel(); GeoPoint point1 = randomGeoPoint(planetModel); From 39e3b8d4371fa3b133ab7d67e94f5f464a57adfa Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 19:44:06 +0200 Subject: [PATCH 48/68] Remove @Rule (unused). --- .../lucene/spatial/spatial4j/ShapeRectRelationTestCase.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/ShapeRectRelationTestCase.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/ShapeRectRelationTestCase.java index 992f228e8f73..108fe97d6d96 100644 --- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/ShapeRectRelationTestCase.java +++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/ShapeRectRelationTestCase.java @@ -18,8 +18,6 @@ import static org.locationtech.spatial4j.distance.DistanceUtils.DEGREES_TO_RADIANS; -import org.junit.Rule; -import org.locationtech.spatial4j.TestLog; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Circle; import org.locationtech.spatial4j.shape.Point; @@ -30,8 +28,6 @@ public abstract class ShapeRectRelationTestCase extends RandomizedShapeTestCase { protected static final double RADIANS_PER_DEGREE = Math.PI / 180.0; - @Rule public final TestLog testLog = TestLog.instance; - protected int maxRadius = 180; public ShapeRectRelationTestCase() { From 9fc51315e479af93cb2af59b1e1158756c65d245 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 19:56:45 +0200 Subject: [PATCH 49/68] Correct setup/teardown behavior (junit5 annotations are not inherited). --- .../complexPhrase/TestComplexPhraseQuery.java | 2 +- .../lucene/tests/util/LuceneTestCaseJupiter.java | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java index 260d9df9d65c..cba81e845e99 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java @@ -265,8 +265,8 @@ public void setUp() throws Exception { @Override public void tearDown() throws Exception { - IOUtils.close(reader, rd); super.tearDown(); + IOUtils.close(reader, rd); } static class DocData { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index bbfcd2d21069..556c2efee4b5 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -550,12 +550,22 @@ public void afterEach(ExtensionContext context) throws Exception { // infrastructure. // - /// a [BeforeEach] callback. In subclasses, if you override, you must call `super.setUp` too. + /// [BeforeEach] isn't inherited in junit5, so call this method explicitly, even if overridden. @BeforeEach + void callSetUp() throws Exception { + setUp(); + } + + /// a [BeforeEach] callback. In subclasses, if you override, you must call `super.setUp` too. public void setUp() throws Exception {} - /// a [AfterEach] callback. In subclasses, if you override, you must call `super.setUp` too. + /// [AfterEach] isn't inherited in junit5, so call this method explicitly, even if overridden. @AfterEach + public void callTearDown() throws Exception { + tearDown(); + } + + /// a [AfterEach] callback. In subclasses, if you override, you must call `super.setUp` too. public void tearDown() throws Exception {} /** From cc05043ec626d28dcb54a1be2b6609320c6c9866 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 20:13:01 +0200 Subject: [PATCH 50/68] Remove ai tests/refactoring remnants. --- dev-tools/refactorings/.editorconfig | 5 - .../FindAnnotatedTestMethods.java | 63 ---------- ...TestClassesNotExtendingLuceneTestCase.java | 112 ------------------ .../RemoveRedundantTestAnnotations.java | 91 -------------- .../remove-redundant-test-annotations.md | 50 -------- ...t-classes-not-extending-LuceneTestCase.txt | 51 -------- 6 files changed, 372 deletions(-) delete mode 100644 dev-tools/refactorings/.editorconfig delete mode 100644 dev-tools/refactorings/FindAnnotatedTestMethods.java delete mode 100644 dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java delete mode 100644 dev-tools/refactorings/RemoveRedundantTestAnnotations.java delete mode 100644 dev-tools/refactorings/remove-redundant-test-annotations.md delete mode 100644 dev-tools/refactorings/test-classes-not-extending-LuceneTestCase.txt diff --git a/dev-tools/refactorings/.editorconfig b/dev-tools/refactorings/.editorconfig deleted file mode 100644 index 87f877b2844b..000000000000 --- a/dev-tools/refactorings/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf diff --git a/dev-tools/refactorings/FindAnnotatedTestMethods.java b/dev-tools/refactorings/FindAnnotatedTestMethods.java deleted file mode 100644 index d116979d4c4a..000000000000 --- a/dev-tools/refactorings/FindAnnotatedTestMethods.java +++ /dev/null @@ -1,63 +0,0 @@ -///usr/bin/env jbang "$0" "$@" ; exit $? -//JAVA 17+ -//DEPS com.github.javaparser:javaparser-core:3.28.0 - -import com.github.javaparser.JavaParser; -import com.github.javaparser.ParserConfiguration; -import com.github.javaparser.ast.body.MethodDeclaration; - -import java.io.IOException; -import java.nio.file.*; -import java.util.stream.Stream; - -/** - * Finds all methods whose name starts with "test" and that carry a @Test annotation. - * - * Usage: - * jbang FindAnnotatedTestMethods.java [root-directory] - * - * Docker: - * docker run --rm \ - * -v jbang-cache:/root/.jbang/cache \ - * -v "$(pwd)":/workdir \ - * jbangdev/jbang \ - * jbang /workdir/dev-tools/scripts/FindAnnotatedTestMethods.java /workdir - */ -public class FindAnnotatedTestMethods { - - public static void main(String[] args) throws IOException { - Path root = args.length > 0 ? Paths.get(args[0]) : Paths.get("."); - - var config = new ParserConfiguration() - .setLanguageLevel(ParserConfiguration.LanguageLevel.BLEEDING_EDGE); - var parser = new JavaParser(config); - - try (Stream paths = Files.walk(root)) { - paths.filter(p -> p.toString().endsWith(".java")) - .sorted() - .forEach(file -> { - try { - parser.parse(file).getResult().ifPresent(cu -> - cu.findAll(MethodDeclaration.class).stream() - .filter(m -> m.getNameAsString().startsWith("test")) - .filter(m -> m.getAnnotations().stream() - .anyMatch(a -> a.getNameAsString().equals("Test"))) - .forEach(m -> { - int line = m.getBegin().map(p -> p.line).orElse(-1); - String rel = root.relativize(file).toString(); - String ann = m.getAnnotations().stream() - .filter(a -> a.getNameAsString().equals("Test")) - .findFirst() - .map(Object::toString) - .orElse("@Test"); - System.out.printf("%s:%d: %s %s%n", - rel, line, ann, m.getSignature()); - }) - ); - } catch (IOException e) { - System.err.println("# skip: " + file + " — " + e.getMessage()); - } - }); - } - } -} diff --git a/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java b/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java deleted file mode 100644 index e6847cdabd7c..000000000000 --- a/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java +++ /dev/null @@ -1,112 +0,0 @@ -///usr/bin/env jbang "$0" "$@" ; exit $? -//JAVA 17+ -//DEPS com.github.javaparser:javaparser-core:3.28.0 - -import com.github.javaparser.JavaParser; -import com.github.javaparser.ParserConfiguration; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; - -import java.io.IOException; -import java.nio.file.*; -import java.util.*; -import java.util.stream.*; - -/** - * Finds test classes (in src/test trees) that do not descend from LuceneTestCase. - * - * A "test class" is any non-abstract class in a src/test source tree that has at - * least one method whose name starts with "test". - * - * The superclass graph is built from ALL .java files under the given root (both - * src/main and src/test), so abstract base classes defined inside the project are - * resolved transitively. Classes whose superclass cannot be resolved within the - * project are flagged with "(unresolved)" — those are the ones most worth reviewing. - * - * Usage / Docker: - * docker run --rm \ - * -v jbang-cache:/root/.jbang/cache \ - * -v "$(pwd)":/workdir \ - * jbangdev/jbang \ - * /workdir/dev-tools/refactorings/FindTestClassesNotExtendingLuceneTestCase.java /workdir - */ -public class FindTestClassesNotExtendingLuceneTestCase { - - public static void main(String[] args) throws IOException { - Path root = args.length > 0 ? Paths.get(args[0]) : Paths.get("."); - - var config = new ParserConfiguration() - .setLanguageLevel(ParserConfiguration.LanguageLevel.BLEEDING_EDGE); - var parser = new JavaParser(config); - - // simple class name -> simple superclass name (first declared, ignoring generics) - Map superOf = new HashMap<>(); - // simple class name -> relative file path, for test classes with test* methods - Map testClasses = new LinkedHashMap<>(); - - try (Stream paths = Files.walk(root)) { - paths.filter(p -> p.toString().endsWith(".java")) - .sorted() - .forEach(file -> { - try { - var result = parser.parse(file); - if (!result.getResult().isPresent()) return; - - String rel = root.relativize(file).toString(); - boolean isTestTree = rel.contains("/src/test/"); - - result.getResult().get() - .findAll(ClassOrInterfaceDeclaration.class).forEach(cls -> { - if (cls.isInterface()) return; - - String name = cls.getNameAsString(); - - // Record superclass (simple name, strip generics) - cls.getExtendedTypes().stream().findFirst().ifPresent(t -> - superOf.put(name, t.getNameAsString())); - - // A test class: non-abstract, in a test tree, has test* methods - if (isTestTree && !cls.isAbstract()) { - boolean hasTestMethods = cls.findAll(MethodDeclaration.class) - .stream() - .anyMatch(m -> m.getNameAsString().startsWith("test")); - if (hasTestMethods) { - testClasses.put(name, rel); - } - } - }); - } catch (IOException e) { - System.err.println("# skip: " + file); - } - }); - } - - // Transitive closure: all classes that are descendants of LuceneTestCase - Set descendants = new HashSet<>(); - descendants.add("LuceneTestCase"); - boolean changed = true; - while (changed) { - changed = false; - for (var entry : superOf.entrySet()) { - if (descendants.contains(entry.getValue()) && descendants.add(entry.getKey())) { - changed = true; - } - } - } - - // Report test classes outside the LuceneTestCase hierarchy - long count = testClasses.entrySet().stream() - .filter(e -> !descendants.contains(e.getKey())) - .peek(e -> { - String sup = superOf.containsKey(e.getKey()) - ? superOf.get(e.getKey()) - : "(no superclass)"; - boolean resolved = descendants.contains(sup) || superOf.containsKey(sup); - String tag = resolved ? "" : " *** unresolved superclass"; - System.out.printf("%s [extends %s]%s%n", e.getValue(), sup, tag); - }) - .count(); - - System.err.printf("%n# %d test class(es) not descending from LuceneTestCase%n", count); - } -} diff --git a/dev-tools/refactorings/RemoveRedundantTestAnnotations.java b/dev-tools/refactorings/RemoveRedundantTestAnnotations.java deleted file mode 100644 index 9295f36b83e6..000000000000 --- a/dev-tools/refactorings/RemoveRedundantTestAnnotations.java +++ /dev/null @@ -1,91 +0,0 @@ -///usr/bin/env jbang "$0" "$@" ; exit $? -//JAVA 17+ -//DEPS com.github.javaparser:javaparser-core:3.28.0 - -import com.github.javaparser.JavaParser; -import com.github.javaparser.ParserConfiguration; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.expr.AnnotationExpr; -import com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter; - -import java.io.IOException; -import java.nio.file.*; -import java.util.List; -import java.util.stream.Stream; - -/** - * Removes redundant @Test annotations from methods whose names already start with "test". - * Also removes the "import org.junit.Test" line if no other @Test usages remain in the file. - * Uses LexicalPreservingPrinter so only the removed nodes are affected; no reformatting occurs. - * - * Usage: - * jbang RemoveRedundantTestAnnotations.java [root-directory] - * - * Docker: - * docker run --rm \ - * -v jbang-cache:/root/.jbang/cache \ - * -v "$(pwd)":/workdir \ - * jbangdev/jbang \ - * /workdir/dev-tools/scripts/RemoveRedundantTestAnnotations.java /workdir - */ -public class RemoveRedundantTestAnnotations { - - public static void main(String[] args) throws IOException { - Path root = args.length > 0 ? Paths.get(args[0]) : Paths.get("."); - - var config = new ParserConfiguration() - .setLanguageLevel(ParserConfiguration.LanguageLevel.BLEEDING_EDGE); - var parser = new JavaParser(config); - - try (Stream paths = Files.walk(root)) { - paths.filter(p -> p.toString().endsWith(".java")) - .sorted() - .forEach(file -> { - try { - var result = parser.parse(file); - if (!result.isSuccessful()) { - System.err.println("# parse error: " + file); - return; - } - - CompilationUnit cu = result.getResult().get(); - LexicalPreservingPrinter.setup(cu); - - boolean modified = false; - - for (MethodDeclaration m : cu.findAll(MethodDeclaration.class)) { - if (!m.getNameAsString().startsWith("test")) continue; - - List toRemove = m.getAnnotations().stream() - .filter(a -> a.getNameAsString().equals("Test")) - .toList(); - - for (AnnotationExpr ann : toRemove) { - m.getAnnotations().remove(ann); - modified = true; - } - } - - if (!modified) return; - - // Remove the import if no @Test annotations remain anywhere in the file. - boolean hasOtherTestAnnotations = cu.findAll(AnnotationExpr.class).stream() - .anyMatch(a -> a.getNameAsString().equals("Test")); - - if (!hasOtherTestAnnotations) { - cu.getImports().removeIf(imp -> - imp.getNameAsString().equals("org.junit.Test")); - } - - String rel = root.relativize(file).toString(); - System.out.println(rel); - Files.writeString(file, LexicalPreservingPrinter.print(cu)); - - } catch (IOException e) { - System.err.println("# error: " + file + " — " + e.getMessage()); - } - }); - } - } -} diff --git a/dev-tools/refactorings/remove-redundant-test-annotations.md b/dev-tools/refactorings/remove-redundant-test-annotations.md deleted file mode 100644 index 201c2bffb4d1..000000000000 --- a/dev-tools/refactorings/remove-redundant-test-annotations.md +++ /dev/null @@ -1,50 +0,0 @@ -# Removing redundant @Test annotations from test* methods - -In Lucene's test framework (RandomizedTesting / LuceneTestCase), any method whose name -starts with `test` is automatically discovered as a test — the `@Test` annotation is -redundant on those methods. These scripts find and remove them. - -## Prerequisites - -Docker (no local Java/Maven needed). The named volume `jbang-cache` persists downloaded -jars so the second run is instant. - -## Step 1 — audit (find, don't touch) - -```bash -docker run --rm \ - -v jbang-cache:/root/.jbang/cache \ - -v "$(pwd)":/workdir \ - jbangdev/jbang \ - /workdir/dev-tools/refactorings/FindAnnotatedTestMethods.java /workdir 2>/dev/null -``` - -Output: one line per match — `path/to/File.java:line: @Test methodSignature(...)`. -Pipe through `grep -v '@Test test'` to surface any non-plain `@Test(...)` survivors. - -## Step 2 — remove - -```bash -docker run --rm \ - -v jbang-cache:/root/.jbang/cache \ - -v "$(pwd)":/workdir \ - jbangdev/jbang \ - /workdir/dev-tools/refactorings/RemoveRedundantTestAnnotations.java /workdir 2>/dev/null -``` - -- Prints each modified file path to stdout. -- Uses `LexicalPreservingPrinter` — only the removed annotation node is touched, - no other reformatting occurs. -- Also removes `import org.junit.Test;` from files where no `@Test` usages remain. -- Run it twice if you see output: the second run should produce nothing (idempotent). - -## Known quirks - -**Build-tool sources** — `build-tools/build-infra/**` contains Gradle plugin sources -that use Groovy-interop annotations; several fail to parse. None of them contain test -methods, so the failures are harmless. - -## Re-running after new test files are added - -Just run Step 2 again from the repo root. It is idempotent: files with no redundant -annotations are left untouched. diff --git a/dev-tools/refactorings/test-classes-not-extending-LuceneTestCase.txt b/dev-tools/refactorings/test-classes-not-extending-LuceneTestCase.txt deleted file mode 100644 index e2a882cd82c7..000000000000 --- a/dev-tools/refactorings/test-classes-not-extending-LuceneTestCase.txt +++ /dev/null @@ -1,51 +0,0 @@ -lucene/analysis/common - lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspellRepositoryTestCases.java [extends (no superclass)] *** unresolved superclass - -lucene/core - lucene/core/src/test/org/apache/lucene/document/TestXYLineShapeQueries.java [extends Validator] *** unresolved superclass - lucene/core/src/test/org/apache/lucene/document/TestXYMultiLineShapeQueries.java [extends Validator] *** unresolved superclass - lucene/core/src/test/org/apache/lucene/document/TestXYMultiPointShapeQueries.java [extends Validator] *** unresolved superclass - lucene/core/src/test/org/apache/lucene/document/TestXYMultiPolygonShapeQueries.java [extends Validator] *** unresolved superclass - lucene/core/src/test/org/apache/lucene/document/TestXYPointShapeQueries.java [extends Validator] *** unresolved superclass - lucene/core/src/test/org/apache/lucene/document/TestXYPolygonShapeQueries.java [extends Validator] *** unresolved superclass - lucene/core/src/test/org/apache/lucene/index/TestClassloadingDeadlock.java [extends Assert] *** unresolved superclass - lucene/core/src/test/org/apache/lucene/search/TestMultiThreadTermVectors.java [extends Thread] *** unresolved superclass - -lucene/core.tests - lucene/core.tests/src/test/org/apache/lucene/core/tests/TestRuntimeDependenciesSane.java [extends (no superclass)] *** unresolved superclass - -lucene/distribution.tests - lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestModularLayer.java [extends AbstractLuceneDistributionTest] - lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestScripts.java [extends AbstractLuceneDistributionTest] - -lucene/memory - lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java [extends LuceneTestCaseJupiter] - lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java [extends LuceneTestCaseJupiter] - lucene/memory/src/test/org/apache/lucene/index/memory/TestSlicedIntBlockPool.java [extends LuceneTestCaseJupiter] - -lucene/monitor - lucene/monitor/src/test/org/apache/lucene/monitor/outsidepackage/TestCandidateMatcherVisibility.java [extends (no superclass)] *** unresolved superclass - -lucene/queryparser - lucene/queryparser/src/test/org/apache/lucene/queryparser/complexPhrase/TestComplexPhraseQuery.java [extends LuceneTestCaseJupiter] - -lucene/suggest - lucene/suggest/src/test/org/apache/lucene/search/suggest/SuggestRebuildTestUtil.java [extends (no superclass)] *** unresolved superclass - -lucene/test-framework - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestBeforeAfterOverrides.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestCodecReported.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestExceptionInBeforeClassHooks.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestFailIfDirectoryNotClosed.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestFailIfUnreferencedFiles.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestJUnitRuleOrder.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestJvmInfo.java [extends RandomizedTest] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestMaxFailuresRule.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestReproduceMessage.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestReproduceMessageWithRepeated.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSeedFromUncaught.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSetupTeardownChaining.java [extends WithNestedTests] *** unresolved superclass - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSysoutsLimits.java [extends ParentNestedTest] - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSysoutsLimits.java [extends ParentNestedTest] - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSysoutsLimits.java [extends ParentNestedTest] - lucene/test-framework/src/test/org/apache/lucene/tests/util/TestSysoutsLimits.java [extends WithNestedTests] *** unresolved superclass From 74a83e355e2f2b8440b8070ff03d284bdbd1ade7 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 20:36:38 +0200 Subject: [PATCH 51/68] Apply prek fixes. --- lucene/MIGRATE.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lucene/MIGRATE.md b/lucene/MIGRATE.md index 1f473a1fab18..41fd8a4e18f9 100644 --- a/lucene/MIGRATE.md +++ b/lucene/MIGRATE.md @@ -31,19 +31,19 @@ support. #### Key changes -* All tests must be Jupiter tests, typically this means +- All tests must be Jupiter tests, typically this means methods must be annotated with `@Test`. Method prefix `test*` is not sufficient. Methods that are named `test*` but are not tests will cause validation errors. -* You can use parameterized tests, dynamic tests, etc. All these are supported. -* You *must not* call the static `random()` method on the parent +- You can use parameterized tests, dynamic tests, etc. All these are supported. +- You *must not* call the static `random()` method on the parent class, even though it is there. Add a `Random` parameter to your test methods or callbacks - it will be automatically injected by the test framework. See the `memory` module tests for examples. -* Use `@BeforeEach`, `@AfterEach` and other junit5-specific callback +- Use `@BeforeEach`, `@AfterEach` and other junit5-specific callback annotations instead of `setUp` and `tearDown` methods. -* Static utility methods have been pulled up to a parent class +- Static utility methods have been pulled up to a parent class called `LuceneTestCaseParent` but you should reference them either without an explicit type or via the type of the parent class for your test framework. The parent class may be removed in the future. @@ -337,7 +337,7 @@ Support for the optional complement syntax (`~`) that was deprecated in Lucene 1 has been removed. The `DEPRECATED_COMPLEMENT` flag and `REGEXP_DEPRECATED_COMPLEMENT` enum value are no longer available. -Users should migrate to using _complement bracket expressions_ (`[^...]`) instead. +Users should migrate to using *complement bracket expressions* (`[^...]`) instead. For example, `[^fo]` matches any character that is not an `f` or `o`. ### DocValuesFieldExistsQuery, NormsFieldExistsQuery and KnnVectorFieldExistsQuery removed in favor of FieldExistsQuery (LUCENE-10436) From 59d42239cec65c1fa2dfc1e011f638300c17a8a7 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 20:40:55 +0200 Subject: [PATCH 52/68] Remove wildcard import. --- .../apache/lucene/tests/util/TestEnvInfo.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestEnvInfo.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestEnvInfo.java index 0d148d7f4f36..9518e39b8479 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestEnvInfo.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TestEnvInfo.java @@ -17,7 +17,24 @@ package org.apache.lucene.tests.util; -import static org.apache.lucene.tests.util.LuceneTestCaseParent.*; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.DEFAULT_LINE_DOCS_FILE; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.JENKINS_LARGE_LINE_DOCS_FILE; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.RANDOM_MULTIPLIER; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.SYSPROP_AWAITSFIX; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.SYSPROP_MONSTER; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.SYSPROP_NIGHTLY; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.SYSPROP_WEEKLY; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_ASSERTS_ENABLED; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_AWAITSFIX; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_CODEC; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_DIRECTORY; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_DOCVALUESFORMAT; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_LINE_DOCS_FILE; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_MONSTER; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_NIGHTLY; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_POSTINGSFORMAT; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.TEST_WEEKLY; +import static org.apache.lucene.tests.util.LuceneTestCaseParent.defaultRandomMultiplier; import java.io.PrintWriter; import java.io.StringWriter; From 63e27f78f3fe570c3f0c3d34e991b02506968b9a Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 21:13:15 +0200 Subject: [PATCH 53/68] Add suppressions to several static fields. --- .../lucene/index/memory/TestMemoryIndexAgainstDirectory.java | 2 +- .../src/java/org/apache/lucene/tests/util/LuceneTestCase.java | 1 + .../org/apache/lucene/tests/util/LuceneTestCaseJupiter.java | 3 ++- .../org/apache/lucene/tests/util/LuceneTestCaseParent.java | 1 + .../lucene/tests/util/RunListenerPrintReproduceInfo.java | 1 + .../apache/lucene/tests/util/TestLuceneTestCaseJupiter.java | 2 ++ 6 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java index e902c1f02d6d..b58c1ea1c171 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndexAgainstDirectory.java @@ -97,7 +97,7 @@ * same results for queries on some randomish indexes. */ public class TestMemoryIndexAgainstDirectory extends LuceneTestCaseJupiter { - private static Set queries = new HashSet<>(); + private static final Set queries = new HashSet<>(); @BeforeAll public static void prepare() throws Exception { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index 9b8f04c9904f..dfbf09d403e5 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -358,6 +358,7 @@ public static TestRuleIgnoreAfterMaxFailures replaceMaxFailureRule( RuleChain.outerRule(new TestRuleIgnoreTestSuites()) .around( new TestRuleAdapter() { + @SuppressWarnings("NonFinalStaticField") private static TestFrameworkInfra testFrameworkInfra; @Override diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 556c2efee4b5..56dc5d6fb797 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -400,6 +400,7 @@ static class PrintReproduceInfoExtension public static final CharSequence TEST_ENV_LEAD = TestEnvInfo.TEST_ENV_LEAD; // Used for tests only to replace syserrs. + @SuppressWarnings("NonFinalStaticField") public static PrintStream debugStream; TestEnvInfo testEnvInfo; @@ -536,7 +537,7 @@ public void afterEach(ExtensionContext context) throws Exception { @RegisterExtension @Order(2) - static ClassLevelCallbackChain classLevelCallbackChain = + static final ClassLevelCallbackChain classLevelCallbackChain = new ClassLevelCallbackChain( Objects.requireNonNull(suiteFailureTracker), Objects.requireNonNull(printReproduceInfoExtension)); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index ab9a311a349b..f7433e7bc970 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -2832,5 +2832,6 @@ public static Path createTempFile(String prefix, String suffix) throws IOExcepti // // TODO: to remove from here? // + @SuppressWarnings("NonFinalStaticField") static FieldToType fieldToType = new FieldToType(); } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java index f06259bc410b..eda3a5a7d9d2 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/RunListenerPrintReproduceInfo.java @@ -46,6 +46,7 @@ public final class RunListenerPrintReproduceInfo extends RunListener { private boolean suppressReproduceLine; /** Environment settings for the run. Set by {@link LuceneTestCase}. */ + @SuppressWarnings("NonFinalStaticField") static TestEnvInfo envInfoJunit4; @Override diff --git a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java index 32a9a2e8efcd..a1333834c4a0 100644 --- a/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/test/org/apache/lucene/tests/util/TestLuceneTestCaseJupiter.java @@ -74,6 +74,7 @@ enum Pointcut { AFTER_ALL, } + @SuppressWarnings("NonFinalStaticField") static Map pointcuts; private static void call(Pointcut pointcut) throws Throwable { @@ -404,6 +405,7 @@ public void testIndexWriterIsRestoredAfterEachTest() throws Exception { } static class AlterIndexSearcher extends LuceneTestCaseJupiter { + @SuppressWarnings("NonFinalStaticField") static int expectedValue; @Test From 4385082a4a78db591e2b113de4e9a4be512041fc Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 21:27:12 +0200 Subject: [PATCH 54/68] Remove unused modules. --- lucene/test-framework/src/java/module-info.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/lucene/test-framework/src/java/module-info.java b/lucene/test-framework/src/java/module-info.java index 644d10b58d85..b841ae72c441 100644 --- a/lucene/test-framework/src/java/module-info.java +++ b/lucene/test-framework/src/java/module-info.java @@ -25,8 +25,6 @@ requires transitive com.carrotsearch.randomizedtesting; requires transitive org.junit.jupiter.api; requires org.hamcrest; - requires java.management; - requires org.junit.platform.engine; // Open certain packages for junit because it scans methods via reflection. opens org.apache.lucene.tests.index to From a80c363787251300a2a13020a4057a1861139c51 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sat, 2 May 2026 21:34:57 +0200 Subject: [PATCH 55/68] Add missing javadocs. --- .../java/org/apache/lucene/tests/util/CustomMethodOrderer.java | 1 + .../org/apache/lucene/tests/util/EnsureSequentialExecution.java | 1 + .../java/org/apache/lucene/tests/util/LuceneTestCaseParent.java | 1 + .../src/java/org/apache/lucene/tests/util/TagState.java | 1 + 4 files changed, 4 insertions(+) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/CustomMethodOrderer.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/CustomMethodOrderer.java index e63bf6da4755..68bec397346a 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/CustomMethodOrderer.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/CustomMethodOrderer.java @@ -27,6 +27,7 @@ import org.junit.jupiter.api.MethodOrdererContext; import org.junit.jupiter.api.parallel.ExecutionMode; +/** A {@link MethodOrderer} that provides random-seed dependent ordering. */ public final class CustomMethodOrderer implements MethodOrderer { @Override public void orderMethods(MethodOrdererContext context) { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/EnsureSequentialExecution.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/EnsureSequentialExecution.java index 42b18ad93242..4944c17e1c78 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/EnsureSequentialExecution.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/EnsureSequentialExecution.java @@ -20,6 +20,7 @@ import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.parallel.ExecutionMode; +/** An extension to ensure we're running in single-thread (same-thread) mode. */ public class EnsureSequentialExecution implements BeforeAllCallback { @Override public void beforeAll(ExtensionContext context) throws Exception { diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index f7433e7bc970..b72bdceebcac 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -332,6 +332,7 @@ public static Random nonAssertingRandom(Random rnd) { // to this class. // ----------------------------------------------------------------- + /** Junit4/Junit5-dependent implementations. */ protected interface TestFrameworkInfra { Random threadRandom(); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java index f4ba5e23dc0b..a0db4564e039 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/TagState.java @@ -39,6 +39,7 @@ String sysProperty(); + /** Execution condition to ignore a tagged test depending on the tag's system property state. */ final class Condition implements ExecutionCondition { @Override public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { From 3c4e1ced399648d8b57770e921ee57b618f7a7c0 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sun, 3 May 2026 14:29:16 +0200 Subject: [PATCH 56/68] Move fieldToType to framework specific subclasses. --- .../apache/lucene/tests/util/FieldToType.java | 6 ++++- .../lucene/tests/util/LuceneTestCase.java | 22 ++++++++++++++----- .../tests/util/LuceneTestCaseJupiter.java | 12 ++++++++++ .../tests/util/LuceneTestCaseParent.java | 10 +++------ 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/FieldToType.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/FieldToType.java index e8a7260b66a5..a8d0ef494a04 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/FieldToType.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/FieldToType.java @@ -28,7 +28,11 @@ class FieldToType implements BeforeAfterCallback { private final Map fieldToType = new HashMap<>(); @Override - public synchronized void after() throws Exception { + public void after() throws Exception { + reset(); + } + + synchronized void reset() { fieldToType.clear(); } diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java index dfbf09d403e5..a8f51bf0511d 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCase.java @@ -55,6 +55,8 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; import java.util.regex.Pattern; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; import org.apache.lucene.tests.codecs.asserting.AssertingCodec; import org.junit.After; import org.junit.Before; @@ -67,13 +69,14 @@ /// Base class for all Lucene unit tests (JUnit4 variant). /// -/// **Please consider using the new JUnit Jupiter base class [LuceneTestCaseJupiter] instead. This class -/// will be eventually removed from Lucene codebase.** +/// **Please consider using the new JUnit Jupiter base class [LuceneTestCaseJupiter] instead. This +/// class will be eventually removed from Lucene codebase.** /// /// ## Class and instance setup /// /// The preferred way to specify class (suite-level) setup/cleanup is to use static methods -/// annotated with [org.junit.BeforeClass] and [org.junit.AfterClass]. Any code in these methods is executed +/// annotated with [org.junit.BeforeClass] and [org.junit.AfterClass]. Any code in these methods +/// is executed /// within the test framework's control and ensure proper setup has been made. **Try not to use /// static initializers (including complex final field initializers).** Static initializers are /// executed before any setup rules are fired and may cause you (or somebody else) headaches. @@ -107,7 +110,7 @@ /// - as part of the main thread executing the test case (if your test hangs, just dump the stack /// trace of all threads, and you'll see the seed), /// - the master seed can also be accessed manually by getting the current context ( -/// [RandomizedContext#current()]) and then calling +/// [RandomizedContext#current()]) and then callingd /// [RandomizedContext#getRunnerSeedAsString()]. /// @RunWith(RandomizedRunner.class) @@ -340,6 +343,8 @@ public static TestRuleIgnoreAfterMaxFailures replaceMaxFailureRule( @SuppressWarnings("NonFinalStaticField") private static TestRuleMarkFailure suiteFailureMarker; + private static final FieldToType fieldToType; + static { var setupAndRestoreClassEnv = new SetupAndRestoreStaticEnv( @@ -410,6 +415,12 @@ public TemporaryFilesSupplier getTempFilesSupplier() { public SuiteFailureState getSuiteFailureState() { return suiteFailureMarker; } + + @Override + public Field newField( + Random random, String name, Object value, FieldType type) { + return fieldToType.newField(random, name, value, type); + } }); } @@ -446,6 +457,7 @@ protected boolean verify(Method key) { // side-effect "user.language", "user.timezone")) .around(new CallbacksToRuleAdapter(setupAndRestoreClassEnv)) + .around(new CallbacksToRuleAdapter(fieldToType = new FieldToType())) .around( new CallbacksToRuleAdapter( new BeforeAfterCallback() { @@ -513,7 +525,7 @@ public void tearDown() throws Exception { // Test is supposed to call this itself, but we do this defensively in case it forgot: restoreIndexWriterMaxDocs(); - fieldToType.after(); + fieldToType.reset(); } // ----------------------------------------------------------------- diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java index 56dc5d6fb797..e0be5b494d97 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseJupiter.java @@ -33,6 +33,8 @@ import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldType; import org.apache.lucene.util.IOUtils; import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; @@ -275,6 +277,8 @@ static class ClassLevelCallbackChain private TestFrameworkInfra jupiterFrameworkInfra; private OrderedBeforeAfterCallbacks beforeAfters; + private FieldToType fieldToType; + ClassLevelCallbackChain( SuiteFailureTracker suiteFailureTracker, PrintReproduceInfoExtension printReproduceInfoExtension) { @@ -298,6 +302,8 @@ public void beforeAll(ExtensionContext context) throws Exception { suiteFailureTracker, LuceneTestCaseJupiter::random, () -> activeTestClass); var perThreadRandom = new PerThreadRandom(getRandomSupplier(context.getExecutableInvoker())); + fieldToType = new FieldToType(); + this.jupiterFrameworkInfra = new TestFrameworkInfra() { @Override @@ -319,6 +325,11 @@ public TemporaryFilesSupplier getTempFilesSupplier() { public SuiteFailureState getSuiteFailureState() { return suiteFailureTracker; } + + @Override + public Field newField(Random random, String name, Object value, FieldType type) { + return fieldToType.newField(random, name, value, type); + } }; var installFrameworkInfraSupport = @@ -356,6 +367,7 @@ public void before() throws Exception { perThreadRandom, installFrameworkInfraSupport, classEnvRule, + fieldToType, installEnvInfo, tempFileSupplier)); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java index b72bdceebcac..9fcfb9e259d7 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/LuceneTestCaseParent.java @@ -341,6 +341,8 @@ protected interface TestFrameworkInfra { TemporaryFilesSupplier getTempFilesSupplier(); SuiteFailureState getSuiteFailureState(); + + Field newField(Random random, String name, Object value, FieldType type); } private static final AtomicReference testFrameworkInfra = @@ -2071,7 +2073,7 @@ public static Field newField(Random random, String name, Object value, FieldType // write-once schema sort of helper class then we can // remove the sync here. We can also fold the random // "enable norms" (now commented out, below) into that: - return fieldToType.newField(random, name, value, type); + return getTestFrameworkInfra().newField(random, name, value, type); } private static final String[] availableLanguageTags = @@ -2829,10 +2831,4 @@ public static Path createTempDir(String prefix) { public static Path createTempFile(String prefix, String suffix) throws IOException { return getTestFrameworkInfra().getTempFilesSupplier().createTempFile(prefix, suffix); } - - // - // TODO: to remove from here? - // - @SuppressWarnings("NonFinalStaticField") - static FieldToType fieldToType = new FieldToType(); } From 40f62b3339a0d0b43b0fd77dd1337a9cf9e6f974 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sun, 3 May 2026 14:37:49 +0200 Subject: [PATCH 57/68] Convert lucene/expressions to junit5. --- .../expressions/TestDemoExpressions.java | 34 +++++++++++++------ .../expressions/TestExpressionRescorer.java | 25 ++++++++------ .../expressions/TestExpressionSortField.java | 8 +++-- .../expressions/TestExpressionSorts.java | 25 ++++++++------ .../expressions/TestExpressionValidation.java | 13 +++++-- .../TestExpressionValueSource.java | 31 ++++++++++------- .../expressions/js/CompilerTestCase.java | 4 +-- .../lucene/expressions/js/TestAPISanity.java | 2 ++ .../expressions/js/TestCustomFunctions.java | 17 ++++++++++ .../expressions/js/TestExpressionMath.java | 6 ++-- .../js/TestJavascriptCompiler.java | 13 +++++++ .../js/TestJavascriptFunction.java | 27 +++++++++++++++ .../js/TestJavascriptOperations.java | 28 +++++++++++++++ .../expressions/js/TestVariableContext.java | 10 ++++++ 14 files changed, 190 insertions(+), 53 deletions(-) diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java index 11b064463578..3af9dc20463f 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java @@ -20,6 +20,7 @@ import static org.apache.lucene.expressions.js.VariableContext.Type.MEMBER; import static org.apache.lucene.expressions.js.VariableContext.Type.STR_INDEX; +import java.util.Random; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumericDocValuesField; @@ -37,19 +38,22 @@ import org.apache.lucene.search.TopFieldDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; +import org.apache.lucene.util.IOUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** simple demo of using expressions */ -public class TestDemoExpressions extends LuceneTestCase { +public class TestDemoExpressions extends LuceneTestCaseJupiter { IndexSearcher searcher; DirectoryReader reader; Directory dir; - @Override - public void setUp() throws Exception { - super.setUp(); + @BeforeEach + final void beforeEach(Random random) throws Exception { dir = newDirectory(); - RandomIndexWriter iw = new RandomIndexWriter(random(), dir); + RandomIndexWriter iw = new RandomIndexWriter(random, dir); Document doc = new Document(); doc.add(newStringField("id", "1", Field.Store.YES)); @@ -80,14 +84,13 @@ public void setUp() throws Exception { iw.close(); } - @Override - public void tearDown() throws Exception { - reader.close(); - dir.close(); - super.tearDown(); + @AfterEach + final void afterEach() throws Exception { + IOUtils.close(reader, dir); } /** an example of how to rank by an expression */ + @Test public void test() throws Exception { // compile an expression: Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)"); @@ -104,6 +107,7 @@ public void test() throws Exception { } /** tests the returned sort values are correct */ + @Test public void testSortValues() throws Exception { Expression expr = JavascriptCompiler.compile("sqrt(_score)"); @@ -122,6 +126,7 @@ public void testSortValues() throws Exception { } /** tests same binding used more than once in an expression */ + @Test public void testTwoOfSameBinding() throws Exception { Expression expr = JavascriptCompiler.compile("_score + _score"); @@ -140,6 +145,7 @@ public void testTwoOfSameBinding() throws Exception { } /** Uses variables with $ */ + @Test public void testDollarVariable() throws Exception { Expression expr = JavascriptCompiler.compile("$0+$score"); @@ -159,6 +165,7 @@ public void testDollarVariable() throws Exception { } /** tests expression referring to another expression */ + @Test public void testExpressionRefersToExpression() throws Exception { Expression expr1 = JavascriptCompiler.compile("_score"); Expression expr2 = JavascriptCompiler.compile("2*expr1"); @@ -179,6 +186,7 @@ public void testExpressionRefersToExpression() throws Exception { } /** tests huge amounts of variables in the expression */ + @Test public void testLotsOfBindings() throws Exception { doTestLotsOfBindings(Byte.MAX_VALUE - 1); doTestLotsOfBindings(Byte.MAX_VALUE); @@ -211,6 +219,7 @@ private void doTestLotsOfBindings(int n) throws Exception { } } + @Test public void testDistanceSort() throws Exception { Expression distance = JavascriptCompiler.compile("haversin(40.7143528,-74.0059731,latitude,longitude)"); @@ -230,6 +239,7 @@ public void testDistanceSort() throws Exception { assertEquals(5.2859D, (Double) d.fields[0], 1E-1); } + @Test public void testHaversinMetersDistanceSort() throws Exception { Expression distance = JavascriptCompiler.compile("haversinMeters(40.7143528,-74.0059731,latitude,longitude)"); @@ -249,6 +259,7 @@ public void testHaversinMetersDistanceSort() throws Exception { assertEquals(5285.9D, (Double) d.fields[0], 1E-1); } + @Test public void testStaticExtendedVariableExample() throws Exception { Expression popularity = JavascriptCompiler.compile("doc[\"popularity\"].value"); SimpleBindings bindings = new SimpleBindings(); @@ -266,6 +277,7 @@ public void testStaticExtendedVariableExample() throws Exception { assertEquals(2D, (Double) d.fields[0], 1E-4); } + @Test public void testDynamicExtendedVariableExample() throws Exception { Expression popularity = JavascriptCompiler.compile("doc['popularity'].value + magicarray[0] + fourtytwo"); diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionRescorer.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionRescorer.java index 01a012de3469..0b29b236843e 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionRescorer.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionRescorer.java @@ -16,6 +16,7 @@ */ package org.apache.lucene.expressions; +import java.util.Random; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumericDocValuesField; @@ -32,20 +33,23 @@ import org.apache.lucene.search.similarities.ClassicSimilarity; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; +import org.apache.lucene.util.IOUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class TestExpressionRescorer extends LuceneTestCase { +public class TestExpressionRescorer extends LuceneTestCaseJupiter { IndexSearcher searcher; DirectoryReader reader; Directory dir; - @Override - public void setUp() throws Exception { - super.setUp(); + @BeforeEach + final void beforeEach(Random random) throws Exception { dir = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter( - random(), dir, newIndexWriterConfig().setSimilarity(new ClassicSimilarity())); + random, dir, newIndexWriterConfig().setSimilarity(new ClassicSimilarity())); Document doc = new Document(); doc.add(newStringField("id", "1", Field.Store.YES)); @@ -72,13 +76,12 @@ public void setUp() throws Exception { iw.close(); } - @Override - public void tearDown() throws Exception { - reader.close(); - dir.close(); - super.tearDown(); + @AfterEach + final void afterEach() throws Exception { + IOUtils.close(reader, dir); } + @Test public void testBasic() throws Exception { // create a sort field and sort by it (reverse order) diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSortField.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSortField.java index 6351dec17855..312fcb08931c 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSortField.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSortField.java @@ -19,10 +19,12 @@ import org.apache.lucene.expressions.js.JavascriptCompiler; import org.apache.lucene.search.DoubleValuesSource; import org.apache.lucene.search.SortField; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; +import org.junit.jupiter.api.Test; -public class TestExpressionSortField extends LuceneTestCase { +public class TestExpressionSortField extends LuceneTestCaseJupiter { + @Test public void testToString() throws Exception { Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)"); @@ -35,6 +37,7 @@ public void testToString() throws Exception { } @SuppressWarnings("SelfAssertion") + @Test public void testEquals() throws Exception { Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)"); @@ -68,6 +71,7 @@ public void testEquals() throws Exception { assertEquals(sf1, sf1); } + @Test public void testNeedsScores() throws Exception { SimpleBindings bindings = new SimpleBindings(); // refers to score directly diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSorts.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSorts.java index 33e2a8b9437d..aa2ba3793875 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSorts.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSorts.java @@ -18,6 +18,7 @@ import java.util.Arrays; import java.util.Collections; +import java.util.Random; import org.apache.lucene.document.Document; import org.apache.lucene.document.DoubleDocValuesField; import org.apache.lucene.document.Field; @@ -40,24 +41,27 @@ import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.search.CheckHits; import org.apache.lucene.tests.util.English; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; import org.apache.lucene.tests.util.TestUtil; import org.apache.lucene.util.ArrayUtil; +import org.apache.lucene.util.IOUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** * Tests some basic expressions against different queries, and fieldcache/docvalues fields against * an equivalent sort. */ -public class TestExpressionSorts extends LuceneTestCase { +public class TestExpressionSorts extends LuceneTestCaseJupiter { private Directory dir; private IndexReader reader; private IndexSearcher searcher; - @Override - public void setUp() throws Exception { - super.setUp(); + @BeforeEach + final void beforeEach(Random random) throws Exception { dir = newDirectory(); - RandomIndexWriter iw = new RandomIndexWriter(random(), dir); + RandomIndexWriter iw = new RandomIndexWriter(random, dir); int numDocs = atLeast(500); for (int i = 0; i < numDocs; i++) { Document document = new Document(); @@ -74,13 +78,12 @@ public void setUp() throws Exception { searcher = newSearcher(reader); } - @Override - public void tearDown() throws Exception { - reader.close(); - dir.close(); - super.tearDown(); + @AfterEach + final void afterEach() throws Exception { + IOUtils.close(reader, dir); } + @Test public void testQueries() throws Exception { int n = atLeast(1); for (int i = 0; i < n; i++) { diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java index dbb98dbf749f..255e32a60a3e 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java @@ -18,11 +18,13 @@ import org.apache.lucene.expressions.js.JavascriptCompiler; import org.apache.lucene.search.DoubleValuesSource; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; +import org.junit.jupiter.api.Test; /** Tests validation of bindings */ -public class TestExpressionValidation extends LuceneTestCase { +public class TestExpressionValidation extends LuceneTestCaseJupiter { + @Test public void testValidExternals() throws Exception { SimpleBindings bindings = new SimpleBindings(); bindings.add("valid0", DoubleValuesSource.fromIntField("valid0")); @@ -37,6 +39,7 @@ public void testValidExternals() throws Exception { bindings.validate(); } + @Test public void testInvalidExternal() throws Exception { SimpleBindings bindings = new SimpleBindings(); bindings.add("valid", DoubleValuesSource.fromIntField("valid")); @@ -50,6 +53,7 @@ public void testInvalidExternal() throws Exception { assertTrue(expected.getMessage().contains("Invalid reference")); } + @Test public void testInvalidExternal2() throws Exception { SimpleBindings bindings = new SimpleBindings(); bindings.add("valid", DoubleValuesSource.fromIntField("valid")); @@ -63,6 +67,7 @@ public void testInvalidExternal2() throws Exception { assertTrue(expected.getMessage().contains("Invalid reference")); } + @Test public void testSelfRecursion() throws Exception { SimpleBindings bindings = new SimpleBindings(); bindings.add("cycle0", JavascriptCompiler.compile("cycle0")); @@ -75,6 +80,7 @@ public void testSelfRecursion() throws Exception { assertTrue(expected.getMessage().contains("Cycle detected")); } + @Test public void testCoRecursion() throws Exception { SimpleBindings bindings = new SimpleBindings(); bindings.add("cycle0", JavascriptCompiler.compile("cycle1")); @@ -88,6 +94,7 @@ public void testCoRecursion() throws Exception { assertTrue(expected.getMessage().contains("Cycle detected")); } + @Test public void testCoRecursion2() throws Exception { SimpleBindings bindings = new SimpleBindings(); bindings.add("cycle0", JavascriptCompiler.compile("cycle1")); @@ -102,6 +109,7 @@ public void testCoRecursion2() throws Exception { assertTrue(expected.getMessage().contains("Cycle detected")); } + @Test public void testCoRecursion3() throws Exception { SimpleBindings bindings = new SimpleBindings(); bindings.add("cycle0", JavascriptCompiler.compile("100")); @@ -116,6 +124,7 @@ public void testCoRecursion3() throws Exception { assertTrue(expected.getMessage().contains("Cycle detected")); } + @Test public void testCoRecursion4() throws Exception { SimpleBindings bindings = new SimpleBindings(); bindings.add("cycle0", JavascriptCompiler.compile("100")); diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValueSource.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValueSource.java index 6f6dcce17cf6..5d61881b9594 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValueSource.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValueSource.java @@ -17,6 +17,7 @@ package org.apache.lucene.expressions; import java.io.IOException; +import java.util.Random; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumericDocValuesField; @@ -30,19 +31,22 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.index.RandomIndexWriter; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; +import org.apache.lucene.util.IOUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class TestExpressionValueSource extends LuceneTestCase { +public class TestExpressionValueSource extends LuceneTestCaseJupiter { DirectoryReader reader; Directory dir; - @Override - public void setUp() throws Exception { - super.setUp(); + @BeforeEach + final void beforeEach(Random random) throws Exception { dir = newDirectory(); - IndexWriterConfig iwc = newIndexWriterConfig(new MockAnalyzer(random())); + IndexWriterConfig iwc = newIndexWriterConfig(new MockAnalyzer(random)); iwc.setMergePolicy(newLogMergePolicy()); - RandomIndexWriter iw = new RandomIndexWriter(random(), dir, iwc); + RandomIndexWriter iw = new RandomIndexWriter(random, dir, iwc); Document doc = new Document(); doc.add(newStringField("id", "1", Field.Store.YES)); @@ -68,13 +72,12 @@ public void setUp() throws Exception { iw.close(); } - @Override - public void tearDown() throws Exception { - reader.close(); - dir.close(); - super.tearDown(); + @AfterEach + final void afterEach() throws Exception { + IOUtils.close(reader, dir); } + @Test public void testDoubleValuesSourceTypes() throws Exception { Expression expr = JavascriptCompiler.compile("2*popularity + count"); SimpleBindings bindings = new SimpleBindings(); @@ -95,6 +98,7 @@ public void testDoubleValuesSourceTypes() throws Exception { } @SuppressWarnings({"unlikely-arg-type", "SelfAssertion"}) + @Test public void testDoubleValuesSourceEquals() throws Exception { Expression expr = JavascriptCompiler.compile("sqrt(a) + ln(b)"); @@ -127,6 +131,7 @@ public void testDoubleValuesSourceEquals() throws Exception { assertFalse(vs1.equals(vs4)); } + @Test public void testFibonacciExpr() throws Exception { int n = 40; SimpleBindings bindings = new SimpleBindings(); @@ -150,6 +155,7 @@ public void testFibonacciExpr() throws Exception { assertEquals(fib(n), (int) values.doubleValue()); } + @Test public void testLazyDependencies() throws Exception { SimpleBindings bindings = new SimpleBindings(); bindings.add("f0", DoubleValuesSource.constant(1)); @@ -187,6 +193,7 @@ private int fib(int n) { return curr; } + @Test public void testRewrite() throws Exception { Expression expr = JavascriptCompiler.compile("a"); diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/js/CompilerTestCase.java b/lucene/expressions/src/test/org/apache/lucene/expressions/js/CompilerTestCase.java index 54547275a66b..d7cc843efdac 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/js/CompilerTestCase.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/js/CompilerTestCase.java @@ -21,10 +21,10 @@ import java.text.ParseException; import java.util.Map; import org.apache.lucene.expressions.Expression; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; /** Base class for testing JS compiler */ -public abstract class CompilerTestCase extends LuceneTestCase { +public abstract class CompilerTestCase extends LuceneTestCaseJupiter { /** compiles expression for sourceText with default functions list */ protected Expression compile(String sourceText) throws ParseException { diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestAPISanity.java b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestAPISanity.java index faf73c980fc2..8dedd22dfcf8 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestAPISanity.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestAPISanity.java @@ -19,6 +19,7 @@ import java.io.IOException; import org.apache.lucene.expressions.Expression; import org.apache.lucene.search.DoubleValues; +import org.junit.jupiter.api.Test; /** Some sanity checks with API as those are not detected by {@link JavascriptCompiler} */ public class TestAPISanity extends CompilerTestCase { @@ -37,6 +38,7 @@ public double evaluate(DoubleValues[] functionValues) throws IOException { } } + @Test public void testBytecodeExceptions() throws Exception { Expression expr = compile("1"); assertArrayEquals( diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestCustomFunctions.java b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestCustomFunctions.java index 84248f477d1f..58fe14013e11 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestCustomFunctions.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestCustomFunctions.java @@ -27,6 +27,7 @@ import java.util.Map; import org.apache.lucene.expressions.Expression; import org.apache.lucene.tests.util.LuceneTestCase; +import org.junit.jupiter.api.Test; /** Tests customing the function map */ public class TestCustomFunctions extends CompilerTestCase { @@ -34,6 +35,7 @@ public class TestCustomFunctions extends CompilerTestCase { private static final Lookup LOOKUP = MethodHandles.lookup(); /** empty list of methods */ + @Test public void testEmpty() throws Exception { Map functions = Map.of(); ParseException expected = @@ -48,6 +50,7 @@ public void testEmpty() throws Exception { } /** using the default map explicitly */ + @Test public void testDefaultList() throws Exception { Map functions = JavascriptCompiler.DEFAULT_FUNCTIONS; Expression expr = compile("sqrt(20)", functions); @@ -70,6 +73,7 @@ private static MethodHandle localMethod(String name, int arity) } /** tests a method with no arguments */ + @Test public void testNoArgMethod() throws Exception { Map functions = Map.of("foo", localMethod("zeroArgMethod", 0)); Expression expr = compile("foo()", functions); @@ -81,6 +85,7 @@ public static double oneArgMethod(double arg1) { } /** tests a method with one arguments */ + @Test public void testOneArgMethod() throws Exception { Map functions = Map.of("foo", localMethod("oneArgMethod", 1)); Expression expr = compile("foo(3)", functions); @@ -92,6 +97,7 @@ public static double threeArgMethod(double arg1, double arg2, double arg3) { } /** tests a method with three arguments */ + @Test public void testThreeArgMethod() throws Exception { Map functions = Map.of("foo", localMethod("threeArgMethod", 3)); Expression expr = compile("foo(3, 4, 5)", functions); @@ -99,6 +105,7 @@ public void testThreeArgMethod() throws Exception { } /** tests a map with 2 functions */ + @Test public void testTwoMethods() throws Exception { Map functions = Map.of("foo", localMethod("zeroArgMethod", 0), "bar", localMethod("oneArgMethod", 1)); @@ -107,6 +114,7 @@ public void testTwoMethods() throws Exception { } /** tests invalid methods that are not allowed to become variables to be mapped */ + @Test public void testInvalidVariableMethods() { ParseException expected = expectThrows( @@ -147,6 +155,7 @@ public static String bogusReturnType() { } /** wrong return type: must be double */ + @Test public void testWrongReturnType() throws Exception { Map functions = Map.of("foo", localMethod("bogusReturnType", MethodType.methodType(String.class))); @@ -164,6 +173,7 @@ public static double bogusParameterType(String s) { } /** wrong param type: must be doubles */ + @Test public void testWrongParameterType() throws Exception { Map functions = Map.of( @@ -183,6 +193,7 @@ public double nonStaticMethod() { } /** wrong modifiers: must be static */ + @Test public void testWrongNotStatic() throws Exception { Map functions = Map.of( @@ -204,6 +215,7 @@ private static double nonPublicMethod() { } /** non public methods work as the lookup allows access */ + @Test public void testNotPublic() throws Exception { Map functions = Map.of("foo", localMethod("nonPublicMethod", 0)); Expression expr = compile("foo()", functions); @@ -218,6 +230,7 @@ public static double method() { } /** class containing method is not public */ + @Test public void testNestedNotPublic() throws Exception { Map functions = Map.of( @@ -229,6 +242,7 @@ public void testNestedNotPublic() throws Exception { } /** class containing method is not public */ + @Test public void testNonDirectMethodHandle() throws Exception { Map functions = Map.of( @@ -250,6 +264,7 @@ public static double staticThrowingException() { * the method throws an exception. We should check the stack trace that it contains the source * code of the expression as file name. */ + @Test public void testThrowingException() throws Exception { Map functions = Map.of("foo", localMethod("staticThrowingException", 0)); String source = "3 * foo() / 5"; @@ -274,6 +289,7 @@ public void testThrowingException() throws Exception { } /** test that namespaces work with custom expressions as direct method handle. */ + @Test public void testNamespacesWithDirectMH() throws Exception { Map functions = Map.of("foo.bar", localMethod("zeroArgMethod", 0)); String source = "foo.bar()"; @@ -284,6 +300,7 @@ public void testNamespacesWithDirectMH() throws Exception { /** * test that namespaces work with general method handles (ensure field name of handle is correct). */ + @Test public void testNamespacesWithoutDirectMH() throws Exception { Map functions = Map.of( diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestExpressionMath.java b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestExpressionMath.java index 5428a9e4e98b..1be629ee834f 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestExpressionMath.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestExpressionMath.java @@ -20,10 +20,12 @@ import static org.apache.lucene.expressions.js.ExpressionMath.haversinKilometers; import java.util.Random; -import org.apache.lucene.tests.util.LuceneTestCase; +import org.apache.lucene.tests.util.LuceneTestCaseJupiter; +import org.junit.jupiter.api.Test; -public class TestExpressionMath extends LuceneTestCase { +public class TestExpressionMath extends LuceneTestCaseJupiter { + @Test public void testHaversin() { assertTrue(Double.isNaN(haversinKilometers(1, 1, 1, Double.NaN))); assertTrue(Double.isNaN(haversinKilometers(1, 1, Double.NaN, 1))); diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptCompiler.java b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptCompiler.java index 402236d2e096..94d180df5f9d 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptCompiler.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptCompiler.java @@ -18,9 +18,11 @@ import java.text.ParseException; import org.apache.lucene.expressions.Expression; +import org.junit.jupiter.api.Test; public class TestJavascriptCompiler extends CompilerTestCase { + @Test public void testNullExpression() throws Exception { expectThrows( NullPointerException.class, @@ -29,6 +31,7 @@ public void testNullExpression() throws Exception { }); } + @Test public void testNullFunctions() throws Exception { expectThrows( NullPointerException.class, @@ -37,11 +40,13 @@ public void testNullFunctions() throws Exception { }); } + @Test public void testEnormousExpressionSource() throws Exception { String expr = " ".repeat(20000) + "100"; assertNotNull(compile(expr)); } + @Test public void testValidCompiles() throws Exception { assertNotNull(compile("100")); assertNotNull(compile("valid0+100")); @@ -49,6 +54,7 @@ public void testValidCompiles() throws Exception { assertNotNull(compile("logn(2, 20+10-5.0)")); } + @Test public void testValidVariables() throws Exception { doTestValidVariable("object.valid0"); doTestValidVariable("object0.object1.valid1"); @@ -92,6 +98,7 @@ void doTestValidVariable(String variable, String output) throws Exception { assertEquals(output, e.variables[0]); } + @Test public void testInvalidVariables() throws Exception { doTestInvalidVariable("object.0invalid"); doTestInvalidVariable("0.invalid"); @@ -117,6 +124,7 @@ void doTestInvalidVariable(String variable) { }); } + @Test public void testInvalidLexer() throws Exception { ParseException expected = expectThrows( @@ -127,6 +135,7 @@ public void testInvalidLexer() throws Exception { assertTrue(expected.getMessage().contains("unexpected character '.' on line (2) position (1)")); } + @Test public void testInvalidCompiles() throws Exception { expectThrows( ParseException.class, @@ -159,6 +168,7 @@ public void testInvalidCompiles() throws Exception { }); } + @Test public void testEmpty() { expectThrows( ParseException.class, @@ -179,6 +189,7 @@ public void testEmpty() { }); } + @Test public void testNull() throws Exception { expectThrows( NullPointerException.class, @@ -187,6 +198,7 @@ public void testNull() throws Exception { }); } + @Test public void testWrongArity() throws Exception { ParseException expected = expectThrows( @@ -231,6 +243,7 @@ public void testWrongArity() throws Exception { assertEquals(expected.getErrorOffset(), 4); } + @Test public void testVariableNormalization() throws Exception { // multiple double quotes Expression x = compile("foo[\"a\"][\"b\"]"); diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptFunction.java b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptFunction.java index 54b7417dafe2..12545e8785f7 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptFunction.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptFunction.java @@ -17,6 +17,7 @@ package org.apache.lucene.expressions.js; import org.apache.lucene.expressions.Expression; +import org.junit.jupiter.api.Test; public class TestJavascriptFunction extends CompilerTestCase { private static final double DELTA = 0.0000001; @@ -27,6 +28,7 @@ private void assertEvaluatesTo(String expression, double expected) throws Except assertEquals(expected, actual, DELTA); } + @Test public void testAbsMethod() throws Exception { assertEvaluatesTo("abs(0)", 0); assertEvaluatesTo("abs(119)", 119); @@ -35,6 +37,7 @@ public void testAbsMethod() throws Exception { assertEvaluatesTo("abs(-1)", 1); } + @Test public void testAcosMethod() throws Exception { assertEvaluatesTo("acos(-1)", Math.PI); assertEvaluatesTo("acos(-0.8660254)", Math.PI * 5 / 6); @@ -47,12 +50,14 @@ public void testAcosMethod() throws Exception { assertEvaluatesTo("acos(1)", 0); } + @Test public void testAcoshMethod() throws Exception { assertEvaluatesTo("acosh(1)", 0); assertEvaluatesTo("acosh(2.5)", 1.5667992369724109); assertEvaluatesTo("acosh(1234567.89)", 14.719378760739708); } + @Test public void testAsinMethod() throws Exception { assertEvaluatesTo("asin(-1)", -Math.PI / 2); assertEvaluatesTo("asin(-0.8660254)", -Math.PI / 3); @@ -65,6 +70,7 @@ public void testAsinMethod() throws Exception { assertEvaluatesTo("asin(1)", Math.PI / 2); } + @Test public void testAsinhMethod() throws Exception { assertEvaluatesTo("asinh(-1234567.89)", -14.719378760740035); assertEvaluatesTo("asinh(-2.5)", -1.6472311463710958); @@ -75,6 +81,7 @@ public void testAsinhMethod() throws Exception { assertEvaluatesTo("asinh(1234567.89)", 14.719378760740035); } + @Test public void testAtanMethod() throws Exception { assertEvaluatesTo("atan(-1.732050808)", -Math.PI / 3); assertEvaluatesTo("atan(-1)", -Math.PI / 4); @@ -85,6 +92,7 @@ public void testAtanMethod() throws Exception { assertEvaluatesTo("atan(1.732050808)", Math.PI / 3); } + @Test public void testAtan2Method() throws Exception { assertEvaluatesTo("atan2(+0,+0)", +0.0); assertEvaluatesTo("atan2(+0,-0)", +Math.PI); @@ -96,6 +104,7 @@ public void testAtan2Method() throws Exception { assertEvaluatesTo("atan2(-2,-2)", -Math.PI * 3 / 4); } + @Test public void testAtanhMethod() throws Exception { assertEvaluatesTo("atanh(-1)", Double.NEGATIVE_INFINITY); assertEvaluatesTo("atanh(-0.5)", -0.5493061443340549); @@ -104,6 +113,7 @@ public void testAtanhMethod() throws Exception { assertEvaluatesTo("atanh(1)", Double.POSITIVE_INFINITY); } + @Test public void testCeilMethod() throws Exception { assertEvaluatesTo("ceil(0)", 0); assertEvaluatesTo("ceil(0.1)", 1); @@ -114,6 +124,7 @@ public void testCeilMethod() throws Exception { assertEvaluatesTo("ceil(-1.1)", -1); } + @Test public void testCosMethod() throws Exception { assertEvaluatesTo("cos(0)", 1); assertEvaluatesTo("cos(" + Math.PI / 2 + ")", 0); @@ -126,6 +137,7 @@ public void testCosMethod() throws Exception { assertEvaluatesTo("cos(" + -Math.PI / 6 + ")", 0.8660254); } + @Test public void testCoshMethod() throws Exception { assertEvaluatesTo("cosh(0)", 1); assertEvaluatesTo("cosh(-1)", 1.5430806348152437); @@ -136,6 +148,7 @@ public void testCoshMethod() throws Exception { assertEvaluatesTo("cosh(12.3456789)", 114982.09728671524); } + @Test public void testExpMethod() throws Exception { assertEvaluatesTo("exp(0)", 1); assertEvaluatesTo("exp(-1)", 0.36787944117); @@ -146,6 +159,7 @@ public void testExpMethod() throws Exception { assertEvaluatesTo("exp(12.3456789)", 229964.194569); } + @Test public void testFloorMethod() throws Exception { assertEvaluatesTo("floor(0)", 0); assertEvaluatesTo("floor(0.1)", 0); @@ -156,10 +170,12 @@ public void testFloorMethod() throws Exception { assertEvaluatesTo("floor(-1.1)", -2); } + @Test public void testHaversinMethod() throws Exception { assertEvaluatesTo("haversin(40.7143528,-74.0059731,40.759011,-73.9844722)", 5.285885589128259); } + @Test public void testLnMethod() throws Exception { assertEvaluatesTo("ln(0)", Double.NEGATIVE_INFINITY); assertEvaluatesTo("ln(" + Math.E + ")", 1); @@ -169,6 +185,7 @@ public void testLnMethod() throws Exception { assertEvaluatesTo("ln(12.3456789)", 2.51330611521); } + @Test public void testLog10Method() throws Exception { assertEvaluatesTo("log10(0)", Double.NEGATIVE_INFINITY); assertEvaluatesTo("log10(1)", 0); @@ -177,6 +194,7 @@ public void testLog10Method() throws Exception { assertEvaluatesTo("log10(12.3456789)", 1.0915149771692705); } + @Test public void testLognMethod() throws Exception { assertEvaluatesTo("logn(2, 0)", Double.NEGATIVE_INFINITY); assertEvaluatesTo("logn(2, 1)", 0); @@ -190,6 +208,7 @@ public void testLognMethod() throws Exception { assertEvaluatesTo("logn(2.5, 12.3456789)", 2.7429133874016745); } + @Test public void testMaxMethod() throws Exception { assertEvaluatesTo("max(0, 0)", 0); assertEvaluatesTo("max(1, 0)", 1); @@ -198,6 +217,7 @@ public void testMaxMethod() throws Exception { assertEvaluatesTo("max(25, 23)", 25); } + @Test public void testMinMethod() throws Exception { assertEvaluatesTo("min(0, 0)", 0); assertEvaluatesTo("min(1, 0)", 0); @@ -206,6 +226,7 @@ public void testMinMethod() throws Exception { assertEvaluatesTo("min(25, 23)", 23); } + @Test public void testPowMethod() throws Exception { assertEvaluatesTo("pow(0, 0)", 1); assertEvaluatesTo("pow(0.1, 2)", 0.01); @@ -216,6 +237,7 @@ public void testPowMethod() throws Exception { assertEvaluatesTo("pow(-1.1, 2)", 1.21); } + @Test public void testSinMethod() throws Exception { assertEvaluatesTo("sin(0)", 0); assertEvaluatesTo("sin(" + Math.PI / 2 + ")", 1); @@ -228,6 +250,7 @@ public void testSinMethod() throws Exception { assertEvaluatesTo("sin(" + -Math.PI / 6 + ")", -0.5); } + @Test public void testSinhMethod() throws Exception { assertEvaluatesTo("sinh(0)", 0); assertEvaluatesTo("sinh(-1)", -1.1752011936438014); @@ -238,6 +261,7 @@ public void testSinhMethod() throws Exception { assertEvaluatesTo("sinh(12.3456789)", 114982.09728236674); } + @Test public void testSqrtMethod() throws Exception { assertEvaluatesTo("sqrt(0)", 0); assertEvaluatesTo("sqrt(-1)", Double.NaN); @@ -245,6 +269,7 @@ public void testSqrtMethod() throws Exception { assertEvaluatesTo("sqrt(49)", 7); } + @Test public void testTanMethod() throws Exception { assertEvaluatesTo("tan(0)", 0); assertEvaluatesTo("tan(-1)", -1.55740772465); @@ -255,6 +280,7 @@ public void testTanMethod() throws Exception { assertEvaluatesTo("tan(1.3)", 3.60210244797); } + @Test public void testTanhMethod() throws Exception { assertEvaluatesTo("tanh(0)", 0); assertEvaluatesTo("tanh(-1)", -0.76159415595); @@ -266,6 +292,7 @@ public void testTanhMethod() throws Exception { } /** checks that dynamic constants work and only produce one entry in constant pool */ + @Test public void testSameFunction() throws Exception { assertEvaluatesTo("sqrt(49) * abs(-2) * sqrt(25)", 7 * 2 * 5); } diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptOperations.java b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptOperations.java index 44e86bbaa9f7..cfeb474e2bc9 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptOperations.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestJavascriptOperations.java @@ -17,6 +17,7 @@ package org.apache.lucene.expressions.js; import org.apache.lucene.expressions.Expression; +import org.junit.jupiter.api.Test; public class TestJavascriptOperations extends CompilerTestCase { private void assertEvaluatesTo(String expression, long expected) throws Exception { @@ -25,6 +26,7 @@ private void assertEvaluatesTo(String expression, long expected) throws Exceptio assertEquals(expected, actual); } + @Test public void testNegationOperation() throws Exception { assertEvaluatesTo("-1", -1); assertEvaluatesTo("--1", 1); @@ -33,6 +35,7 @@ public void testNegationOperation() throws Exception { assertEvaluatesTo("--0", 0); } + @Test public void testAddOperation() throws Exception { assertEvaluatesTo("1+1", 2); assertEvaluatesTo("1+0.5+0.5", 2); @@ -45,6 +48,7 @@ public void testAddOperation() throws Exception { assertEvaluatesTo("0+0", 0); } + @Test public void testSubtractOperation() throws Exception { assertEvaluatesTo("1-1", 0); assertEvaluatesTo("5-10", -5); @@ -57,6 +61,7 @@ public void testSubtractOperation() throws Exception { assertEvaluatesTo("0-0", 0); } + @Test public void testMultiplyOperation() throws Exception { assertEvaluatesTo("1*1", 1); assertEvaluatesTo("5*10", 50); @@ -68,6 +73,7 @@ public void testMultiplyOperation() throws Exception { assertEvaluatesTo("0*0", 0); } + @Test public void testDivisionOperation() throws Exception { assertEvaluatesTo("1*1", 1); assertEvaluatesTo("10/5", 2); @@ -78,6 +84,7 @@ public void testDivisionOperation() throws Exception { assertEvaluatesTo("1/0", 9223372036854775807L); } + @Test public void testModuloOperation() throws Exception { assertEvaluatesTo("1%1", 0); assertEvaluatesTo("10%3", 1); @@ -86,6 +93,7 @@ public void testModuloOperation() throws Exception { assertEvaluatesTo("27%(9%5)", 3); } + @Test public void testLessThanOperation() throws Exception { assertEvaluatesTo("1 < 1", 0); assertEvaluatesTo("2 < 1", 0); @@ -97,6 +105,7 @@ public void testLessThanOperation() throws Exception { assertEvaluatesTo("-1 < 0", 1); } + @Test public void testLessThanEqualsOperation() throws Exception { assertEvaluatesTo("1 <= 1", 1); assertEvaluatesTo("2 <= 1", 0); @@ -108,6 +117,7 @@ public void testLessThanEqualsOperation() throws Exception { assertEvaluatesTo("-1 <= 0", 1); } + @Test public void testGreaterThanOperation() throws Exception { assertEvaluatesTo("1 > 1", 0); assertEvaluatesTo("2 > 1", 1); @@ -119,6 +129,7 @@ public void testGreaterThanOperation() throws Exception { assertEvaluatesTo("-1 > 0", 0); } + @Test public void testGreaterThanEqualsOperation() throws Exception { assertEvaluatesTo("1 >= 1", 1); assertEvaluatesTo("2 >= 1", 1); @@ -130,6 +141,7 @@ public void testGreaterThanEqualsOperation() throws Exception { assertEvaluatesTo("-1 >= 0", 0); } + @Test public void testEqualsOperation() throws Exception { assertEvaluatesTo("1 == 1", 1); assertEvaluatesTo("0 == 0", 1); @@ -145,6 +157,7 @@ public void testEqualsOperation() throws Exception { assertEvaluatesTo("-2 == -1", 0); } + @Test public void testNotEqualsOperation() throws Exception { assertEvaluatesTo("1 != 1", 0); assertEvaluatesTo("0 != 0", 0); @@ -160,6 +173,7 @@ public void testNotEqualsOperation() throws Exception { assertEvaluatesTo("-2 != -1", 1); } + @Test public void testBoolNotOperation() throws Exception { assertEvaluatesTo("!1", 0); assertEvaluatesTo("!!1", 1); @@ -170,6 +184,7 @@ public void testBoolNotOperation() throws Exception { assertEvaluatesTo("!-2", 0); } + @Test public void testBoolAndOperation() throws Exception { assertEvaluatesTo("1 && 1", 1); assertEvaluatesTo("1 && 0", 0); @@ -181,6 +196,7 @@ public void testBoolAndOperation() throws Exception { assertEvaluatesTo("-0 && -0", 0); } + @Test public void testBoolOrOperation() throws Exception { assertEvaluatesTo("1 || 1", 1); assertEvaluatesTo("1 || 0", 1); @@ -192,6 +208,7 @@ public void testBoolOrOperation() throws Exception { assertEvaluatesTo("-0 || -0", 0); } + @Test public void testConditionalOperation() throws Exception { assertEvaluatesTo("1 ? 2 : 3", 2); assertEvaluatesTo("-1 ? 2 : 3", 2); @@ -206,6 +223,7 @@ public void testConditionalOperation() throws Exception { assertEvaluatesTo("(0 ? 1 : 0) ? 3 : 4", 4); } + @Test public void testBitShiftLeft() throws Exception { assertEvaluatesTo("1 << 1", 2); assertEvaluatesTo("2 << 1", 4); @@ -220,6 +238,7 @@ public void testBitShiftLeft() throws Exception { assertEvaluatesTo("-15 << 62", 4611686018427387904L); } + @Test public void testBitShiftRight() throws Exception { assertEvaluatesTo("1 >> 1", 0); assertEvaluatesTo("2 >> 1", 1); @@ -234,6 +253,7 @@ public void testBitShiftRight() throws Exception { assertEvaluatesTo("-2147483646 >> 1", -1073741823); } + @Test public void testBitShiftRightUnsigned() throws Exception { assertEvaluatesTo("1 >>> 1", 0); assertEvaluatesTo("2 >>> 1", 1); @@ -248,6 +268,7 @@ public void testBitShiftRightUnsigned() throws Exception { assertEvaluatesTo("2147483648 >>> 1", 1073741824); } + @Test public void testBitwiseAnd() throws Exception { assertEvaluatesTo("4 & 4", 4); assertEvaluatesTo("3 & 2", 2); @@ -259,6 +280,7 @@ public void testBitwiseAnd() throws Exception { assertEvaluatesTo("1 & 0", 0); } + @Test public void testBitwiseOr() throws Exception { assertEvaluatesTo("4 | 4", 4); assertEvaluatesTo("5 | 2", 7); @@ -270,6 +292,7 @@ public void testBitwiseOr() throws Exception { assertEvaluatesTo("1 | 0", 1); } + @Test public void testBitwiseXor() throws Exception { assertEvaluatesTo("4 ^ 4", 0); assertEvaluatesTo("5 ^ 2", 7); @@ -282,6 +305,7 @@ public void testBitwiseXor() throws Exception { assertEvaluatesTo("0 ^ 0", 0); } + @Test public void testBitwiseNot() throws Exception { assertEvaluatesTo("~-5", 4); assertEvaluatesTo("~25", -26); @@ -289,6 +313,7 @@ public void testBitwiseNot() throws Exception { assertEvaluatesTo("~-1", 0); } + @Test public void testDecimalConst() throws Exception { assertEvaluatesTo("0", 0); assertEvaluatesTo("1", 1); @@ -298,6 +323,7 @@ public void testDecimalConst() throws Exception { assertEvaluatesTo("500E-2", 5); } + @Test public void testHexConst() throws Exception { assertEvaluatesTo("0x0", 0); assertEvaluatesTo("0x1", 1); @@ -309,6 +335,7 @@ public void testHexConst() throws Exception { assertEvaluatesTo("0xA << 2", 0xA << 2); } + @Test public void testHexConst2() throws Exception { assertEvaluatesTo("0X0", 0); assertEvaluatesTo("0X1", 1); @@ -316,6 +343,7 @@ public void testHexConst2() throws Exception { assertEvaluatesTo("0X1234ABCDEF", 78193085935L); } + @Test public void testOctalConst() throws Exception { assertEvaluatesTo("00", 0); assertEvaluatesTo("01", 1); diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestVariableContext.java b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestVariableContext.java index 5b75b78f071a..80f02bdae422 100644 --- a/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestVariableContext.java +++ b/lucene/expressions/src/test/org/apache/lucene/expressions/js/TestVariableContext.java @@ -22,9 +22,11 @@ import static org.apache.lucene.expressions.js.VariableContext.Type.STR_INDEX; import org.apache.lucene.tests.util.LuceneTestCase; +import org.junit.jupiter.api.Test; public class TestVariableContext extends LuceneTestCase { + @Test public void testSimpleVar() { VariableContext[] x = VariableContext.parse("foo"); assertEquals(1, x.length); @@ -32,6 +34,7 @@ public void testSimpleVar() { assertEquals(x[0].text, "foo"); } + @Test public void testEmptyString() { VariableContext[] x = VariableContext.parse("foo['']"); assertEquals(2, x.length); @@ -39,6 +42,7 @@ public void testEmptyString() { assertEquals(x[1].text, ""); } + @Test public void testUnescapeString() { VariableContext[] x = VariableContext.parse("foo['\\'\\\\']"); assertEquals(2, x.length); @@ -46,6 +50,7 @@ public void testUnescapeString() { assertEquals(x[1].text, "'\\"); } + @Test public void testMember() { VariableContext[] x = VariableContext.parse("foo.bar"); assertEquals(2, x.length); @@ -53,6 +58,7 @@ public void testMember() { assertEquals(x[1].text, "bar"); } + @Test public void testMemberFollowedByMember() { VariableContext[] x = VariableContext.parse("foo.bar.baz"); assertEquals(3, x.length); @@ -60,6 +66,7 @@ public void testMemberFollowedByMember() { assertEquals(x[2].text, "baz"); } + @Test public void testMemberFollowedByIntArray() { VariableContext[] x = VariableContext.parse("foo.bar[1]"); assertEquals(3, x.length); @@ -67,6 +74,7 @@ public void testMemberFollowedByIntArray() { assertEquals(x[2].integer, 1); } + @Test public void testMethodWithMember() { VariableContext[] x = VariableContext.parse("m.m()"); assertEquals(2, x.length); @@ -74,6 +82,7 @@ public void testMethodWithMember() { assertEquals(x[1].text, "m"); } + @Test public void testMethodWithStrIndex() { VariableContext[] x = VariableContext.parse("member['blah'].getMethod()"); assertEquals(3, x.length); @@ -81,6 +90,7 @@ public void testMethodWithStrIndex() { assertEquals(x[2].text, "getMethod"); } + @Test public void testMethodWithNumericalIndex() { VariableContext[] x = VariableContext.parse("member[0].getMethod()"); assertEquals(3, x.length); From ed3dc566ccd3ebf9fb41b3208d6a5630915806e2 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sun, 3 May 2026 15:09:12 +0200 Subject: [PATCH 58/68] Add forbidden apis check for junit4 api (with the exception of Assert). --- .../java/ApplyForbiddenApisPlugin.java | 15 ++ .../forbidden-apis/non-standard/junit4.txt | 209 ++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 gradle/validation/forbidden-apis/non-standard/junit4.txt diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ApplyForbiddenApisPlugin.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ApplyForbiddenApisPlugin.java index f08bf3d63e54..aa440736504b 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ApplyForbiddenApisPlugin.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ApplyForbiddenApisPlugin.java @@ -132,6 +132,21 @@ public void apply(Project project) { .toFile()))); }); + // Junit4->Junit5 transition. + var forbiddenApisTestTask = allForbiddenApisTasks.named("forbiddenApisTest"); + switch (project.getPath()) { + case ":lucene:expressions", ":lucene:memory": + forbiddenApisTestTask.configure( + task -> { + task.setSignaturesFiles( + task.getSignaturesFiles() + .plus( + project.files( + forbiddenApisDir.resolve("non-standard/junit4.txt").toFile()))); + }); + break; + } + // Configure non-standard, per-project stuff. var forbiddenApisMainTask = allForbiddenApisTasks.named("forbiddenApisMain"); diff --git a/gradle/validation/forbidden-apis/non-standard/junit4.txt b/gradle/validation/forbidden-apis/non-standard/junit4.txt new file mode 100644 index 000000000000..dd7aa51d0bbc --- /dev/null +++ b/gradle/validation/forbidden-apis/non-standard/junit4.txt @@ -0,0 +1,209 @@ +@defaultMessage Use JUnit5/jupiter assertions or assertj (preferred) +junit.textui.TestRunner +junit.textui.ResultPrinter +junit.framework.Protectable +junit.framework.AssertionFailedError +junit.framework.Test +junit.framework.Assert +junit.framework.TestResult +junit.framework.JUnit4TestAdapterCache +junit.framework.ComparisonFailure +junit.framework.TestListener +junit.framework.JUnit4TestCaseFacade +junit.framework.TestSuite +junit.framework.ComparisonCompactor +junit.framework.TestCase +junit.framework.JUnit4TestAdapter +junit.framework.TestFailure +junit.runner.TestRunListener +junit.runner.BaseTestRunner +junit.runner.Version +junit.extensions.RepeatedTest +junit.extensions.TestDecorator +junit.extensions.TestSetup +junit.extensions.ActiveTestSuite +org.junit.experimental.theories.ParametersSuppliedBy +org.junit.experimental.theories.suppliers.TestedOn +org.junit.experimental.theories.suppliers.TestedOnSupplier +org.junit.experimental.theories.PotentialAssignment +org.junit.experimental.theories.ParameterSignature +org.junit.experimental.theories.Theory +org.junit.experimental.theories.internal.Assignments +org.junit.experimental.theories.internal.SpecificDataPointsSupplier +org.junit.experimental.theories.internal.BooleanSupplier +org.junit.experimental.theories.internal.EnumSupplier +org.junit.experimental.theories.internal.ParameterizedAssertionError +org.junit.experimental.theories.internal.AllMembersSupplier +org.junit.experimental.theories.FromDataPoints +org.junit.experimental.theories.ParameterSupplier +org.junit.experimental.theories.DataPoint +org.junit.experimental.theories.DataPoints +org.junit.experimental.theories.Theories +org.junit.experimental.max.MaxCore +org.junit.experimental.max.MaxHistory +org.junit.experimental.max.CouldNotReadCoreException +org.junit.experimental.results.FailureList +org.junit.experimental.results.ResultMatchers +org.junit.experimental.results.PrintableResult +org.junit.experimental.runners.Enclosed +org.junit.experimental.ParallelComputer +org.junit.experimental.categories.IncludeCategories +org.junit.experimental.categories.CategoryValidator +org.junit.experimental.categories.Categories +org.junit.experimental.categories.CategoryFilterFactory +org.junit.experimental.categories.Category +org.junit.experimental.categories.ExcludeCategories +org.junit.TestCouldNotBeSkippedException +org.junit.validator.AnnotationValidatorFactory +org.junit.validator.AnnotationValidator +org.junit.validator.PublicClassValidator +org.junit.validator.TestClassValidator +org.junit.validator.ValidateWith +org.junit.validator.AnnotationsValidator +org.junit.Test +# we need to support this in superclass, for now. +# org.junit.Assert +org.junit.Ignore +org.junit.ComparisonFailure +org.junit.runner.Description +org.junit.runner.Describable +org.junit.runner.OrderWith +org.junit.runner.manipulation.Sortable +org.junit.runner.manipulation.InvalidOrderingException +org.junit.runner.manipulation.Orderable +org.junit.runner.manipulation.Sorter +org.junit.runner.manipulation.Orderer +org.junit.runner.manipulation.Alphanumeric +org.junit.runner.manipulation.Filter +org.junit.runner.manipulation.Filterable +org.junit.runner.manipulation.NoTestsRemainException +org.junit.runner.manipulation.Ordering +org.junit.runner.JUnitCore +org.junit.runner.notification.Failure +org.junit.runner.notification.SynchronizedRunListener +org.junit.runner.notification.StoppedByUserException +org.junit.runner.notification.RunListener +org.junit.runner.notification.RunNotifier +org.junit.runner.OrderWithValidator +org.junit.runner.Result +org.junit.runner.FilterFactories +org.junit.runner.Runner +org.junit.runner.FilterFactory +org.junit.runner.Request +org.junit.runner.JUnitCommandLineParseResult +org.junit.runner.FilterFactoryParams +org.junit.runner.Computer +org.junit.runner.RunWith +org.junit.After +org.junit.internal.MethodSorter +org.junit.internal.TextListener +org.junit.internal.InexactComparisonCriteria +org.junit.internal.JUnitSystem +org.junit.internal.builders.AnnotatedBuilder +org.junit.internal.builders.SuiteMethodBuilder +org.junit.internal.builders.NullBuilder +org.junit.internal.builders.AllDefaultPossibilitiesBuilder +org.junit.internal.builders.IgnoredBuilder +org.junit.internal.builders.JUnit4Builder +org.junit.internal.builders.JUnit3Builder +org.junit.internal.builders.IgnoredClassRunner +org.junit.internal.ComparisonCriteria +org.junit.internal.RealSystem +org.junit.internal.Classes +org.junit.internal.SerializableValueDescription +org.junit.internal.management.ThreadMXBean +org.junit.internal.management.FakeRuntimeMXBean +org.junit.internal.management.RuntimeMXBean +org.junit.internal.management.ManagementFactory +org.junit.internal.management.ReflectiveThreadMXBean +org.junit.internal.management.FakeThreadMXBean +org.junit.internal.management.ReflectiveRuntimeMXBean +org.junit.internal.Checks +org.junit.internal.requests.MemoizingRequest +org.junit.internal.requests.OrderingRequest +org.junit.internal.requests.FilterRequest +org.junit.internal.requests.SortingRequest +org.junit.internal.requests.ClassRequest +org.junit.internal.AssumptionViolatedException +org.junit.internal.ArrayComparisonFailure +org.junit.internal.SerializableMatcherDescription +org.junit.internal.runners.MethodValidator +org.junit.internal.runners.InitializationError +org.junit.internal.runners.JUnit4ClassRunner +org.junit.internal.runners.ClassRoadie +org.junit.internal.runners.statements.RunAfters +org.junit.internal.runners.statements.FailOnTimeout +org.junit.internal.runners.statements.InvokeMethod +org.junit.internal.runners.statements.ExpectException +org.junit.internal.runners.statements.Fail +org.junit.internal.runners.statements.RunBefores +org.junit.internal.runners.TestClass +org.junit.internal.runners.model.EachTestNotifier +org.junit.internal.runners.model.ReflectiveCallable +org.junit.internal.runners.model.MultipleFailureException +org.junit.internal.runners.rules.ValidationError +org.junit.internal.runners.rules.RuleMemberValidator +org.junit.internal.runners.SuiteMethod +org.junit.internal.runners.JUnit38ClassRunner +org.junit.internal.runners.ErrorReportingRunner +org.junit.internal.runners.FailedBefore +org.junit.internal.runners.MethodRoadie +org.junit.internal.runners.TestMethod +org.junit.internal.matchers.TypeSafeMatcher +org.junit.internal.matchers.StacktracePrintingMatcher +org.junit.internal.matchers.ThrowableCauseMatcher +org.junit.internal.matchers.ThrowableMessageMatcher +org.junit.internal.Throwables +org.junit.internal.ExactComparisonCriteria +org.junit.function.ThrowingRunnable +org.junit.ClassRule +org.junit.AssumptionViolatedException +org.junit.Before +org.junit.AfterClass +org.junit.rules.Timeout +org.junit.rules.TemporaryFolder +org.junit.rules.Verifier +org.junit.rules.TestWatcher +org.junit.rules.RuleChain +org.junit.rules.DisableOnDebug +org.junit.rules.ErrorCollector +org.junit.rules.ExpectedExceptionMatcherBuilder +org.junit.rules.RunRules +org.junit.rules.MethodRule +org.junit.rules.Stopwatch +org.junit.rules.ExpectedException +org.junit.rules.TestRule +org.junit.rules.ExternalResource +org.junit.rules.TestName +org.junit.rules.TestWatchman +org.junit.BeforeClass +org.junit.Rule +org.junit.runners.RuleContainer +org.junit.runners.parameterized.ParametersRunnerFactory +org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParametersFactory +org.junit.runners.parameterized.TestWithParameters +org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters +org.junit.runners.ParentRunner +org.junit.runners.BlockJUnit4ClassRunner +org.junit.runners.Parameterized +org.junit.runners.Suite +org.junit.runners.AllTests +org.junit.runners.MethodSorters +org.junit.runners.model.MemberValueConsumer +org.junit.runners.model.FrameworkMember +org.junit.runners.model.InitializationError +org.junit.runners.model.RunnerBuilder +org.junit.runners.model.NoGenericTypeParametersValidator +org.junit.runners.model.TestClass +org.junit.runners.model.RunnerScheduler +org.junit.runners.model.TestTimedOutException +org.junit.runners.model.MultipleFailureException +org.junit.runners.model.InvalidTestClassError +org.junit.runners.model.FrameworkMethod +org.junit.runners.model.Annotatable +org.junit.runners.model.Statement +org.junit.runners.model.FrameworkField +org.junit.runners.JUnit4 +org.junit.FixMethodOrder +org.junit.matchers.JUnitMatchers +org.junit.Assume From f8e42f9738cb38573a1419c21eb919797d377777 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Sun, 3 May 2026 15:10:36 +0200 Subject: [PATCH 59/68] Bump randomizedtesting-jupiter to 0.3.0. --- gradle/libs.versions.toml | 2 +- lucene/licenses/randomizedtesting-jupiter-0.2.0.jar.sha1 | 1 - lucene/licenses/randomizedtesting-jupiter-0.3.0.jar.sha1 | 1 + versions.lock | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 lucene/licenses/randomizedtesting-jupiter-0.2.0.jar.sha1 create mode 100644 lucene/licenses/randomizedtesting-jupiter-0.3.0.jar.sha1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8e1305665bee..d3365df9d6db 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -51,7 +51,7 @@ opennlp = "2.5.8" procfork = "1.0.6" # unit tests randomizedtesting = "2.8.4" -randomizedtesting-jupiter = "0.2.0" +randomizedtesting-jupiter = "0.3.0" # spatial-extras/ support s2-geometry = "1.0.0" # spatial-extras/ support diff --git a/lucene/licenses/randomizedtesting-jupiter-0.2.0.jar.sha1 b/lucene/licenses/randomizedtesting-jupiter-0.2.0.jar.sha1 deleted file mode 100644 index 3923da66ac1b..000000000000 --- a/lucene/licenses/randomizedtesting-jupiter-0.2.0.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -b205d971bdbba960f6aa7b177f7dae2602112568 diff --git a/lucene/licenses/randomizedtesting-jupiter-0.3.0.jar.sha1 b/lucene/licenses/randomizedtesting-jupiter-0.3.0.jar.sha1 new file mode 100644 index 000000000000..6959fd5037eb --- /dev/null +++ b/lucene/licenses/randomizedtesting-jupiter-0.3.0.jar.sha1 @@ -0,0 +1 @@ +a733add4ffdacbc2cfdfc15d77de69867c647d00 diff --git a/versions.lock b/versions.lock index dffe5ea79848..0e44b8d4f2b1 100644 --- a/versions.lock +++ b/versions.lock @@ -2,7 +2,7 @@ "comment" : "An inventory of resolved dependency versions. Do not edit this file directly.", "configurationGroups" : { "main_dependencies" : { - "com.carrotsearch.randomizedtesting:randomizedtesting-jupiter:0.2.0" : "fa9ef26b,refs=4", + "com.carrotsearch.randomizedtesting:randomizedtesting-jupiter:0.3.0" : "fa9ef26b,refs=4", "com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.8.4" : "fa9ef26b,refs=4", "com.ibm.icu:icu4j:78.3" : "47ea4550,refs=6", "commons-codec:commons-codec:1.21.0" : "e6288df0,refs=6", @@ -37,7 +37,7 @@ "xerces:xercesImpl:2.12.2" : "5ce8cdc6,refs=2" }, "test_dependencies" : { - "com.carrotsearch.randomizedtesting:randomizedtesting-jupiter:0.2.0" : "543b6dba,refs=74", + "com.carrotsearch.randomizedtesting:randomizedtesting-jupiter:0.3.0" : "543b6dba,refs=74", "com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.8.4" : "129da9bf,refs=76", "com.carrotsearch:procfork:1.0.6" : "b7ba1646,refs=2", "com.github.ben-manes.caffeine:caffeine:3.0.5" : "90685606,refs=39", From c96ada36498a87f5be915332f79c631fc74a5a3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 08:26:31 +0200 Subject: [PATCH 60/68] deps(java): bump gradle-wrapper from 9.4.1 to 9.5.0 (#16036) * deps(java): bump gradle-wrapper from 9.4.1 to 9.5.0 Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.4.1 to 9.5.0. - [Release notes](https://github.com/gradle/gradle/releases) - [Commits](https://github.com/gradle/gradle/compare/v9.4.1...v9.5.0) --- updated-dependencies: - dependency-name: gradle-wrapper dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update launch scripts, wrapper checksum, an explicit Project reference. * Add changelog. --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dawid Weiss --- gradle/libs.versions.toml | 2 +- gradle/wrapper/gradle-wrapper.jar.sha256 | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++- gradlew | 2 +- gradlew.bat | 41 +++++++++--------------- lucene/CHANGES.txt | 2 ++ lucene/distribution/build.gradle | 2 +- 7 files changed, 24 insertions(+), 31 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cf0eff645da3..3b580feec3b6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -36,7 +36,7 @@ jts = "1.20.0" junit = "4.13.2" junit5 = "6.0.3" # @keep Minimum gradle version to run the build -minGradle = "9.4.1" +minGradle = "9.5.0" # @keep This is the minimum required Java version. minJava = "25" # analysis/morfologik polish support diff --git a/gradle/wrapper/gradle-wrapper.jar.sha256 b/gradle/wrapper/gradle-wrapper.jar.sha256 index e52364bd5268..01bf52d7082b 100644 --- a/gradle/wrapper/gradle-wrapper.jar.sha256 +++ b/gradle/wrapper/gradle-wrapper.jar.sha256 @@ -1 +1 @@ -55243ef57851f12b070ad14f7f5bb8302daceeebc5bce5ece5fa6edb23e1145c *gradle-wrapper.jar +497c8c2a7e5031f6aa847f88104aa80a93532ec32ee17bdb8d1d2f67a194a9c7 *gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c61a118f7ddb..b52fb7e713a5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip networkTimeout=10000 +retries=0 +retryBackOffMs=500 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 7edc3329c5c0..88520aab1aeb 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/bin/sh # # Copyright © 2015 the original authors. diff --git a/gradlew.bat b/gradlew.bat index a12c0d39b598..68108657805e 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -23,8 +23,8 @@ @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -51,7 +51,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -65,7 +65,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line @@ -93,10 +93,10 @@ for /f "tokens=* delims=" %%H in ('certutil -hashfile "%GRADLE_WRAPPER_JAR%" SHA if /i "%ACTUAL%" NEQ "%EXPECTED%" ( "%JAVA_EXE%" -XX:TieredStopAtLevel=1 %JAVA_OPTS% "%APP_HOME%/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/WrapperDownloader.java" "%GRADLE_WRAPPER_JAR%" IF %ERRORLEVEL% EQU 1 goto failWithJvmMessage - IF %ERRORLEVEL% NEQ 0 goto fail + IF %ERRORLEVEL% NEQ 0 goto exitWithErrorLevel ) -@rem Generate gradle.properties if they don't exist +@rem Generate gradle.properties if it does not exist IF NOT EXIST "%APP_HOME%\gradle.properties" ( @rem local expansion is needed to check ERRORLEVEL inside control blocks. setlocal enableDelayedExpansion @@ -105,29 +105,18 @@ IF NOT EXIST "%APP_HOME%\gradle.properties" ( endlocal ) -@rem END OF LUCENE CUSTOMIZATION - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd -goto fail - :failWithJvmMessage @rem https://github.com/apache/lucene/pull/819 echo Error: Something went wrong. Make sure you're using the minimum required Java version to compile Lucene. +goto exitWithErrorLevel -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% +@rem END OF LUCENE CUSTOMIZATION -:mainEnd -if "%OS%"=="Windows_NT" endlocal +@rem Execute Gradle +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 32b06ff6795e..f32886c682c2 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -218,6 +218,8 @@ Build recognizes jdk.CPUTimeSample; CodeProfilingPlugin picks gradle/testing/profiling.cputime.jfc or profiling.jfc by host OS. (Prithvi S) +* GITHUB#16036: Upgrade gradle to 9.5.0 (Dawid Weiss) + Other --------------------- diff --git a/lucene/distribution/build.gradle b/lucene/distribution/build.gradle index 9495078d2ff4..0c076d3e95e2 100644 --- a/lucene/distribution/build.gradle +++ b/lucene/distribution/build.gradle @@ -112,7 +112,7 @@ dependencies { // The third-party JARs consist of all the transitive dependencies from a subset of // all Lucene modules. We only include the demos and Luke. Everything else has to be downloaded // manually or via maven POMs. - for (Project module : [ + for (def module : [ project(":lucene:luke"), project(":lucene:demo") ]) { From 3703e7d856686cc6aeb0ac0635b75b5874a84145 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 08:26:40 +0200 Subject: [PATCH 61/68] deps(java): bump org.apache.opennlp:opennlp-tools from 2.5.8 to 2.5.9 (#16037) * deps(java): bump org.apache.opennlp:opennlp-tools from 2.5.8 to 2.5.9 Bumps [org.apache.opennlp:opennlp-tools](https://github.com/apache/opennlp) from 2.5.8 to 2.5.9. - [Release notes](https://github.com/apache/opennlp/releases) - [Commits](https://github.com/apache/opennlp/compare/opennlp-2.5.8...opennlp-2.5.9) --- updated-dependencies: - dependency-name: org.apache.opennlp:opennlp-tools dependency-version: 2.5.9 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Checksums, lockfile. --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dawid Weiss --- gradle/libs.versions.toml | 2 +- lucene/licenses/opennlp-tools-2.5.8.jar.sha1 | 1 - lucene/licenses/opennlp-tools-2.5.9.jar.sha1 | 1 + versions.lock | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 lucene/licenses/opennlp-tools-2.5.8.jar.sha1 create mode 100644 lucene/licenses/opennlp-tools-2.5.9.jar.sha1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3b580feec3b6..aa9d976d7132 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,7 +46,7 @@ morfologik-ukrainian = "4.9.1" # benchmark/ html parsing nekohtml = "1.9.22" # analysis/opennlp/ support -opennlp = "2.5.8" +opennlp = "2.5.9" # distribution.tests/ process management procfork = "1.0.6" # unit tests diff --git a/lucene/licenses/opennlp-tools-2.5.8.jar.sha1 b/lucene/licenses/opennlp-tools-2.5.8.jar.sha1 deleted file mode 100644 index 00b00808b45b..000000000000 --- a/lucene/licenses/opennlp-tools-2.5.8.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -6fbf727022dde9be666c4542a3f67401584593e5 diff --git a/lucene/licenses/opennlp-tools-2.5.9.jar.sha1 b/lucene/licenses/opennlp-tools-2.5.9.jar.sha1 new file mode 100644 index 000000000000..df06e0116e6e --- /dev/null +++ b/lucene/licenses/opennlp-tools-2.5.9.jar.sha1 @@ -0,0 +1 @@ +3a9c5279e4ad1950a92ab5aa85fa88e970d82927 diff --git a/versions.lock b/versions.lock index c518554e9df7..5afe30f723e0 100644 --- a/versions.lock +++ b/versions.lock @@ -15,7 +15,7 @@ "org.apache.commons:commons-compress:1.28.0" : "5ce8cdc6,refs=2", "org.apache.commons:commons-lang3:3.18.0" : "5ce8cdc6,refs=2", "org.apache.commons:commons-math3:3.6.1" : "85a1e4c6,refs=2", - "org.apache.opennlp:opennlp-tools:2.5.8" : "2f760bab,refs=4", + "org.apache.opennlp:opennlp-tools:2.5.9" : "2f760bab,refs=4", "org.apiguardian:apiguardian-api:1.1.2" : "bd5e3ce4,refs=2", "org.carrot2:morfologik-fsa:2.1.9" : "79af844b,refs=4", "org.carrot2:morfologik-polish:2.1.9" : "fe494320,refs=3", @@ -70,7 +70,7 @@ "org.apache.commons:commons-compress:1.28.0" : "6f16ff86,refs=2", "org.apache.commons:commons-lang3:3.18.0" : "6f16ff86,refs=2", "org.apache.commons:commons-math3:3.6.1" : "152d9f78,refs=3", - "org.apache.opennlp:opennlp-tools:2.5.8" : "b91715f0,refs=6", + "org.apache.opennlp:opennlp-tools:2.5.9" : "b91715f0,refs=6", "org.apiguardian:apiguardian-api:1.1.2" : "cab355bc,refs=37", "org.assertj:assertj-core:3.27.7" : "39ba18cb,refs=4", "org.carrot2:morfologik-fsa:2.1.9" : "e077a675,refs=8", From 03e26be8eec1427165e47068907207284513a9ae Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Wed, 6 May 2026 14:50:52 +0200 Subject: [PATCH 62/68] Revert "deps(java): bump gradle-wrapper from 9.4.1 to 9.5.0 (#16036)" (#16038) This reverts commit 1bc3e6e642fcaa5cdeeeba026830185e85b465ca. --- gradle/libs.versions.toml | 2 +- gradle/wrapper/gradle-wrapper.jar.sha256 | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +-- gradlew | 2 +- gradlew.bat | 41 +++++++++++++++--------- lucene/CHANGES.txt | 2 -- lucene/distribution/build.gradle | 2 +- 7 files changed, 31 insertions(+), 24 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index aa9d976d7132..6fa7def1197b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -36,7 +36,7 @@ jts = "1.20.0" junit = "4.13.2" junit5 = "6.0.3" # @keep Minimum gradle version to run the build -minGradle = "9.5.0" +minGradle = "9.4.1" # @keep This is the minimum required Java version. minJava = "25" # analysis/morfologik polish support diff --git a/gradle/wrapper/gradle-wrapper.jar.sha256 b/gradle/wrapper/gradle-wrapper.jar.sha256 index 01bf52d7082b..e52364bd5268 100644 --- a/gradle/wrapper/gradle-wrapper.jar.sha256 +++ b/gradle/wrapper/gradle-wrapper.jar.sha256 @@ -1 +1 @@ -497c8c2a7e5031f6aa847f88104aa80a93532ec32ee17bdb8d1d2f67a194a9c7 *gradle-wrapper.jar +55243ef57851f12b070ad14f7f5bb8302daceeebc5bce5ece5fa6edb23e1145c *gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b52fb7e713a5..c61a118f7ddb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,9 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip networkTimeout=10000 -retries=0 -retryBackOffMs=500 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 88520aab1aeb..7edc3329c5c0 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env sh # # Copyright © 2015 the original authors. diff --git a/gradlew.bat b/gradlew.bat index 68108657805e..a12c0d39b598 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -23,8 +23,8 @@ @rem @rem ########################################################################## -@rem Set local scope for the variables, and ensure extensions are enabled -setlocal EnableExtensions +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -51,7 +51,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -"%COMSPEC%" /c exit 1 +goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -65,7 +65,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -"%COMSPEC%" /c exit 1 +goto fail :execute @rem Setup the command line @@ -93,10 +93,10 @@ for /f "tokens=* delims=" %%H in ('certutil -hashfile "%GRADLE_WRAPPER_JAR%" SHA if /i "%ACTUAL%" NEQ "%EXPECTED%" ( "%JAVA_EXE%" -XX:TieredStopAtLevel=1 %JAVA_OPTS% "%APP_HOME%/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/WrapperDownloader.java" "%GRADLE_WRAPPER_JAR%" IF %ERRORLEVEL% EQU 1 goto failWithJvmMessage - IF %ERRORLEVEL% NEQ 0 goto exitWithErrorLevel + IF %ERRORLEVEL% NEQ 0 goto fail ) -@rem Generate gradle.properties if it does not exist +@rem Generate gradle.properties if they don't exist IF NOT EXIST "%APP_HOME%\gradle.properties" ( @rem local expansion is needed to check ERRORLEVEL inside control blocks. setlocal enableDelayedExpansion @@ -105,18 +105,29 @@ IF NOT EXIST "%APP_HOME%\gradle.properties" ( endlocal ) +@rem END OF LUCENE CUSTOMIZATION + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd +goto fail + :failWithJvmMessage @rem https://github.com/apache/lucene/pull/819 echo Error: Something went wrong. Make sure you're using the minimum required Java version to compile Lucene. -goto exitWithErrorLevel -@rem END OF LUCENE CUSTOMIZATION +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% -@rem Execute Gradle -@rem endlocal doesn't take effect until after the line is parsed and variables are expanded -@rem which allows us to clear the local environment before executing the java command -endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel +:mainEnd +if "%OS%"=="Windows_NT" endlocal -:exitWithErrorLevel -@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts -"%COMSPEC%" /c exit %ERRORLEVEL% +:omega diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index f32886c682c2..32b06ff6795e 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -218,8 +218,6 @@ Build recognizes jdk.CPUTimeSample; CodeProfilingPlugin picks gradle/testing/profiling.cputime.jfc or profiling.jfc by host OS. (Prithvi S) -* GITHUB#16036: Upgrade gradle to 9.5.0 (Dawid Weiss) - Other --------------------- diff --git a/lucene/distribution/build.gradle b/lucene/distribution/build.gradle index 0c076d3e95e2..9495078d2ff4 100644 --- a/lucene/distribution/build.gradle +++ b/lucene/distribution/build.gradle @@ -112,7 +112,7 @@ dependencies { // The third-party JARs consist of all the transitive dependencies from a subset of // all Lucene modules. We only include the demos and Luke. Everything else has to be downloaded // manually or via maven POMs. - for (def module : [ + for (Project module : [ project(":lucene:luke"), project(":lucene:demo") ]) { From 7c816e94b3043ad3fe0e54e1d0a452f45d129242 Mon Sep 17 00:00:00 2001 From: Prithvi Date: Thu, 7 May 2026 02:39:21 +0530 Subject: [PATCH 63/68] Eliminate redundant cardinality() pass in MaxScoreBulkScorer (#15971) Signed-off-by: prithvi --- lucene/CHANGES.txt | 9 ++++++--- .../org/apache/lucene/search/MaxScoreBulkScorer.java | 5 +++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 32b06ff6795e..7692210b06c2 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -320,6 +320,12 @@ Optimizations --------------------- * GITHUB#15861: Optimise PhraseScorer by short circuiting non competitive documents in TOP_SCORES mode. (Prithvi S) +* GITHUB#15868: Optimize DisjunctionMaxBulkScorer by reusing the inner LeafCollector across + sub-scorers and resetting windowScores inline during replay instead of Arrays.fill. (Prithvi S) + +* Eliminate redundant cardinality() pass in MaxScoreBulkScorer by pre-allocating the + doc/score buffer to the max window size. (Prithvi S) + * GITHUB#15637: Lazily allocate ByteArrayDataInputs in SegmentTermsEnumFrame#15637 (Misha Dmitriev) * GITHUB#15718 Skip per-document stored field reads on sorted indices when no stored fields are present (Francisco Fernández Castaño) @@ -349,9 +355,6 @@ Optimizations * GITHUB#15970: Reduce memory usage of fields with long terms during segment merges. (Alan Woodward) -* GITHUB#15868: Optimize DisjunctionMaxBulkScorer by reusing the inner LeafCollector across - sub-scorers and resetting windowScores inline during replay instead of Arrays.fill. (Prithvi S) - * GITHUB#15732: Prevent writing vectors twice during merging HNSW graphs by allowing doing deferred work after calling merge for vectors is finshed. (Ignacio Vera) diff --git a/lucene/core/src/java/org/apache/lucene/search/MaxScoreBulkScorer.java b/lucene/core/src/java/org/apache/lucene/search/MaxScoreBulkScorer.java index 9bc732ba19e3..81ebc6d0cfe7 100644 --- a/lucene/core/src/java/org/apache/lucene/search/MaxScoreBulkScorer.java +++ b/lucene/core/src/java/org/apache/lucene/search/MaxScoreBulkScorer.java @@ -51,7 +51,7 @@ final class MaxScoreBulkScorer extends BulkScorer { private final double[] windowScores = new double[INNER_WINDOW_SIZE]; private final DocAndFloatFeatureBuffer docAndScoreBuffer = new DocAndFloatFeatureBuffer(); - private final DocAndScoreAccBuffer docAndScoreAccBuffer = new DocAndScoreAccBuffer(); + private final DocAndScoreAccBuffer docAndScoreAccBuffer; MaxScoreBulkScorer(int maxDoc, List scorers, Scorer filter) throws IOException { this.maxDoc = maxDoc; @@ -68,6 +68,8 @@ final class MaxScoreBulkScorer extends BulkScorer { this.cost = cost; essentialQueue = DisiPriorityQueue.ofMaxSize(allScorers.length); maxScoreSums = new double[allScorers.length]; + docAndScoreAccBuffer = new DocAndScoreAccBuffer(); + docAndScoreAccBuffer.growNoCopy(INNER_WINDOW_SIZE); } // Number of outer windows that have been evaluated @@ -263,7 +265,6 @@ private void scoreInnerWindowMultipleEssentialClauses( top = essentialQueue.updateTop(); } while (top.doc < innerWindowMax); - docAndScoreAccBuffer.growNoCopy(windowMatches.cardinality(0, innerWindowSize)); docAndScoreAccBuffer.size = 0; windowMatches.forEach( 0, From 1aa3b7cad8c30c774531fdbf95bdb48d0bc550cb Mon Sep 17 00:00:00 2001 From: Guo Feng <52390227+gf2121@users.noreply.github.com> Date: Thu, 7 May 2026 16:55:06 +0800 Subject: [PATCH 64/68] Optimize trie builder (#15977) This speeds up TrieBuilder and reduces its memory footprint by replacing the in-memory object tree with a compact prefix-coded byte buffer during the building phase, and using a frontier-based approach during the saving phase. --- lucene/CHANGES.txt | 3 +- .../lucene103/blocktree/TrieBuilder.java | 725 +++++++++--------- .../codecs/lucene103/blocktree/TestTrie.java | 11 - 3 files changed, 380 insertions(+), 359 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 7692210b06c2..5b3b27f7c02a 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -353,7 +353,8 @@ Optimizations * GITHUB#15938: Optimize ReaderUtil#partitionByLeaf to use binary search on leaf boundaries instead of linear scan. (Greg Miller) -* GITHUB#15970: Reduce memory usage of fields with long terms during segment merges. (Alan Woodward) +* GITHUB#15970, GITHUB#15977: Speed up TrieBuilder and reduce its memory footprint by replacing the in-memory object + tree with a compact prefix-coded byte buffer. (Alan Woodward, Guo Feng) * GITHUB#15732: Prevent writing vectors twice during merging HNSW graphs by allowing doing deferred work after calling merge for vectors is finshed. (Ignacio Vera) diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene103/blocktree/TrieBuilder.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene103/blocktree/TrieBuilder.java index 8d290cafe37e..0a042571d1d7 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/lucene103/blocktree/TrieBuilder.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene103/blocktree/TrieBuilder.java @@ -17,20 +17,27 @@ package org.apache.lucene.codecs.lucene103.blocktree; import java.io.IOException; -import java.util.ArrayDeque; +import java.io.UncheckedIOException; import java.util.Arrays; -import java.util.Deque; import java.util.function.BiConsumer; +import org.apache.lucene.store.ByteBuffersDataInput; +import org.apache.lucene.store.ByteBuffersDataOutput; import org.apache.lucene.store.DataOutput; import org.apache.lucene.store.IndexOutput; import org.apache.lucene.store.RandomAccessInput; +import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; /** * A builder to build prefix tree (trie) as the index of block tree, and can be saved to disk. * - *

TODO make this trie builder a more memory efficient structure. + *

Entries are stored in a compact prefix-coded byte buffer during building. The first non-empty + * key (minKey) is stored separately so that {@link #append} can re-encode only that one entry and + * bulk-copy the remaining bytes. At {@link #save} time the trie structure is reconstructed + * on-the-fly using a frontier array and serialized to disk in a single pass. + * + *

Memory usage is O(total encoded bytes) during building and O(max key depth) during save. */ class TrieBuilder { @@ -54,343 +61,400 @@ class TrieBuilder { */ record Output(long fp, boolean hasTerms, BytesRef floorData) {} - private enum Status { - BUILDING, - SAVED, - DESTROYED - } + // ====== Prefix-coded buffer entry format ====== + // Each entry: + // [prefixLen: vInt] [suffixLen: vInt] [suffix: bytes] + // [fp: vLong] [hasTerms: byte (0/1)] [floorDataLen: vInt] [floorData: bytes] + // + // The first non-empty-key entry (minKey) is stored separately and NOT in the buffer. + // Buffer entries start from the second entry onward, prefix-encoded against their predecessor. - private static class Node { - - // The utf8 digit that leads to this Node, 0 for root node - private final int label; - // The output of this node. - private Output output; - // The number of children of this node. - private int childrenNum; - // Pointers to relative nodes - private Node next; - private Node firstChild; - private Node lastChild; - - Node(int label, Output output) { - this.label = label; - this.output = output; - } - } + /** Output for the empty ("") key, if any. */ + private Output emptyOutput; - /** - * Transient state used only during {@link #saveNodes}. Keeps save-time bookkeeping off of {@link - * Node} so that Nodes are smaller during the (much longer) building phase. - */ - private static class SaveFrame { - final Node node; - // Iteration cursor: the latest child that has been pushed for saving. - Node savedTo; - // File pointer assigned when this node is written. -1 until then. - long fp = -1; - // File pointers of children, collected as they are popped. Null for leaf nodes. - long[] childFps; - int numChildFps; + /** The first non-empty key, stored separately from the buffer. */ + private final BytesRef minKey; - SaveFrame(Node node) { - this.node = node; - if (node.childrenNum > 0) { - this.childFps = new long[node.childrenNum]; - } - } + /** Output for minKey. Null if there is no non-empty key entry. */ + private Output minOutput; - void addChildFp(long childFp) { - childFps[numChildFps++] = childFp; - } - } + /** Buffer holding all entries after minKey, prefix-encoded. */ + private final ByteBuffersDataOutput buffer = new ByteBuffersDataOutput(); - private final Node root = new Node(0, null); - private final BytesRef minKey; - private BytesRef maxKey; - private Status status = Status.BUILDING; + /** + * The last key appended. Since entries are always appended in sorted order this doubles as the + * lexicographically largest key for ordered-append assertions. + */ + private final BytesRefBuilder lastKey = new BytesRefBuilder(); + + /** The maximum key length across all entries. */ + private int maxKeyDepth; static TrieBuilder bytesRefToTrie(BytesRef k, Output v) { return new TrieBuilder(k, v); } private TrieBuilder(BytesRef k, Output v) { - minKey = maxKey = BytesRef.deepCopyOf(k); + minKey = BytesRef.deepCopyOf(k); + maxKeyDepth = k.length; + if (k.length == 0) { - root.output = v; - return; - } - Node parent = root; - for (int i = 0; i < k.length; i++) { - int b = k.bytes[i + k.offset] & 0xFF; - Output output = i == k.length - 1 ? v : null; - Node node = new Node(b, output); - parent.firstChild = parent.lastChild = node; - parent.childrenNum = 1; - parent = node; + emptyOutput = v; + } else { + minOutput = v; + lastKey.copyBytes(k); } } /** * Append all (K, V) pairs from the given trie into this one. The given trie builder need to * ensure its keys greater or equals than max key of this one. - * - *

Note: the given trie will be destroyed after appending. */ - void append(TrieBuilder trieBuilder) { - if (status != Status.BUILDING || trieBuilder.status != Status.BUILDING) { - throw new IllegalStateException( - "tries have wrong status, got this: " + status + ", append: " + trieBuilder.status); - } - assert this.maxKey.compareTo(trieBuilder.minKey) < 0; - - int mismatch = - Arrays.mismatch( - this.maxKey.bytes, - this.maxKey.offset, - this.maxKey.offset + this.maxKey.length, - trieBuilder.minKey.bytes, - trieBuilder.minKey.offset, - trieBuilder.minKey.offset + trieBuilder.minKey.length); - Node a = this.root; - Node b = trieBuilder.root; - - for (int i = 0; i < mismatch; i++) { - final Node aLast = a.lastChild; - final Node bFirst = b.firstChild; - assert aLast.label == bFirst.label; - - if (b.childrenNum > 1) { - aLast.next = bFirst.next; - a.childrenNum += b.childrenNum - 1; - a.lastChild = b.lastChild; - assert assertChildrenLabelInOrder(a); - } + void append(TrieBuilder other) { + assert this.lastKey.get().compareTo(other.minKey) < 0; - a = aLast; - b = bFirst; + if (other.emptyOutput != null && this.emptyOutput == null) { + this.emptyOutput = other.emptyOutput; } - assert b.childrenNum > 0; - if (a.childrenNum == 0) { - a.firstChild = b.firstChild; - a.lastChild = b.lastChild; - a.childrenNum = b.childrenNum; - } else { - assert a.lastChild.label < b.firstChild.label; - a.lastChild.next = b.firstChild; - a.lastChild = b.lastChild; - a.childrenNum += b.childrenNum; + if (other.minOutput != null) { + try { + + // Encode and append the min entry in 'other' into the buffer, prefix-encoded against + // lastKey. + BytesRef lastKeyRef = lastKey.get(); + int mismatch = + Arrays.mismatch( + lastKeyRef.bytes, + lastKeyRef.offset, + lastKeyRef.offset + lastKeyRef.length, + other.minKey.bytes, + other.minKey.offset, + other.minKey.offset + other.minKey.length); + if (mismatch == -1) { + mismatch = Math.min(lastKeyRef.length, other.minKey.length); + } + int suffixLen = other.minKey.length - mismatch; + buffer.writeVInt(mismatch); + buffer.writeVInt(suffixLen); + buffer.writeBytes(other.minKey.bytes, other.minKey.offset + mismatch, suffixLen); + buffer.writeVLong(other.minOutput.fp); + buffer.writeByte((byte) (other.minOutput.hasTerms ? 1 : 0)); + if (other.minOutput.floorData != null) { + BytesRef floorData = other.minOutput.floorData; + buffer.writeVInt(floorData.length); + buffer.writeBytes(floorData.bytes, floorData.offset, floorData.length); + } else { + buffer.writeVInt(0); + } + + // Remaining buffer entries in 'other' are prefix-encoded against other.minKey which now + // equals our lastKey, so bulk-copy is safe without re-encoding. + if (other.buffer.size() > 0) { + ByteBuffersDataInput otherIn = other.buffer.toDataInput(); + buffer.copyBytes(otherIn, otherIn.length()); + } + + } catch (IOException e) { + throw new UncheckedIOException("should not happen on in-memory buffer", e); + } } - assert assertChildrenLabelInOrder(a); - this.maxKey = trieBuilder.maxKey; - trieBuilder.status = Status.DESTROYED; + lastKey.copyBytes(other.lastKey); + this.maxKeyDepth = Math.max(this.maxKeyDepth, other.maxKeyDepth); } Output getEmptyOutput() { - return root.output; + return emptyOutput; } + // ====== Entry iteration (shared by visit and saveNodes) ====== + /** - * Used for tests only. The recursive impl need to be avoided if someone plans to use for - * production one day. + * Iterates over all non-empty-key entries: first the separately-stored minKey, then the + * prefix-coded buffer entries. Maintains a reusable key buffer and exposes the prefix length from + * the encoding, which equals the common prefix length with the preceding key. + * + *

Supports two-phase iteration via {@link #readHeader()} and {@link #readBody()}: after + * readHeader(), {@link #key} still holds the previous key's bytes (the new suffix has not been + * written yet), and {@link #prefixLen} gives the boundary for freezing. After readBody(), {@link + * #key} is updated to the current key. */ - void visit(BiConsumer consumer) { - assert status == Status.BUILDING; - if (root.output != null) { - consumer.accept(new BytesRef(), root.output); + class EntryIterator { + private final ByteBuffersDataInput in; + private boolean minKeyConsumed; + boolean headerRead = false; + + // header + int suffixLen; + int prefixLen; + + // body + byte[] key; + int keyLen; + Output output; + + EntryIterator() { + key = new byte[Math.max(maxKeyDepth, 1)]; + System.arraycopy(minKey.bytes, minKey.offset, key, 0, minKey.length); + keyLen = 0; + minKeyConsumed = (minOutput == null); + in = buffer.size() > 0 ? buffer.toDataInput() : null; } - visit(root.firstChild, new BytesRefBuilder(), consumer); - } - private void visit(Node first, BytesRefBuilder key, BiConsumer consumer) { - while (first != null) { - key.append((byte) first.label); - if (first.output != null) { - consumer.accept(key.toBytesRef(), first.output); + boolean hasNext() { + if (!minKeyConsumed) return true; + return in != null && in.position() < in.length(); + } + + /** + * Phase 1: Read only the header (prefixLen and suffixLen). + * + *

After this call, {@link #key}[0..keyLen) still contains the previous key's bytes + * because the new suffix has not been written yet. This allows the caller to use key[] safely + * for freezing nodes between depth keyLen and prefixLen. + */ + void readHeader() throws IOException { + assert headerRead == false; + headerRead = true; + + if (!minKeyConsumed) { + prefixLen = 0; + suffixLen = minKey.length; + return; + } + + prefixLen = in.readVInt(); + suffixLen = in.readVInt(); + } + + /** + * Phase 2: Read the suffix bytes (overwriting key[prefixLen..]) and the output. + * + *

After this call, {@link #key}[0..keyLen) holds the current key and {@link + * #output} holds the current entry's output. + */ + void readBody() throws IOException { + assert headerRead == true; + headerRead = false; + + if (!minKeyConsumed) { + keyLen = minKey.length; + output = minOutput; + minKeyConsumed = true; + return; + } + + keyLen = prefixLen + suffixLen; + in.readBytes(key, prefixLen, suffixLen); + long fp = in.readVLong(); + boolean hasTerms = in.readByte() == 1; + int floorDataLen = in.readVInt(); + BytesRef floorData = null; + if (floorDataLen > 0) { + byte[] fd = new byte[floorDataLen]; + in.readBytes(fd, 0, floorDataLen); + floorData = new BytesRef(fd); } - visit(first.firstChild, key, consumer); - key.setLength(key.length() - 1); - first = first.next; + output = new Output(fp, hasTerms, floorData); } } void save(DataOutput meta, IndexOutput index) throws IOException { - if (status != Status.BUILDING) { - throw new IllegalStateException("only unsaved trie can be saved, got: " + status); - } meta.writeVLong(index.getFilePointer()); meta.writeVLong(saveNodes(index)); index.writeLong(0L); // additional 8 bytes for over-reading meta.writeVLong(index.getFilePointer()); - status = Status.SAVED; } + // ====== Frontier-based save ====== + + /** + * A frontier slot for one depth level. frontier[d] represents the trie node at depth d on the + * path from root to the last inserted key. + */ + private static class FrontierNode { + Output output; + int childrenNum; + int[] childLabels; + long[] childFps; + + FrontierNode() { + childLabels = new int[4]; + childFps = new long[4]; + } + + void reset() { + output = null; + childrenNum = 0; + } + + void addChild(int label, long fp) { + childLabels = ArrayUtil.grow(childLabels, childrenNum + 1); + childFps = ArrayUtil.grow(childFps, childrenNum + 1); + childLabels[childrenNum] = label; + childFps[childrenNum] = fp; + childrenNum++; + } + } + + /** + * Reconstruct the trie from the prefix-coded entries and serialize it to disk. + * + *

Uses a two-phase iteration: readHeader() exposes the prefixLen (which is the common prefix + * length with the previous key, already encoded in the buffer at append time) while key[] still + * holds the previous key's content — this allows freezeFrom() to read the correct labels without + * maintaining a separate prevKey copy. readBody() then overwrites key[] with the current entry. + */ long saveNodes(IndexOutput index) throws IOException { final long startFP = index.getFilePointer(); - Deque stack = new ArrayDeque<>(); - SaveFrame rootFrame = new SaveFrame(root); - stack.push(rootFrame); - - // Visit and save nodes of this trie in a post-order depth-first traversal. - while (stack.isEmpty() == false) { - SaveFrame frame = stack.peek(); - Node node = frame.node; - assert frame.fp == -1; - assert assertChildrenLabelInOrder(node); - - final int childrenNum = node.childrenNum; - - if (childrenNum == 0) { // leaf node - assert node.output != null : "leaf nodes should have output."; - - frame.fp = index.getFilePointer() - startFP; - stack.pop(); - if (stack.isEmpty() == false) { - stack.peek().addChildFp(frame.fp); - } - // [n bytes] floor data - // [n bytes] output fp - // [1bit] x | [1bit] has floor | [1bit] has terms | [3bit] output fp bytes | [2bit] sign + FrontierNode[] frontier = new FrontierNode[maxKeyDepth + 1]; + for (int i = 0; i <= maxKeyDepth; i++) { + frontier[i] = new FrontierNode(); + } + frontier[0].output = emptyOutput; + + EntryIterator iter = new EntryIterator(); + while (iter.hasNext()) { + // Phase 1: read prefixLen only; iter.key still holds the previous key's bytes. + int prevKeyLen = iter.keyLen; + iter.readHeader(); + + // Freeze frontier nodes from prevKeyLen down to iter.prefixLen. + // On the first entry prevKeyLen == 0 and prefixLen == 0, so the loop is a no-op. + freezeFrom(iter.key, prevKeyLen, iter.prefixLen, frontier, startFP, index); + + // Phase 2: read suffix + output; iter.key now holds the current key. + iter.readBody(); + frontier[iter.keyLen].output = iter.output; + } + + // Freeze all remaining nodes for the last key. + freezeFrom(iter.key, iter.keyLen, 0, frontier, startFP, index); + + return freezeNode(frontier[0], startFP, index); + } + /** + * Freeze frontier nodes from depth {@code keyLen} down to depth {@code toDepth + 1}. Each frozen + * node's fp is registered as a child of its parent (one level up). + */ + private void freezeFrom( + byte[] key, int keyLen, int toDepth, FrontierNode[] frontier, long startFP, IndexOutput index) + throws IOException { + for (int d = keyLen; d > toDepth; d--) { + long fp = freezeNode(frontier[d], startFP, index); + frontier[d - 1].addChild(key[d - 1] & 0xFF, fp); + frontier[d].reset(); + } + } + + /** + * Serialize a single frontier node to the index output and return its fp (relative to startFP). + */ + private long freezeNode(FrontierNode node, long startFP, IndexOutput index) throws IOException { + int childrenNum = node.childrenNum; + + if (childrenNum == 0) { + assert node.output != null : "leaf nodes should have output."; + long bottomFp = index.getFilePointer() - startFP; + Output output = node.output; + int outputFpBytes = bytesRequiredVLong(output.fp); + int header = + SIGN_NO_CHILDREN + | ((outputFpBytes - 1) << 2) + | (output.hasTerms ? LEAF_NODE_HAS_TERMS : 0) + | (output.floorData != null ? LEAF_NODE_HAS_FLOOR : 0); + index.writeByte(((byte) header)); + writeLongNBytes(output.fp, outputFpBytes, index); + if (output.floorData != null) { + index.writeBytes(output.floorData.bytes, output.floorData.offset, output.floorData.length); + } + return bottomFp; + } + + if (childrenNum == 1) { + long bottomFp = index.getFilePointer() - startFP; + long childDeltaFp = bottomFp - node.childFps[0]; + assert childDeltaFp > 0 : "parent node is always written after children: " + childDeltaFp; + int childFpBytes = bytesRequiredVLong(childDeltaFp); + int encodedOutputFpBytes = node.output == null ? 0 : bytesRequiredVLong(node.output.fp << 2); + + int sign = + node.output != null ? SIGN_SINGLE_CHILD_WITH_OUTPUT : SIGN_SINGLE_CHILD_WITHOUT_OUTPUT; + int header = sign | ((childFpBytes - 1) << 2) | ((encodedOutputFpBytes - 1) << 5); + index.writeByte((byte) header); + index.writeByte((byte) node.childLabels[0]); + writeLongNBytes(childDeltaFp, childFpBytes, index); + + if (node.output != null) { Output output = node.output; - int outputFpBytes = bytesRequiredVLong(output.fp); - int header = - SIGN_NO_CHILDREN - | ((outputFpBytes - 1) << 2) - | (output.hasTerms ? LEAF_NODE_HAS_TERMS : 0) - | (output.floorData != null ? LEAF_NODE_HAS_FLOOR : 0); - index.writeByte(((byte) header)); - writeLongNBytes(output.fp, outputFpBytes, index); + long encodedFp = encodeFP(output); + writeLongNBytes(encodedFp, encodedOutputFpBytes, index); if (output.floorData != null) { index.writeBytes( output.floorData.bytes, output.floorData.offset, output.floorData.length); } - continue; - } - - // If there are any children have not been saved, push the first one into stack and continue. - // We want to ensure saving children before parent. - - if (frame.savedTo == null) { - frame.savedTo = node.firstChild; - stack.push(new SaveFrame(frame.savedTo)); - continue; - } - if (frame.savedTo.next != null) { - assert frame.numChildFps > 0 && frame.childFps[frame.numChildFps - 1] >= 0; - frame.savedTo = frame.savedTo.next; - stack.push(new SaveFrame(frame.savedTo)); - continue; } + return bottomFp; + } - // All children have been written, now it's time to write the parent! - - assert assertNonLeafFramePreparingSaving(frame); - frame.fp = index.getFilePointer() - startFP; - stack.pop(); - if (stack.isEmpty() == false) { - stack.peek().addChildFp(frame.fp); + // Multi-children + long bottomFp = index.getFilePointer() - startFP; + + final int minLabel = node.childLabels[0]; + final int maxLabel = node.childLabels[childrenNum - 1]; + assert maxLabel > minLabel; + ChildSaveStrategy childSaveStrategy = ChildSaveStrategy.choose(minLabel, maxLabel, childrenNum); + int strategyBytes = childSaveStrategy.needBytes(minLabel, maxLabel, childrenNum); + assert strategyBytes > 0 && strategyBytes <= 32; + + long maxChildDeltaFp = bottomFp - node.childFps[0]; + assert maxChildDeltaFp > 0 : "parent always written after all children"; + + int childrenFpBytes = bytesRequiredVLong(maxChildDeltaFp); + int encodedOutputFpBytes = node.output == null ? 1 : bytesRequiredVLong(node.output.fp << 2); + int header = + SIGN_MULTI_CHILDREN + | ((childrenFpBytes - 1) << 2) + | ((node.output != null ? 1 : 0) << 5) + | ((encodedOutputFpBytes - 1) << 6) + | (childSaveStrategy.code << 9) + | ((strategyBytes - 1) << 11) + | (minLabel << 16); + + writeLongNBytes(header, 3, index); + + if (node.output != null) { + Output output = node.output; + long encodedFp = encodeFP(output); + writeLongNBytes(encodedFp, encodedOutputFpBytes, index); + if (output.floorData != null) { + index.writeByte((byte) (childrenNum - 1)); } + } - if (childrenNum == 1) { - - // [n bytes] floor data - // [n bytes] encoded output fp | [n bytes] child fp | [1 byte] label - // [3bit] encoded output fp bytes | [3bit] child fp bytes | [2bit] sign - - long childDeltaFp = frame.fp - frame.childFps[0]; - assert childDeltaFp > 0 : "parent node is always written after children: " + childDeltaFp; - int childFpBytes = bytesRequiredVLong(childDeltaFp); - int encodedOutputFpBytes = - node.output == null ? 0 : bytesRequiredVLong(node.output.fp << 2); - - // TODO if we have only one child and no output, we can store child labels in this node. - // E.g. for a single term trie [foobar], we can save only two nodes [fooba] and [r] - - int sign = - node.output != null ? SIGN_SINGLE_CHILD_WITH_OUTPUT : SIGN_SINGLE_CHILD_WITHOUT_OUTPUT; - int header = sign | ((childFpBytes - 1) << 2) | ((encodedOutputFpBytes - 1) << 5); - index.writeByte((byte) header); - index.writeByte((byte) node.firstChild.label); - writeLongNBytes(childDeltaFp, childFpBytes, index); - - if (node.output != null) { - Output output = node.output; - long encodedFp = encodeFP(output); - writeLongNBytes(encodedFp, encodedOutputFpBytes, index); - if (output.floorData != null) { - index.writeBytes( - output.floorData.bytes, output.floorData.offset, output.floorData.length); - } - } - } else { - - // [n bytes] floor data - // [n bytes] children fps | [n bytes] strategy data - // [1 byte] children count (if floor data) | [n bytes] encoded output fp | [1 byte] label - // [5bit] strategy bytes | 2bit children strategy | [3bit] encoded output fp bytes - // [1bit] has output | [3bit] children fp bytes | [2bit] sign - - final int minLabel = node.firstChild.label; - final int maxLabel = node.lastChild.label; - assert maxLabel > minLabel; - ChildSaveStrategy childSaveStrategy = - ChildSaveStrategy.choose(minLabel, maxLabel, childrenNum); - int strategyBytes = childSaveStrategy.needBytes(minLabel, maxLabel, childrenNum); - assert strategyBytes > 0 && strategyBytes <= 32; - - // children fps are in order, so the first child's fp is min, then delta is max. - long maxChildDeltaFp = frame.fp - frame.childFps[0]; - assert maxChildDeltaFp > 0 : "parent always written after all children"; - - int childrenFpBytes = bytesRequiredVLong(maxChildDeltaFp); - int encodedOutputFpBytes = - node.output == null ? 1 : bytesRequiredVLong(node.output.fp << 2); - int header = - SIGN_MULTI_CHILDREN - | ((childrenFpBytes - 1) << 2) - | ((node.output != null ? 1 : 0) << 5) - | ((encodedOutputFpBytes - 1) << 6) - | (childSaveStrategy.code << 9) - | ((strategyBytes - 1) << 11) - | (minLabel << 16); - - writeLongNBytes(header, 3, index); - - if (node.output != null) { - Output output = node.output; - long encodedFp = encodeFP(output); - writeLongNBytes(encodedFp, encodedOutputFpBytes, index); - if (output.floorData != null) { - // We need this childrenNum to compute where the floor data start. - index.writeByte((byte) (childrenNum - 1)); - } - } - - long strategyStartFp = index.getFilePointer(); - childSaveStrategy.save(node, childrenNum, strategyBytes, index); - assert index.getFilePointer() == strategyStartFp + strategyBytes - : childSaveStrategy.name() - + " strategy bytes compute error, computed: " - + strategyBytes - + " actual: " - + (index.getFilePointer() - strategyStartFp); - - for (int i = 0; i < frame.numChildFps; i++) { - assert frame.fp > frame.childFps[i] : "parent always written after all children"; - writeLongNBytes(frame.fp - frame.childFps[i], childrenFpBytes, index); - } + long strategyStartFp = index.getFilePointer(); + childSaveStrategy.save(node.childLabels, childrenNum, strategyBytes, index); + assert index.getFilePointer() == strategyStartFp + strategyBytes + : childSaveStrategy.name() + + " strategy bytes compute error, computed: " + + strategyBytes + + " actual: " + + (index.getFilePointer() - strategyStartFp); + + for (int i = 0; i < childrenNum; i++) { + assert bottomFp > node.childFps[i] : "parent always written after all children"; + writeLongNBytes(bottomFp - node.childFps[i], childrenFpBytes, index); + } - if (node.output != null && node.output.floorData != null) { - BytesRef floorData = node.output.floorData; - index.writeBytes(floorData.bytes, floorData.offset, floorData.length); - } - } + if (node.output != null && node.output.floorData != null) { + BytesRef floorData = node.output.floorData; + index.writeBytes(floorData.bytes, floorData.offset, floorData.length); } - return rootFrame.fp; + + return bottomFp; } private long encodeFP(Output output) { @@ -412,59 +476,12 @@ private static int bytesRequiredVLong(long v) { */ private static void writeLongNBytes(long v, int n, DataOutput out) throws IOException { for (int i = 0; i < n; i++) { - // Note that we sometimes write trailing 0 bytes here, when the incoming int n is bigger than - // would be required for a "normal" vLong out.writeByte((byte) v); v >>>= 8; } assert v == 0; } - private static boolean assertChildrenLabelInOrder(Node node) { - if (node.childrenNum == 0) { - assert node.firstChild == null; - assert node.lastChild == null; - } else if (node.childrenNum == 1) { - assert node.firstChild == node.lastChild; - assert node.firstChild.next == null; - } else if (node.childrenNum > 1) { - int n = 0; - for (Node child = node.firstChild; child != null; child = child.next) { - n++; - assert child.next == null || child.label < child.next.label - : " the label of children nodes should always be in strictly increasing order."; - } - assert node.childrenNum == n; - } - return true; - } - - private static boolean assertNonLeafFramePreparingSaving(SaveFrame frame) { - Node node = frame.node; - assert assertChildrenLabelInOrder(node); - assert node.childrenNum != 0; - assert frame.numChildFps == node.childrenNum - : "expected " + node.childrenNum + " child fps, got " + frame.numChildFps; - if (node.childrenNum == 1) { - assert node.firstChild == node.lastChild; - assert node.firstChild.next == null; - assert frame.savedTo == node.firstChild; - assert frame.childFps[0] >= 0; - } else { - int n = 0; - for (int i = 0; i < frame.numChildFps; i++) { - n++; - assert frame.childFps[i] >= 0; - assert i == frame.numChildFps - 1 || frame.childFps[i] < frame.childFps[i + 1] - : " the fp of children nodes should always be in order."; - } - assert node.childrenNum == n; - assert node.lastChild == frame.savedTo; - assert frame.savedTo.next == null; - } - return true; - } - enum ChildSaveStrategy { /** @@ -479,13 +496,13 @@ int needBytes(int minLabel, int maxLabel, int labelCnt) { } @Override - void save(Node parent, int labelCnt, int strategyBytes, IndexOutput output) + void save(int[] childLabels, int labelCnt, int strategyBytes, IndexOutput output) throws IOException { byte presenceBits = 1; // The first arc is always present. int presenceIndex = 0; - int previousLabel = parent.firstChild.label; - for (Node child = parent.firstChild.next; child != null; child = child.next) { - int label = child.label; + int previousLabel = childLabels[0]; + for (int i = 1; i < labelCnt; i++) { + int label = childLabels[i]; assert label > previousLabel; presenceIndex += label - previousLabel; while (presenceIndex >= Byte.SIZE) { @@ -493,13 +510,9 @@ void save(Node parent, int labelCnt, int strategyBytes, IndexOutput output) presenceBits = 0; presenceIndex -= Byte.SIZE; } - // Set the bit at presenceIndex to flag that the corresponding arc is present. presenceBits |= 1 << presenceIndex; previousLabel = label; } - assert presenceIndex == (parent.lastChild.label - parent.firstChild.label) % 8; - assert presenceBits != 0; // The last byte is not 0. - assert (presenceBits & (1 << presenceIndex)) != 0; // The last arc is always present. output.writeByte(presenceBits); } @@ -535,14 +548,14 @@ int lookup( ARRAY(1) { @Override int needBytes(int minLabel, int maxLabel, int labelCnt) { - return labelCnt - 1; // min label saved + return labelCnt - 1; } @Override - void save(Node parent, int labelCnt, int strategyBytes, IndexOutput output) + void save(int[] childLabels, int labelCnt, int strategyBytes, IndexOutput output) throws IOException { - for (Node child = parent.firstChild.next; child != null; child = child.next) { - output.writeByte((byte) child.label); + for (int i = 1; i < labelCnt; i++) { + output.writeByte((byte) childLabels[i]); } } @@ -560,7 +573,7 @@ int lookup( } else if (midLabel > targetLabel) { high = mid - 1; } else { - return mid + 1; // min label not included, plus 1 + return mid + 1; } } return -1; @@ -582,12 +595,12 @@ int needBytes(int minLabel, int maxLabel, int labelCnt) { } @Override - void save(Node parent, int labelCnt, int strategyBytes, IndexOutput output) + void save(int[] childLabels, int labelCnt, int strategyBytes, IndexOutput output) throws IOException { - output.writeByte((byte) parent.lastChild.label); - int lastLabel = parent.firstChild.label; - for (Node child = parent.firstChild.next; child != null; child = child.next) { - while (++lastLabel < child.label) { + output.writeByte((byte) childLabels[labelCnt - 1]); + int lastLabel = childLabels[0]; + for (int i = 1; i < labelCnt; i++) { + while (++lastLabel < childLabels[i]) { output.writeByte((byte) lastLabel); } } @@ -642,7 +655,7 @@ int lookup( abstract int needBytes(int minLabel, int maxLabel, int labelCnt); - abstract void save(Node parent, int labelCnt, int strategyBytes, IndexOutput output) + abstract void save(int[] childLabels, int labelCnt, int strategyBytes, IndexOutput output) throws IOException; abstract int lookup( @@ -668,4 +681,22 @@ static ChildSaveStrategy choose(int minLabel, int maxLabel, int labelCnt) { return childSaveStrategy; } } + + /** Used for tests only. */ + void visit(BiConsumer consumer) { + if (emptyOutput != null) { + consumer.accept(new BytesRef(), emptyOutput); + } + try { + EntryIterator iter = new EntryIterator(); + while (iter.hasNext()) { + iter.readHeader(); + iter.readBody(); + consumer.accept( + new BytesRef(ArrayUtil.copyOfSubArray(iter.key, 0, iter.keyLen)), iter.output); + } + } catch (IOException e) { + throw new UncheckedIOException("should not happen on in-memory buffer", e); + } + } } diff --git a/lucene/core/src/test/org/apache/lucene/codecs/lucene103/blocktree/TestTrie.java b/lucene/core/src/test/org/apache/lucene/codecs/lucene103/blocktree/TestTrie.java index f1bc495f656e..e6f022df54e8 100644 --- a/lucene/core/src/test/org/apache/lucene/codecs/lucene103/blocktree/TestTrie.java +++ b/lucene/core/src/test/org/apache/lucene/codecs/lucene103/blocktree/TestTrie.java @@ -95,8 +95,6 @@ private void testTrieBuilder(Supplier randomBytesSupplier, int count) { } TrieBuilder add = TrieBuilder.bytesRefToTrie(entry.getKey(), entry.getValue()); trieBuilder.append(add); - Assert.assertThrows(IllegalStateException.class, () -> add.append(trieBuilder)); - Assert.assertThrows(IllegalStateException.class, () -> trieBuilder.append(add)); } Map actual = new TreeMap<>(); trieBuilder.visit(actual::put); @@ -128,21 +126,12 @@ private void testTrieLookup(Supplier randomBytesSupplier, int round) thr } TrieBuilder add = TrieBuilder.bytesRefToTrie(entry.getKey(), entry.getValue()); trieBuilder.append(add); - Assert.assertThrows(IllegalStateException.class, () -> add.append(trieBuilder)); - Assert.assertThrows(IllegalStateException.class, () -> trieBuilder.append(add)); } try (Directory directory = newDirectory()) { try (IndexOutput index = directory.createOutput("index", IOContext.DEFAULT); IndexOutput meta = directory.createOutput("meta", IOContext.DEFAULT)) { trieBuilder.save(meta, index); - assertThrows(IllegalStateException.class, () -> trieBuilder.save(meta, index)); - assertThrows( - IllegalStateException.class, - () -> - trieBuilder.append( - TrieBuilder.bytesRefToTrie( - new BytesRef(), new TrieBuilder.Output(0L, true, null)))); } try (IndexInput indexIn = directory.openInput("index", IOContext.DEFAULT); From 0f68edef764435e3c274e2db3cfa3864217206f5 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 7 May 2026 13:04:33 +0200 Subject: [PATCH 65/68] Upgrade to Gradle 9.5.0 (corrected) (#16039) --- .../workflows/run-checks-gradle-upgrade.yml | 22 +++++++++- gradle/libs.versions.toml | 2 +- gradle/wrapper/gradle-wrapper.jar.sha256 | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 2 +- gradlew.bat | 43 ++++++++----------- lucene/CHANGES.txt | 2 + lucene/distribution/build.gradle | 2 +- 8 files changed, 48 insertions(+), 31 deletions(-) diff --git a/.github/workflows/run-checks-gradle-upgrade.yml b/.github/workflows/run-checks-gradle-upgrade.yml index d419e2ed8746..36b5f5fa9b30 100644 --- a/.github/workflows/run-checks-gradle-upgrade.yml +++ b/.github/workflows/run-checks-gradle-upgrade.yml @@ -53,10 +53,30 @@ jobs: exit 1 fi + gradleWindowsSanityCheck: + name: "Check gradlew help works on Windows." + timeout-minutes: 30 + runs-on: windows-latest + steps: + - name: Correct git autocrlf on Windows + run: git config --global core.autocrlf false + + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - uses: ./.github/actions/prepare-for-build + with: + java-version: '25' + use-cache: false + + - run: ./gradlew help + gradleSanityCheck: name: "Run tasks (java: ${{ matrix.java-version }}, alt-java: ${{ matrix.uses-alt-java }})" timeout-minutes: 30 - needs: gradleScriptBootstrapCheck + needs: [gradleScriptBootstrapCheck, gradleWindowsSanityCheck] strategy: matrix: diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6fa7def1197b..aa9d976d7132 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -36,7 +36,7 @@ jts = "1.20.0" junit = "4.13.2" junit5 = "6.0.3" # @keep Minimum gradle version to run the build -minGradle = "9.4.1" +minGradle = "9.5.0" # @keep This is the minimum required Java version. minJava = "25" # analysis/morfologik polish support diff --git a/gradle/wrapper/gradle-wrapper.jar.sha256 b/gradle/wrapper/gradle-wrapper.jar.sha256 index e52364bd5268..01bf52d7082b 100644 --- a/gradle/wrapper/gradle-wrapper.jar.sha256 +++ b/gradle/wrapper/gradle-wrapper.jar.sha256 @@ -1 +1 @@ -55243ef57851f12b070ad14f7f5bb8302daceeebc5bce5ece5fa6edb23e1145c *gradle-wrapper.jar +497c8c2a7e5031f6aa847f88104aa80a93532ec32ee17bdb8d1d2f67a194a9c7 *gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c61a118f7ddb..b52fb7e713a5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip networkTimeout=10000 +retries=0 +retryBackOffMs=500 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 7edc3329c5c0..88520aab1aeb 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/bin/sh # # Copyright © 2015 the original authors. diff --git a/gradlew.bat b/gradlew.bat index a12c0d39b598..9a4928299a96 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -23,8 +23,8 @@ @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -51,7 +51,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -65,7 +65,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line @@ -93,10 +93,10 @@ for /f "tokens=* delims=" %%H in ('certutil -hashfile "%GRADLE_WRAPPER_JAR%" SHA if /i "%ACTUAL%" NEQ "%EXPECTED%" ( "%JAVA_EXE%" -XX:TieredStopAtLevel=1 %JAVA_OPTS% "%APP_HOME%/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/WrapperDownloader.java" "%GRADLE_WRAPPER_JAR%" IF %ERRORLEVEL% EQU 1 goto failWithJvmMessage - IF %ERRORLEVEL% NEQ 0 goto fail + IF %ERRORLEVEL% NEQ 0 goto exitWithErrorLevel ) -@rem Generate gradle.properties if they don't exist +@rem Generate gradle.properties if it does not exist IF NOT EXIST "%APP_HOME%\gradle.properties" ( @rem local expansion is needed to check ERRORLEVEL inside control blocks. setlocal enableDelayedExpansion @@ -105,29 +105,22 @@ IF NOT EXIST "%APP_HOME%\gradle.properties" ( endlocal ) -@rem END OF LUCENE CUSTOMIZATION - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd -goto fail +goto launchGradle :failWithJvmMessage @rem https://github.com/apache/lucene/pull/819 echo Error: Something went wrong. Make sure you're using the minimum required Java version to compile Lucene. +goto exitWithErrorLevel + +:launchGradle -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% +@rem END OF LUCENE CUSTOMIZATION -:mainEnd -if "%OS%"=="Windows_NT" endlocal +@rem Execute Gradle +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 5b3b27f7c02a..e54d58b8cc2b 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -218,6 +218,8 @@ Build recognizes jdk.CPUTimeSample; CodeProfilingPlugin picks gradle/testing/profiling.cputime.jfc or profiling.jfc by host OS. (Prithvi S) +* GITHUB#16036: Upgrade gradle to 9.5.0 (Dawid Weiss) + Other --------------------- diff --git a/lucene/distribution/build.gradle b/lucene/distribution/build.gradle index 9495078d2ff4..0c076d3e95e2 100644 --- a/lucene/distribution/build.gradle +++ b/lucene/distribution/build.gradle @@ -112,7 +112,7 @@ dependencies { // The third-party JARs consist of all the transitive dependencies from a subset of // all Lucene modules. We only include the demos and Luke. Everything else has to be downloaded // manually or via maven POMs. - for (Project module : [ + for (def module : [ project(":lucene:luke"), project(":lucene:demo") ]) { From 27b1affe71bc03305770f4140ccf595e763bb844 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Tue, 12 May 2026 11:23:43 +0200 Subject: [PATCH 66/68] Remove `getCollectors()` from `TopFieldCot llectorManager` (#15608) `TopFieldCollectorManager` had an internal `ArrayList` tracking collectors via `getCollectors()`, which is unused anywhere in Lucene. Consumers are also not expected to call such method, as there is no need to retrieve the collectors that the collector manager created while searching. What matters is the `TopFieldDocs` that `reduce` returns, which in turn `IndexSearcher#search` exposes. This commit removes the internal list and the public getter method. It also clarifies javadocs: thread-safety is guaranteed for shared internal states (hit counting, minimum score propagation) across collectors, not for `newCollector()` itself which is designed to be called from a single thread. Resolves #15605 Signed-off-by: Prudhvi Godithi --- lucene/CHANGES.txt | 3 +++ .../search/TopFieldCollectorManager.java | 20 +++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index e54d58b8cc2b..950c1f525c4b 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -90,6 +90,9 @@ API Changes Also removed QueryParserBase.setDeterminizeWorkLimit/getDeterminizeWorkLimit, which are no longer needed. (Dimitris Rempapis) +* GITHUB#15605: Remove unused getCollectors() and internal collector tracking from + TopFieldCollectorManager. Clarify thread-safety documentation. (Prudhvi Godithi) + * GITHUB#: Add junit5/jupiter support to the test-framework module. (Dawid Weiss) New Features diff --git a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollectorManager.java b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollectorManager.java index c62e9dc9f255..e625400e8550 100644 --- a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollectorManager.java +++ b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollectorManager.java @@ -17,9 +17,7 @@ package org.apache.lucene.search; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; /** * Create a TopFieldCollectorManager which uses a shared hit counter to maintain number of hits and @@ -34,7 +32,6 @@ public class TopFieldCollectorManager implements CollectorManager collectors; /** * Creates a new {@link TopFieldCollectorManager} from the given arguments. @@ -61,8 +58,12 @@ public TopFieldCollectorManager( } /** - * Creates a new {@link TopFieldCollectorManager} from the given arguments, with thread-safe - * internal states. + * Creates a new {@link TopFieldCollectorManager} from the given arguments. + * + *

Thread safety is guaranteed for the shared internal states (hit counting, minimum score + * propagation) across collectors created by {@link #newCollector()}. Note that {@link + * #newCollector()} itself is designed to be called from a single thread; {@link IndexSearcher} + * handles this by calling it sequentially before parallel slice execution. * *

NOTE: The instances returned by this method pre-allocate a full array of length * numHits. @@ -111,12 +112,10 @@ public TopFieldCollectorManager(Sort sort, int numHits, FieldDoc after, int tota this.after = after; this.totalHitsThreshold = totalHitsThreshold; this.minScoreAcc = totalHitsThreshold != Integer.MAX_VALUE ? new MaxScoreAccumulator() : null; - this.collectors = new ArrayList<>(); } /** - * Creates a new {@link TopFieldCollectorManager} from the given arguments, with thread-safe - * internal states. + * Creates a new {@link TopFieldCollectorManager} from the given arguments. * *

NOTE: The instances returned by this method pre-allocate a full array of length * numHits. @@ -168,7 +167,6 @@ public TopFieldCollector newCollector() { sort, queue, after, numHits, totalHitsThreshold, minScoreAcc); } - collectors.add(collector); return collector; } @@ -181,8 +179,4 @@ public TopFieldDocs reduce(Collection collectors) throws IOEx } return TopDocs.merge(sort, 0, numHits, topDocs); } - - public List getCollectors() { - return collectors; - } } From c2019af287c5b5f7dab34eebf027adb009548e57 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Thu, 7 May 2026 15:34:35 +0200 Subject: [PATCH 67/68] Fix sandbox workflow/ faiss (#16041) --- .github/workflows/run-special-checks-sandbox.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-special-checks-sandbox.yml b/.github/workflows/run-special-checks-sandbox.yml index acda243c01aa..fd2585720c7e 100644 --- a/.github/workflows/run-special-checks-sandbox.yml +++ b/.github/workflows/run-special-checks-sandbox.yml @@ -39,10 +39,19 @@ jobs: conda-remove-defaults: 'true' - name: Install Faiss - run: mamba install faiss-cpu="${FAISS_VERSION}" + run: mamba install faiss-cpu="${FAISS_VERSION}" "mkl=2024.*" env: FAISS_VERSION: ${{ matrix.faiss-version }} + - name: Debug Faiss/MKL libraries + run: | + echo "=== MKL libs in conda prefix ===" + find "$CONDA_PREFIX/lib" -name "libmkl*" | sort + echo "=== faiss libs ===" + find "$CONDA_PREFIX/lib" -name "libfaiss*" | sort + echo "=== ldd on libfaiss_c.so ===" + ldd "$CONDA_PREFIX/lib/libfaiss_c.so" || true + - name: Checkout Lucene uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: From 0114b796a8ccdc52d573d4bd1b897abbaa9fbbed Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Sat, 9 May 2026 11:44:56 +0100 Subject: [PATCH 68/68] Specify the field name when getting the FlatVectorsScorer from a FlatVectorsReader (#16043) This makes getFlatVectorScorer consistent with getRandomVectorScorer, so both take the field name the scorer is for. --- lucene/CHANGES.txt | 3 +++ .../Lucene102BinaryQuantizedVectorsReader.java | 7 ++++++- .../Lucene99ScalarQuantizedVectorsReader.java | 8 +++++++- .../lucene/codecs/hnsw/FlatVectorsReader.java | 16 ++++------------ .../Lucene104ScalarQuantizedVectorsReader.java | 7 ++++++- .../lucene99/Lucene99FlatVectorsReader.java | 8 +++++++- .../lucene99/Lucene99HnswVectorsWriter.java | 2 +- 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 950c1f525c4b..bbc90b9ed39c 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -278,6 +278,9 @@ API Changes * GITHUB#15584: Add support for termdoc fields that use custom term freqs (via IndexOptions.DOCS_AND_CUSTOM_FREQS). IndexWriter counts their terms rather than summing their freqs. Use +* GITHUB#16043: Add field parameter to FlatVectorsReader.getFlatVectorScorer to match the other + scorer methods in that class. (Simon Cooper) + New Features --------------------- diff --git a/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/lucene102/Lucene102BinaryQuantizedVectorsReader.java b/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/lucene102/Lucene102BinaryQuantizedVectorsReader.java index 7a5643bf0ef3..a9683ab80394 100644 --- a/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/lucene102/Lucene102BinaryQuantizedVectorsReader.java +++ b/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/lucene102/Lucene102BinaryQuantizedVectorsReader.java @@ -33,6 +33,7 @@ import org.apache.lucene.codecs.CodecUtil; import org.apache.lucene.codecs.KnnVectorsReader; import org.apache.lucene.codecs.hnsw.FlatVectorsReader; +import org.apache.lucene.codecs.hnsw.FlatVectorsScorer; import org.apache.lucene.codecs.lucene95.OrdToDocDISIReaderConfiguration; import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.CorruptIndexException; @@ -94,7 +95,6 @@ public Lucene102BinaryQuantizedVectorsReader( FlatVectorsReader rawVectorsReader, Lucene102BinaryFlatVectorsScorer vectorsScorer) throws IOException { - super(vectorsScorer); this.vectorScorer = vectorsScorer; this.rawVectorsReader = rawVectorsReader; int versionMeta = -1; @@ -177,6 +177,11 @@ static void validateFieldEntry(FieldInfo info, FieldEntry fieldEntry) { } } + @Override + public FlatVectorsScorer getFlatVectorScorer(String field) throws IOException { + return vectorScorer; + } + @Override public RandomVectorScorer getRandomVectorScorer(String field, float[] target) throws IOException { FieldEntry fi = fields.get(field); diff --git a/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/lucene99/Lucene99ScalarQuantizedVectorsReader.java b/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/lucene99/Lucene99ScalarQuantizedVectorsReader.java index 317e5e60f16d..17eebc3ddc9d 100644 --- a/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/lucene99/Lucene99ScalarQuantizedVectorsReader.java +++ b/lucene/backward-codecs/src/java/org/apache/lucene/backward_codecs/lucene99/Lucene99ScalarQuantizedVectorsReader.java @@ -66,6 +66,7 @@ public final class Lucene99ScalarQuantizedVectorsReader extends FlatVectorsReade RamUsageEstimator.shallowSizeOfInstance(Lucene99ScalarQuantizedVectorsReader.class); private final IntObjectHashMap fields = new IntObjectHashMap<>(); + private final FlatVectorsScorer vectorScorer; private final IndexInput quantizedVectorData; private final FlatVectorsReader rawVectorsReader; private final FieldInfos fieldInfos; @@ -74,7 +75,7 @@ public final class Lucene99ScalarQuantizedVectorsReader extends FlatVectorsReade public Lucene99ScalarQuantizedVectorsReader( SegmentReadState state, FlatVectorsReader rawVectorsReader, FlatVectorsScorer scorer) throws IOException { - super(scorer); + this.vectorScorer = scorer; this.rawVectorsReader = rawVectorsReader; this.fieldInfos = state.fieldInfos; int versionMeta = -1; @@ -263,6 +264,11 @@ private static IndexInput openDataInput( } } + @Override + public FlatVectorsScorer getFlatVectorScorer(String field) throws IOException { + return vectorScorer; + } + @Override public RandomVectorScorer getRandomVectorScorer(String field, float[] target) throws IOException { final FieldEntry fieldEntry = getFieldEntry(field); diff --git a/lucene/core/src/java/org/apache/lucene/codecs/hnsw/FlatVectorsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/hnsw/FlatVectorsReader.java index 5dfa5e1ec2e8..850648409f93 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/hnsw/FlatVectorsReader.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/hnsw/FlatVectorsReader.java @@ -40,20 +40,12 @@ */ public abstract class FlatVectorsReader extends KnnVectorsReader implements Accountable { - /** Scorer for flat vectors */ - protected final FlatVectorsScorer vectorScorer; - - /** Sole constructor */ - protected FlatVectorsReader(FlatVectorsScorer vectorsScorer) { - this.vectorScorer = vectorsScorer; - } - /** - * @return the {@link FlatVectorsScorer} for this reader. + * Returns a {@link FlatVectorsScorer} for the given field. + * + * @param field the field to search */ - public FlatVectorsScorer getFlatVectorScorer() { - return vectorScorer; - } + public abstract FlatVectorsScorer getFlatVectorScorer(String field) throws IOException; @Override public void search(String field, float[] target, KnnCollector knnCollector, AcceptDocs acceptDocs) diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene104/Lucene104ScalarQuantizedVectorsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene104/Lucene104ScalarQuantizedVectorsReader.java index 15fe4950036f..041488a46ffe 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/lucene104/Lucene104ScalarQuantizedVectorsReader.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene104/Lucene104ScalarQuantizedVectorsReader.java @@ -30,6 +30,7 @@ import org.apache.lucene.codecs.CodecUtil; import org.apache.lucene.codecs.KnnVectorsReader; import org.apache.lucene.codecs.hnsw.FlatVectorsReader; +import org.apache.lucene.codecs.hnsw.FlatVectorsScorer; import org.apache.lucene.codecs.lucene95.OrdToDocDISIReaderConfiguration; import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.CorruptIndexException; @@ -98,7 +99,6 @@ public Lucene104ScalarQuantizedVectorsReader( Lucene104ScalarQuantizedVectorScorer vectorsScorer, DataAccessHint accessHint) throws IOException { - super(vectorsScorer); this.vectorScorer = vectorsScorer; this.rawVectorsReader = rawVectorsReader; int versionMeta = -1; @@ -186,6 +186,11 @@ static void validateFieldEntry(FieldInfo info, FieldEntry fieldEntry) { } } + @Override + public FlatVectorsScorer getFlatVectorScorer(String field) throws IOException { + return vectorScorer; + } + @Override public RandomVectorScorer getRandomVectorScorer(String field, float[] target) throws IOException { FieldEntry fi = fields.get(field); diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99FlatVectorsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99FlatVectorsReader.java index 0a9102d6b74b..68edb71c14df 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99FlatVectorsReader.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99FlatVectorsReader.java @@ -62,6 +62,7 @@ public final class Lucene99FlatVectorsReader extends FlatVectorsReader { RamUsageEstimator.shallowSizeOfInstance(Lucene99FlatVectorsFormat.class); private final IntObjectHashMap fields = new IntObjectHashMap<>(); + private final FlatVectorsScorer vectorScorer; private final IndexInput vectorData; private final FieldInfos fieldInfos; private final IOContext dataContext; @@ -81,8 +82,8 @@ public Lucene99FlatVectorsReader(SegmentReadState state, FlatVectorsScorer score public Lucene99FlatVectorsReader( SegmentReadState state, FlatVectorsScorer scorer, DataAccessHint accessHint) throws IOException { - super(scorer); int versionMeta = readMetadata(state); + this.vectorScorer = scorer; this.fieldInfos = state.fieldInfos; FileOpenHint[] hints = Stream.of(FileTypeHint.DATA, FileDataHint.KNN_VECTORS, accessHint) @@ -251,6 +252,11 @@ public ByteVectorValues getByteVectorValues(String field) throws IOException { vectorData); } + @Override + public FlatVectorsScorer getFlatVectorScorer(String field) throws IOException { + return vectorScorer; + } + @Override public RandomVectorScorer getRandomVectorScorer(String field, float[] target) throws IOException { final FieldEntry fieldEntry = getFieldEntry(field, VectorEncoding.FLOAT32); diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99HnswVectorsWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99HnswVectorsWriter.java index 8882fc4f644b..4f06b06321b4 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99HnswVectorsWriter.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99HnswVectorsWriter.java @@ -447,7 +447,7 @@ public IORunnable mergeOneField(FieldInfo fieldInfo, MergeState mergeState) thro } else { RandomVectorScorerSupplier scorerSupplier = flatVectorsReader - .getFlatVectorScorer() + .getFlatVectorScorer(fieldInfo.getName()) .getRandomVectorScorerSupplier( fieldInfo.getVectorSimilarityFunction(), vectorValues); buildAndWriteGraph(fieldInfo, mergeState, vectorValues, scorerSupplier, totalVectorCount);