@@ -122,7 +122,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
122
122
})
123
123
}
124
124
cc := epc .Etcdctl ()
125
- t .Logf ("Cluster created" )
125
+ t .Log ("Cluster created" )
126
126
if len (epc .Procs ) > 1 {
127
127
t .Log ("Waiting health interval to required to make membership changes" )
128
128
time .Sleep (etcdserver .HealthInterval )
@@ -132,7 +132,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
132
132
resp , err := cc .MemberAddAsLearner (context .Background (), "fake1" , []string {"http://127.0.0.1:1001" })
133
133
require .NoError (t , err )
134
134
if triggerSnapshot {
135
- t .Logf ("Generating snapshot" )
135
+ t .Log ("Generating snapshot" )
136
136
generateSnapshot (t , snapshotCount , cc )
137
137
verifySnapshot (t , epc )
138
138
}
@@ -142,7 +142,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
142
142
beforeMembers , beforeKV := getMembersAndKeys (t , cc )
143
143
144
144
if triggerCancellation == cancelRightBeforeEnable {
145
- t .Logf ("Cancelling downgrade before enabling" )
145
+ t .Log ("Cancelling downgrade before enabling" )
146
146
e2e .DowngradeCancel (t , epc )
147
147
t .Log ("Downgrade cancelled, validating if cluster is in the right state" )
148
148
e2e .ValidateMemberVersions (t , epc , generateIdenticalVersions (clusterSize , currentVersion ))
@@ -151,7 +151,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
151
151
}
152
152
e2e .DowngradeEnable (t , epc , lastVersion )
153
153
if triggerCancellation == cancelRightAfterEnable {
154
- t .Logf ("Cancelling downgrade right after enabling (no node is downgraded yet)" )
154
+ t .Log ("Cancelling downgrade right after enabling (no node is downgraded yet)" )
155
155
e2e .DowngradeCancel (t , epc )
156
156
t .Log ("Downgrade cancelled, validating if cluster is in the right state" )
157
157
e2e .ValidateMemberVersions (t , epc , generateIdenticalVersions (clusterSize , currentVersion ))
@@ -188,7 +188,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
188
188
resp , err = cc .MemberAddAsLearner (context .Background (), "fake2" , []string {"http://127.0.0.1:1002" })
189
189
require .NoError (t , err )
190
190
if triggerSnapshot {
191
- t .Logf ("Generating snapshot" )
191
+ t .Log ("Generating snapshot" )
192
192
generateSnapshot (t , snapshotCount , cc )
193
193
verifySnapshot (t , epc )
194
194
}
@@ -207,6 +207,77 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
207
207
assert .Equal (t , beforeMembers .Members , afterMembers .Members )
208
208
}
209
209
210
+ func TestAutomaticDowngradeCancellationAfterCompletingDowngradingInClusterOf3 (t * testing.T ) {
211
+ clusterSize := 3
212
+
213
+ currentEtcdBinary := e2e .BinPath .Etcd
214
+ lastReleaseBinary := e2e .BinPath .EtcdLastRelease
215
+ if ! fileutil .Exist (lastReleaseBinary ) {
216
+ t .Skipf ("%q does not exist" , lastReleaseBinary )
217
+ }
218
+
219
+ currentVersion , err := e2e .GetVersionFromBinary (currentEtcdBinary )
220
+ require .NoError (t , err )
221
+ // wipe any pre-release suffix like -alpha.0 we see commonly in builds
222
+ currentVersion .PreRelease = ""
223
+
224
+ lastVersion , err := e2e .GetVersionFromBinary (lastReleaseBinary )
225
+ require .NoError (t , err )
226
+
227
+ require .Equalf (t , lastVersion .Minor , currentVersion .Minor - 1 , "unexpected minor version difference" )
228
+ currentVersionStr := currentVersion .String ()
229
+ lastVersionStr := lastVersion .String ()
230
+
231
+ lastClusterVersion := semver .New (lastVersionStr )
232
+ lastClusterVersion .Patch = 0
233
+
234
+ e2e .BeforeTest (t )
235
+
236
+ t .Logf ("Create cluster with version %s" , currentVersionStr )
237
+ var snapshotCount uint64 = 10
238
+ epc := newCluster (t , clusterSize , snapshotCount )
239
+ for i := 0 ; i < len (epc .Procs ); i ++ {
240
+ e2e .ValidateVersion (t , epc .Cfg , epc .Procs [i ], version.Versions {
241
+ Cluster : currentVersionStr ,
242
+ Server : version .Version ,
243
+ Storage : currentVersionStr ,
244
+ })
245
+ }
246
+ cc := epc .Etcdctl ()
247
+ t .Log ("Cluster created" )
248
+ if len (epc .Procs ) > 1 {
249
+ t .Log ("Waiting health interval to required to make membership changes" )
250
+ time .Sleep (etcdserver .HealthInterval )
251
+ }
252
+
253
+ t .Log ("Adding member to test membership, but a learner avoid breaking quorum" )
254
+ resp , err := cc .MemberAddAsLearner (context .Background (), "fake1" , []string {"http://127.0.0.1:1001" })
255
+ require .NoError (t , err )
256
+ t .Log ("Removing learner to test membership" )
257
+ _ , err = cc .MemberRemove (context .Background (), resp .Member .ID )
258
+ require .NoError (t , err )
259
+ beforeMembers , beforeKV := getMembersAndKeys (t , cc )
260
+
261
+ e2e .DowngradeEnable (t , epc , lastVersion )
262
+
263
+ t .Logf ("Starting downgrade process for all nodes to %q" , lastVersionStr )
264
+ err = e2e .DowngradeUpgradeMembersByID (t , nil , epc , []int {0 , 1 , 2 }, currentVersion , lastClusterVersion )
265
+ require .NoError (t , err )
266
+
267
+ afterMembers , afterKV := getMembersAndKeys (t , cc )
268
+ assert .Equal (t , beforeKV .Kvs , afterKV .Kvs )
269
+ assert .Equal (t , beforeMembers .Members , afterMembers .Members )
270
+
271
+ if len (epc .Procs ) > 1 {
272
+ t .Log ("Waiting health interval to required to make membership changes" )
273
+ time .Sleep (etcdserver .HealthInterval )
274
+ }
275
+
276
+ e2e .DowngradeAutoCancelCheck (t , epc )
277
+ t .Log ("Downgrade cancellation is automatically cancelled since the cluster has been downgraded, validating if cluster is in the right state" )
278
+ e2e .ValidateMemberVersions (t , epc , generateIdenticalVersions (clusterSize , lastClusterVersion ))
279
+ }
280
+
210
281
func newCluster (t * testing.T , clusterSize int , snapshotCount uint64 ) * e2e.EtcdProcessCluster {
211
282
epc , err := e2e .NewEtcdProcessCluster (context .TODO (), t ,
212
283
e2e .WithClusterSize (clusterSize ),
@@ -250,7 +321,7 @@ func generateSnapshot(t *testing.T, snapshotCount uint64, cc *e2e.EtcdctlV3) {
250
321
defer cancel ()
251
322
252
323
var i uint64
253
- t .Logf ("Adding keys" )
324
+ t .Log ("Adding keys" )
254
325
for i = 0 ; i < snapshotCount * 3 ; i ++ {
255
326
err := cc .Put (ctx , fmt .Sprintf ("%d" , i ), "1" , config.PutOptions {})
256
327
assert .NoError (t , err )
@@ -264,7 +335,7 @@ func verifySnapshot(t *testing.T, epc *e2e.EtcdProcessCluster) {
264
335
_ , err := ss .Load ()
265
336
require .NoError (t , err )
266
337
}
267
- t .Logf ("All members have a valid snapshot" )
338
+ t .Log ("All members have a valid snapshot" )
268
339
}
269
340
270
341
func verifySnapshotMembers (t * testing.T , epc * e2e.EtcdProcessCluster , expectedMembers * clientv3.MemberListResponse ) {
@@ -301,11 +372,17 @@ func getMembersAndKeys(t *testing.T, cc *e2e.EtcdctlV3) (*clientv3.MemberListRes
301
372
func generateIdenticalVersions (clusterSize int , ver * semver.Version ) []* version.Versions {
302
373
ret := make ([]* version.Versions , clusterSize )
303
374
375
+ // storage version string is non-empty starting from 3.6.0
376
+ storageStr := ver .String ()
377
+ if ver .LessThan (version .V3_6 ) {
378
+ storageStr = ""
379
+ }
380
+
304
381
for i := range clusterSize {
305
382
ret [i ] = & version.Versions {
306
383
Cluster : ver .String (),
307
384
Server : ver .String (),
308
- Storage : ver . String () ,
385
+ Storage : storageStr ,
309
386
}
310
387
}
311
388
0 commit comments