You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by no...@apache.org on 2024/05/06 18:11:00 UTC
(solr) 01/01: updated the test to verify leader election state.json updates
This is an automated email from the ASF dual-hosted git repository.
noble pushed a commit to branch jira/solr17271
in repository https://gitbox.apache.org/repos/asf/solr.git
commit 9361e99befc71b1cd72bfde01c465496fb482f00
Author: noblepaul <no...@gmail.com>
AuthorDate: Tue May 7 04:10:47 2024 +1000
updated the test to verify leader election state.json updates
---
.../cloud/PerReplicaStatesIntegrationTest.java | 52 ++++++++++++++++++++--
1 file changed, 48 insertions(+), 4 deletions(-)
diff --git a/solr/solrj/src/test/org/apache/solr/common/cloud/PerReplicaStatesIntegrationTest.java b/solr/solrj/src/test/org/apache/solr/common/cloud/PerReplicaStatesIntegrationTest.java
index e75100f1a50..8cada5b149c 100644
--- a/solr/solrj/src/test/org/apache/solr/common/cloud/PerReplicaStatesIntegrationTest.java
+++ b/solr/solrj/src/test/org/apache/solr/common/cloud/PerReplicaStatesIntegrationTest.java
@@ -22,8 +22,11 @@ import static org.apache.solr.common.params.CollectionAdminParams.PER_REPLICA_ST
import java.lang.invoke.MethodHandles;
import java.util.Collections;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.BiPredicate;
+
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.client.solrj.request.V2Request;
@@ -40,6 +43,7 @@ import org.slf4j.LoggerFactory;
/** This test would be faster if we simulated the zk state instead. */
@LogLevel(
"org.apache.solr.common.cloud.ZkStateReader=DEBUG;"
+ + "org.apache.solr.cloud.overseer.ZkStateWriter=DEBUG;"
+ "org.apache.solr.handler.admin.CollectionsHandler=DEBUG;"
+ "org.apache.solr.common.cloud.PerReplicaStatesOps=DEBUG;"
+ "org.apache.solr.cloud.Overseer=INFO;"
@@ -315,7 +319,8 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
CollectionAdminRequest.createCollection(PRS_COLL, "conf", 10, 1)
.setPerReplicaState(Boolean.TRUE)
.process(cluster.getSolrClient());
- stat = cluster.getZkClient().exists(DocCollection.getCollectionPath(PRS_COLL), null, true);
+ String PRS_PATH = DocCollection.getCollectionPath(PRS_COLL);
+ stat = cluster.getZkClient().exists(PRS_PATH, null, true);
// +1 after all replica are added with on state.json write to CreateCollectionCmd.setData()
assertEquals(1, stat.getVersion());
// For each replica:
@@ -330,7 +335,7 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
CollectionAdminRequest.addReplicaToShard(PRS_COLL, "shard1")
.process(cluster.getSolrClient());
cluster.waitForActiveCollection(PRS_COLL, 10, 11);
- stat = cluster.getZkClient().exists(DocCollection.getCollectionPath(PRS_COLL), null, true);
+ stat = cluster.getZkClient().exists(PRS_PATH, null, true);
// For the new replica:
// +2 for state.json overseer writes, even though there's no longer PRS updates from
// overseer, current code would still do a "TOUCH" on the PRS entry
@@ -350,7 +355,7 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
CollectionAdminRequest.deleteReplica(PRS_COLL, "shard1", addedReplica.getName())
.process(cluster.getSolrClient());
cluster.waitForActiveCollection(PRS_COLL, 10, 10);
- stat = cluster.getZkClient().exists(DocCollection.getCollectionPath(PRS_COLL), null, true);
+ stat = cluster.getZkClient().exists(PRS_PATH, null, true);
// For replica deletion
// +1 for ZkController#unregister, which delete the PRS entry from data node
// overseer, current code would still do a "TOUCH" on the PRS entry
@@ -359,11 +364,50 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
for (JettySolrRunner j : cluster.getJettySolrRunners()) {
j.stop();
j.start(true);
- stat = cluster.getZkClient().exists(DocCollection.getCollectionPath(PRS_COLL), null, true);
+ stat = cluster.getZkClient().exists(PRS_PATH, null, true);
// ensure restart does not update the state.json, after addReplica/deleteReplica, 2 more
// updates hence at version 3 on state.json version
assertEquals(3, stat.getVersion());
}
+
+ // test for leader election
+ Replica leader =
+ cluster.getZkStateReader().clusterState.getCollection(PRS_COLL).getLeader("shard2");
+
+ JettySolrRunner j2 = cluster.startJettySolrRunner();
+ response =
+ CollectionAdminRequest.addReplicaToShard(PRS_COLL, "shard2")
+ .setNode(j2.getNodeName())
+ .process(cluster.getSolrClient());
+
+ //wait for the new replica to be active
+ cluster.waitForActiveCollection(PRS_COLL, 10, 11);
+ stat = cluster.getZkClient().exists(PRS_PATH, null, true);
+ //+1 for a new replica
+ assertEquals(4, stat.getVersion());
+ log.info("jetty:{}, response: {}, v: {}",j2.getNodeName(), response.jsonStr(), stat.getVersion());
+ DocCollection c = cluster
+ .getZkStateReader()
+ .getCollection(PRS_COLL);
+ Replica newreplica = c.getReplica((s, replica) -> replica.node.equals(j2.getNodeName()));
+
+
+ log.info("old :{}, new :{} , leader: {}" ,leader.name ,newreplica.name, c.getLeader("shard2") );
+
+ //let's stop the old leader
+ JettySolrRunner oldJetty = cluster.getReplicaJetty(leader);
+ oldJetty.stop();
+
+ cluster.getZkStateReader().waitForState(PRS_COLL, 10, TimeUnit.SECONDS,
+ (liveNodes, collectionState) -> PerReplicaStatesOps.fetch(PRS_PATH, cluster.getZkClient(), null).states.get(newreplica.name).isLeader);
+ PerReplicaStates prs = PerReplicaStatesOps.fetch(PRS_PATH, cluster.getZkClient(), null);
+ log.info("prs:{}, new replica :{}",prs, prs.states.get(newreplica.name).isLeader);
+ stat = cluster.getZkClient().exists(PRS_PATH, null, true);
+ log.info("leader:{}, v after leader election: {}, state.json {}",c.getLeader("shard2"), stat.getVersion(), cluster
+ .getZkStateReader()
+ .getCollection(PRS_COLL));
+ //the version should not have updated
+ assertEquals(4, stat.getVersion());
} finally {
cluster.shutdown();
}