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