github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/common/ledger/util/leveldbhelper/leveldb_helper_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  	"path/filepath"
    13  	"testing"
    14  
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  	"github.com/syndtr/goleveldb/leveldb"
    18  )
    19  
    20  func TestLevelDBHelperWriteWithoutOpen(t *testing.T) {
    21  	env := newTestDBEnv(t, testDBPath)
    22  	defer env.cleanup()
    23  	db := env.db
    24  	defer func() {
    25  		if recover() == nil {
    26  			t.Fatalf("A panic is expected when writing to db before opening")
    27  		}
    28  	}()
    29  	db.Put([]byte("key"), []byte("value"), false)
    30  }
    31  
    32  func TestLevelDBHelperReadWithoutOpen(t *testing.T) {
    33  	env := newTestDBEnv(t, testDBPath)
    34  	defer env.cleanup()
    35  	db := env.db
    36  	defer func() {
    37  		if recover() == nil {
    38  			t.Fatalf("A panic is expected when writing to db before opening")
    39  		}
    40  	}()
    41  	db.Get([]byte("key"))
    42  }
    43  
    44  func TestLevelDBHelper(t *testing.T) {
    45  	env := newTestDBEnv(t, testDBPath)
    46  	//defer env.cleanup()
    47  	db := env.db
    48  
    49  	db.Open()
    50  	// second time open should not have any side effect
    51  	db.Open()
    52  	IsEmpty, err := db.IsEmpty()
    53  	assert.NoError(t, err)
    54  	assert.True(t, IsEmpty)
    55  	db.Put([]byte("key1"), []byte("value1"), false)
    56  	db.Put([]byte("key2"), []byte("value2"), true)
    57  	db.Put([]byte("key3"), []byte("value3"), true)
    58  
    59  	val, _ := db.Get([]byte("key2"))
    60  	assert.Equal(t, "value2", string(val))
    61  
    62  	db.Delete([]byte("key1"), false)
    63  	db.Delete([]byte("key2"), true)
    64  
    65  	val1, err1 := db.Get([]byte("key1"))
    66  	assert.NoError(t, err1, "")
    67  	assert.Equal(t, "", string(val1))
    68  
    69  	val2, err2 := db.Get([]byte("key2"))
    70  	assert.NoError(t, err2, "")
    71  	assert.Equal(t, "", string(val2))
    72  
    73  	db.Close()
    74  	// second time Close should not have any side effect
    75  	db.Close()
    76  
    77  	_, err = db.IsEmpty()
    78  	require.Error(t, err)
    79  
    80  	val3, err3 := db.Get([]byte("key3"))
    81  	assert.Error(t, err3)
    82  	assert.Equal(t, "", string(val3))
    83  
    84  	db.Open()
    85  	IsEmpty, err = db.IsEmpty()
    86  	assert.NoError(t, err)
    87  	assert.False(t, IsEmpty)
    88  
    89  	batch := &leveldb.Batch{}
    90  	batch.Put([]byte("key1"), []byte("value1"))
    91  	batch.Put([]byte("key2"), []byte("value2"))
    92  	batch.Delete([]byte("key3"))
    93  	db.WriteBatch(batch, true)
    94  
    95  	val1, err1 = db.Get([]byte("key1"))
    96  	assert.NoError(t, err1, "")
    97  	assert.Equal(t, "value1", string(val1))
    98  
    99  	val2, err2 = db.Get([]byte("key2"))
   100  	assert.NoError(t, err2, "")
   101  	assert.Equal(t, "value2", string(val2))
   102  
   103  	val3, err3 = db.Get([]byte("key3"))
   104  	assert.NoError(t, err3, "")
   105  	assert.Equal(t, "", string(val3))
   106  
   107  	keys := []string{}
   108  	itr := db.GetIterator(nil, nil)
   109  	for itr.Next() {
   110  		keys = append(keys, string(itr.Key()))
   111  	}
   112  	assert.Equal(t, []string{"key1", "key2"}, keys)
   113  }
   114  
   115  func TestFileLock(t *testing.T) {
   116  	// create 1st fileLock manager
   117  	fileLockPath := testDBPath + "/fileLock"
   118  	fileLock1 := NewFileLock(fileLockPath)
   119  	assert.Nil(t, fileLock1.db)
   120  	assert.Equal(t, fileLock1.filePath, fileLockPath)
   121  
   122  	// acquire the file lock using the fileLock manager 1
   123  	err := fileLock1.Lock()
   124  	assert.NoError(t, err)
   125  	assert.NotNil(t, fileLock1.db)
   126  
   127  	// create 2nd fileLock manager
   128  	fileLock2 := NewFileLock(fileLockPath)
   129  	assert.Nil(t, fileLock2.db)
   130  	assert.Equal(t, fileLock2.filePath, fileLockPath)
   131  
   132  	// try to acquire the file lock again using the fileLock2
   133  	// would result in an error
   134  	err = fileLock2.Lock()
   135  	expectedErr := fmt.Sprintf("lock is already acquired on file %s", fileLockPath)
   136  	assert.EqualError(t, err, expectedErr)
   137  	assert.Nil(t, fileLock2.db)
   138  
   139  	// release the file lock acquired using fileLock1
   140  	fileLock1.Unlock()
   141  	assert.Nil(t, fileLock1.db)
   142  
   143  	// As the fileLock1 has released the lock,
   144  	// the fileLock2 can acquire the lock.
   145  	err = fileLock2.Lock()
   146  	assert.NoError(t, err)
   147  	assert.NotNil(t, fileLock2.db)
   148  
   149  	// release the file lock acquired using fileLock 2
   150  	fileLock2.Unlock()
   151  	assert.Nil(t, fileLock1.db)
   152  
   153  	// unlock can be called multiple times and it is safe
   154  	fileLock2.Unlock()
   155  	assert.Nil(t, fileLock1.db)
   156  
   157  	// cleanup
   158  	assert.NoError(t, os.RemoveAll(fileLockPath))
   159  }
   160  
   161  func TestCreateDBInEmptyDir(t *testing.T) {
   162  	assert.NoError(t, os.RemoveAll(testDBPath), "")
   163  	assert.NoError(t, os.MkdirAll(testDBPath, 0775), "")
   164  	db := CreateDB(&Conf{DBPath: testDBPath})
   165  	defer db.Close()
   166  	defer func() {
   167  		if r := recover(); r != nil {
   168  			t.Fatalf("Panic is not expected when opening db in an existing empty dir. %s", r)
   169  		}
   170  	}()
   171  	db.Open()
   172  }
   173  
   174  func TestCreateDBInNonEmptyDir(t *testing.T) {
   175  	assert.NoError(t, os.RemoveAll(testDBPath), "")
   176  	assert.NoError(t, os.MkdirAll(testDBPath, 0775), "")
   177  	file, err := os.Create(filepath.Join(testDBPath, "dummyfile.txt"))
   178  	assert.NoError(t, err, "")
   179  	file.Close()
   180  	db := CreateDB(&Conf{DBPath: testDBPath})
   181  	defer db.Close()
   182  	defer func() {
   183  		if r := recover(); r == nil {
   184  			t.Fatalf("A panic is expected when opening db in an existing non-empty dir. %s", r)
   185  		}
   186  	}()
   187  	db.Open()
   188  }