This is an automated email from the ASF dual-hosted git repository.

janhoy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new eaee0a20cbb Speed up BATS tests (#4478)
eaee0a20cbb is described below

commit eaee0a20cbb7af08f86a0339654b1ce6f421dc24
Author: Jan Høydahl <[email protected]>
AuthorDate: Fri Jun 5 00:51:03 2026 +0200

    Speed up BATS tests (#4478)
---
 .../test/org/apache/solr/cli/PackageToolTest.java  | 57 +++++++++++++++
 solr/packaging/build.gradle                        | 11 +++
 solr/packaging/test/README.md                      | 18 +++++
 solr/packaging/test/test_example.bats              | 25 +++++--
 solr/packaging/test/test_example_noprompt.bats     | 35 ----------
 solr/packaging/test/test_healthcheck.bats          | 20 +++---
 solr/packaging/test/test_opennlp.bats              |  2 +-
 solr/packaging/test/test_packages.bats             | 81 ----------------------
 solr/packaging/test/test_ssl.bats                  | 16 ++---
 solr/packaging/test/test_start_solr.bats           |  2 +-
 solr/packaging/test/test_status.bats               | 26 +++----
 solr/packaging/test/test_zk.bats                   |  9 +--
 12 files changed, 134 insertions(+), 168 deletions(-)

diff --git a/solr/core/src/test/org/apache/solr/cli/PackageToolTest.java 
b/solr/core/src/test/org/apache/solr/cli/PackageToolTest.java
index e8cb48874b6..9282af37e52 100644
--- a/solr/core/src/test/org/apache/solr/cli/PackageToolTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/PackageToolTest.java
@@ -373,6 +373,63 @@ public class PackageToolTest extends SolrCloudTestCase {
         success);
   }
 
+  /** Validates that collection existence is checked before package 
resolution. */
+  @Test
+  public void testDeployValidationMessages() throws Exception {
+    String solrUrl = cluster.getJettySolrRunner(0).getBaseUrl().toString();
+
+    withBasicAuth(CollectionAdminRequest.createCollection("validation-test", 
"conf1", 1, 1))
+        .processAndWait(cluster.getSolrClient(), 10);
+
+    CLITestHelper.TestingRuntime captureRuntime = new 
CLITestHelper.TestingRuntime(true);
+    PackageTool tool = new PackageTool(captureRuntime);
+
+    // Collection exists but package does not — collection validation should 
pass,
+    // package lookup should fail.
+    tool.runTool(
+        SolrCLI.processCommandLineArgs(
+            tool,
+            new String[] {
+              "--solr-url",
+              solrUrl,
+              "deploy",
+              "NONEXISTENT_PKG",
+              "--collections",
+              "validation-test",
+              "--credentials",
+              SecurityJson.USER_PASS
+            }));
+    String deployOut = captureRuntime.getOutput();
+    assertFalse(
+        "Should not complain about invalid collection", 
deployOut.contains("Invalid collection"));
+    assertTrue(
+        "Should report missing package",
+        deployOut.contains("Package instance doesn't exist: 
NONEXISTENT_PKG:null"));
+
+    captureRuntime.clearOutput();
+
+    // Undeploy of a package that was never deployed should give a clear 
message.
+    tool.runTool(
+        SolrCLI.processCommandLineArgs(
+            tool,
+            new String[] {
+              "--solr-url",
+              solrUrl,
+              "undeploy",
+              "NONEXISTENT_PKG",
+              "--collections",
+              "validation-test",
+              "--credentials",
+              SecurityJson.USER_PASS
+            }));
+    String undeployOut = captureRuntime.getOutput();
+    assertFalse(
+        "Should not complain about invalid collection", 
undeployOut.contains("Invalid collection"));
+    assertTrue(
+        "Should report package not deployed",
+        undeployOut.contains("Package NONEXISTENT_PKG not deployed on 
collection validation-test"));
+  }
+
   private void run(PackageTool tool, String[] args) throws Exception {
     int res = tool.runTool(SolrCLI.processCommandLineArgs(tool, args));
     assertEquals("Non-zero status returned for: " + Arrays.toString(args), 0, 
res);
diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle
index 7320f2ebe2b..953adafe01d 100644
--- a/solr/packaging/build.gradle
+++ b/solr/packaging/build.gradle
@@ -281,6 +281,10 @@ task integrationTests(type: BatsTask) {
     }
   }
 
+  if (!Boolean.parseBoolean((String) 
project.findProperty('solr.bats.nightly'))) {
+    filterTags = '!nightly'
+  }
+
   inputs.dir(distDir)
   inputs.dir('test')  // Track .bats test files and helper as inputs
   outputs.dir(integrationTestOutput)
@@ -320,6 +324,10 @@ class BatsTask extends Exec {
   @Input
   var testFiles = []
 
+  @Input
+  @Optional
+  String filterTags = null
+
   @Option(option = "tests", description = "Sets test cases to be included")
   public void setTestNamePatterns(List<String> tests) {
     // TODO: bats --filter <regex>
@@ -335,6 +343,9 @@ class BatsTask extends Exec {
     if (logger.isInfoEnabled()) {
       batsArgs << '--verbose-run'
     }
+    if (filterTags) {
+      batsArgs += ['--filter-tags', filterTags]
+    }
     batsArgs += ['-T', '--print-output-on-failure', '--report-formatter', 
'junit', '--output', "$project.buildDir/test-output"]
     // Note: tests to run must be listed after all other arguments
     batsArgs += testFiles.empty ? [testDir] : testFiles
diff --git a/solr/packaging/test/README.md b/solr/packaging/test/README.md
index bd73d494589..e575502090b 100644
--- a/solr/packaging/test/README.md
+++ b/solr/packaging/test/README.md
@@ -55,6 +55,24 @@ Some tests will start clusters or create collections,
 
 It is recommended that you install and run `shellcheck` to verify your test 
scripts and catch common mistakes before committing your changes.
 
+## Nightly Tests
+
+Some BATS tests are slow or require network access (e.g. downloading models) 
and are
+excluded from regular runs by default. These tests use BATS native tagging via
+`# bats test_tags=nightly` and are filtered out with `--filter-tags !nightly`.
+
+To include nightly tests, pass the Gradle property `solr.bats.nightly`:
+
+    ./gradlew integrationTests -Psolr.bats.nightly=true
+
+When writing a new test that should only run in nightly builds, add the BATS 
tag comment
+directly before the `@test` declaration:
+
+    # bats test_tags=nightly
+    @test "my slow test" {
+      ...
+    }
+
 ## Limitations
 
 1. Currently this test suite is only available for \*nix environments. 
Although, newer
diff --git a/solr/packaging/test/test_example.bats 
b/solr/packaging/test/test_example.bats
index a15ba4b6f62..a5b4108e549 100644
--- a/solr/packaging/test/test_example.bats
+++ b/solr/packaging/test/test_example.bats
@@ -17,25 +17,36 @@
 
 load bats_helper
 
-setup() {
+setup_file() {
   common_clean_setup
+  solr start -e cloud --no-prompt --jvm-opts "-Dcustom.prop=helloworld"
+  solr assert --started http://localhost:${SOLR_PORT} --cloud 
http://localhost:${SOLR_PORT} --timeout 60000
+  solr assert --started http://localhost:${SOLR2_PORT} --cloud 
http://localhost:${SOLR2_PORT} --timeout 60000
+}
+
+teardown_file() {
+  common_setup
+  solr stop --all >/dev/null 2>&1
+}
+
+setup() {
+  common_setup
 }
 
 teardown() {
   # save a snapshot of SOLR_HOME for failed tests
   save_home_on_failure
+}
 
-  solr stop --all >/dev/null 2>&1
+@test "start -e cloud works with --no-prompt" {
+  solr assert --started http://localhost:${SOLR_PORT} --cloud 
http://localhost:${SOLR_PORT} --timeout 10000
+  solr assert --started http://localhost:${SOLR2_PORT} --cloud 
http://localhost:${SOLR2_PORT} --timeout 10000
 }
 
 @test "start -e cloud works with --jvm-opts" {
-  solr start -e cloud --no-prompt --jvm-opts "-Dcustom.prop=helloworld"
-  solr assert --started http://localhost:${SOLR_PORT} --cloud 
http://localhost:${SOLR_PORT} --timeout 60000
-  solr assert --started http://localhost:${SOLR2_PORT} --cloud 
http://localhost:${SOLR2_PORT} --timeout 60000
-
   run curl "http://localhost:${SOLR_PORT}/solr/admin/info/properties";
   assert_output --partial 'helloworld'
-  
+
   run curl "http://localhost:${SOLR2_PORT}/solr/admin/info/properties";
   assert_output --partial 'helloworld'
 }
diff --git a/solr/packaging/test/test_example_noprompt.bats 
b/solr/packaging/test/test_example_noprompt.bats
deleted file mode 100644
index 19329a8041a..00000000000
--- a/solr/packaging/test/test_example_noprompt.bats
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bats
-
-# 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.
-
-load bats_helper
-
-setup() {
-  common_clean_setup
-}
-
-teardown() {
-  # save a snapshot of SOLR_HOME for failed tests
-  save_home_on_failure
-
-  solr stop --all >/dev/null 2>&1
-}
-
-@test "start -e cloud works with --no-prompt" {
-  solr start -e cloud --no-prompt
-  solr assert --started http://localhost:${SOLR_PORT} --cloud 
http://localhost:${SOLR_PORT} --timeout 10000
-  solr assert --started http://localhost:${SOLR2_PORT} --cloud 
http://localhost:${SOLR2_PORT} --timeout 10000
-}
diff --git a/solr/packaging/test/test_healthcheck.bats 
b/solr/packaging/test/test_healthcheck.bats
index e8f6069cb08..5492fb8b514 100644
--- a/solr/packaging/test/test_healthcheck.bats
+++ b/solr/packaging/test/test_healthcheck.bats
@@ -29,22 +29,18 @@ teardown() {
 }
 
 @test "healthcheck on cloud solr" {
-  solr start -e films
-  run solr healthcheck -c films
+  solr start
+  solr create -c healthcheck_test -d _default
+  # Local
+  run solr healthcheck -c healthcheck_test
   refute_output --partial 'error'
-
-}
-
-@test "healthcheck on remote cloud solr" {
-  solr start -e films
-  run solr healthcheck -c films --solr-connection 
http://localhost:${SOLR_PORT}/solr
+  # Remote
+  run solr healthcheck -c healthcheck_test --solr-connection 
http://localhost:${SOLR_PORT}/solr
   refute_output --partial 'error'
-
 }
 
 @test "healthcheck errors on standalone solr" {
-  solr start --user-managed -e films
-  run solr healthcheck -c films
+  solr start --user-managed
+  run solr healthcheck -c healthcheck_test
   assert_output --partial 'Healthcheck tool only works in Solr Cloud mode'
-
 }
diff --git a/solr/packaging/test/test_opennlp.bats 
b/solr/packaging/test/test_opennlp.bats
index 69ee71253cf..4f71259682f 100644
--- a/solr/packaging/test/test_opennlp.bats
+++ b/solr/packaging/test/test_opennlp.bats
@@ -42,8 +42,8 @@ teardown() {
 # long test as an "integration" test is something we decide is okay?
 # I also have dreams of incorporating this as code snippets in a Tutorial via 
the ascii doc tags
 # like we use for the SolrJ code snippets.  That way we know the snippets 
continue to work!
+# bats test_tags=nightly
 @test "Check lifecycle of sentiment classification" {
-
   echo "Downloading onnx model and vocab..."
   
   mkdir -p ${SOLR_TIP}/models/sentiment/
diff --git a/solr/packaging/test/test_packages.bats 
b/solr/packaging/test/test_packages.bats
deleted file mode 100644
index 1f60523e53f..00000000000
--- a/solr/packaging/test/test_packages.bats
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env bats
-
-# 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.
-
-load bats_helper
-
-setup() {
-  common_clean_setup
-}
-
-teardown() {
-  # save a snapshot of SOLR_HOME for failed tests
-  save_home_on_failure
-
-  solr stop --all >/dev/null 2>&1
-}
-
-@test "lifecycle of package" {
-  run solr start -Dsolr.packages.enabled=true
-
-  run solr package --help
-  assert_output --partial "Add a repository to Solr"
-
-  run solr package list-available
-  assert_output --partial "Available packages:"
-}
-
-@test "deploying and undeploying a collection level package" {
-  run solr start -Dsolr.packages.enabled=true
-
-  solr create -c foo-1.2
-
-  # Deploy package - the package doesn't need to exist before the collection 
validation kicks in
-  run solr package deploy PACKAGE_NAME --collections foo-1.2
-  # assert_output --partial "Deployment successful"
-  refute_output --partial "Invalid collection"
-  
-  # Until PACKAGE_NAME refers to an actual installable package, this is as far 
as we get.
-  assert_output --partial "Package instance doesn't exist: PACKAGE_NAME:null"
-
-  # Undeploy package
-  run solr package undeploy PACKAGE_NAME --collections foo-1.2
-  refute_output --partial "Invalid collection"
-  assert_output --partial "Package PACKAGE_NAME not deployed on collection 
foo-1.2"
-}
-
-# This test is useful if you are debugging/working with packages.
-# We have disabled it for now since it depends on a live internet
-# connection to run.  This could be updated with a local Repo server if we had
-# a package that is part of the Solr project to use.
-@test "deploying and undeploying a cluster level package" {
-  skip "For developing package infra; requires a connection to github"
-
-  run solr start -Dsolr.packages.enabled=true
-  
-  run solr package add-repo splainer 
"https://raw.githubusercontent.com/o19s/splainer/refs/heads/main/solr-splainer-package/repo/";
-  assert_output --partial "Added repository: splainer"
-  
-  run solr package list-available
-  assert_output --partial "solr-splainer               Splainer for Solr"
-  run solr package install solr-splainer
-  assert_output --partial "solr-splainer installed."
-
-  run solr package deploy solr-splainer -y --cluster
-  assert_output --partial "Deployment successful"
-  
-  run -0 curl --fail http://localhost:${SOLR_PORT}/v2/splainer/index.html
-}
diff --git a/solr/packaging/test/test_ssl.bats 
b/solr/packaging/test/test_ssl.bats
index 5075ec76338..cf92d144d4f 100644
--- a/solr/packaging/test/test_ssl.bats
+++ b/solr/packaging/test/test_ssl.bats
@@ -572,26 +572,26 @@ teardown() {
     # Replace server1 keystore with client's
     cp cert2.keystore.p12 server1.keystore.p12
   )
-  # Give some time for the server reload
-  sleep 6
+  # Wait for Jetty keystore-reload scan to pick up the new certificate
+  wait_for 30 1 solr api --solr-url 
"https://localhost:${SOLR_PORT}/solr/admin/info/system";
 
-  run solr healthcheck --solr-url https://localhost:${SOLR_PORT}
+  run solr healthcheck -c test --solr-url https://localhost:${SOLR_PORT}
 
   # Server 2 still uses the cert1, so this request should fail
   run ! solr api --solr-url 
"https://localhost:${SOLR2_PORT}/solr/test/select?q=query2";
 
-  run ! solr healthcheck --solr-url https://localhost:${SOLR2_PORT}
+  run ! solr healthcheck -c test --solr-url https://localhost:${SOLR2_PORT}
 
   (
     cd "$ssl_dir"
     # Replace server2 keystore with client's
     cp cert2.keystore.p12 server2.keystore.p12
   )
-  # Give some time for the server reload
-  sleep 6
+  # Wait for Jetty keystore-reload scan to pick up the new certificate
+  wait_for 30 1 solr api --solr-url 
"https://localhost:${SOLR2_PORT}/solr/admin/info/system";
 
-  run solr healthcheck --solr-url https://localhost:${SOLR_PORT}
-  run solr healthcheck --solr-url https://localhost:${SOLR2_PORT}
+  run solr healthcheck -c test --solr-url https://localhost:${SOLR_PORT}
+  run solr healthcheck -c test --solr-url https://localhost:${SOLR2_PORT}
 
   run solr api --solr-url 
"https://localhost:${SOLR_PORT}/solr/test/select?q=query3";
   assert_output --partial '"numFound":0'
diff --git a/solr/packaging/test/test_start_solr.bats 
b/solr/packaging/test/test_start_solr.bats
index 0b206dc7278..f85c0e5918d 100644
--- a/solr/packaging/test/test_start_solr.bats
+++ b/solr/packaging/test/test_start_solr.bats
@@ -25,7 +25,7 @@ teardown() {
   # save a snapshot of SOLR_HOME for failed tests
   save_home_on_failure
 
-  solr stop --all >/dev/null 2>&1
+  SOLR_STOP_WAIT=30 solr stop --all >/dev/null 2>&1
 }
 
 @test "SOLR-11740 check 'solr stop' connection" {
diff --git a/solr/packaging/test/test_status.bats 
b/solr/packaging/test/test_status.bats
index 69a5278aca1..c03e07bfc60 100644
--- a/solr/packaging/test/test_status.bats
+++ b/solr/packaging/test/test_status.bats
@@ -17,40 +17,38 @@
 
 load bats_helper
 
-setup() {
+setup_file() {
   common_clean_setup
+  solr start
+}
+
+teardown_file() {
+  common_setup
+  solr stop --all
+}
+
+setup() {
+  common_setup
 }
 
 teardown() {
   # save a snapshot of SOLR_HOME for failed tests
   save_home_on_failure
-
-  solr stop --all >/dev/null 2>&1
 }
 
 @test "status detects locally running solr" {
-  run solr status
-  assert_output --partial "No Solr nodes are running."
-  solr start
   run solr status
   assert_output --partial "running on port ${SOLR_PORT}"
-  solr stop
-  run solr status
-  assert_output --partial "No Solr nodes are running."
 }
 
 @test "status with --solr-url from user" {
-  solr start
   run solr status --solr-url http://localhost:${SOLR_PORT}
   assert_output --partial "\"solr_home\":"
-  solr stop
 }
 
 @test "status with --port from user" {
-  solr start
   run solr status --port ${SOLR_PORT}
   assert_output --partial "running on port ${SOLR_PORT}"
-  solr stop
 }
 
 @test "multiple connection options are prevented" {
@@ -64,8 +62,6 @@ teardown() {
 }
 
 @test "status with --short format" {
-  solr start
   run solr status --port ${SOLR_PORT} --short
   assert_output --partial "http://localhost:${SOLR_PORT}/solr";
-  solr stop
 }
diff --git a/solr/packaging/test/test_zk.bats b/solr/packaging/test/test_zk.bats
index 4cb77a6f590..e2732354799 100644
--- a/solr/packaging/test/test_zk.bats
+++ b/solr/packaging/test/test_zk.bats
@@ -59,13 +59,11 @@ teardown() {
 }
 
 @test "listing out files" {
-  sleep 1
   run solr zk ls / -z localhost:${ZK_PORT} --recursive
   assert_output --partial "aliases.json"
 }
 
 @test "connecting to solr via various solr urls and zk hosts" {
-  sleep 1
   run solr zk ls / --solr-url http://localhost:${SOLR_PORT}
   assert_output --partial "aliases.json"
 
@@ -90,20 +88,17 @@ teardown() {
 
   run solr zk cp myfile.txt zk:/myfile.txt -z localhost:${ZK_PORT}
   assert_output --partial "Copying from 'myfile.txt' to 'zk:/myfile.txt'. 
ZooKeeper at localhost:${ZK_PORT}"
-  sleep 1
   run solr zk ls / -z localhost:${ZK_PORT}
   assert_output --partial "myfile.txt"
 
   touch myfile2.txt
   run solr zk cp myfile2.txt zk:myfile2.txt -z localhost:${ZK_PORT}
-  sleep 1
   run solr zk ls / -z localhost:${ZK_PORT}
   assert_output --partial "myfile2.txt"
 
   touch myfile3.txt
   run solr zk cp myfile3.txt zk:/myfile3.txt -z localhost:${ZK_PORT}
   assert_output --partial "Copying from 'myfile3.txt' to 'zk:/myfile3.txt'. 
ZooKeeper at localhost:${ZK_PORT}"
-  sleep 1
   run solr zk ls / -z localhost:${ZK_PORT}
   assert_output --partial "myfile3.txt"
 
@@ -125,7 +120,7 @@ teardown() {
   assert_output --partial "Uploading"
   refute_output --partial "ERROR"
 
-  sleep 1
+  wait_for 10 1 bash -c "curl -s 
'http://localhost:${SOLR_PORT}/api/configsets' | grep -q techproducts2"
   run curl "http://localhost:${SOLR_PORT}/api/configsets";
   assert_output --partial '"configSets":["_default","techproducts2"]'
 }
@@ -172,8 +167,6 @@ teardown() {
 }
 
 @test "env var ZK_HOST is honored" {
-  sleep 1
-
   # Need to unset SOLR_PORT to avoid the tool being smart and look at SOLR_PORT
   export SOLR_PORT_KEEP=$SOLR_PORT_LISTEN
   unset SOLR_PORT_LISTEN

Reply via email to