From 60161317852951887fa4ee73dcd54139325abc00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 20:31:05 +0200 Subject: [PATCH 01/13] Gate OpenNLP BATS test behind OPENNLP_TESTS env var The test downloads ONNX models from the network and its own comment describes it as exploratory rather than a regular integration test. Skip it by default; set OPENNLP_TESTS=true to opt in. --- solr/packaging/test/test_opennlp.bats | 3 +++ 1 file changed, 3 insertions(+) diff --git a/solr/packaging/test/test_opennlp.bats b/solr/packaging/test/test_opennlp.bats index 69ee71253cf4..975ed4697e11 100644 --- a/solr/packaging/test/test_opennlp.bats +++ b/solr/packaging/test/test_opennlp.bats @@ -43,6 +43,9 @@ teardown() { # 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! @test "Check lifecycle of sentiment classification" { + if [ -z "${OPENNLP_TESTS:-}" ]; then + skip "Set OPENNLP_TESTS=true to run OpenNLP integration tests (downloads models from network)" + fi echo "Downloading onnx model and vocab..." From 62ac939c8ec5614cca86e78983fe0bbfe8c7b957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 20:31:27 +0200 Subject: [PATCH 02/13] Restructure test_status.bats to share one Solr invocation Previously each of the four tests that needed a running Solr started and stopped their own instance, costing four separate Solr startups. Switch to a setup_file/teardown_file pair so all tests share a single startup. The "No Solr nodes running" assertion is removed from the lifecycle test since it is already verified by the suite-wide test_zz_cleanup.bats. --- solr/packaging/test/test_status.bats | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/solr/packaging/test/test_status.bats b/solr/packaging/test/test_status.bats index 5399a0b9fd6c..22589b35a1f7 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 } From e5722f4c5d1079e1e71fdf091ac2e3107df49ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 20:31:46 +0200 Subject: [PATCH 03/13] Replace expensive -e films startup in test_healthcheck.bats Both healthcheck tests previously used 'solr start -e films' which loads and indexes the full films example dataset. Replace with a plain 'solr start' plus 'solr create -c healthcheck_test -d _default' for the cloud test, and a plain 'solr start --user-managed' for the standalone test (which fails before any collection is needed). --- solr/packaging/test/test_healthcheck.bats | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/solr/packaging/test/test_healthcheck.bats b/solr/packaging/test/test_healthcheck.bats index 30edfeff2357..ce5f480398d7 100644 --- a/solr/packaging/test/test_healthcheck.bats +++ b/solr/packaging/test/test_healthcheck.bats @@ -29,15 +29,14 @@ teardown() { } @test "healthcheck on cloud solr" { - solr start -e films - run solr healthcheck -c films + solr start + solr create -c healthcheck_test -d _default + run solr healthcheck -c healthcheck_test 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' - } From 064e3475c7085d5474cf089e6ca9ea2a38c3f097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 20:32:32 +0200 Subject: [PATCH 04/13] Convert test_packages.bats to JUnit and delete BATS file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PackageToolTest already tests the full lifecycle (list-available, add-repo, install, deploy, undeploy). Add testDeployValidationMessages() to cover the two remaining BATS assertions: - collection exists but package not found → "Package instance doesn't exist" - undeploy of never-deployed package → "Package … not deployed on collection" Delete test_packages.bats. --- .../org/apache/solr/cli/PackageToolTest.java | 57 +++++++++++++ solr/packaging/test/test_packages.bats | 81 ------------------- 2 files changed, 57 insertions(+), 81 deletions(-) delete mode 100644 solr/packaging/test/test_packages.bats 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 e8cb48874b68..9282af37e520 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 static void testForResponseElement( 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/test/test_packages.bats b/solr/packaging/test/test_packages.bats deleted file mode 100644 index 1f60523e53f0..000000000000 --- 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 -} From 3bf997e1f77f83fdd5b0a69602dd8c59dd19684c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 20:35:33 +0200 Subject: [PATCH 05/13] Convert test_compression.bats to JUnit and delete BATS file Add GzipCompressionTest (SolrCloudTestCase) to solr/core which verifies: - Requests without Accept-Encoding get no Content-Encoding header - Requests with Accept-Encoding: gzip get Content-Encoding: gzip The minGzipSize Jetty property is lowered to 1 byte for the test cluster so that any non-empty response body is eligible for compression. Uses the Jetty HttpClient already available via JettySolrRunner, consistent with CacheHeaderTest and SecurityHeadersTest. Delete test_compression.bats. --- .../solr/servlet/GzipCompressionTest.java | 97 +++++++++++++++++++ solr/packaging/test/test_compression.bats | 47 --------- 2 files changed, 97 insertions(+), 47 deletions(-) create mode 100644 solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java delete mode 100644 solr/packaging/test/test_compression.bats diff --git a/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java b/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java new file mode 100644 index 000000000000..0be2dff5e37e --- /dev/null +++ b/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java @@ -0,0 +1,97 @@ +/* + * 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.solr.servlet; + +import org.apache.solr.client.solrj.request.CollectionAdminRequest; +import org.apache.solr.client.solrj.request.UpdateRequest; +import org.apache.solr.cloud.SolrCloudTestCase; +import org.apache.solr.common.SolrInputDocument; +import org.eclipse.jetty.client.ContentResponse; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.http.HttpHeader; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Verifies that Solr's Jetty GzipHandler correctly compresses HTTP responses when the client + * sends {@code Accept-Encoding: gzip} and omits compression when that header is absent. + * + *

Replaces the BATS integration test {@code test_compression.bats}. + */ +public class GzipCompressionTest extends SolrCloudTestCase { + + private static final String COLLECTION = "gzip-test"; + + @BeforeClass + public static void setupCluster() throws Exception { + // Lower the minGzipSize threshold so any non-empty response body is eligible for compression. + // jetty-gzip.xml reads this property at Jetty start time via . + System.setProperty("jetty.gzip.minGzipSize", "1"); + + configureCluster(1).configure(); + + CollectionAdminRequest.createCollection(COLLECTION, null, 1, 1) + .process(cluster.getSolrClient()); + + // Index a few documents so the select response has a non-trivial body + UpdateRequest req = new UpdateRequest(); + for (int i = 0; i < 10; i++) { + SolrInputDocument doc = new SolrInputDocument(); + doc.addField("id", "doc-" + i); + doc.addField("name_s", "Document number " + i + " for gzip compression test"); + req.add(doc); + } + req.commit(cluster.getSolrClient(), COLLECTION); + } + + @AfterClass + public static void clearGzipSysProp() { + System.clearProperty("jetty.gzip.minGzipSize"); + } + + private HttpClient getHttpClient() { + return cluster.getJettySolrRunner(0).getSolrClient().getHttpClient(); + } + + private String getSelectUrl() { + return cluster.getJettySolrRunner(0).getBaseUrl() + "/" + COLLECTION + "/select?q=*:*&rows=10"; + } + + @Test + public void testNoCompressionWithoutAcceptEncodingHeader() throws Exception { + ContentResponse response = getHttpClient().GET(getSelectUrl()); + assertEquals("Expected HTTP 200", 200, response.getStatus()); + assertNull( + "Content-Encoding should not be set when Accept-Encoding header is absent", + response.getHeaders().get(HttpHeader.CONTENT_ENCODING)); + } + + @Test + public void testGzipCompressionWithAcceptEncodingHeader() throws Exception { + ContentResponse response = + getHttpClient() + .newRequest(getSelectUrl()) + .headers(h -> h.add(HttpHeader.ACCEPT_ENCODING, "gzip")) + .send(); + assertEquals("Expected HTTP 200", 200, response.getStatus()); + assertEquals( + "Expected gzip Content-Encoding when Accept-Encoding: gzip was requested", + "gzip", + response.getHeaders().get(HttpHeader.CONTENT_ENCODING)); + } +} diff --git a/solr/packaging/test/test_compression.bats b/solr/packaging/test/test_compression.bats deleted file mode 100644 index 575490c8f99a..000000000000 --- a/solr/packaging/test/test_compression.bats +++ /dev/null @@ -1,47 +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_file() { - common_clean_setup - solr start -e films -} - -setup() { - common_setup -} - -teardown_file() { - save_home_on_failure - solr stop --all >/dev/null 2>&1 -} - -@test "server does not compress response without Accept-Encoding header" { - run curl -s -D - -o /dev/null "http://localhost:${SOLR_PORT}/solr/films/select?q=*:*&rows=100" - refute_output --partial "Content-Encoding:" -} - -@test "server compresses response when Accept-Encoding: gzip is requested" { - run curl -s -D - -o /dev/null -H "Accept-Encoding: gzip" "http://localhost:${SOLR_PORT}/solr/films/select?q=*:*&rows=100" - assert_output --partial "gzip" -} - -@test "compressed response can be decompressed and parsed" { - run curl -s --compressed "http://localhost:${SOLR_PORT}/solr/films/select?q=*:*&rows=100" - assert_output --partial '"status":0' -} From c5f15a91f48308f97e73731d1505008c14fe70cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 20:36:52 +0200 Subject: [PATCH 06/13] Remove unnecessary sleep calls in test_zk.bats solr start already waits until Solr is ready before returning, so the sleep 1 calls at the start of "listing out files" and "connecting to solr via various solr urls" were unnecessary. solr zk cp is synchronous; the three sleep 1 calls that followed it before listing the copied file were also unnecessary. The sleep 1 before the ZK_HOST env-var test had no purpose. Replace the sleep 1 after solr zk upconfig with wait_for so we poll until the configsets REST endpoint actually reflects the new config instead of relying on a fixed delay. --- solr/packaging/test/test_zk.bats | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/solr/packaging/test/test_zk.bats b/solr/packaging/test/test_zk.bats index 11ee3a7a76d1..5f5fe6b1ad2f 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" @@ -87,20 +85,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" @@ -122,7 +117,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"]' } @@ -169,8 +164,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 From 127ba60645ae50a2caf4d6ea3812f75e57410d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 20:49:11 +0200 Subject: [PATCH 07/13] BATS: cap solr stop wait in test_start_solr.bats to avoid 3-minute hang Default SOLR_STOP_WAIT is ~180 s; on CI test 105 ("deprecated system properties") was taking 196 s entirely because teardown waited for the 180 s timeout before giving up. Set SOLR_STOP_WAIT=30 in teardown so worst-case the stop waits 30 s, saving ~150 s per affected test. --- solr/packaging/test/test_start_solr.bats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/packaging/test/test_start_solr.bats b/solr/packaging/test/test_start_solr.bats index a24ceadd24c5..d136413c882b 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" { From 8b13e5bc7e32863fc20bf2a84f803622354549d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 20:49:53 +0200 Subject: [PATCH 08/13] BATS: merge test_example_noprompt into test_example, share one cloud startup Both tests ran 'solr start -e cloud --no-prompt'. Merge them into a single file with setup_file/teardown_file so the two-node cloud is started once and both tests reuse it. Deletes test_example_noprompt.bats. Saves ~78 s on CI (one full two-node cloud startup removed). --- solr/packaging/test/test_example.bats | 25 +++++++++---- .../packaging/test/test_example_noprompt.bats | 35 ------------------- 2 files changed, 18 insertions(+), 42 deletions(-) delete mode 100644 solr/packaging/test/test_example_noprompt.bats diff --git a/solr/packaging/test/test_example.bats b/solr/packaging/test/test_example.bats index a15ba4b6f625..a5b4108e549d 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 19329a8041af..000000000000 --- 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 -} From 6de8b121684c5315281b6d9ba1d84ae03eaa1b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 21:00:16 +0200 Subject: [PATCH 09/13] BATS: replace fixed sleep 6 with wait_for polling in keystore reload test 'test keystore reload' (test 100, 75 s on CI) slept 6 s twice to give Jetty time to pick up the replaced keystore file. Replace both with wait_for so the test proceeds as soon as the reload completes rather than always paying 12 s. Timeout is 30 s to handle slow CI boxes. --- solr/packaging/test/test_ssl.bats | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/solr/packaging/test/test_ssl.bats b/solr/packaging/test/test_ssl.bats index 5075ec763380..83083fb9c1c1 100644 --- a/solr/packaging/test/test_ssl.bats +++ b/solr/packaging/test/test_ssl.bats @@ -572,8 +572,8 @@ 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 healthcheck --solr-url https://localhost:${SOLR_PORT} run solr healthcheck --solr-url https://localhost:${SOLR_PORT} @@ -587,8 +587,8 @@ teardown() { # 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 healthcheck --solr-url https://localhost:${SOLR2_PORT} run solr healthcheck --solr-url https://localhost:${SOLR_PORT} run solr healthcheck --solr-url https://localhost:${SOLR2_PORT} From 9aadafd324de53c36105dad1713e45ec1daccaa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 21:00:16 +0200 Subject: [PATCH 10/13] BATS: rename OPENNLP_TESTS skip guard to SOLR_BATS_OPENNLP_TESTS More descriptive name that makes it clear the variable is specific to the Solr BATS test suite. --- solr/packaging/test/test_opennlp.bats | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solr/packaging/test/test_opennlp.bats b/solr/packaging/test/test_opennlp.bats index 975ed4697e11..c5d53c78f581 100644 --- a/solr/packaging/test/test_opennlp.bats +++ b/solr/packaging/test/test_opennlp.bats @@ -43,8 +43,8 @@ teardown() { # 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! @test "Check lifecycle of sentiment classification" { - if [ -z "${OPENNLP_TESTS:-}" ]; then - skip "Set OPENNLP_TESTS=true to run OpenNLP integration tests (downloads models from network)" + if [ -z "${SOLR_BATS_OPENNLP_TESTS:-}" ]; then + skip "Set SOLR_BATS_OPENNLP_TESTS=true to run OpenNLP integration tests (downloads models from network)" fi echo "Downloading onnx model and vocab..." From e94e174336e23b8fccc24eb67538c5fb32ed9cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 30 May 2026 23:14:38 +0200 Subject: [PATCH 11/13] Precommit --- .../test/org/apache/solr/servlet/GzipCompressionTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java b/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java index 0be2dff5e37e..f887e8818b80 100644 --- a/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java +++ b/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java @@ -28,8 +28,8 @@ import org.junit.Test; /** - * Verifies that Solr's Jetty GzipHandler correctly compresses HTTP responses when the client - * sends {@code Accept-Encoding: gzip} and omits compression when that header is absent. + * Verifies that Solr's Jetty GzipHandler correctly compresses HTTP responses when the client sends + * {@code Accept-Encoding: gzip} and omits compression when that header is absent. * *

Replaces the BATS integration test {@code test_compression.bats}. */ @@ -40,7 +40,8 @@ public class GzipCompressionTest extends SolrCloudTestCase { @BeforeClass public static void setupCluster() throws Exception { // Lower the minGzipSize threshold so any non-empty response body is eligible for compression. - // jetty-gzip.xml reads this property at Jetty start time via . + // jetty-gzip.xml reads this property at Jetty start time via . System.setProperty("jetty.gzip.minGzipSize", "1"); configureCluster(1).configure(); From 29f3cca7d83281524c0a9a308d27ca9803e805aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 31 May 2026 00:00:26 +0200 Subject: [PATCH 12/13] Fix test_ssl.bats --- solr/packaging/test/test_ssl.bats | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/solr/packaging/test/test_ssl.bats b/solr/packaging/test/test_ssl.bats index 83083fb9c1c1..cf92d144d4f9 100644 --- a/solr/packaging/test/test_ssl.bats +++ b/solr/packaging/test/test_ssl.bats @@ -573,14 +573,14 @@ teardown() { cp cert2.keystore.p12 server1.keystore.p12 ) # Wait for Jetty keystore-reload scan to pick up the new certificate - wait_for 30 1 solr healthcheck --solr-url https://localhost:${SOLR_PORT} + 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" @@ -588,10 +588,10 @@ teardown() { cp cert2.keystore.p12 server2.keystore.p12 ) # Wait for Jetty keystore-reload scan to pick up the new certificate - wait_for 30 1 solr healthcheck --solr-url https://localhost:${SOLR2_PORT} + 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' From abea3e1c3ef705fd6e8b9b7503575cc1d7f121d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 31 May 2026 16:02:17 +0200 Subject: [PATCH 13/13] Remove needless comment about BATS integration test --- .../src/test/org/apache/solr/servlet/GzipCompressionTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java b/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java index f887e8818b80..c6a2d69b4ab6 100644 --- a/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java +++ b/solr/core/src/test/org/apache/solr/servlet/GzipCompressionTest.java @@ -30,8 +30,6 @@ /** * Verifies that Solr's Jetty GzipHandler correctly compresses HTTP responses when the client sends * {@code Accept-Encoding: gzip} and omits compression when that header is absent. - * - *

Replaces the BATS integration test {@code test_compression.bats}. */ public class GzipCompressionTest extends SolrCloudTestCase {