@@ -127,7 +127,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
127
127
})
128
128
}
129
129
cc := epc .Etcdctl ()
130
- t .Logf ("Cluster created" )
130
+ t .Log ("Cluster created" )
131
131
if len (epc .Procs ) > 1 {
132
132
t .Log ("Waiting health interval to required to make membership changes" )
133
133
time .Sleep (etcdserver .HealthInterval )
@@ -140,7 +140,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
140
140
resp , err := cc .MemberAddAsLearner (t .Context (), "fake1" , []string {"http://127.0.0.1:1001" })
141
141
require .NoError (t , err )
142
142
if triggerSnapshot {
143
- t .Logf ("Generating snapshot" )
143
+ t .Log ("Generating snapshot" )
144
144
generateSnapshot (t , snapshotCount , cc )
145
145
verifySnapshot (t , epc )
146
146
}
@@ -150,7 +150,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
150
150
beforeMembers , beforeKV := getMembersAndKeys (t , cc )
151
151
152
152
if triggerCancellation == cancelRightBeforeEnable {
153
- t .Logf ("Cancelling downgrade before enabling" )
153
+ t .Log ("Cancelling downgrade before enabling" )
154
154
e2e .DowngradeCancel (t , epc )
155
155
t .Log ("Downgrade cancelled, validating if cluster is in the right state" )
156
156
e2e .ValidateMemberVersions (t , epc , generateIdenticalVersions (clusterSize , currentVersion ))
@@ -163,7 +163,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
163
163
e2e .ValidateDowngradeInfo (t , epc , & pb.DowngradeInfo {Enabled : true , TargetVersion : lastClusterVersion .String ()})
164
164
165
165
if triggerCancellation == cancelRightAfterEnable {
166
- t .Logf ("Cancelling downgrade right after enabling (no node is downgraded yet)" )
166
+ t .Log ("Cancelling downgrade right after enabling (no node is downgraded yet)" )
167
167
e2e .DowngradeCancel (t , epc )
168
168
t .Log ("Downgrade cancelled, validating if cluster is in the right state" )
169
169
e2e .ValidateMemberVersions (t , epc , generateIdenticalVersions (clusterSize , currentVersion ))
@@ -200,7 +200,7 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
200
200
resp , err = cc .MemberAddAsLearner (t .Context (), "fake2" , []string {"http://127.0.0.1:1002" })
201
201
require .NoError (t , err )
202
202
if triggerSnapshot {
203
- t .Logf ("Generating snapshot" )
203
+ t .Log ("Generating snapshot" )
204
204
generateSnapshot (t , snapshotCount , cc )
205
205
verifySnapshot (t , epc )
206
206
}
@@ -228,6 +228,85 @@ func testDowngradeUpgrade(t *testing.T, numberOfMembersToDowngrade int, clusterS
228
228
assert .Equal (t , beforeMembers .Members , afterMembers .Members )
229
229
}
230
230
231
+ func TestDowngradeAutoCancelAfterCompletion (t * testing.T ) {
232
+ clusterSize := 3
233
+
234
+ currentEtcdBinary := e2e .BinPath .Etcd
235
+ lastReleaseBinary := e2e .BinPath .EtcdLastRelease
236
+ if ! fileutil .Exist (lastReleaseBinary ) {
237
+ t .Skipf ("%q does not exist" , lastReleaseBinary )
238
+ }
239
+
240
+ currentVersion , err := e2e .GetVersionFromBinary (currentEtcdBinary )
241
+ require .NoError (t , err )
242
+ // wipe any pre-release suffix like -alpha.0 we see commonly in builds
243
+ currentVersion .PreRelease = ""
244
+
245
+ lastVersion , err := e2e .GetVersionFromBinary (lastReleaseBinary )
246
+ require .NoError (t , err )
247
+
248
+ require .Equalf (t , lastVersion .Minor , currentVersion .Minor - 1 , "unexpected minor version difference" )
249
+ currentVersionStr := currentVersion .String ()
250
+ lastVersionStr := lastVersion .String ()
251
+
252
+ lastClusterVersion := semver .New (lastVersionStr )
253
+ lastClusterVersion .Patch = 0
254
+
255
+ e2e .BeforeTest (t )
256
+
257
+ t .Logf ("Create cluster with version %s" , currentVersionStr )
258
+ var snapshotCount uint64 = 10
259
+ epc := newCluster (t , clusterSize , snapshotCount )
260
+ for i := 0 ; i < len (epc .Procs ); i ++ {
261
+ e2e .ValidateVersion (t , epc .Cfg , epc .Procs [i ], version.Versions {
262
+ Cluster : currentVersionStr ,
263
+ Server : version .Version ,
264
+ Storage : currentVersionStr ,
265
+ })
266
+ }
267
+ cc := epc .Etcdctl ()
268
+ t .Log ("Cluster created" )
269
+ if len (epc .Procs ) > 1 {
270
+ t .Log ("Waiting health interval to required to make membership changes" )
271
+ time .Sleep (etcdserver .HealthInterval )
272
+ }
273
+
274
+ t .Log ("Downgrade should be disabled" )
275
+ e2e .ValidateDowngradeInfo (t , epc , & pb.DowngradeInfo {Enabled : false })
276
+
277
+ t .Log ("Adding member to test membership, but a learner avoid breaking quorum" )
278
+ resp , err := cc .MemberAddAsLearner (context .Background (), "fake1" , []string {"http://127.0.0.1:1001" })
279
+ require .NoError (t , err )
280
+ t .Log ("Removing learner to test membership" )
281
+ _ , err = cc .MemberRemove (context .Background (), resp .Member .ID )
282
+ require .NoError (t , err )
283
+ beforeMembers , beforeKV := getMembersAndKeys (t , cc )
284
+
285
+ e2e .DowngradeEnable (t , epc , lastVersion )
286
+
287
+ t .Log ("Downgrade should be enabled" )
288
+ e2e .ValidateDowngradeInfo (t , epc , & pb.DowngradeInfo {Enabled : true , TargetVersion : lastClusterVersion .String ()})
289
+
290
+ t .Logf ("Starting downgrade process for all nodes to %q" , lastVersionStr )
291
+ err = e2e .DowngradeUpgradeMembersByID (t , nil , epc , []int {0 , 1 , 2 }, true , currentVersion , lastClusterVersion )
292
+ require .NoError (t , err )
293
+
294
+ afterMembers , afterKV := getMembersAndKeys (t , cc )
295
+ assert .Equal (t , beforeKV .Kvs , afterKV .Kvs )
296
+ assert .Equal (t , beforeMembers .Members , afterMembers .Members )
297
+
298
+ if len (epc .Procs ) > 1 {
299
+ t .Log ("Waiting health interval to required to make membership changes" )
300
+ time .Sleep (etcdserver .HealthInterval )
301
+ }
302
+
303
+ t .Log ("Downgrade should be disabled" )
304
+ e2e .ValidateDowngradeInfo (t , epc , & pb.DowngradeInfo {Enabled : false })
305
+
306
+ t .Log ("Downgrade cancellation is automatically cancelled since the cluster has been downgraded, validating if cluster is in the right state" )
307
+ e2e .ValidateMemberVersions (t , epc , generateIdenticalVersions (clusterSize , lastClusterVersion ))
308
+ }
309
+
231
310
func newCluster (t * testing.T , clusterSize int , snapshotCount uint64 ) * e2e.EtcdProcessCluster {
232
311
epc , err := e2e .NewEtcdProcessCluster (t .Context (), t ,
233
312
e2e .WithClusterSize (clusterSize ),
@@ -250,7 +329,7 @@ func generateSnapshot(t *testing.T, snapshotCount uint64, cc *e2e.EtcdctlV3) {
250
329
defer cancel ()
251
330
252
331
var i uint64
253
- t .Logf ("Adding keys" )
332
+ t .Log ("Adding keys" )
254
333
for i = 0 ; i < snapshotCount * 3 ; i ++ {
255
334
err := cc .Put (ctx , fmt .Sprintf ("%d" , i ), "1" , config.PutOptions {})
256
335
assert .NoError (t , err )
@@ -264,7 +343,7 @@ func verifySnapshot(t *testing.T, epc *e2e.EtcdProcessCluster) {
264
343
_ , err := ss .Load ()
265
344
require .NoError (t , err )
266
345
}
267
- t .Logf ("All members have a valid snapshot" )
346
+ t .Log ("All members have a valid snapshot" )
268
347
}
269
348
270
349
func verifySnapshotMembers (t * testing.T , epc * e2e.EtcdProcessCluster , expectedMembers * clientv3.MemberListResponse ) {
@@ -301,11 +380,17 @@ func getMembersAndKeys(t *testing.T, cc *e2e.EtcdctlV3) (*clientv3.MemberListRes
301
380
func generateIdenticalVersions (clusterSize int , ver * semver.Version ) []* version.Versions {
302
381
ret := make ([]* version.Versions , clusterSize )
303
382
383
+ // storage version string is non-empty starting from 3.6.0
384
+ storageStr := ver .String ()
385
+ if ver .LessThan (version .V3_6 ) {
386
+ storageStr = ""
387
+ }
388
+
304
389
for i := range clusterSize {
305
390
ret [i ] = & version.Versions {
306
391
Cluster : ver .String (),
307
392
Server : ver .String (),
308
- Storage : ver . String () ,
393
+ Storage : storageStr ,
309
394
}
310
395
}
311
396
0 commit comments