You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by cp...@apache.org on 2022/08/19 14:47:51 UTC
[solr] branch main updated: SOLR-10059: add SearchHandlerAppendsCloudTest (#426)
This is an automated email from the ASF dual-hosted git repository.
cpoerschke 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 03946ee1f58 SOLR-10059: add SearchHandlerAppendsCloudTest (#426)
03946ee1f58 is described below
commit 03946ee1f585017bd2c3c0c79edd645ef962f8bd
Author: Christine Poerschke <cp...@apache.org>
AuthorDate: Fri Aug 19 15:47:45 2022 +0100
SOLR-10059: add SearchHandlerAppendsCloudTest (#426)
---
.../component/SearchHandlerAppendsCloudTest.java | 188 +++++++++++++++++++++
1 file changed, 188 insertions(+)
diff --git a/solr/core/src/test/org/apache/solr/handler/component/SearchHandlerAppendsCloudTest.java b/solr/core/src/test/org/apache/solr/handler/component/SearchHandlerAppendsCloudTest.java
new file mode 100644
index 00000000000..1d9c2ca96e1
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/handler/component/SearchHandlerAppendsCloudTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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.handler.component;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.client.solrj.request.QueryRequest;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.cloud.AbstractDistribZkTestBase;
+import org.apache.solr.cloud.ConfigRequest;
+import org.apache.solr.cloud.SolrCloudTestCase;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.ShardParams;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class SearchHandlerAppendsCloudTest extends SolrCloudTestCase {
+
+ private static String COLLECTION;
+ private static int NUM_SHARDS;
+ private static int NUM_REPLICAS;
+
+ @BeforeClass
+ public static void setupCluster() throws Exception {
+
+ // decide collection name ...
+ COLLECTION = "collection" + (1 + random().nextInt(100));
+ // ... and shard/replica/node numbers
+ NUM_SHARDS = (1 + random().nextInt(3)); // 1..3
+ NUM_REPLICAS = (1 + random().nextInt(2)); // 1..2
+
+ // create and configure cluster
+ configureCluster(NUM_SHARDS * NUM_REPLICAS /* nodeCount */)
+ .addConfig("conf", configset("cloud-dynamic"))
+ .configure();
+
+ // create an empty collection
+ CollectionAdminRequest.createCollection(COLLECTION, "conf", NUM_SHARDS, NUM_REPLICAS)
+ .processAndWait(cluster.getSolrClient(), DEFAULT_TIMEOUT);
+ AbstractDistribZkTestBase.waitForRecoveriesToFinish(
+ COLLECTION, ZkStateReader.from(cluster.getSolrClient()), false, true, DEFAULT_TIMEOUT);
+ }
+
+ @Test
+ public void test() throws Exception {
+
+ // field names
+ final String id = "id";
+ final String bee_t = "bee_t";
+ final String forage_t = "forage_t";
+
+ // add custom handlers (the exact custom handler names should not matter)
+ final String[] searchHandlerNames =
+ new String[] {
+ null, "/custom_select" + random().nextInt(), "/custom_select" + random().nextInt()
+ };
+ final String[] searchHandlerAppends =
+ new String[] {
+ null,
+ " 'appends' : { 'fq' : '-" + forage_t + ":pollen' }, \n",
+ " 'appends' : { 'fq' : '-" + forage_t + ":nectar' }, \n",
+ };
+ for (int ii = 0; ii < searchHandlerNames.length; ++ii) {
+ if (searchHandlerNames[ii] != null) {
+ cluster
+ .getSolrClient()
+ .request(
+ new ConfigRequest(
+ "{\n"
+ + " 'add-requesthandler': {\n"
+ + " 'name' : '"
+ + searchHandlerNames[ii]
+ + "',\n"
+ + " 'class' : 'org.apache.solr.handler.component.SearchHandler',\n"
+ + searchHandlerAppends[ii]
+ + " }\n"
+ + "}"),
+ COLLECTION);
+ }
+ }
+
+ // add some documents
+ {
+ new UpdateRequest()
+ .add(sdoc(id, 1, bee_t, "bumble bee", forage_t, "nectar"))
+ .add(sdoc(id, 2, bee_t, "honey bee", forage_t, "propolis"))
+ .add(sdoc(id, 3, bee_t, "solitary bee", forage_t, "pollen"))
+ .commit(cluster.getSolrClient(), COLLECTION);
+ }
+
+ // search (with all possible search handler combinations)
+ for (boolean shortCircuit : new boolean[] {false, true}) {
+ for (boolean withFilterQuery : new boolean[] {false, true}) {
+ for (int ii = 0; ii < searchHandlerNames.length; ++ii) {
+ for (int jj = 0; jj < searchHandlerNames.length; ++jj) {
+
+ final int numAppendedFilterQueries;
+ if (searchHandlerNames[ii] != null
+ && searchHandlerNames[jj] != null
+ && !searchHandlerNames[ii].equals(searchHandlerNames[jj])) {
+ numAppendedFilterQueries = 2; // both handlers appended their filter query
+ } else if (searchHandlerNames[ii] != null || searchHandlerNames[jj] != null) {
+ numAppendedFilterQueries =
+ 1; // one filter query from one handler or the same filter query from both
+ // handlers
+ } else {
+ numAppendedFilterQueries = 0; // no custom handlers, no appended filter queries
+ }
+
+ // compose the query
+ final SolrQuery solrQuery = new SolrQuery(bee_t + ":bee");
+ if (searchHandlerNames[ii] != null) {
+ solrQuery.setParam(CommonParams.QT, searchHandlerNames[ii]);
+ }
+ if (searchHandlerNames[jj] != null) {
+ solrQuery.setParam(ShardParams.SHARDS_QT, searchHandlerNames[jj]);
+ }
+ if (withFilterQuery) {
+ solrQuery.setFilterQueries("-" + forage_t + ":water");
+ }
+ solrQuery.setParam("shortCircuit", shortCircuit);
+ solrQuery.setParam(CommonParams.DEBUG, CommonParams.QUERY);
+
+ // make the query
+ final QueryResponse queryResponse =
+ new QueryRequest(solrQuery).process(cluster.getSolrClient(), COLLECTION);
+
+ // analyse the response
+ final StringBuilder contextInfo = new StringBuilder();
+ contextInfo.append("COLLECTION=" + COLLECTION);
+ contextInfo.append(",NUM_SHARDS=" + NUM_SHARDS);
+ contextInfo.append(",NUM_REPLICAS=" + NUM_REPLICAS);
+ contextInfo.append(",shortCircuit=" + shortCircuit);
+ contextInfo.append(",withFilterQuery=" + withFilterQuery);
+ contextInfo.append(",ii=" + ii);
+ contextInfo.append(",jj=" + jj);
+
+ final int expectedNumFilterQueries =
+ (withFilterQuery ? 1 : 0) + numAppendedFilterQueries;
+
+ assertNotNull(queryResponse);
+ final Map<String, Object> debugMap = queryResponse.getDebugMap();
+ assertNotNull(debugMap);
+ final List<?> filterQueriesList =
+ (List<?>) debugMap.getOrDefault("filter_queries", Collections.EMPTY_LIST);
+ final Set<?> filterQueriesSet = new HashSet<>(filterQueriesList);
+
+ contextInfo.append(",filterQueriesList=" + filterQueriesList.toString());
+
+ if (searchHandlerNames[ii] != null
+ && (searchHandlerNames[jj] == null
+ || searchHandlerNames[jj].equals(searchHandlerNames[ii]))) {
+ assertEquals(
+ contextInfo.toString(), expectedNumFilterQueries, filterQueriesSet.size());
+ // SOLR-10059: sometimes (but not always) filterQueriesList contains duplicates
+ continue;
+ }
+
+ assertEquals(
+ contextInfo.toString(), expectedNumFilterQueries, filterQueriesList.size());
+ assertEquals(contextInfo.toString(), filterQueriesSet.size(), filterQueriesList.size());
+ }
+ }
+ }
+ }
+ }
+}