github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/core/ledger/kvledger/pause_resume_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package kvledger 8 9 import ( 10 "testing" 11 12 "github.com/golang/protobuf/proto" 13 "github.com/hyperledger/fabric-protos-go/common" 14 configtxtest "github.com/osdi23p228/fabric/common/configtx/test" 15 "github.com/osdi23p228/fabric/core/ledger/mock" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestPauseAndResume(t *testing.T) { 20 conf, cleanup := testConfig(t) 21 conf.HistoryDBConfig.Enabled = false 22 defer cleanup() 23 provider := testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 24 25 numLedgers := 10 26 activeLedgerIDs, err := provider.List() 27 require.NoError(t, err) 28 require.Len(t, activeLedgerIDs, 0) 29 genesisBlocks := make([]*common.Block, numLedgers) 30 for i := 0; i < numLedgers; i++ { 31 genesisBlock, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(i)) 32 genesisBlocks[i] = genesisBlock 33 provider.Create(genesisBlock) 34 } 35 activeLedgerIDs, err = provider.List() 36 require.NoError(t, err) 37 require.Len(t, activeLedgerIDs, numLedgers) 38 provider.Close() 39 40 // pause channels 41 pausedLedgers := []int{1, 3, 5} 42 for _, i := range pausedLedgers { 43 err = PauseChannel(conf.RootFSPath, constructTestLedgerID(i)) 44 require.NoError(t, err) 45 } 46 // pause again should not fail 47 err = PauseChannel(conf.RootFSPath, constructTestLedgerID(1)) 48 require.NoError(t, err) 49 // verify ledger status after pause 50 provider = testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 51 assertLedgerStatus(t, provider, genesisBlocks, numLedgers, pausedLedgers) 52 provider.Close() 53 54 // resume channels 55 resumedLedgers := []int{1, 5} 56 for _, i := range resumedLedgers { 57 err = ResumeChannel(conf.RootFSPath, constructTestLedgerID(i)) 58 require.NoError(t, err) 59 } 60 // resume again should not fail 61 err = ResumeChannel(conf.RootFSPath, constructTestLedgerID(1)) 62 require.NoError(t, err) 63 // verify ledger status after resume 64 pausedLedgersAfterResume := []int{3} 65 provider = testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 66 defer provider.Close() 67 assertLedgerStatus(t, provider, genesisBlocks, numLedgers, pausedLedgersAfterResume) 68 69 // open paused channel should fail 70 _, err = provider.Open(constructTestLedgerID(3)) 71 require.Equal(t, ErrInactiveLedger, err) 72 } 73 74 func TestPauseAndResumeErrors(t *testing.T) { 75 conf, cleanup := testConfig(t) 76 conf.HistoryDBConfig.Enabled = false 77 defer cleanup() 78 provider := testutilNewProvider(conf, t, &mock.DeployedChaincodeInfoProvider{}) 79 80 ledgerID := constructTestLedgerID(0) 81 genesisBlock, _ := configtxtest.MakeGenesisBlock(ledgerID) 82 provider.Create(genesisBlock) 83 // purposely set an invalid metatdata 84 provider.idStore.db.Put(provider.idStore.encodeLedgerKey(ledgerID, metadataKeyPrefix), []byte("invalid"), true) 85 86 // fail if provider is open (e.g., peer is up running) 87 err := PauseChannel(conf.RootFSPath, constructTestLedgerID(0)) 88 require.Error(t, err, "as another peer node command is executing, wait for that command to complete its execution or terminate it before retrying") 89 90 err = ResumeChannel(conf.RootFSPath, constructTestLedgerID(0)) 91 require.Error(t, err, "as another peer node command is executing, wait for that command to complete its execution or terminate it before retrying") 92 93 provider.Close() 94 95 // fail if ledgerID does not exists 96 err = PauseChannel(conf.RootFSPath, "dummy") 97 require.Error(t, err, "LedgerID does not exist") 98 99 err = ResumeChannel(conf.RootFSPath, "dummy") 100 require.Error(t, err, "LedgerID does not exist") 101 102 // error if metadata cannot be unmarshaled 103 err = PauseChannel(conf.RootFSPath, ledgerID) 104 require.EqualError(t, err, "error unmarshalling ledger metadata: unexpected EOF") 105 106 err = ResumeChannel(conf.RootFSPath, ledgerID) 107 require.EqualError(t, err, "error unmarshalling ledger metadata: unexpected EOF") 108 } 109 110 // verify status for paused ledgers and non-paused ledgers 111 func assertLedgerStatus(t *testing.T, provider *Provider, genesisBlocks []*common.Block, numLedgers int, pausedLedgers []int) { 112 s := provider.idStore 113 114 activeLedgerIDs, err := provider.List() 115 require.NoError(t, err) 116 require.Len(t, activeLedgerIDs, numLedgers-len(pausedLedgers)) 117 for i := 0; i < numLedgers; i++ { 118 if !contains(pausedLedgers, i) { 119 require.Contains(t, activeLedgerIDs, constructTestLedgerID(i)) 120 } 121 } 122 123 for i := 0; i < numLedgers; i++ { 124 active, exists, err := s.ledgerIDActive(constructTestLedgerID(i)) 125 require.NoError(t, err) 126 if !contains(pausedLedgers, i) { 127 require.True(t, active) 128 require.True(t, exists) 129 } else { 130 require.False(t, active) 131 require.True(t, exists) 132 } 133 134 // every channel (paused or non-paused) should have an entry for genesis block 135 gbBytes, err := s.db.Get(s.encodeLedgerKey(constructTestLedgerID(i), ledgerKeyPrefix)) 136 require.NoError(t, err) 137 gb := &common.Block{} 138 require.NoError(t, proto.Unmarshal(gbBytes, gb)) 139 require.True(t, proto.Equal(gb, genesisBlocks[i]), "proto messages are not equal") 140 141 } 142 } 143 144 func contains(slice []int, val int) bool { 145 for _, item := range slice { 146 if item == val { 147 return true 148 } 149 } 150 return false 151 }