@@ -132,6 +132,46 @@ func TestRemoveMember(t *testing.T) {
132
132
checkMemberCount (t , c .Members [1 ], 2 )
133
133
}
134
134
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
+
135
175
func checkMemberCount (t * testing.T , m * integration.Member , expectedMemberCount int ) {
136
176
be := schema .NewMembershipBackend (m .Logger , m .Server .Backend ())
137
177
membersFromBackend , _ := be .MustReadMembersFromBackend ()
0 commit comments