github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/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/osdi23p228/fabric/common/ledger/dataformat"
    15  
    16  	"github.com/osdi23p228/fabric/common/flogging"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestMain(m *testing.M) {
    22  	flogging.ActivateSpec("leveldbhelper=debug")
    23  	os.Exit(m.Run())
    24  }
    25  
    26  func TestDBBasicWriteAndReads(t *testing.T) {
    27  	testDBBasicWriteAndReads(t, "db1", "db2", "")
    28  }
    29  
    30  func TestIterator(t *testing.T) {
    31  	env := newTestProviderEnv(t, testDBPath)
    32  	defer env.cleanup()
    33  	p := env.provider
    34  
    35  	db1 := p.GetDBHandle("db1")
    36  	db2 := p.GetDBHandle("db2")
    37  	db3 := p.GetDBHandle("db3")
    38  	for i := 0; i < 20; i++ {
    39  		db1.Put([]byte(createTestKey(i)), []byte(createTestValue("db1", i)), false)
    40  		db2.Put([]byte(createTestKey(i)), []byte(createTestValue("db2", i)), false)
    41  		db3.Put([]byte(createTestKey(i)), []byte(createTestValue("db3", i)), false)
    42  	}
    43  
    44  	rangeTestCases := []struct {
    45  		startKey       []byte
    46  		endKey         []byte
    47  		expectedKeys   []string
    48  		expectedValues []string
    49  	}{
    50  		{
    51  			startKey:       []byte(createTestKey(2)),
    52  			endKey:         []byte(createTestKey(4)),
    53  			expectedKeys:   createTestKeys(2, 3),
    54  			expectedValues: createTestValues("db2", 2, 3),
    55  		},
    56  		{
    57  			startKey:       []byte(createTestKey(2)),
    58  			endKey:         nil,
    59  			expectedKeys:   createTestKeys(2, 19),
    60  			expectedValues: createTestValues("db2", 2, 19),
    61  		},
    62  		{
    63  			startKey:       nil,
    64  			endKey:         nil,
    65  			expectedKeys:   createTestKeys(0, 19),
    66  			expectedValues: createTestValues("db2", 0, 19),
    67  		},
    68  	}
    69  
    70  	for i, testCase := range rangeTestCases {
    71  		t.Run(
    72  			fmt.Sprintf("range testCase %d", i),
    73  			func(t *testing.T) {
    74  				itr, err := db2.GetIterator(testCase.startKey, testCase.endKey)
    75  				require.NoError(t, err)
    76  				defer itr.Release()
    77  				checkItrResults(t, itr, testCase.expectedKeys, testCase.expectedValues)
    78  			},
    79  		)
    80  	}
    81  
    82  	rangeWithSeekTestCases := []struct {
    83  		startKey          []byte
    84  		endKey            []byte
    85  		seekToKey         []byte
    86  		itrAtKeyAfterSeek []byte
    87  		expectedKeys      []string
    88  		expectedValues    []string
    89  	}{
    90  		{
    91  			startKey:          nil,
    92  			endKey:            nil,
    93  			seekToKey:         []byte(createTestKey(10)),
    94  			itrAtKeyAfterSeek: []byte(createTestKey(10)),
    95  			expectedKeys:      createTestKeys(11, 19),
    96  			expectedValues:    createTestValues("db1", 11, 19),
    97  		},
    98  		{
    99  			startKey:          []byte(createTestKey(11)),
   100  			endKey:            nil,
   101  			seekToKey:         []byte(createTestKey(5)),
   102  			itrAtKeyAfterSeek: []byte(createTestKey(11)),
   103  			expectedKeys:      createTestKeys(12, 19),
   104  			expectedValues:    createTestValues("db1", 12, 19),
   105  		},
   106  		{
   107  			startKey:          nil,
   108  			endKey:            nil,
   109  			seekToKey:         []byte(createTestKey(19)),
   110  			itrAtKeyAfterSeek: []byte(createTestKey(19)),
   111  			expectedKeys:      nil,
   112  			expectedValues:    nil,
   113  		},
   114  	}
   115  
   116  	for i, testCase := range rangeWithSeekTestCases {
   117  		t.Run(
   118  			fmt.Sprintf("range with seek testCase %d", i),
   119  			func(t *testing.T) {
   120  				itr, err := db1.GetIterator(testCase.startKey, testCase.endKey)
   121  				require.NoError(t, err)
   122  				defer itr.Release()
   123  				require.True(t, itr.Seek(testCase.seekToKey))
   124  				require.Equal(t, testCase.itrAtKeyAfterSeek, itr.Key())
   125  				checkItrResults(t, itr, testCase.expectedKeys, testCase.expectedValues)
   126  			},
   127  		)
   128  	}
   129  
   130  	t.Run("test-first-prev", func(t *testing.T) {
   131  		itr, err := db1.GetIterator(nil, nil)
   132  		require.NoError(t, err)
   133  		defer itr.Release()
   134  		require.True(t, itr.Seek([]byte(createTestKey(10))))
   135  		require.Equal(t, []byte(createTestKey(10)), itr.Key())
   136  		checkItrResults(t, itr, createTestKeys(11, 19), createTestValues("db1", 11, 19))
   137  
   138  		require.True(t, itr.First())
   139  		require.True(t, itr.Seek([]byte(createTestKey(10))))
   140  		require.Equal(t, []byte(createTestKey(10)), itr.Key())
   141  		require.True(t, itr.Prev())
   142  		checkItrResults(t, itr, createTestKeys(10, 19), createTestValues("db1", 10, 19))
   143  
   144  		require.True(t, itr.First())
   145  		require.False(t, itr.Seek([]byte(createTestKey(20))))
   146  		require.True(t, itr.First())
   147  		checkItrResults(t, itr, createTestKeys(1, 19), createTestValues("db1", 1, 19))
   148  
   149  		require.True(t, itr.First())
   150  		require.False(t, itr.Prev())
   151  		checkItrResults(t, itr, createTestKeys(0, 19), createTestValues("db1", 0, 19))
   152  
   153  		require.True(t, itr.First())
   154  		require.True(t, itr.Last())
   155  		checkItrResults(t, itr, nil, nil)
   156  	})
   157  
   158  	t.Run("test-error-path", func(t *testing.T) {
   159  		env.provider.Close()
   160  		itr, err := db1.GetIterator(nil, nil)
   161  		require.EqualError(t, err, "internal leveldb error while obtaining db iterator: leveldb: closed")
   162  		require.Nil(t, itr)
   163  	})
   164  }
   165  
   166  func TestBatchedUpdates(t *testing.T) {
   167  	env := newTestProviderEnv(t, testDBPath)
   168  	defer env.cleanup()
   169  	p := env.provider
   170  
   171  	db1 := p.GetDBHandle("db1")
   172  	db2 := p.GetDBHandle("db2")
   173  
   174  	dbs := []*DBHandle{db1, db2}
   175  	for _, db := range dbs {
   176  		batch := db.NewUpdateBatch()
   177  		batch.Put([]byte("key1"), []byte("value1"))
   178  		batch.Put([]byte("key2"), []byte("value2"))
   179  		batch.Put([]byte("key3"), []byte("value3"))
   180  		db.WriteBatch(batch, true)
   181  	}
   182  
   183  	for _, db := range dbs {
   184  		batch := db.NewUpdateBatch()
   185  		batch.Delete([]byte("key2"))
   186  		db.WriteBatch(batch, true)
   187  	}
   188  
   189  	for _, db := range dbs {
   190  		val1, _ := db.Get([]byte("key1"))
   191  		assert.Equal(t, "value1", string(val1))
   192  
   193  		val2, err2 := db.Get([]byte("key2"))
   194  		assert.NoError(t, err2, "")
   195  		assert.Nil(t, val2)
   196  
   197  		val3, _ := db.Get([]byte("key3"))
   198  		assert.Equal(t, "value3", string(val3))
   199  	}
   200  }
   201  
   202  func TestDeleteAll(t *testing.T) {
   203  	env := newTestProviderEnv(t, testDBPath)
   204  	defer env.cleanup()
   205  	p := env.provider
   206  
   207  	db1 := p.GetDBHandle("db1")
   208  	db2 := p.GetDBHandle("db2")
   209  	db3 := p.GetDBHandle("db3")
   210  	db4 := p.GetDBHandle("db4")
   211  	for i := 0; i < 20; i++ {
   212  		db1.Put([]byte(createTestKey(i)), []byte(createTestValue("db1", i)), false)
   213  		db2.Put([]byte(createTestKey(i)), []byte(createTestValue("db2", i)), false)
   214  		db3.Put([]byte(createTestKey(i)), []byte(createTestValue("db3", i)), false)
   215  	}
   216  	// db4 is used to test remove when multiple batches are needed (each long key has 125 bytes)
   217  	for i := 0; i < 10000; i++ {
   218  		db4.Put([]byte(createTestLongKey(i)), []byte(createTestValue("db4", i)), false)
   219  	}
   220  
   221  	expectedSetup := []struct {
   222  		db             *DBHandle
   223  		expectedKeys   []string
   224  		expectedValues []string
   225  	}{
   226  		{
   227  			db:             db1,
   228  			expectedKeys:   createTestKeys(0, 19),
   229  			expectedValues: createTestValues("db1", 0, 19),
   230  		},
   231  		{
   232  			db:             db2,
   233  			expectedKeys:   createTestKeys(0, 19),
   234  			expectedValues: createTestValues("db2", 0, 19),
   235  		},
   236  		{
   237  			db:             db3,
   238  			expectedKeys:   createTestKeys(0, 19),
   239  			expectedValues: createTestValues("db3", 0, 19),
   240  		},
   241  		{
   242  			db:             db4,
   243  			expectedKeys:   createTestLongKeys(0, 9999),
   244  			expectedValues: createTestValues("db4", 0, 9999),
   245  		},
   246  	}
   247  
   248  	for _, dbSetup := range expectedSetup {
   249  		itr, err := dbSetup.db.GetIterator(nil, nil)
   250  		require.NoError(t, err)
   251  		checkItrResults(t, itr, dbSetup.expectedKeys, dbSetup.expectedValues)
   252  		itr.Release()
   253  	}
   254  
   255  	require.NoError(t, db1.DeleteAll())
   256  	require.NoError(t, db4.DeleteAll())
   257  
   258  	expectedResults := []struct {
   259  		db             *DBHandle
   260  		expectedKeys   []string
   261  		expectedValues []string
   262  	}{
   263  		{
   264  			db:             db1,
   265  			expectedKeys:   nil,
   266  			expectedValues: nil,
   267  		},
   268  		{
   269  			db:             db2,
   270  			expectedKeys:   createTestKeys(0, 19),
   271  			expectedValues: createTestValues("db2", 0, 19),
   272  		},
   273  		{
   274  			db:             db3,
   275  			expectedKeys:   createTestKeys(0, 19),
   276  			expectedValues: createTestValues("db3", 0, 19),
   277  		},
   278  		{
   279  			db:             db4,
   280  			expectedKeys:   nil,
   281  			expectedValues: nil,
   282  		},
   283  	}
   284  
   285  	for _, result := range expectedResults {
   286  		itr, err := result.db.GetIterator(nil, nil)
   287  		require.NoError(t, err)
   288  		checkItrResults(t, itr, result.expectedKeys, result.expectedValues)
   289  		itr.Release()
   290  	}
   291  
   292  	// negative test
   293  	p.Close()
   294  	require.EqualError(t, db2.DeleteAll(), "internal leveldb error while obtaining db iterator: leveldb: closed")
   295  }
   296  
   297  func TestFormatCheck(t *testing.T) {
   298  	testCases := []struct {
   299  		dataFormat     string
   300  		dataExists     bool
   301  		expectedFormat string
   302  		expectedErr    *dataformat.ErrFormatMismatch
   303  	}{
   304  		{
   305  			dataFormat:     "",
   306  			dataExists:     true,
   307  			expectedFormat: "",
   308  			expectedErr:    nil,
   309  		},
   310  		{
   311  			dataFormat:     "",
   312  			dataExists:     false,
   313  			expectedFormat: "",
   314  			expectedErr:    nil,
   315  		},
   316  		{
   317  			dataFormat:     "",
   318  			dataExists:     false,
   319  			expectedFormat: "2.0",
   320  			expectedErr:    nil,
   321  		},
   322  		{
   323  			dataFormat:     "",
   324  			dataExists:     true,
   325  			expectedFormat: "2.0",
   326  			expectedErr:    &dataformat.ErrFormatMismatch{Format: "", ExpectedFormat: "2.0"},
   327  		},
   328  		{
   329  			dataFormat:     "2.0",
   330  			dataExists:     true,
   331  			expectedFormat: "2.0",
   332  			expectedErr:    nil,
   333  		},
   334  		{
   335  			dataFormat:     "2.0",
   336  			dataExists:     true,
   337  			expectedFormat: "3.0",
   338  			expectedErr:    &dataformat.ErrFormatMismatch{Format: "2.0", ExpectedFormat: "3.0"},
   339  		},
   340  	}
   341  
   342  	for i, testCase := range testCases {
   343  		t.Run(
   344  			fmt.Sprintf("testCase %d", i),
   345  			func(t *testing.T) {
   346  				testFormatCheck(t, testCase.dataFormat, testCase.expectedFormat, testCase.dataExists, testCase.expectedErr)
   347  			})
   348  	}
   349  }
   350  
   351  func TestClose(t *testing.T) {
   352  	env := newTestProviderEnv(t, testDBPath)
   353  	defer env.cleanup()
   354  	p := env.provider
   355  
   356  	db1 := p.GetDBHandle("db1")
   357  	db2 := p.GetDBHandle("db2")
   358  
   359  	expectedDBHandles := map[string]*DBHandle{
   360  		"db1": db1,
   361  		"db2": db2,
   362  	}
   363  	require.Equal(t, expectedDBHandles, p.dbHandles)
   364  
   365  	db1.Close()
   366  	expectedDBHandles = map[string]*DBHandle{
   367  		"db2": db2,
   368  	}
   369  	require.Equal(t, expectedDBHandles, p.dbHandles)
   370  
   371  	db2.Close()
   372  	require.Equal(t, map[string]*DBHandle{}, p.dbHandles)
   373  }
   374  
   375  func testFormatCheck(t *testing.T, dataFormat, expectedFormat string, dataExists bool, expectedErr *dataformat.ErrFormatMismatch) {
   376  	assert.NoError(t, os.RemoveAll(testDBPath))
   377  	defer func() {
   378  		assert.NoError(t, os.RemoveAll(testDBPath))
   379  	}()
   380  
   381  	// setup test pre-conditions (create a db with dbformat)
   382  	p, err := NewProvider(&Conf{DBPath: testDBPath, ExpectedFormat: dataFormat})
   383  	assert.NoError(t, err)
   384  	f, err := p.GetDataFormat()
   385  	assert.NoError(t, err)
   386  	assert.Equal(t, dataFormat, f)
   387  	if dataExists {
   388  		assert.NoError(t, p.GetDBHandle("testdb").Put([]byte("key"), []byte("value"), true))
   389  	}
   390  
   391  	// close and reopen with new conf
   392  	p.Close()
   393  	p, err = NewProvider(&Conf{DBPath: testDBPath, ExpectedFormat: expectedFormat})
   394  	if expectedErr != nil {
   395  		expectedErr.DBInfo = fmt.Sprintf("leveldb at [%s]", testDBPath)
   396  		assert.Equal(t, err, expectedErr)
   397  		return
   398  	}
   399  	assert.NoError(t, err)
   400  	f, err = p.GetDataFormat()
   401  	assert.NoError(t, err)
   402  	assert.Equal(t, expectedFormat, f)
   403  }
   404  
   405  func testDBBasicWriteAndReads(t *testing.T, dbNames ...string) {
   406  	env := newTestProviderEnv(t, testDBPath)
   407  	defer env.cleanup()
   408  	p := env.provider
   409  
   410  	for _, dbName := range dbNames {
   411  		db := p.GetDBHandle(dbName)
   412  		db.Put([]byte("key1"), []byte("value1_"+dbName), false)
   413  		db.Put([]byte("key2"), []byte("value2_"+dbName), false)
   414  		db.Put([]byte("key3"), []byte("value3_"+dbName), false)
   415  	}
   416  
   417  	for _, dbName := range dbNames {
   418  		db := p.GetDBHandle(dbName)
   419  		val, err := db.Get([]byte("key1"))
   420  		assert.NoError(t, err, "")
   421  		assert.Equal(t, []byte("value1_"+dbName), val)
   422  
   423  		val, err = db.Get([]byte("key2"))
   424  		assert.NoError(t, err, "")
   425  		assert.Equal(t, []byte("value2_"+dbName), val)
   426  
   427  		val, err = db.Get([]byte("key3"))
   428  		assert.NoError(t, err, "")
   429  		assert.Equal(t, []byte("value3_"+dbName), val)
   430  	}
   431  
   432  	for _, dbName := range dbNames {
   433  		db := p.GetDBHandle(dbName)
   434  		assert.NoError(t, db.Delete([]byte("key1"), false), "")
   435  		val, err := db.Get([]byte("key1"))
   436  		assert.NoError(t, err, "")
   437  		assert.Nil(t, val)
   438  
   439  		assert.NoError(t, db.Delete([]byte("key2"), false), "")
   440  		val, err = db.Get([]byte("key2"))
   441  		assert.NoError(t, err, "")
   442  		assert.Nil(t, val)
   443  
   444  		assert.NoError(t, db.Delete([]byte("key3"), false), "")
   445  		val, err = db.Get([]byte("key3"))
   446  		assert.NoError(t, err, "")
   447  		assert.Nil(t, val)
   448  	}
   449  }
   450  
   451  func checkItrResults(t *testing.T, itr *Iterator, expectedKeys []string, expectedValues []string) {
   452  	var actualKeys []string
   453  	var actualValues []string
   454  	for itr.Next(); itr.Valid(); itr.Next() {
   455  		actualKeys = append(actualKeys, string(itr.Key()))
   456  		actualValues = append(actualValues, string(itr.Value()))
   457  	}
   458  	assert.Equal(t, expectedKeys, actualKeys)
   459  	assert.Equal(t, expectedValues, actualValues)
   460  	assert.Equal(t, false, itr.Next())
   461  }
   462  
   463  func createTestKey(i int) string {
   464  	return fmt.Sprintf("key_%06d", i)
   465  }
   466  
   467  const padding100 = "_0123456789_0123456789_0123456789_0123456789_0123456789_0123456789_0123456789_0123456789_0123456789_"
   468  
   469  func createTestLongKey(i int) string {
   470  	return fmt.Sprintf("key_%s_%10d", padding100, i)
   471  }
   472  
   473  func createTestValue(dbname string, i int) string {
   474  	return fmt.Sprintf("value_%s_%06d", dbname, i)
   475  }
   476  
   477  func createTestKeys(start int, end int) []string {
   478  	var keys []string
   479  	for i := start; i <= end; i++ {
   480  		keys = append(keys, createTestKey(i))
   481  	}
   482  	return keys
   483  }
   484  
   485  func createTestLongKeys(start int, end int) []string {
   486  	var keys []string
   487  	for i := start; i <= end; i++ {
   488  		keys = append(keys, createTestLongKey(i))
   489  	}
   490  	return keys
   491  }
   492  
   493  func createTestValues(dbname string, start int, end int) []string {
   494  	var values []string
   495  	for i := start; i <= end; i++ {
   496  		values = append(values, createTestValue(dbname, i))
   497  	}
   498  	return values
   499  }