This is an automated email from the ASF dual-hosted git repository.

twice pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks-controller.git


The following commit(s) were added to refs/heads/unstable by this push:
     new efb7d54  Fix flaky test case in raft engine (#235)
efb7d54 is described below

commit efb7d546299b871479444856a9f8b51faa2c3e63
Author: hulk <[email protected]>
AuthorDate: Thu Dec 19 21:32:53 2024 +0800

    Fix flaky test case in raft engine (#235)
---
 store/engine/raft/node.go      |  6 +++++-
 store/engine/raft/node_test.go | 39 +++++++++++++++++++++------------------
 2 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/store/engine/raft/node.go b/store/engine/raft/node.go
index 3786f58..70a7069 100644
--- a/store/engine/raft/node.go
+++ b/store/engine/raft/node.go
@@ -241,7 +241,11 @@ func (n *Node) watchLeaderChange() {
                                lead := n.GetRaftLead()
                                if lead != n.leader {
                                        n.leader = lead
-                                       n.leaderChanged <- true
+                                       select {
+                                       case <-n.shutdown:
+                                               return
+                                       case n.leaderChanged <- true:
+                                       }
                                        n.logger.Info("Found leader changed", 
zap.Uint64("leader", lead))
                                }
                        }
diff --git a/store/engine/raft/node_test.go b/store/engine/raft/node_test.go
index 15643b6..973cc61 100644
--- a/store/engine/raft/node_test.go
+++ b/store/engine/raft/node_test.go
@@ -109,12 +109,7 @@ func (c *TestCluster) SetSnapshotThreshold(threshold 
uint64) {
 }
 
 func (c *TestCluster) IsReady(ctx context.Context) bool {
-       for _, n := range c.nodes {
-               if !n.IsReady(ctx) {
-                       return false
-               }
-       }
-       return true
+       return c.GetLeaderID(raft.None) != raft.None
 }
 
 func (c *TestCluster) GetNode(i int) *Node {
@@ -124,18 +119,22 @@ func (c *TestCluster) GetNode(i int) *Node {
        return c.nodes[i]
 }
 
-func (c *TestCluster) GetLeaderNode() *Node {
+// GetLeaderNode returns the leader node, if there is no leader or reach 
consensus return raft.None.
+// excludeNodeID is the node ID that will be excluded from the leader check, 
it's useful when we want to
+// check if the leader is changed.
+func (c *TestCluster) GetLeaderID(excludeNodeID uint64) uint64 {
        leaderID := raft.None
        for _, n := range c.nodes {
-               if n.GetRaftLead() == leaderID {
+               if n.config.ID == excludeNodeID {
                        continue
                }
+               // If the leader is not the same means nodes are not reach 
consensus.
+               if leaderID != raft.None && leaderID != n.GetRaftLead() {
+                       return raft.None
+               }
                leaderID = n.GetRaftLead()
        }
-       if leaderID == raft.None {
-               return nil
-       }
-       return c.GetNode(int(leaderID - 1))
+       return leaderID
 }
 
 func (c *TestCluster) ListNodes() []*Node {
@@ -200,16 +199,20 @@ func TestCluster_MultiNodes(t *testing.T) {
        })
 
        t.Run("works well if 1/3 nodes down", func(t *testing.T) {
-               oldLeaderNode := cluster.GetLeaderNode()
-               require.NotNil(t, oldLeaderNode)
-               oldLeaderNode.Close()
+               oldLeaderID := cluster.GetLeaderID(raft.None)
+               require.NotEqual(t, raft.None, oldLeaderID)
+               leaderNode := cluster.GetNode(int(oldLeaderID - 1))
+               require.NotNil(t, leaderNode)
+               leaderNode.Close()
 
                require.Eventually(t, func() bool {
-                       newLeaderNode := cluster.GetLeaderNode()
-                       return newLeaderNode != nil && newLeaderNode != 
oldLeaderNode
+                       newLeaderID := cluster.GetLeaderID(oldLeaderID)
+                       return newLeaderID != raft.None && newLeaderID != 
oldLeaderID
                }, 10*time.Second, 200*time.Millisecond)
 
-               leaderNode := cluster.GetLeaderNode()
+               newLeaderID := cluster.GetLeaderID(oldLeaderID)
+               require.NotEqual(t, raft.None, newLeaderID)
+               leaderNode = cluster.GetNode(int(newLeaderID - 1))
                require.NoError(t, leaderNode.Set(ctx, "foo", []byte("bar")))
        })
 }

Reply via email to