Ugh... sorry for the noise, I thought my repo was up to date but i was stale by a few hours.
Fix looks good. : Date: Wed, 20 Sep 2023 11:49:36 -0700 : From: Patson Luk <pat...@fullstory.com.invalid> : Reply-To: dev@solr.apache.org : To: dev@solr.apache.org : Cc: no...@apache.org : Subject: Re: [solr] branch main updated: More test cases for Coordinator node : role (#1782) : : Hi Chris, : : Thanks for bringing that to our attention! The test cases were added by me : and Houston has informed us of similar failure as well. : : We have applied and merged a fix as in : https://github.com/apache/solr/pull/1939. Hopefully it calms the test cases. : : Please let me know if you still see the same failures, and so sorry about : the troubles! : : Cheers, : Patson : : On Wed, Sep 20, 2023 at 11:43 AM Chris Hostetter <hossman_luc...@fucit.org> : wrote: : : > : > : Noble: This new test has been failing ~50% of all jenkins builds since : > it : > : was added. : > : > I *THINK* the problem is that (like most tests) this test class uses SSL : > randomization on solr, but testConfigset() assumes it can open a : > raw URLConnection w/o any knowledge of the certificates in use. : > : > We have other tests that look at HTTP headers -- like CacheHeaderTest -- : > and the way they work is by using HttpSolrClient.getHttpClient() (which : > should have all the SSL test context configured on them IIUC) : > : > : > : > org.apache.solr.search.TestCoordinatorRole > testConfigset FAILED : > javax.net.ssl.SSLHandshakeException: PKIX path building failed: : > sun.security.provider.certpath.SunCertPathBuilderException: unable to find : > valid certification : > path to requested target : > at : > __randomizedtesting.SeedInfo.seed([8D2A8B2582BA7A2D:9E6C35FFB67C7C05]:0) : > at : > java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) : > at : > : > java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:371) : > at : > : > java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:314) : > at : > : > java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:309) : > at : > : > java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1357) : > at : > : > java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1232) : > at : > : > java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1175) : > at : > java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396) : > at : > : > java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480) : > at : > : > java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:458) : > at : > : > java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:201) : > at : > java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172) : > at : > java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1505) : > at : > : > java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1420) : > at : > : > java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455) : > at : > : > java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426) : > at : > : > java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:580) : > at : > : > java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:187) : > at : > : > java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:142) : > at : > : > org.apache.solr.search.TestCoordinatorRole.testConfigset(TestCoordinatorRole.java:626) : > : > : > : : > : : > : : Date: Mon, 18 Sep 2023 19:41:15 +0000 : > : : From: no...@apache.org : > : : Reply-To: dev@solr.apache.org : > : : To: "comm...@solr.apache.org" <comm...@solr.apache.org> : > : : Subject: [solr] branch main updated: More test cases for Coordinator : > node role : > : : (#1782) : > : : : > : : This is an automated email from the ASF dual-hosted git repository. : > : : : > : : noble 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 b33dd14b60b More test cases for Coordinator node role (#1782) : > : : b33dd14b60b is described below : > : : : > : : commit b33dd14b60b237980044d406dc7911f20c605530 : > : : Author: patsonluk <patson...@users.noreply.github.com> : > : : AuthorDate: Mon Sep 18 12:41:08 2023 -0700 : > : : : > : : More test cases for Coordinator node role (#1782) : > : : --- : > : : .../solr/configsets/cache-control/conf/schema.xml | 27 +++ : > : : .../configsets/cache-control/conf/solrconfig.xml | 54 +++++ : > : : .../apache/solr/search/TestCoordinatorRole.java | 260 : > +++++++++++++++++++-- : > : : 3 files changed, 324 insertions(+), 17 deletions(-) : > : : : > : : diff --git : > a/solr/core/src/test-files/solr/configsets/cache-control/conf/schema.xml : > b/solr/core/src/test-files/solr/configsets/cache-control/conf/schema.xml : > : : new file mode 100644 : > : : index 00000000000..36d5cfd2588 : > : : --- /dev/null : > : : +++ : > b/solr/core/src/test-files/solr/configsets/cache-control/conf/schema.xml : > : : @@ -0,0 +1,27 @@ : > : : +<?xml version="1.0" encoding="UTF-8" ?> : > : : +<!-- : > : : + 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. : > : : +--> : > : : +<schema name="minimal" version="1.1"> : > : : + <fieldType name="string" class="solr.StrField"/> : > : : + <fieldType name="int" class="${solr.tests.IntegerFieldType}" : > docValues="${solr.tests.numeric.dv}" precisionStep="0" omitNorms="true" : > positionIncrementGap="0"/> : > : : + <fieldType name="long" class="${solr.tests.LongFieldType}" : > docValues="${solr.tests.numeric.dv}" precisionStep="0" omitNorms="true" : > positionIncrementGap="0"/> : > : : + <dynamicField name="*" type="string" indexed="true" : > stored="true"/> : > : : + <!-- for versioning --> : > : : + <field name="_version_" type="long" indexed="true" stored="true"/> : > : : + <field name="_root_" type="string" indexed="true" stored="true" : > multiValued="false" required="false"/> : > : : + <field name="id" type="string" indexed="true" stored="true"/> : > : : + <dynamicField name="*_s" type="string" indexed="true" : > stored="true" /> : > : : + <uniqueKey>id</uniqueKey> : > : : +</schema> : > : : \ No newline at end of file : > : : diff --git : > a/solr/core/src/test-files/solr/configsets/cache-control/conf/solrconfig.xml : > b/solr/core/src/test-files/solr/configsets/cache-control/conf/solrconfig.xml : > : : new file mode 100644 : > : : index 00000000000..bd27a88952a : > : : --- /dev/null : > : : +++ : > b/solr/core/src/test-files/solr/configsets/cache-control/conf/solrconfig.xml : > : : @@ -0,0 +1,54 @@ : > : : +<?xml version="1.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. : > : : +--> : > : : + : > : : +<!-- Minimal solrconfig.xml with /select, /admin and /update only --> : > : : + : > : : +<config> : > : : + : > : : + <dataDir>${solr.data.dir:}</dataDir> : > : : + : > : : + <directoryFactory name="DirectoryFactory" : > : : + : > class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/> : > : : + <schemaFactory class="ClassicIndexSchemaFactory"/> : > : : + : > : : + : > <luceneMatchVersion>${tests.luceneMatchVersion:LATEST}</luceneMatchVersion> : > : : + : > : : + <updateHandler class="solr.DirectUpdateHandler2"> : > : : + <commitWithin> : > : : + : > <softCommit>${solr.commitwithin.softcommit:true}</softCommit> : > : : + </commitWithin> : > : : + <updateLog class="${solr.ulog:solr.UpdateLog}"></updateLog> : > : : + </updateHandler> : > : : + : > : : + <requestDispatcher> : > : : + <httpCaching> : > : : + <cacheControl>max-age=30, public</cacheControl> : > : : + </httpCaching> : > : : + </requestDispatcher> : > : : + : > : : + <requestHandler name="/select" class="solr.SearchHandler"> : > : : + <lst name="defaults"> : > : : + <str name="echoParams">explicit</str> : > : : + <str name="indent">true</str> : > : : + <str name="df">text</str> : > : : + </lst> : > : : + : > : : + </requestHandler> : > : : + <indexConfig> : > : : + <mergeScheduler : > class="${solr.mscheduler:org.apache.lucene.index.ConcurrentMergeScheduler}"/> : > : : + : </indexConfig> : > : : +</config> : > : : \ No newline at end of file : > : : diff --git : > a/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java : > b/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java : > : : index 538c6b44703..581f048785d 100644 : > : : --- : > a/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java : > : : +++ : > b/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java : > : : @@ -21,6 +21,8 @@ import static : > org.apache.solr.common.params.CommonParams.OMIT_HEADER; : > : : import static org.apache.solr.common.params.CommonParams.TRUE; : > : : : > : : import java.lang.invoke.MethodHandles; : > : : +import java.net.HttpURLConnection; : > : : +import java.net.URL; : > : : import java.util.ArrayList; : > : : import java.util.Date; : > : : import java.util.EnumSet; : > : : @@ -51,6 +53,7 @@ import org.apache.solr.common.SolrException; : > : : import org.apache.solr.common.SolrInputDocument; : > : : import org.apache.solr.common.cloud.DocCollection; : > : : import org.apache.solr.common.cloud.Replica; : > : : +import org.apache.solr.common.cloud.Slice; : > : : import org.apache.solr.common.cloud.ZkStateReader; : > : : import org.apache.solr.common.cloud.ZkStateReaderAccessor; : > : : import org.apache.solr.common.params.CommonParams; : > : : @@ -585,18 +588,70 @@ public class TestCoordinatorRole extends : > SolrCloudTestCase { : > : : } : > : : } : > : : : > : : + public void testConfigset() throws Exception { : > : : + final int DATA_NODE_COUNT = 1; : > : : + MiniSolrCloudCluster cluster = : > : : + configureCluster(DATA_NODE_COUNT) : > : : + .addConfig("conf1", configset("cloud-minimal")) : > : : + .addConfig("conf2", configset("cache-control")) : > : : + .configure(); : > : : + : > : : + List<String> dataNodes = : > : : + cluster.getJettySolrRunners().stream() : > : : + .map(JettySolrRunner::getNodeName) : > : : + .collect(Collectors.toUnmodifiableList()); : > : : + : > : : + try { : > : : + CollectionAdminRequest.createCollection("c1", "conf1", 2, : > 1).process(cluster.getSolrClient()); : > : : + cluster.waitForActiveCollection("c1", 2, 2); : > : : + CollectionAdminRequest.createCollection("c2", "conf2", 2, : > 1).process(cluster.getSolrClient()); : > : : + cluster.waitForActiveCollection("c2", 2, 2); : > : : + : > : : + System.setProperty(NodeRoles.NODE_ROLES_PROP, "coordinator:on"); : > : : + JettySolrRunner coordinatorJetty; : > : : + try { : > : : + coordinatorJetty = cluster.startJettySolrRunner(); : > : : + } finally { : > : : + System.clearProperty(NodeRoles.NODE_ROLES_PROP); : > : : + } : > : : + : > : : + // Tricky to test configset, since operation such as collection : > status would direct it to the : > : : + // OS node. : > : : + // So we use query and check the cache response header which is : > determined by the : > : : + // solr-config.xml in the configset : > : : + // However using solr client would drop cache respons header : > hence we need to use plain java : > : : + // HttpURLConnection : > : : + URL url = new URL(coordinatorJetty.getBaseUrl() + : > "/c1/select?q=*:*"); : > : : + HttpURLConnection urlConnection = (HttpURLConnection) : > url.openConnection(); : > : : + urlConnection.connect(); : > : : + : > : : + // conf1 has no cache-control : > : : + assertNull(urlConnection.getHeaderField("cache-control")); : > : : + : > : : + url = new URL(coordinatorJetty.getBaseUrl() + : > "/c2/select?q=*:*"); : > : : + urlConnection = (HttpURLConnection) url.openConnection(); : > : : + urlConnection.connect(); : > : : + : > : : + // conf2 has cache-control defined : > : : + : > assertTrue(urlConnection.getHeaderField("cache-control").contains("max-age=30")); : > : : + } finally { : > : : + cluster.shutdown(); : > : : + } : > : : + } : > : : + : > : : public void testWatch() throws Exception { : > : : - final int DATA_NODE_COUNT = 2; : > : : + final int DATA_NODE_COUNT = 1; : > : : MiniSolrCloudCluster cluster = : > : : configureCluster(DATA_NODE_COUNT) : > : : .addConfig("conf1", configset("cloud-minimal")) : > : : .configure(); : > : : - final String TEST_COLLECTION = "c1"; : > : : + final String TEST_COLLECTION_1 = "c1"; : > : : + final String TEST_COLLECTION_2 = "c2"; : > : : : > : : try { : > : : CloudSolrClient client = cluster.getSolrClient(); : > : : - CollectionAdminRequest.createCollection(TEST_COLLECTION, : > "conf1", 1, 2).process(client); : > : : - cluster.waitForActiveCollection(TEST_COLLECTION, 1, 2); : > : : + CollectionAdminRequest.createCollection(TEST_COLLECTION_1, : > "conf1", 1, 2).process(client); : > : : + cluster.waitForActiveCollection(TEST_COLLECTION_1, 1, 2); : > : : System.setProperty(NodeRoles.NODE_ROLES_PROP, "coordinator:on"); : > : : JettySolrRunner coordinatorJetty; : > : : try { : > : : @@ -610,26 +665,37 @@ public class TestCoordinatorRole extends : > SolrCloudTestCase { : > : : ZkStateReaderAccessor zkWatchAccessor = new : > ZkStateReaderAccessor(zkStateReader); : > : : : > : : // no watch at first : > : : - : > assertTrue(!zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION)); : > : : + : > assertTrue(!zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION_1)); : > : : new QueryRequest(new SolrQuery("*:*")) : > : : .setPreferredNodes(List.of(coordinatorJetty.getNodeName())) : > : : - .process(client, TEST_COLLECTION); // ok no exception thrown : > : : + .process(client, TEST_COLLECTION_1); // ok no exception : > thrown : > : : : > : : // now it should be watching it after the query : > : : - : > assertTrue(zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION)); : > : : + : > assertTrue(zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION_1)); : > : : + : > : : + // add another collection : > : : + CollectionAdminRequest.createCollection(TEST_COLLECTION_2, : > "conf1", 1, 2).process(client); : > : : + cluster.waitForActiveCollection(TEST_COLLECTION_2, 1, 2); : > : : + new QueryRequest(new SolrQuery("*:*")) : > : : + .setPreferredNodes(List.of(coordinatorJetty.getNodeName())) : > : : + .process(client, TEST_COLLECTION_2); : > : : + // watch both collections : > : : + : > assertTrue(zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION_1)); : > : : + : > assertTrue(zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION_2)); : > : : : > : : - CollectionAdminRequest.deleteReplica(TEST_COLLECTION, "shard1", : > 1).process(client); : > : : - cluster.waitForActiveCollection(TEST_COLLECTION, 1, 1); : > : : + CollectionAdminRequest.deleteReplica(TEST_COLLECTION_1, : > "shard1", 1).process(client); : > : : + cluster.waitForActiveCollection(TEST_COLLECTION_1, 1, 1); : > : : new QueryRequest(new SolrQuery("*:*")) : > : : .setPreferredNodes(List.of(coordinatorJetty.getNodeName())) : > : : - .process(client, TEST_COLLECTION); // ok no exception thrown : > : : + .process(client, TEST_COLLECTION_1); // ok no exception : > thrown : > : : : > : : // still one replica left, should not remove the watch : > : : - : > assertTrue(zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION)); : > : : + : > assertTrue(zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION_1)); : > : : : > : : - : > CollectionAdminRequest.deleteCollection(TEST_COLLECTION).process(client); : > : : - zkStateReader.waitForState(TEST_COLLECTION, 30, : > TimeUnit.SECONDS, Objects::isNull); : > : : - assertNull(zkStateReader.getCollection(TEST_COLLECTION)); // : > check the cluster state : > : : + // now delete c1 and ensure it's cleared from various logic : > : : + : > CollectionAdminRequest.deleteCollection(TEST_COLLECTION_1).process(client); : > : : + zkStateReader.waitForState(TEST_COLLECTION_1, 30, : > TimeUnit.SECONDS, Objects::isNull); : > : : + assertNull(zkStateReader.getCollection(TEST_COLLECTION_1)); // : > check the cluster state : > : : : > : : // ensure querying throws exception : > : : assertExceptionThrownWithMessageContaining( : > : : @@ -638,10 +704,170 @@ public class TestCoordinatorRole extends : > SolrCloudTestCase { : > : : () -> : > : : new QueryRequest(new SolrQuery("*:*")) : > : : : > .setPreferredNodes(List.of(coordinatorJetty.getNodeName())) : > : : - .process(client, TEST_COLLECTION)); : > : : + .process(client, TEST_COLLECTION_1)); : > : : + : > : : + // watch should be removed after c1 deletion : > : : + : > assertTrue(!zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION_1)); : > : : + // still watching c2 : > : : + : > assertTrue(zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION_2)); : > : : + } finally { : > : : + cluster.shutdown(); : > : : + } : > : : + } : > : : + : > : : + public void testSplitShard() throws Exception { : > : : + final int DATA_NODE_COUNT = 1; : > : : + MiniSolrCloudCluster cluster = : > : : + configureCluster(DATA_NODE_COUNT) : > : : + .addConfig("conf1", configset("cloud-minimal")) : > : : + .configure(); : > : : + : > : : + try { : > : : + : > : : + final String COLLECTION_NAME = "c1"; : > : : + CollectionAdminRequest.createCollection(COLLECTION_NAME, : > "conf1", 1, 1) : > : : + .process(cluster.getSolrClient()); : > : : + cluster.waitForActiveCollection(COLLECTION_NAME, 1, 1); : > : : + : > : : + int DOC_PER_COLLECTION_COUNT = 1000; : > : : + UpdateRequest ur = new UpdateRequest(); : > : : + for (int i = 0; i < DOC_PER_COLLECTION_COUNT; i++) { : > : : + SolrInputDocument doc = new SolrInputDocument(); : > : : + doc.addField("id", COLLECTION_NAME + "-" + i); : > : : + ur.add(doc); : > : : + } : > : : + CloudSolrClient client = cluster.getSolrClient(); : > : : + ur.commit(client, COLLECTION_NAME); : > : : + : > : : + System.setProperty(NodeRoles.NODE_ROLES_PROP, "coordinator:on"); : > : : + JettySolrRunner coordinatorJetty; : > : : + try { : > : : + coordinatorJetty = cluster.startJettySolrRunner(); : > : : + } finally { : > : : + System.clearProperty(NodeRoles.NODE_ROLES_PROP); : > : : + } : > : : + : > : : + QueryResponse response = : > : : + new QueryRequest(new SolrQuery("*:*")) : > : : + : > .setPreferredNodes(List.of(coordinatorJetty.getNodeName())) : > : : + .process(client, COLLECTION_NAME); : > : : + : > : : + assertEquals(DOC_PER_COLLECTION_COUNT, : > response.getResults().getNumFound()); : > : : + : > : : + // now split the shard : > : : + : > CollectionAdminRequest.splitShard(COLLECTION_NAME).setShardName("shard1").process(client); : > : : + waitForState( : > : : + "Failed to wait for child shards after split", : > : : + COLLECTION_NAME, : > : : + (liveNodes, collectionState) -> : > : : + collectionState.getSlice("shard1_0") != null : > : : + && collectionState.getSlice("shard1_0").getState() : > == Slice.State.ACTIVE : > : : + && collectionState.getSlice("shard1_1") != null : > : : + && collectionState.getSlice("shard1_1").getState() : > == Slice.State.ACTIVE); : > : : + : > : : + // delete the parent shard : > : : + CollectionAdminRequest.deleteShard(COLLECTION_NAME, : > "shard1").process(client); : > : : + waitForState( : > : : + "Parent shard is not yet deleted after split", : > : : + COLLECTION_NAME, : > : : + (liveNodes, collectionState) -> : > collectionState.getSlice("shard1") == null); : > : : + : > : : + response = : > : : + new QueryRequest(new SolrQuery("*:*")) : > : : + : > .setPreferredNodes(List.of(coordinatorJetty.getNodeName())) : > : : + .process(client, COLLECTION_NAME); : > : : + : > : : + assertEquals(DOC_PER_COLLECTION_COUNT, : > response.getResults().getNumFound()); : > : : + } finally { : > : : + cluster.shutdown(); : > : : + } : > : : + } : > : : + : > : : + public void testMoveReplica() throws Exception { : > : : + final int DATA_NODE_COUNT = 2; : > : : + MiniSolrCloudCluster cluster = : > : : + configureCluster(DATA_NODE_COUNT) : > : : + .addConfig("conf1", configset("cloud-minimal")) : > : : + .configure(); : > : : + : > : : + List<String> dataNodes = : > : : + cluster.getJettySolrRunners().stream() : > : : + .map(JettySolrRunner::getNodeName) : > : : + .collect(Collectors.toUnmodifiableList()); : > : : + try { : > : : + : > : : + final String COLLECTION_NAME = "c1"; : > : : + String fromNode = dataNodes.get(0); // put the shard on first : > data node : > : : + CollectionAdminRequest.createCollection(COLLECTION_NAME, : > "conf1", 1, 1) : > : : + .setCreateNodeSet(fromNode) : > : : + .process(cluster.getSolrClient()); : > : : + // ensure replica is placed on the expected node : > : : + waitForState( : > : : + "Cannot find replica on first node yet", : > : : + COLLECTION_NAME, : > : : + (liveNodes, collectionState) -> { : > : : + if (collectionState.getReplicas().size() == 1) { : > : : + Replica replica = collectionState.getReplicas().get(0); : > : : + return fromNode.equals(replica.getNodeName()) : > : : + && replica.getState() == Replica.State.ACTIVE; : > : : + } : > : : + return false; : > : : + }); : > : : + : > : : + int DOC_PER_COLLECTION_COUNT = 1000; : > : : + UpdateRequest ur = new UpdateRequest(); : > : : + for (int i = 0; i < DOC_PER_COLLECTION_COUNT; i++) { : > : : + SolrInputDocument doc = new SolrInputDocument(); : > : : + doc.addField("id", COLLECTION_NAME + "-" + i); : > : : + ur.add(doc); : > : : + } : > : : + CloudSolrClient client = cluster.getSolrClient(); : > : : + ur.commit(client, COLLECTION_NAME); : > : : + : > : : + System.setProperty(NodeRoles.NODE_ROLES_PROP, "coordinator:on"); : > : : + JettySolrRunner coordinatorJetty; : > : : + try { : > : : + coordinatorJetty = cluster.startJettySolrRunner(); : > : : + } finally { : > : : + System.clearProperty(NodeRoles.NODE_ROLES_PROP); : > : : + } : > : : + : > : : + QueryResponse response = : > : : + new QueryRequest(new SolrQuery("*:*")) : > : : + : > .setPreferredNodes(List.of(coordinatorJetty.getNodeName())) : > : : + .process(client, COLLECTION_NAME); : > : : + : > : : + assertEquals(DOC_PER_COLLECTION_COUNT, : > response.getResults().getNumFound()); : > : : + : > : : + // now move the shard/replica : > : : + String replicaName = : > getCollectionState(COLLECTION_NAME).getReplicas().get(0).getName(); : > : : + String toNodeName = dataNodes.get(1); : > : : + CollectionAdminRequest.moveReplica(COLLECTION_NAME, : > replicaName, toNodeName).process(client); : > : : + waitForState( : > : : + "Cannot find replica on second node yet after repliac move", : > : : + COLLECTION_NAME, : > : : + (liveNodes, collectionState) -> { : > : : + if (collectionState.getReplicas().size() == 1) { : > : : + Replica replica = collectionState.getReplicas().get(0); : > : : + return toNodeName.equals(replica.getNodeName()) : > : : + && replica.getState() == Replica.State.ACTIVE; : > : : + } : > : : + return false; : > : : + }); : > : : + : > : : + // We must stop the first node to ensure that query directs to : > the correct node from : > : : + // coordinator. : > : : + // In case if coordinator node has the wrong info (replica on : > first node), it might still : > : : + // return valid result if : > : : + // we do not stop the first node as first node might forward : > the query to second node. : > : : + cluster.getJettySolrRunners().get(0).stop(); : > : : + : > : : + response = : > : : + new QueryRequest(new SolrQuery("*:*")) : > : : + : > .setPreferredNodes(List.of(coordinatorJetty.getNodeName())) : > : : + .process(client, COLLECTION_NAME); : > : : : > : : - // watch should be removed after collection deletion : > : : - : > assertTrue(!zkWatchAccessor.getWatchedCollections().contains(TEST_COLLECTION)); : > : : + assertEquals(DOC_PER_COLLECTION_COUNT, : > response.getResults().getNumFound()); : > : : } finally { : > : : cluster.shutdown(); : > : : } : > : : : > : : : > : : > : -Hoss : > : http://www.lucidworks.com/ : > : : > : > -Hoss : > http://www.lucidworks.com/ : > : > --------------------------------------------------------------------- : > To unsubscribe, e-mail: dev-unsubscr...@solr.apache.org : > For additional commands, e-mail: dev-h...@solr.apache.org : > : > : -Hoss http://www.lucidworks.com/
--------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@solr.apache.org For additional commands, e-mail: dev-h...@solr.apache.org