This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_10x in repository https://gitbox.apache.org/repos/asf/solr.git
commit b7808ca432d001dc89b6c44f546c815b473e3064 Author: Andrzej BiaĆecki <[email protected]> AuthorDate: Wed Sep 16 22:09:38 2026 +0200 SOLR-18414: Randomize use of QueryLimits in all tests. (#4894) Co-authored-by: David Smiley <[email protected]> (cherry picked from commit c1e326027eee435b32e7516407741c91ca7f4289) --- .../solr/core/ExitableDirectoryReaderTest.java | 7 ++ .../org/apache/solr/search/TestRangeQuery.java | 10 ++- .../org/apache/solr/ltr/TestLTRQParserPlugin.java | 5 +- .../src/java/org/apache/solr/SolrTestCase.java | 2 + .../solr/util/QueryLimitsTestInjectionRule.java | 77 ++++++++++++++++++++++ 5 files changed, 95 insertions(+), 6 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/core/ExitableDirectoryReaderTest.java b/solr/core/src/test/org/apache/solr/core/ExitableDirectoryReaderTest.java index e8a11f181a7..df4ab85494b 100644 --- a/solr/core/src/test/org/apache/solr/core/ExitableDirectoryReaderTest.java +++ b/solr/core/src/test/org/apache/solr/core/ExitableDirectoryReaderTest.java @@ -20,8 +20,10 @@ import java.util.Map; import java.util.Set; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.search.CallerSpecificQueryLimit; +import org.apache.solr.util.QueryLimitsTestInjectionRule; import org.apache.solr.util.TestInjection; import org.junit.After; +import org.junit.BeforeClass; import org.junit.Test; public class ExitableDirectoryReaderTest extends SolrTestCaseJ4 { @@ -44,6 +46,11 @@ public class ExitableDirectoryReaderTest extends SolrTestCaseJ4 { assertU(commit()); } + @BeforeClass + public static void beforeClass() throws Exception { + QueryLimitsTestInjectionRule.disable(); + } + @After public void tearDownCore() { deleteCore(); diff --git a/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java b/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java index 47da28286ad..b71d1ed932f 100644 --- a/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java +++ b/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java @@ -463,8 +463,14 @@ public class TestRangeQuery extends SolrTestCaseJ4 { queryService.awaitTermination( 1, TimeUnit.SECONDS)); // All queries after should be very fast - assertEquals( - "Create only one DocSet outside of cache", 1, TestInjection.countDocSetDelays.get()); + if (TestInjection.queryTimeout != null) { + assertTrue( + "Create multiple DocSet-s outside of cache because of possible query timeouts", + TestInjection.countDocSetDelays.get() > 0); + } else { + assertEquals( + "Create only one DocSet outside of cache", 1, TestInjection.countDocSetDelays.get()); + } } TestInjection.countDocSetDelays.set(0); } diff --git a/solr/modules/ltr/src/test/org/apache/solr/ltr/TestLTRQParserPlugin.java b/solr/modules/ltr/src/test/org/apache/solr/ltr/TestLTRQParserPlugin.java index 8f5f140f4fd..a835918ea1a 100644 --- a/solr/modules/ltr/src/test/org/apache/solr/ltr/TestLTRQParserPlugin.java +++ b/solr/modules/ltr/src/test/org/apache/solr/ltr/TestLTRQParserPlugin.java @@ -196,10 +196,7 @@ public class TestLTRQParserPlugin extends TestRerankBase { assertJQ( "/query" + query.toQueryString(), - "/error/msg=='org.apache.solr.search.QueryLimitsExceededException: Limits exceeded! (Learning To Rank rescoring - " - + "The full reranking didn\\'t complete. " - + "If partial results are tolerated the reranking got reverted and all documents preserved their original score and ranking.)" - + ": Query limits: [TimeAllowedLimit:LIMIT EXCEEDED]'"); + "/error/msg=='///regex:.*Limits exceeded\\!.*Learning To Rank rescoring.*///'"); } @Test diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCase.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCase.java index d1c3e539bf1..ad0857dee74 100644 --- a/solr/test-framework/src/java/org/apache/solr/SolrTestCase.java +++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCase.java @@ -38,6 +38,7 @@ import org.apache.solr.common.util.ObjectReleaseTracker; import org.apache.solr.core.ConfigSetService; import org.apache.solr.util.ExternalPaths; import org.apache.solr.util.LogLevelTestRule; +import org.apache.solr.util.QueryLimitsTestInjectionRule; import org.apache.solr.util.RevertDefaultThreadHandlerRule; import org.apache.solr.util.StartupLoggingUtils; import org.hamcrest.Matcher; @@ -91,6 +92,7 @@ public class SolrTestCase extends LuceneTestCase { "org.apache.solr.ltr", NAMING_CONVENTION_TEST_PREFIX)) .around(new RevertDefaultThreadHandlerRule()) .around(new LogLevelTestRule()) + .around(new QueryLimitsTestInjectionRule(LuceneTestCase::rarely)) .around( new TestRuleAdapter() { @Override diff --git a/solr/test-framework/src/java/org/apache/solr/util/QueryLimitsTestInjectionRule.java b/solr/test-framework/src/java/org/apache/solr/util/QueryLimitsTestInjectionRule.java new file mode 100644 index 00000000000..e98bdb7d4f4 --- /dev/null +++ b/solr/test-framework/src/java/org/apache/solr/util/QueryLimitsTestInjectionRule.java @@ -0,0 +1,77 @@ +/* + * 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.util; + +import java.lang.invoke.MethodHandles; +import java.util.function.BooleanSupplier; +import org.apache.solr.search.QueryLimit; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class QueryLimitsTestInjectionRule implements TestRule { + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private static BooleanSupplier enableSupplier; + + public QueryLimitsTestInjectionRule(BooleanSupplier enableSupplier) { + QueryLimitsTestInjectionRule.enableSupplier = enableSupplier; + } + + @Override + public Statement apply(final Statement base, final Description description) { + if (!enableSupplier.getAsBoolean()) { + return base; + } + return new Statement() { + @Override + public void evaluate() throws Throwable { + if (!enableSupplier.getAsBoolean()) { + base.evaluate(); + return; + } + log.info("###Test is configured to use QueryLimits"); + try { + assert TestInjection.queryTimeout == null : "Disabled too late, or was init'ed elsewhere"; + TestInjection.queryTimeout = + new QueryLimit() { + @Override + public Object currentValue() { + return "No-Op injected QueryLimit"; + } + + @Override + public boolean shouldExit() { + return false; + } + }; + + base.evaluate(); + } finally { + // always reset the queryTimeout + TestInjection.queryTimeout = null; + } + } + }; + } + + /** Disables for the whole test suite (class), not just for this individual test. */ + public static void disable() { + QueryLimitsTestInjectionRule.enableSupplier = Boolean.FALSE::booleanValue; + } +}
