@@ -24,7 +24,7 @@ import (
24
24
25
25
"github.com/coreos/go-semver/semver"
26
26
"github.com/stretchr/testify/assert"
27
- betesting "go.etcd.io/etcd/server/v3/mvcc/backend/testing "
27
+ "github.com/stretchr/testify/require "
28
28
"go.uber.org/zap"
29
29
"go.uber.org/zap/zaptest"
30
30
@@ -33,6 +33,7 @@ import (
33
33
"go.etcd.io/etcd/raft/v3/raftpb"
34
34
"go.etcd.io/etcd/server/v3/etcdserver/api/v2store"
35
35
"go.etcd.io/etcd/server/v3/mock/mockstore"
36
+ betesting "go.etcd.io/etcd/server/v3/mvcc/backend/testing"
36
37
)
37
38
38
39
func TestClusterMember (t * testing.T ) {
@@ -1210,3 +1211,160 @@ func TestRemoveMemberSyncsBackendAndStoreV2(t *testing.T) {
1210
1211
})
1211
1212
}
1212
1213
}
1214
+
1215
+ func TestSyncLearnerPromotion (t * testing.T ) {
1216
+ tcs := []struct {
1217
+ name string
1218
+
1219
+ storeV2Members []* Member
1220
+ backendMembers []* Member
1221
+
1222
+ expectV3Members map [types.ID ]* Member
1223
+ }{
1224
+ {
1225
+ name : "v3store should keep unchanged if IsLearner isn't the only field that differs" ,
1226
+ storeV2Members : []* Member {
1227
+ {
1228
+ ID : 100 ,
1229
+ RaftAttributes : RaftAttributes {
1230
+ PeerURLs : []string {"http://10.0.0.100:2380" },
1231
+ IsLearner : false ,
1232
+ },
1233
+ },
1234
+ },
1235
+ backendMembers : []* Member {
1236
+ {
1237
+ ID : 100 ,
1238
+ RaftAttributes : RaftAttributes {
1239
+ PeerURLs : []string {"http://10.0.0.9:2380" },
1240
+ IsLearner : true ,
1241
+ },
1242
+ },
1243
+ },
1244
+ expectV3Members : map [types.ID ]* Member {
1245
+ 100 : {
1246
+ ID : 100 ,
1247
+ RaftAttributes : RaftAttributes {
1248
+ PeerURLs : []string {"http://10.0.0.9:2380" },
1249
+ IsLearner : true ,
1250
+ },
1251
+ },
1252
+ },
1253
+ },
1254
+ {
1255
+ name : "v3store should keep unchanged if IsLearner is the only field that differs but v3store.IsLearner is false" ,
1256
+ storeV2Members : []* Member {
1257
+ {
1258
+ ID : 100 ,
1259
+ RaftAttributes : RaftAttributes {
1260
+ PeerURLs : []string {"http://10.0.0.9:2380" },
1261
+ IsLearner : true ,
1262
+ },
1263
+ },
1264
+ },
1265
+ backendMembers : []* Member {
1266
+ {
1267
+ ID : 100 ,
1268
+ RaftAttributes : RaftAttributes {
1269
+ PeerURLs : []string {"http://10.0.0.9:2380" },
1270
+ IsLearner : false ,
1271
+ },
1272
+ },
1273
+ },
1274
+ expectV3Members : map [types.ID ]* Member {
1275
+ 100 : {
1276
+ ID : 100 ,
1277
+ RaftAttributes : RaftAttributes {
1278
+ PeerURLs : []string {"http://10.0.0.9:2380" },
1279
+ IsLearner : false ,
1280
+ },
1281
+ },
1282
+ },
1283
+ },
1284
+ {
1285
+ name : "v3store should be updated if IsLearner is the only field that differs and v3store.IsLearner is true" ,
1286
+ storeV2Members : []* Member {
1287
+ {
1288
+ ID : 100 ,
1289
+ RaftAttributes : RaftAttributes {
1290
+ PeerURLs : []string {"http://10.0.0.9:2380" },
1291
+ IsLearner : false ,
1292
+ },
1293
+ },
1294
+ },
1295
+ backendMembers : []* Member {
1296
+ {
1297
+ ID : 100 ,
1298
+ RaftAttributes : RaftAttributes {
1299
+ PeerURLs : []string {"http://10.0.0.9:2380" },
1300
+ IsLearner : true ,
1301
+ },
1302
+ },
1303
+ },
1304
+ expectV3Members : map [types.ID ]* Member {
1305
+ 100 : {
1306
+ ID : 100 ,
1307
+ RaftAttributes : RaftAttributes {
1308
+ PeerURLs : []string {"http://10.0.0.9:2380" },
1309
+ IsLearner : false ,
1310
+ },
1311
+ },
1312
+ },
1313
+ },
1314
+ {
1315
+ name : "v3store should be updated if IsLearner is the only field that differs and peerURLs are in different order in v2store and v3store" ,
1316
+ storeV2Members : []* Member {
1317
+ {
1318
+ ID : 100 ,
1319
+ RaftAttributes : RaftAttributes {
1320
+ PeerURLs : []string {"http://10.0.0.9:2380" , "http://127.0.0.1:2380" },
1321
+ IsLearner : false ,
1322
+ },
1323
+ },
1324
+ },
1325
+ backendMembers : []* Member {
1326
+ {
1327
+ ID : 100 ,
1328
+ RaftAttributes : RaftAttributes {
1329
+ PeerURLs : []string {"http://127.0.0.1:2380" , "http://10.0.0.9:2380" },
1330
+ IsLearner : true ,
1331
+ },
1332
+ },
1333
+ },
1334
+ expectV3Members : map [types.ID ]* Member {
1335
+ 100 : {
1336
+ ID : 100 ,
1337
+ RaftAttributes : RaftAttributes {
1338
+ PeerURLs : []string {"http://127.0.0.1:2380" , "http://10.0.0.9:2380" },
1339
+ IsLearner : false ,
1340
+ },
1341
+ },
1342
+ },
1343
+ },
1344
+ }
1345
+ for _ , tc := range tcs {
1346
+ t .Run (tc .name , func (t * testing.T ) {
1347
+ lg := zaptest .NewLogger (t )
1348
+ be , _ := betesting .NewDefaultTmpBackend (t )
1349
+ defer be .Close ()
1350
+ mustCreateBackendBuckets (be )
1351
+ for _ , m := range tc .backendMembers {
1352
+ unsafeSaveMemberToBackend (lg , be , m )
1353
+ }
1354
+ be .ForceCommit ()
1355
+
1356
+ st := v2store .New ()
1357
+ for _ , m := range tc .storeV2Members {
1358
+ mustSaveMemberToStore (lg , st , m )
1359
+ }
1360
+
1361
+ cluster := NewCluster (lg )
1362
+ cluster .SetBackend (be )
1363
+ cluster .SetStore (st )
1364
+
1365
+ cluster .SyncLearnerPromotionIfNeeded ()
1366
+ v3Members , _ := cluster .MembersFromBackend ()
1367
+ require .Equal (t , tc .expectV3Members , v3Members )
1368
+ })
1369
+ }
1370
+ }
0 commit comments