github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/confighistory/db_helper_test.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package confighistory
     8  
     9  import (
    10  	"bytes"
    11  	"math"
    12  	"os"
    13  	"testing"
    14  
    15  	"github.com/hechain20/hechain/common/ledger/util/leveldbhelper"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestEncodeDecodeCompositeKey(t *testing.T) {
    20  	sampleKeys := []*compositeKey{
    21  		{ns: "ns0", key: "key0", blockNum: 0},
    22  		{ns: "ns1", key: "key1", blockNum: 1},
    23  		{ns: "ns2", key: "key2", blockNum: 99},
    24  		{ns: "ns3", key: "key3", blockNum: math.MaxUint64},
    25  	}
    26  	for _, k := range sampleKeys {
    27  		k1 := decodeCompositeKey(encodeCompositeKey(k.ns, k.key, k.blockNum))
    28  		require.Equal(t, k, k1)
    29  	}
    30  }
    31  
    32  func TestCompareEncodedHeight(t *testing.T) {
    33  	require.Equal(t, bytes.Compare(encodeBlockNum(20), encodeBlockNum(40)), 1)
    34  	require.Equal(t, bytes.Compare(encodeBlockNum(40), encodeBlockNum(10)), -1)
    35  }
    36  
    37  func TestQueries(t *testing.T) {
    38  	testDBPath := "/tmp/fabric/core/ledger/confighistory"
    39  	deleteTestPath(t, testDBPath)
    40  	provider, err := newDBProvider(testDBPath)
    41  	require.NoError(t, err)
    42  	defer deleteTestPath(t, testDBPath)
    43  
    44  	db := provider.getDB("ledger1")
    45  	// A query on an empty store
    46  	checkEntryAt(t, "testcase-query1", db, "ns1", "key1", 45, nil)
    47  	// test data
    48  	sampleData := []*compositeKV{
    49  		{&compositeKey{ns: "ns1", key: "key1", blockNum: 40}, []byte("val1_40")},
    50  		{&compositeKey{ns: "ns1", key: "key1", blockNum: 30}, []byte("val1_30")},
    51  		{&compositeKey{ns: "ns1", key: "key1", blockNum: 20}, []byte("val1_20")},
    52  		{&compositeKey{ns: "ns1", key: "key1", blockNum: 10}, []byte("val1_10")},
    53  		{&compositeKey{ns: "ns1", key: "key1", blockNum: 0}, []byte("val1_0")},
    54  		{&compositeKey{ns: "ns2", key: "key2", blockNum: 200}, []byte("val200")},
    55  		{&compositeKey{ns: "ns3", key: "key3", blockNum: 300}, []byte("val300")},
    56  		{&compositeKey{ns: "ns3", key: "key4", blockNum: 400}, []byte("val400")},
    57  	}
    58  	populateDBWithSampleData(t, db, sampleData)
    59  	// access most recent entry below ht=[45] - expected item is the one committed at ht = 40
    60  	checkRecentEntryBelow(t, "testcase-query2", db, "ns1", "key1", 45, sampleData[0])
    61  	checkRecentEntryBelow(t, "testcase-query3", db, "ns1", "key1", 35, sampleData[1])
    62  	checkRecentEntryBelow(t, "testcase-query4", db, "ns1", "key1", 30, sampleData[2])
    63  	checkRecentEntryBelow(t, "testcase-query5", db, "ns1", "key1", 10, sampleData[4])
    64  	checkRecentEntryBelow(t, "testcase-query6", db, "ns2", "key2", 2000, sampleData[5])
    65  	checkRecentEntryBelow(t, "testcase-query7", db, "ns2", "key2", 200, nil)
    66  	checkRecentEntryBelow(t, "testcase-query8", db, "ns3", "key3", 299, nil)
    67  
    68  	checkEntryAt(t, "testcase-query9", db, "ns1", "key1", 40, sampleData[0])
    69  	checkEntryAt(t, "testcase-query10", db, "ns1", "key1", 30, sampleData[1])
    70  	checkEntryAt(t, "testcase-query11", db, "ns1", "key1", 0, sampleData[4])
    71  	checkEntryAt(t, "testcase-query12", db, "ns1", "key1", 35, nil)
    72  	checkEntryAt(t, "testcase-query13", db, "ns1", "key1", 45, nil)
    73  
    74  	t.Run("test-iter-error-path", func(t *testing.T) {
    75  		provider.Close()
    76  		ckv, err := db.mostRecentEntryBelow(45, "ns1", "key1")
    77  		require.EqualError(t, err, "internal leveldb error while obtaining db iterator: leveldb: closed")
    78  		require.Nil(t, ckv)
    79  	})
    80  }
    81  
    82  func TestGetNamespaceIterator(t *testing.T) {
    83  	testDBPath := "/tmp/fabric/core/ledger/confighistory"
    84  	provider, err := newDBProvider(testDBPath)
    85  	require.NoError(t, err)
    86  	defer deleteTestPath(t, testDBPath)
    87  
    88  	db := provider.getDB("ledger1")
    89  	nsItr1, err := db.getNamespaceIterator("ns1")
    90  	require.NoError(t, err)
    91  	defer nsItr1.Release()
    92  	verifyNsEntries(t, nsItr1, nil)
    93  
    94  	sampleData := []*compositeKV{
    95  		{&compositeKey{ns: "ns1", key: "key1", blockNum: 40}, []byte("val1_40")}, // index 0
    96  		{&compositeKey{ns: "ns1", key: "key1", blockNum: 30}, []byte("val1_30")}, // index 1
    97  		{&compositeKey{ns: "ns1", key: "key1", blockNum: 20}, []byte("val1_20")}, // index 2
    98  		{&compositeKey{ns: "ns2", key: "key1", blockNum: 50}, []byte("val1_50")}, // index 3
    99  		{&compositeKey{ns: "ns2", key: "key1", blockNum: 20}, []byte("val1_20")}, // index 4
   100  		{&compositeKey{ns: "ns2", key: "key1", blockNum: 10}, []byte("val1_10")}, // index 5
   101  	}
   102  	populateDBWithSampleData(t, db, sampleData)
   103  
   104  	nsItr2, err := db.getNamespaceIterator("ns1")
   105  	require.NoError(t, err)
   106  	defer nsItr2.Release()
   107  	verifyNsEntries(t, nsItr2, sampleData[:3])
   108  
   109  	nsItr3, err := db.getNamespaceIterator("ns2")
   110  	require.NoError(t, err)
   111  	defer nsItr3.Release()
   112  	verifyNsEntries(t, nsItr3, sampleData[3:])
   113  
   114  	t.Run("test-iter-error-path", func(t *testing.T) {
   115  		provider.Close()
   116  		itr, err := db.getNamespaceIterator("ns1")
   117  		require.EqualError(t, err, "internal leveldb error while obtaining db iterator: leveldb: closed")
   118  		require.Nil(t, itr)
   119  	})
   120  }
   121  
   122  func verifyNsEntries(t *testing.T, nsItr *leveldbhelper.Iterator, expectedEntries []*compositeKV) {
   123  	var retrievedEntries []*compositeKV
   124  	for nsItr.Next() {
   125  		require.NoError(t, nsItr.Error())
   126  		key := decodeCompositeKey(nsItr.Key())
   127  		val := make([]byte, len(nsItr.Value()))
   128  		copy(val, nsItr.Value())
   129  		retrievedEntries = append(retrievedEntries, &compositeKV{key, val})
   130  	}
   131  	require.Equal(t, expectedEntries, retrievedEntries)
   132  }
   133  
   134  func populateDBWithSampleData(t *testing.T, db *db, sampledata []*compositeKV) {
   135  	batch := db.newBatch()
   136  	for _, data := range sampledata {
   137  		batch.add(data.ns, data.key, data.blockNum, data.value)
   138  	}
   139  	require.NoError(t, db.writeBatch(batch, true))
   140  }
   141  
   142  func checkRecentEntryBelow(t *testing.T, testcase string, db *db, ns, key string, commitHt uint64, expectedOutput *compositeKV) {
   143  	t.Run(testcase,
   144  		func(t *testing.T) {
   145  			kv, err := db.mostRecentEntryBelow(commitHt, ns, key)
   146  			require.NoError(t, err)
   147  			require.Equal(t, expectedOutput, kv)
   148  		})
   149  }
   150  
   151  func checkEntryAt(t *testing.T, testcase string, db *db, ns, key string, commitHt uint64, expectedOutput *compositeKV) {
   152  	t.Run(testcase,
   153  		func(t *testing.T) {
   154  			kv, err := db.entryAt(commitHt, ns, key)
   155  			require.NoError(t, err)
   156  			require.Equal(t, expectedOutput, kv)
   157  		})
   158  }
   159  
   160  func deleteTestPath(t *testing.T, dbPath string) {
   161  	err := os.RemoveAll(dbPath)
   162  	require.NoError(t, err)
   163  }