github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/core/ledger/kvledger/kv_ledger_provider_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package kvledger 18 19 import ( 20 "fmt" 21 "os" 22 "path/filepath" 23 "testing" 24 25 configtxtest "github.com/hyperledger/fabric/common/configtx/test" 26 "github.com/hyperledger/fabric/common/ledger/blkstorage/fsblkstorage" 27 "github.com/hyperledger/fabric/common/ledger/testutil" 28 "github.com/hyperledger/fabric/core/ledger" 29 "github.com/hyperledger/fabric/core/ledger/ledgerconfig" 30 "github.com/hyperledger/fabric/protos/common" 31 "github.com/hyperledger/fabric/protos/ledger/queryresult" 32 putils "github.com/hyperledger/fabric/protos/utils" 33 "github.com/spf13/viper" 34 ) 35 36 func TestLedgerProvider(t *testing.T) { 37 env := newTestEnv(t) 38 defer env.cleanup() 39 numLedgers := 10 40 provider, _ := NewProvider() 41 existingLedgerIDs, err := provider.List() 42 testutil.AssertNoError(t, err, "") 43 testutil.AssertEquals(t, len(existingLedgerIDs), 0) 44 for i := 0; i < numLedgers; i++ { 45 genesisBlock, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(i)) 46 provider.Create(genesisBlock) 47 } 48 existingLedgerIDs, err = provider.List() 49 testutil.AssertNoError(t, err, "") 50 testutil.AssertEquals(t, len(existingLedgerIDs), numLedgers) 51 52 provider.Close() 53 54 provider, _ = NewProvider() 55 defer provider.Close() 56 ledgerIds, _ := provider.List() 57 testutil.AssertEquals(t, len(ledgerIds), numLedgers) 58 t.Logf("ledgerIDs=%#v", ledgerIds) 59 for i := 0; i < numLedgers; i++ { 60 testutil.AssertEquals(t, ledgerIds[i], constructTestLedgerID(i)) 61 } 62 for i := 0; i < numLedgers; i++ { 63 status, _ := provider.Exists(constructTestLedgerID(i)) 64 testutil.AssertEquals(t, status, true) 65 ledger, err := provider.Open(constructTestLedgerID(i)) 66 testutil.AssertNoError(t, err, "") 67 bcInfo, err := ledger.GetBlockchainInfo() 68 ledger.Close() 69 testutil.AssertNoError(t, err, "") 70 testutil.AssertEquals(t, bcInfo.Height, uint64(1)) 71 } 72 gb, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(2)) 73 _, err = provider.Create(gb) 74 testutil.AssertEquals(t, err, ErrLedgerIDExists) 75 76 status, err := provider.Exists(constructTestLedgerID(numLedgers)) 77 testutil.AssertNoError(t, err, "Failed to check for ledger existence") 78 testutil.AssertEquals(t, false, status) 79 80 _, err = provider.Open(constructTestLedgerID(numLedgers)) 81 testutil.AssertEquals(t, err, ErrNonExistingLedgerID) 82 } 83 84 func TestRecovery(t *testing.T) { 85 env := newTestEnv(t) 86 defer env.cleanup() 87 provider, _ := NewProvider() 88 89 // now create the genesis block 90 genesisBlock, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(1)) 91 ledger, err := provider.(*Provider).openInternal(constructTestLedgerID(1)) 92 ledger.Commit(genesisBlock) 93 ledger.Close() 94 95 // Case 1: assume a crash happens, force underconstruction flag to be set to simulate 96 // a failure where ledgerid is being created - ie., block is written but flag is not unset 97 provider.(*Provider).idStore.setUnderConstructionFlag(constructTestLedgerID(1)) 98 provider.Close() 99 100 // construct a new provider to invoke recovery 101 provider, err = NewProvider() 102 testutil.AssertNoError(t, err, "Provider failed to recover an underConstructionLedger") 103 // verify the underecoveryflag and open the ledger 104 flag, err := provider.(*Provider).idStore.getUnderConstructionFlag() 105 testutil.AssertNoError(t, err, "Failed to read the underconstruction flag") 106 testutil.AssertEquals(t, flag, "") 107 ledger, err = provider.Open(constructTestLedgerID(1)) 108 testutil.AssertNoError(t, err, "Failed to open the ledger") 109 ledger.Close() 110 111 // Case 0: assume a crash happens before the genesis block of ledger 2 is committed 112 // Open the ID store (inventory of chainIds/ledgerIds) 113 provider.(*Provider).idStore.setUnderConstructionFlag(constructTestLedgerID(2)) 114 provider.Close() 115 116 // construct a new provider to invoke recovery 117 provider, err = NewProvider() 118 testutil.AssertNoError(t, err, "Provider failed to recover an underConstructionLedger") 119 flag, err = provider.(*Provider).idStore.getUnderConstructionFlag() 120 testutil.AssertNoError(t, err, "Failed to read the underconstruction flag") 121 testutil.AssertEquals(t, flag, "") 122 123 } 124 125 func TestMultipleLedgerBasicRW(t *testing.T) { 126 env := newTestEnv(t) 127 defer env.cleanup() 128 numLedgers := 10 129 provider, _ := NewProvider() 130 ledgers := make([]ledger.PeerLedger, numLedgers) 131 for i := 0; i < numLedgers; i++ { 132 bg, gb := testutil.NewBlockGenerator(t, constructTestLedgerID(i), false) 133 l, err := provider.Create(gb) 134 testutil.AssertNoError(t, err, "") 135 ledgers[i] = l 136 s, _ := l.NewTxSimulator() 137 err = s.SetState("ns", "testKey", []byte(fmt.Sprintf("testValue_%d", i))) 138 s.Done() 139 testutil.AssertNoError(t, err, "") 140 res, err := s.GetTxSimulationResults() 141 testutil.AssertNoError(t, err, "") 142 b := bg.NextBlock([][]byte{res}) 143 err = l.Commit(b) 144 l.Close() 145 testutil.AssertNoError(t, err, "") 146 } 147 148 provider.Close() 149 150 provider, _ = NewProvider() 151 defer provider.Close() 152 ledgers = make([]ledger.PeerLedger, numLedgers) 153 for i := 0; i < numLedgers; i++ { 154 l, err := provider.Open(constructTestLedgerID(i)) 155 testutil.AssertNoError(t, err, "") 156 ledgers[i] = l 157 } 158 159 for i, l := range ledgers { 160 q, _ := l.NewQueryExecutor() 161 val, err := q.GetState("ns", "testKey") 162 q.Done() 163 testutil.AssertNoError(t, err, "") 164 testutil.AssertEquals(t, val, []byte(fmt.Sprintf("testValue_%d", i))) 165 l.Close() 166 } 167 } 168 169 func TestLedgerBackup(t *testing.T) { 170 ledgerid := "TestLedger" 171 originalPath := "/tmp/fabric/ledgertests/kvledger1" 172 restorePath := "/tmp/fabric/ledgertests/kvledger2" 173 viper.Set("ledger.history.enableHistoryDatabase", true) 174 175 // create and populate a ledger in the original environment 176 env := createTestEnv(t, originalPath) 177 provider, _ := NewProvider() 178 bg, gb := testutil.NewBlockGenerator(t, ledgerid, false) 179 gbHash := gb.Header.Hash() 180 ledger, _ := provider.Create(gb) 181 182 simulator, _ := ledger.NewTxSimulator() 183 simulator.SetState("ns1", "key1", []byte("value1")) 184 simulator.SetState("ns1", "key2", []byte("value2")) 185 simulator.SetState("ns1", "key3", []byte("value3")) 186 simulator.Done() 187 simRes, _ := simulator.GetTxSimulationResults() 188 block1 := bg.NextBlock([][]byte{simRes}) 189 ledger.Commit(block1) 190 191 simulator, _ = ledger.NewTxSimulator() 192 simulator.SetState("ns1", "key1", []byte("value4")) 193 simulator.SetState("ns1", "key2", []byte("value5")) 194 simulator.SetState("ns1", "key3", []byte("value6")) 195 simulator.Done() 196 simRes, _ = simulator.GetTxSimulationResults() 197 block2 := bg.NextBlock([][]byte{simRes}) 198 ledger.Commit(block2) 199 200 ledger.Close() 201 provider.Close() 202 203 // Create restore environment 204 env = createTestEnv(t, restorePath) 205 206 // remove the statedb, historydb, and block indexes (they are supposed to be auto created during opening of an existing ledger) 207 // and rename the originalPath to restorePath 208 testutil.AssertNoError(t, os.RemoveAll(ledgerconfig.GetStateLevelDBPath()), "") 209 testutil.AssertNoError(t, os.RemoveAll(ledgerconfig.GetHistoryLevelDBPath()), "") 210 testutil.AssertNoError(t, os.RemoveAll(filepath.Join(ledgerconfig.GetBlockStorePath(), fsblkstorage.IndexDir)), "") 211 testutil.AssertNoError(t, os.Rename(originalPath, restorePath), "") 212 defer env.cleanup() 213 214 // Instantiate the ledger from restore environment and this should behave exactly as it would have in the original environment 215 provider, _ = NewProvider() 216 defer provider.Close() 217 218 _, err := provider.Create(gb) 219 testutil.AssertEquals(t, err, ErrLedgerIDExists) 220 221 ledger, _ = provider.Open(ledgerid) 222 defer ledger.Close() 223 224 block1Hash := block1.Header.Hash() 225 block2Hash := block2.Header.Hash() 226 bcInfo, _ := ledger.GetBlockchainInfo() 227 testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{ 228 Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash}) 229 230 b0, _ := ledger.GetBlockByHash(gbHash) 231 testutil.AssertEquals(t, b0, gb) 232 233 b1, _ := ledger.GetBlockByHash(block1Hash) 234 testutil.AssertEquals(t, b1, block1) 235 236 b2, _ := ledger.GetBlockByHash(block2Hash) 237 testutil.AssertEquals(t, b2, block2) 238 239 b0, _ = ledger.GetBlockByNumber(0) 240 testutil.AssertEquals(t, b0, gb) 241 242 b1, _ = ledger.GetBlockByNumber(1) 243 testutil.AssertEquals(t, b1, block1) 244 245 b2, _ = ledger.GetBlockByNumber(2) 246 testutil.AssertEquals(t, b2, block2) 247 248 // get the tran id from the 2nd block, then use it to test GetTransactionByID() 249 txEnvBytes2 := block1.Data.Data[0] 250 txEnv2, err := putils.GetEnvelopeFromBlock(txEnvBytes2) 251 testutil.AssertNoError(t, err, "Error upon GetEnvelopeFromBlock") 252 payload2, err := putils.GetPayload(txEnv2) 253 testutil.AssertNoError(t, err, "Error upon GetPayload") 254 chdr, err := putils.UnmarshalChannelHeader(payload2.Header.ChannelHeader) 255 testutil.AssertNoError(t, err, "Error upon GetChannelHeaderFromBytes") 256 txID2 := chdr.TxId 257 processedTran2, err := ledger.GetTransactionByID(txID2) 258 testutil.AssertNoError(t, err, "Error upon GetTransactionByID") 259 // get the tran envelope from the retrieved ProcessedTransaction 260 retrievedTxEnv2 := processedTran2.TransactionEnvelope 261 testutil.AssertEquals(t, retrievedTxEnv2, txEnv2) 262 263 qe, _ := ledger.NewQueryExecutor() 264 value1, _ := qe.GetState("ns1", "key1") 265 testutil.AssertEquals(t, value1, []byte("value4")) 266 267 hqe, err := ledger.NewHistoryQueryExecutor() 268 testutil.AssertNoError(t, err, "") 269 itr, err := hqe.GetHistoryForKey("ns1", "key1") 270 testutil.AssertNoError(t, err, "") 271 defer itr.Close() 272 273 result1, err := itr.Next() 274 testutil.AssertNoError(t, err, "") 275 testutil.AssertEquals(t, result1.(*queryresult.KeyModification).Value, []byte("value1")) 276 result2, err := itr.Next() 277 testutil.AssertNoError(t, err, "") 278 testutil.AssertEquals(t, result2.(*queryresult.KeyModification).Value, []byte("value4")) 279 } 280 281 func constructTestLedgerID(i int) string { 282 return fmt.Sprintf("ledger_%06d", i) 283 }