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  }