github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb_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 historyleveldb 18 19 import ( 20 "os" 21 "strconv" 22 "testing" 23 24 configtxtest "github.com/hyperledger/fabric/common/configtx/test" 25 "github.com/hyperledger/fabric/common/ledger/testutil" 26 "github.com/hyperledger/fabric/core/ledger/util" 27 "github.com/hyperledger/fabric/protos/common" 28 "github.com/hyperledger/fabric/protos/ledger/queryresult" 29 "github.com/hyperledger/fabric/protos/peer" 30 "github.com/spf13/viper" 31 ) 32 33 func TestMain(m *testing.M) { 34 viper.Set("peer.fileSystemPath", "/tmp/fabric/ledgertests/kvledger/history/historydb/historyleveldb") 35 os.Exit(m.Run()) 36 } 37 38 //TestSavepoint tests that save points get written after each block and get returned via GetBlockNumfromSavepoint 39 func TestSavepoint(t *testing.T) { 40 41 env := NewTestHistoryEnv(t) 42 defer env.cleanup() 43 44 // read the savepoint, it should not exist and should return nil Height object 45 savepoint, err := env.testHistoryDB.GetLastSavepoint() 46 testutil.AssertNoError(t, err, "Error upon historyDatabase.GetLastSavepoint()") 47 testutil.AssertNil(t, savepoint) 48 49 // ShouldRecover should return true when no savepoint is found and recovery from block 0 50 status, blockNum, err := env.testHistoryDB.ShouldRecover(0) 51 testutil.AssertNoError(t, err, "Error upon historyDatabase.ShouldRecover()") 52 testutil.AssertEquals(t, status, true) 53 testutil.AssertEquals(t, blockNum, uint64(0)) 54 55 bg, gb := testutil.NewBlockGenerator(t, "testLedger", false) 56 testutil.AssertNoError(t, env.testHistoryDB.Commit(gb), "") 57 // read the savepoint, it should now exist and return a Height object with BlockNum 0 58 savepoint, err = env.testHistoryDB.GetLastSavepoint() 59 testutil.AssertNoError(t, err, "Error upon historyDatabase.GetLastSavepoint()") 60 testutil.AssertEquals(t, savepoint.BlockNum, uint64(0)) 61 62 // create the next block (block 1) 63 simulator, _ := env.txmgr.NewTxSimulator() 64 simulator.SetState("ns1", "key1", []byte("value1")) 65 simulator.Done() 66 simRes, _ := simulator.GetTxSimulationResults() 67 block1 := bg.NextBlock([][]byte{simRes}) 68 testutil.AssertNoError(t, env.testHistoryDB.Commit(block1), "") 69 savepoint, err = env.testHistoryDB.GetLastSavepoint() 70 testutil.AssertNoError(t, err, "Error upon historyDatabase.GetLastSavepoint()") 71 testutil.AssertEquals(t, savepoint.BlockNum, uint64(1)) 72 73 // Should Recover should return false 74 status, blockNum, err = env.testHistoryDB.ShouldRecover(1) 75 testutil.AssertNoError(t, err, "Error upon historyDatabase.ShouldRecover()") 76 testutil.AssertEquals(t, status, false) 77 testutil.AssertEquals(t, blockNum, uint64(2)) 78 79 // create the next block (block 2) 80 simulator, _ = env.txmgr.NewTxSimulator() 81 simulator.SetState("ns1", "key1", []byte("value2")) 82 simulator.Done() 83 simRes, _ = simulator.GetTxSimulationResults() 84 block2 := bg.NextBlock([][]byte{simRes}) 85 86 // assume that the peer failed to commit this block to historyDB and is being recovered now 87 env.testHistoryDB.CommitLostBlock(block2) 88 savepoint, err = env.testHistoryDB.GetLastSavepoint() 89 testutil.AssertNoError(t, err, "Error upon historyDatabase.GetLastSavepoint()") 90 testutil.AssertEquals(t, savepoint.BlockNum, uint64(2)) 91 92 //Pass high blockNum, ShouldRecover should return true with 3 as blocknum to recover from 93 status, blockNum, err = env.testHistoryDB.ShouldRecover(10) 94 testutil.AssertNoError(t, err, "Error upon historyDatabase.ShouldRecover()") 95 testutil.AssertEquals(t, status, true) 96 testutil.AssertEquals(t, blockNum, uint64(3)) 97 } 98 99 func TestHistory(t *testing.T) { 100 101 env := NewTestHistoryEnv(t) 102 defer env.cleanup() 103 provider := env.testBlockStorageEnv.provider 104 ledger1id := "ledger1" 105 store1, err := provider.OpenBlockStore(ledger1id) 106 testutil.AssertNoError(t, err, "Error upon provider.OpenBlockStore()") 107 defer store1.Shutdown() 108 109 bg, gb := testutil.NewBlockGenerator(t, ledger1id, false) 110 testutil.AssertNoError(t, store1.AddBlock(gb), "") 111 testutil.AssertNoError(t, env.testHistoryDB.Commit(gb), "") 112 113 //block1 114 simulator, _ := env.txmgr.NewTxSimulator() 115 value1 := []byte("value1") 116 simulator.SetState("ns1", "key7", value1) 117 simulator.Done() 118 simRes, _ := simulator.GetTxSimulationResults() 119 block1 := bg.NextBlock([][]byte{simRes}) 120 err = store1.AddBlock(block1) 121 testutil.AssertNoError(t, err, "") 122 err = env.testHistoryDB.Commit(block1) 123 testutil.AssertNoError(t, err, "") 124 125 //block2 tran1 126 simulationResults := [][]byte{} 127 simulator, _ = env.txmgr.NewTxSimulator() 128 value2 := []byte("value2") 129 simulator.SetState("ns1", "key7", value2) 130 simulator.Done() 131 simRes, _ = simulator.GetTxSimulationResults() 132 simulationResults = append(simulationResults, simRes) 133 //block2 tran2 134 simulator2, _ := env.txmgr.NewTxSimulator() 135 value3 := []byte("value3") 136 simulator2.SetState("ns1", "key7", value3) 137 simulator2.Done() 138 simRes2, _ := simulator2.GetTxSimulationResults() 139 simulationResults = append(simulationResults, simRes2) 140 block2 := bg.NextBlock(simulationResults) 141 err = store1.AddBlock(block2) 142 testutil.AssertNoError(t, err, "") 143 err = env.testHistoryDB.Commit(block2) 144 testutil.AssertNoError(t, err, "") 145 146 //block3 147 simulator, _ = env.txmgr.NewTxSimulator() 148 simulator.DeleteState("ns1", "key7") 149 simulator.Done() 150 simRes, _ = simulator.GetTxSimulationResults() 151 block3 := bg.NextBlock([][]byte{simRes}) 152 err = store1.AddBlock(block3) 153 testutil.AssertNoError(t, err, "") 154 err = env.testHistoryDB.Commit(block3) 155 testutil.AssertNoError(t, err, "") 156 t.Logf("Inserted all 3 blocks") 157 158 qhistory, err := env.testHistoryDB.NewHistoryQueryExecutor(store1) 159 testutil.AssertNoError(t, err, "Error upon NewHistoryQueryExecutor") 160 161 itr, err2 := qhistory.GetHistoryForKey("ns1", "key7") 162 testutil.AssertNoError(t, err2, "Error upon GetHistoryForKey()") 163 164 count := 0 165 for { 166 kmod, _ := itr.Next() 167 if kmod == nil { 168 break 169 } 170 txid := kmod.(*queryresult.KeyModification).TxId 171 retrievedValue := kmod.(*queryresult.KeyModification).Value 172 retrievedTimestamp := kmod.(*queryresult.KeyModification).Timestamp 173 retrievedIsDelete := kmod.(*queryresult.KeyModification).IsDelete 174 t.Logf("Retrieved history record for key=key7 at TxId=%s with value %v and timestamp %v", 175 txid, retrievedValue, retrievedTimestamp) 176 count++ 177 if count != 4 { 178 expectedValue := []byte("value" + strconv.Itoa(count)) 179 testutil.AssertEquals(t, retrievedValue, expectedValue) 180 testutil.AssertNotEquals(t, retrievedTimestamp, nil) 181 testutil.AssertEquals(t, retrievedIsDelete, false) 182 } else { 183 testutil.AssertEquals(t, retrievedValue, nil) 184 testutil.AssertNotEquals(t, retrievedTimestamp, nil) 185 testutil.AssertEquals(t, retrievedIsDelete, true) 186 } 187 } 188 testutil.AssertEquals(t, count, 4) 189 } 190 191 func TestHistoryForInvalidTran(t *testing.T) { 192 193 env := NewTestHistoryEnv(t) 194 defer env.cleanup() 195 provider := env.testBlockStorageEnv.provider 196 ledger1id := "ledger1" 197 store1, err := provider.OpenBlockStore(ledger1id) 198 testutil.AssertNoError(t, err, "Error upon provider.OpenBlockStore()") 199 defer store1.Shutdown() 200 201 bg, gb := testutil.NewBlockGenerator(t, ledger1id, false) 202 testutil.AssertNoError(t, store1.AddBlock(gb), "") 203 testutil.AssertNoError(t, env.testHistoryDB.Commit(gb), "") 204 205 //block1 206 simulator, _ := env.txmgr.NewTxSimulator() 207 value1 := []byte("value1") 208 simulator.SetState("ns1", "key7", value1) 209 simulator.Done() 210 simRes, _ := simulator.GetTxSimulationResults() 211 block1 := bg.NextBlock([][]byte{simRes}) 212 213 //for this invalid tran test, set the transaction to invalid 214 txsFilter := util.TxValidationFlags(block1.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) 215 txsFilter.SetFlag(0, peer.TxValidationCode_INVALID_OTHER_REASON) 216 block1.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter 217 218 err = store1.AddBlock(block1) 219 testutil.AssertNoError(t, err, "") 220 err = env.testHistoryDB.Commit(block1) 221 testutil.AssertNoError(t, err, "") 222 223 qhistory, err := env.testHistoryDB.NewHistoryQueryExecutor(store1) 224 testutil.AssertNoError(t, err, "Error upon NewHistoryQueryExecutor") 225 226 itr, err2 := qhistory.GetHistoryForKey("ns1", "key7") 227 testutil.AssertNoError(t, err2, "Error upon GetHistoryForKey()") 228 229 // test that there are no history values, since the tran was marked as invalid 230 kmod, _ := itr.Next() 231 testutil.AssertNil(t, kmod) 232 } 233 234 //TestSavepoint tests that save points get written after each block and get returned via GetBlockNumfromSavepoint 235 func TestHistoryDisabled(t *testing.T) { 236 237 env := NewTestHistoryEnv(t) 238 defer env.cleanup() 239 240 viper.Set("ledger.history.enableHistoryDatabase", "false") 241 242 //no need to pass blockstore into history executore, it won't be used in this test 243 qhistory, err := env.testHistoryDB.NewHistoryQueryExecutor(nil) 244 testutil.AssertNoError(t, err, "Error upon NewHistoryQueryExecutor") 245 246 _, err2 := qhistory.GetHistoryForKey("ns1", "key7") 247 testutil.AssertError(t, err2, "Error should have been returned for GetHistoryForKey() when history disabled") 248 } 249 250 //TestGenesisBlockNoError tests that Genesis blocks are ignored by history processing 251 // since we only persist history of chaincode key writes 252 func TestGenesisBlockNoError(t *testing.T) { 253 254 env := NewTestHistoryEnv(t) 255 defer env.cleanup() 256 257 block, err := configtxtest.MakeGenesisBlock("test_chainid") 258 testutil.AssertNoError(t, err, "") 259 260 err = env.testHistoryDB.Commit(block) 261 testutil.AssertNoError(t, err, "") 262 }