Skip to content

Commit 7b35142

Browse files
authored
Merge pull request #19948 from k8s-infra-cherrypick-robot/cherry-pick-19947-to-release-3.6
[release-3.6] [Integration Test]: Add test for panic-free removal of non-existent members
2 parents f5d605a + 6339219 commit 7b35142

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

tests/integration/member_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,46 @@ func TestRemoveMember(t *testing.T) {
132132
checkMemberCount(t, c.Members[1], 2)
133133
}
134134

135+
// TestRemoveMemberAndWALReplay ensures that etcd can properly handle
136+
// member removal followed by restart with WAL replay, ensuring no panics
137+
// occur when replaying already-applied removal operations.
138+
func TestRemoveMemberAndWALReplay(t *testing.T) {
139+
integration.BeforeTest(t)
140+
141+
// Create a cluster with 3 member and a low snapshot count
142+
c := integration.NewCluster(t, &integration.ClusterConfig{
143+
Size: 3,
144+
SnapshotCount: 10,
145+
UseBridge: true,
146+
DisableStrictReconfigCheck: true,
147+
})
148+
defer c.Terminate(t)
149+
150+
// Add some k/v to trigger snapshot
151+
for i := 0; i < 15; i++ {
152+
ctx, cancel := context.WithTimeout(context.Background(), integration.RequestTimeout)
153+
_, err := c.Members[0].Client.Put(ctx, fmt.Sprintf("k%d", i), fmt.Sprintf("v%d", i))
154+
cancel()
155+
require.NoErrorf(t, err, "failed to put key-value")
156+
}
157+
158+
// Record the ID of the member we'll remove
159+
memberToRemoveID := uint64(c.Members[2].Server.MemberID())
160+
161+
// Remove one member from the cluster
162+
err := c.RemoveMember(t, c.Members[0].Client, memberToRemoveID)
163+
require.NoErrorf(t, err, "failed to remove member")
164+
165+
// Stop the remaining members
166+
c.Members[0].Stop(t)
167+
c.Members[1].Stop(t)
168+
169+
// Restart one member - this would previously panic when loading
170+
// WAL entries that try to remove an already removed member
171+
err = c.Members[0].Restart(t)
172+
require.NoErrorf(t, err, "failed to restart member after removal")
173+
}
174+
135175
func checkMemberCount(t *testing.T, m *integration.Member, expectedMemberCount int) {
136176
be := schema.NewMembershipBackend(m.Logger, m.Server.Backend())
137177
membersFromBackend, _ := be.MustReadMembersFromBackend()

0 commit comments

Comments
 (0)