@@ -1388,6 +1388,93 @@ var _ = Describe("EndToEnd reconfiguration and onboarding", func() {
1388
1388
"testchannel" : 5 ,
1389
1389
}, []* nwo.Orderer {o1 , o2 , o3 }, peer , network )
1390
1390
})
1391
+
1392
+ It ("remove channel from all orderers and add channel back" , func () {
1393
+ o1 := network .Orderer ("orderer1" )
1394
+ o2 := network .Orderer ("orderer2" )
1395
+ o3 := network .Orderer ("orderer3" )
1396
+
1397
+ By ("Waiting for them to elect a leader" )
1398
+ FindLeader (ordererRunners )
1399
+
1400
+ assertBlockReception (map [string ]int {
1401
+ "testchannel" : 0 ,
1402
+ }, network .Orderers , peer , network )
1403
+
1404
+ By ("Removing channel from all orderers" )
1405
+ // TODO the channelparticipation.Remove does not clean up the etcdraft folder. This may prevent the
1406
+ // correct re-creation of the channel on this orderer.
1407
+ // See: https://github.com/hyperledger/fabric/issues/3992
1408
+ for _ , o := range network .Orderers {
1409
+ ready := make (chan struct {})
1410
+ go func () {
1411
+ defer GinkgoRecover ()
1412
+ channelparticipation .Remove (network , o , "testchannel" )
1413
+ close (ready )
1414
+ }()
1415
+ Eventually (ready , network .EventuallyTimeout ).Should (BeClosed ())
1416
+
1417
+ Eventually (func () int { // Removal is async
1418
+ channelList := channelparticipation .List (network , o )
1419
+ return len (channelList .Channels )
1420
+ }()).Should (BeZero ())
1421
+ }
1422
+
1423
+ // TODO It is recommended to remove the etcdraft folder for the WAL to be re-created correctly
1424
+ // See: https://github.com/hyperledger/fabric/issues/3992
1425
+ for _ , o := range network .Orderers {
1426
+ err := os .RemoveAll (path .Join (network .OrdererDir (o ), "etcdraft" , "wal" , "testchannel" ))
1427
+ Expect (err ).NotTo (HaveOccurred ())
1428
+ err = os .RemoveAll (path .Join (network .OrdererDir (o ), "etcdraft" , "snapshot" , "testchannel" ))
1429
+ Expect (err ).NotTo (HaveOccurred ())
1430
+ }
1431
+
1432
+ By ("Re-create the genesis block" )
1433
+ for _ , c := range network .Channels {
1434
+ sess , err := network .ConfigTxGen (commands.OutputBlock {
1435
+ ChannelID : c .Name ,
1436
+ Profile : c .Profile ,
1437
+ ConfigPath : network .RootDir ,
1438
+ OutputBlock : network .OutputBlockPath (c .Name ),
1439
+ })
1440
+ Expect (err ).NotTo (HaveOccurred ())
1441
+ Eventually (sess , network .EventuallyTimeout ).Should (gexec .Exit (0 ))
1442
+ }
1443
+
1444
+ By ("Re-adding the channel to the orderers" )
1445
+ channelparticipation .JoinOrderersAppChannelCluster (network , "testchannel" , o1 , o2 , o3 )
1446
+
1447
+ FindLeader (ordererRunners )
1448
+
1449
+ assertBlockReception (map [string ]int {
1450
+ "testchannel" : 0 ,
1451
+ }, network .Orderers , peer , network )
1452
+
1453
+ expectedInfo := channelparticipation .ListOne (network , o1 , "testchannel" )
1454
+
1455
+ By ("Submitting tx" )
1456
+ env := ordererclient .CreateBroadcastEnvelope (network , o2 , "testchannel" , []byte ("foo" ))
1457
+ resp , err := ordererclient .Broadcast (network , o2 , env )
1458
+ Expect (err ).NotTo (HaveOccurred ())
1459
+ Expect (resp .Status ).To (Equal (common .Status_SUCCESS ))
1460
+
1461
+ By ("Waiting for the channel to stabilize" )
1462
+ expectedInfo .Height ++
1463
+ assertCatchup := func (expected channelparticipation.ChannelInfo ) bool {
1464
+ current := channelparticipation .ListOne (network , o1 , "testchannel" )
1465
+ ok := current == expected
1466
+ if ! ok {
1467
+ fmt .Fprintf (GinkgoWriter , "Current ChannelInfo: %+v" , current )
1468
+ }
1469
+ return ok
1470
+ }
1471
+
1472
+ Eventually (assertCatchup (expectedInfo ), network .EventuallyTimeout , 100 * time .Millisecond ).Should (BeTrue ())
1473
+
1474
+ assertBlockReception (map [string ]int {
1475
+ "testchannel" : 1 ,
1476
+ }, []* nwo.Orderer {o1 , o2 , o3 }, peer , network )
1477
+ })
1391
1478
})
1392
1479
1393
1480
It ("notices it even if it is down at the time of its eviction" , func () {
0 commit comments