Skip to content

Commit efb7d54

Browse files
authored
Fix flaky test case in raft engine (#235)
1 parent d5bfaf1 commit efb7d54

File tree

2 files changed

+26
-19
lines changed

2 files changed

+26
-19
lines changed

store/engine/raft/node.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,11 @@ func (n *Node) watchLeaderChange() {
241241
lead := n.GetRaftLead()
242242
if lead != n.leader {
243243
n.leader = lead
244-
n.leaderChanged <- true
244+
select {
245+
case <-n.shutdown:
246+
return
247+
case n.leaderChanged <- true:
248+
}
245249
n.logger.Info("Found leader changed", zap.Uint64("leader", lead))
246250
}
247251
}

store/engine/raft/node_test.go

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,7 @@ func (c *TestCluster) SetSnapshotThreshold(threshold uint64) {
109109
}
110110

111111
func (c *TestCluster) IsReady(ctx context.Context) bool {
112-
for _, n := range c.nodes {
113-
if !n.IsReady(ctx) {
114-
return false
115-
}
116-
}
117-
return true
112+
return c.GetLeaderID(raft.None) != raft.None
118113
}
119114

120115
func (c *TestCluster) GetNode(i int) *Node {
@@ -124,18 +119,22 @@ func (c *TestCluster) GetNode(i int) *Node {
124119
return c.nodes[i]
125120
}
126121

127-
func (c *TestCluster) GetLeaderNode() *Node {
122+
// GetLeaderNode returns the leader node, if there is no leader or reach consensus return raft.None.
123+
// excludeNodeID is the node ID that will be excluded from the leader check, it's useful when we want to
124+
// check if the leader is changed.
125+
func (c *TestCluster) GetLeaderID(excludeNodeID uint64) uint64 {
128126
leaderID := raft.None
129127
for _, n := range c.nodes {
130-
if n.GetRaftLead() == leaderID {
128+
if n.config.ID == excludeNodeID {
131129
continue
132130
}
131+
// If the leader is not the same means nodes are not reach consensus.
132+
if leaderID != raft.None && leaderID != n.GetRaftLead() {
133+
return raft.None
134+
}
133135
leaderID = n.GetRaftLead()
134136
}
135-
if leaderID == raft.None {
136-
return nil
137-
}
138-
return c.GetNode(int(leaderID - 1))
137+
return leaderID
139138
}
140139

141140
func (c *TestCluster) ListNodes() []*Node {
@@ -200,16 +199,20 @@ func TestCluster_MultiNodes(t *testing.T) {
200199
})
201200

202201
t.Run("works well if 1/3 nodes down", func(t *testing.T) {
203-
oldLeaderNode := cluster.GetLeaderNode()
204-
require.NotNil(t, oldLeaderNode)
205-
oldLeaderNode.Close()
202+
oldLeaderID := cluster.GetLeaderID(raft.None)
203+
require.NotEqual(t, raft.None, oldLeaderID)
204+
leaderNode := cluster.GetNode(int(oldLeaderID - 1))
205+
require.NotNil(t, leaderNode)
206+
leaderNode.Close()
206207

207208
require.Eventually(t, func() bool {
208-
newLeaderNode := cluster.GetLeaderNode()
209-
return newLeaderNode != nil && newLeaderNode != oldLeaderNode
209+
newLeaderID := cluster.GetLeaderID(oldLeaderID)
210+
return newLeaderID != raft.None && newLeaderID != oldLeaderID
210211
}, 10*time.Second, 200*time.Millisecond)
211212

212-
leaderNode := cluster.GetLeaderNode()
213+
newLeaderID := cluster.GetLeaderID(oldLeaderID)
214+
require.NotEqual(t, raft.None, newLeaderID)
215+
leaderNode = cluster.GetNode(int(newLeaderID - 1))
213216
require.NoError(t, leaderNode.Set(ctx, "foo", []byte("bar")))
214217
})
215218
}

0 commit comments

Comments
 (0)