github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/common/ledger/util/leveldbhelper/leveldb_provider_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package leveldbhelper
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"testing"
    13  
    14  	"github.com/hyperledger/fabric/common/ledger/dataformat"
    15  
    16  	"github.com/hyperledger/fabric/common/flogging"
    17  	"github.com/stretchr/testify/assert"
    18  )
    19  
    20  func TestMain(m *testing.M) {
    21  	flogging.ActivateSpec("leveldbhelper=debug")
    22  	os.Exit(m.Run())
    23  }
    24  
    25  func TestDBBasicWriteAndReads(t *testing.T) {
    26  	testDBBasicWriteAndReads(t, "db1", "db2", "")
    27  }
    28  
    29  func TestIterator(t *testing.T) {
    30  	env := newTestProviderEnv(t, testDBPath)
    31  	defer env.cleanup()
    32  	p := env.provider
    33  
    34  	db1 := p.GetDBHandle("db1")
    35  	db2 := p.GetDBHandle("db2")
    36  	db3 := p.GetDBHandle("db3")
    37  	for i := 0; i < 20; i++ {
    38  		db1.Put([]byte(createTestKey(i)), []byte(createTestValue("db1", i)), false)
    39  		db2.Put([]byte(createTestKey(i)), []byte(createTestValue("db2", i)), false)
    40  		db3.Put([]byte(createTestKey(i)), []byte(createTestValue("db3", i)), false)
    41  	}
    42  
    43  	itr1 := db2.GetIterator([]byte(createTestKey(2)), []byte(createTestKey(4)))
    44  	defer itr1.Release()
    45  	checkItrResults(t, itr1, createTestKeys(2, 3), createTestValues("db2", 2, 3))
    46  
    47  	itr2 := db2.GetIterator([]byte(createTestKey(2)), nil)
    48  	defer itr2.Release()
    49  	checkItrResults(t, itr2, createTestKeys(2, 19), createTestValues("db2", 2, 19))
    50  
    51  	itr3 := db2.GetIterator(nil, nil)
    52  	defer itr3.Release()
    53  	checkItrResults(t, itr3, createTestKeys(0, 19), createTestValues("db2", 0, 19))
    54  }
    55  
    56  func TestBatchedUpdates(t *testing.T) {
    57  	env := newTestProviderEnv(t, testDBPath)
    58  	defer env.cleanup()
    59  	p := env.provider
    60  
    61  	db1 := p.GetDBHandle("db1")
    62  	db2 := p.GetDBHandle("db2")
    63  
    64  	dbs := []*DBHandle{db1, db2}
    65  	for _, db := range dbs {
    66  		batch := NewUpdateBatch()
    67  		batch.Put([]byte("key1"), []byte("value1"))
    68  		batch.Put([]byte("key2"), []byte("value2"))
    69  		batch.Put([]byte("key3"), []byte("value3"))
    70  		db.WriteBatch(batch, true)
    71  	}
    72  
    73  	for _, db := range dbs {
    74  		batch := NewUpdateBatch()
    75  		batch.Delete([]byte("key2"))
    76  		db.WriteBatch(batch, true)
    77  	}
    78  
    79  	for _, db := range dbs {
    80  		val1, _ := db.Get([]byte("key1"))
    81  		assert.Equal(t, "value1", string(val1))
    82  
    83  		val2, err2 := db.Get([]byte("key2"))
    84  		assert.NoError(t, err2, "")
    85  		assert.Nil(t, val2)
    86  
    87  		val3, _ := db.Get([]byte("key3"))
    88  		assert.Equal(t, "value3", string(val3))
    89  	}
    90  }
    91  
    92  func TestFormatCheck(t *testing.T) {
    93  	testCases := []struct {
    94  		dataFormat     string
    95  		dataExists     bool
    96  		expectedFormat string
    97  		expectedErr    *dataformat.ErrVersionMismatch
    98  	}{
    99  		{
   100  			dataFormat:     "",
   101  			dataExists:     true,
   102  			expectedFormat: "",
   103  			expectedErr:    nil,
   104  		},
   105  		{
   106  			dataFormat:     "",
   107  			dataExists:     false,
   108  			expectedFormat: "",
   109  			expectedErr:    nil,
   110  		},
   111  		{
   112  			dataFormat:     "",
   113  			dataExists:     false,
   114  			expectedFormat: "2.0",
   115  			expectedErr:    nil,
   116  		},
   117  		{
   118  			dataFormat:     "",
   119  			dataExists:     true,
   120  			expectedFormat: "2.0",
   121  			expectedErr:    &dataformat.ErrVersionMismatch{Version: "", ExpectedVersion: "2.0"},
   122  		},
   123  		{
   124  			dataFormat:     "2.0",
   125  			dataExists:     true,
   126  			expectedFormat: "2.0",
   127  			expectedErr:    nil,
   128  		},
   129  		{
   130  			dataFormat:     "2.0",
   131  			dataExists:     true,
   132  			expectedFormat: "3.0",
   133  			expectedErr:    &dataformat.ErrVersionMismatch{Version: "2.0", ExpectedVersion: "3.0"},
   134  		},
   135  	}
   136  
   137  	for i, testCase := range testCases {
   138  		t.Run(
   139  			fmt.Sprintf("testCase %d", i),
   140  			func(t *testing.T) {
   141  				testFormatCheck(t, testCase.dataFormat, testCase.expectedFormat, testCase.dataExists, testCase.expectedErr)
   142  			})
   143  	}
   144  }
   145  
   146  func testFormatCheck(t *testing.T, dataFormat, expectedFormat string, dataExists bool, expectedErr *dataformat.ErrVersionMismatch) {
   147  	assert.NoError(t, os.RemoveAll(testDBPath))
   148  	defer func() {
   149  		assert.NoError(t, os.RemoveAll(testDBPath))
   150  	}()
   151  
   152  	// setup test pre-conditions (create a db with dbformat)
   153  	p, err := NewProvider(&Conf{DBPath: testDBPath, ExpectedFormatVersion: dataFormat})
   154  	assert.NoError(t, err)
   155  	f, err := p.GetDataFormat()
   156  	assert.NoError(t, err)
   157  	assert.Equal(t, dataFormat, f)
   158  	if dataExists {
   159  		assert.NoError(t, p.GetDBHandle("testdb").Put([]byte("key"), []byte("value"), true))
   160  	}
   161  
   162  	// close and reopen with new conf
   163  	p.Close()
   164  	p, err = NewProvider(&Conf{DBPath: testDBPath, ExpectedFormatVersion: expectedFormat})
   165  	if expectedErr != nil {
   166  		expectedErr.DBInfo = fmt.Sprintf("leveldb at [%s]", testDBPath)
   167  		assert.Equal(t, err, expectedErr)
   168  		return
   169  	}
   170  	assert.NoError(t, err)
   171  	f, err = p.GetDataFormat()
   172  	assert.NoError(t, err)
   173  	assert.Equal(t, expectedFormat, f)
   174  }
   175  
   176  func testDBBasicWriteAndReads(t *testing.T, dbNames ...string) {
   177  	env := newTestProviderEnv(t, testDBPath)
   178  	defer env.cleanup()
   179  	p := env.provider
   180  
   181  	for _, dbName := range dbNames {
   182  		db := p.GetDBHandle(dbName)
   183  		db.Put([]byte("key1"), []byte("value1_"+dbName), false)
   184  		db.Put([]byte("key2"), []byte("value2_"+dbName), false)
   185  		db.Put([]byte("key3"), []byte("value3_"+dbName), false)
   186  	}
   187  
   188  	for _, dbName := range dbNames {
   189  		db := p.GetDBHandle(dbName)
   190  		val, err := db.Get([]byte("key1"))
   191  		assert.NoError(t, err, "")
   192  		assert.Equal(t, []byte("value1_"+dbName), val)
   193  
   194  		val, err = db.Get([]byte("key2"))
   195  		assert.NoError(t, err, "")
   196  		assert.Equal(t, []byte("value2_"+dbName), val)
   197  
   198  		val, err = db.Get([]byte("key3"))
   199  		assert.NoError(t, err, "")
   200  		assert.Equal(t, []byte("value3_"+dbName), val)
   201  	}
   202  
   203  	for _, dbName := range dbNames {
   204  		db := p.GetDBHandle(dbName)
   205  		assert.NoError(t, db.Delete([]byte("key1"), false), "")
   206  		val, err := db.Get([]byte("key1"))
   207  		assert.NoError(t, err, "")
   208  		assert.Nil(t, val)
   209  
   210  		assert.NoError(t, db.Delete([]byte("key2"), false), "")
   211  		val, err = db.Get([]byte("key2"))
   212  		assert.NoError(t, err, "")
   213  		assert.Nil(t, val)
   214  
   215  		assert.NoError(t, db.Delete([]byte("key3"), false), "")
   216  		val, err = db.Get([]byte("key3"))
   217  		assert.NoError(t, err, "")
   218  		assert.Nil(t, val)
   219  	}
   220  }
   221  
   222  func checkItrResults(t *testing.T, itr *Iterator, expectedKeys []string, expectedValues []string) {
   223  	defer itr.Release()
   224  	var actualKeys []string
   225  	var actualValues []string
   226  	for itr.Next(); itr.Valid(); itr.Next() {
   227  		actualKeys = append(actualKeys, string(itr.Key()))
   228  		actualValues = append(actualValues, string(itr.Value()))
   229  	}
   230  	assert.Equal(t, expectedKeys, actualKeys)
   231  	assert.Equal(t, expectedValues, actualValues)
   232  	assert.Equal(t, false, itr.Next())
   233  }
   234  
   235  func createTestKey(i int) string {
   236  	return fmt.Sprintf("key_%06d", i)
   237  }
   238  
   239  func createTestValue(dbname string, i int) string {
   240  	return fmt.Sprintf("value_%s_%06d", dbname, i)
   241  }
   242  
   243  func createTestKeys(start int, end int) []string {
   244  	var keys []string
   245  	for i := start; i <= end; i++ {
   246  		keys = append(keys, createTestKey(i))
   247  	}
   248  	return keys
   249  }
   250  
   251  func createTestValues(dbname string, start int, end int) []string {
   252  	var values []string
   253  	for i := start; i <= end; i++ {
   254  		values = append(values, createTestValue(dbname, i))
   255  	}
   256  	return values
   257  }