From 100b248fc99ed759de1fb5b74dafea43929b76e9 Mon Sep 17 00:00:00 2001 From: jules01 Date: Mon, 18 Sep 2023 21:56:15 +0300 Subject: [PATCH] - added unit test --- leveldb/export_test.go | 6 ++++ leveldb/leveldbSerial_test.go | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 leveldb/export_test.go diff --git a/leveldb/export_test.go b/leveldb/export_test.go new file mode 100644 index 00000000..dcd88bf4 --- /dev/null +++ b/leveldb/export_test.go @@ -0,0 +1,6 @@ +package leveldb + +// PutBatch will call the unexported putBatch function +func (s *SerialDB) PutBatch() { + _ = s.putBatch() +} diff --git a/leveldb/leveldbSerial_test.go b/leveldb/leveldbSerial_test.go index f8b39827..7716e2b6 100644 --- a/leveldb/leveldbSerial_test.go +++ b/leveldb/leveldbSerial_test.go @@ -4,6 +4,7 @@ import ( "fmt" "math/big" "sync" + "sync/atomic" "testing" "time" @@ -358,3 +359,60 @@ func TestSerialDB_ConcurrentOperations(t *testing.T) { wg.Wait() } + +func TestSerialDB_PutRemoveGet(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + ldb := createSerialLevelDb(t, 100000, 1000000, 10) + + numKeys := 10000 + for i := 0; i < numKeys; i++ { + _ = ldb.Put([]byte(fmt.Sprintf("key %d", i)), []byte("val")) + } + + time.Sleep(time.Second * 2) + + numErr := uint32(0) + + for i := 0; i < numKeys; i++ { + key := []byte(fmt.Sprintf("key %d", i)) + + recoveredVal, _ := ldb.Get(key) + assert.NotEmpty(t, recoveredVal) + + wg := &sync.WaitGroup{} + wg.Add(2) + + // emulate the following scenario: + // the sequence Remove(key) -> Get(key) is done while the putBatch is called. So the actual edgecase is + // go routine 1: Remove(key) -----------------> Get(key) + // go routine 2: putBatch() + + go func() { + time.Sleep(time.Millisecond * 1) + ldb.PutBatch() + wg.Done() + }() + go func() { + _ = ldb.Remove(key) + + time.Sleep(time.Millisecond * 1) + + recoveredVal2, _ := ldb.Get(key) + if len(recoveredVal2) > 0 { + // the key-value was not removed + atomic.AddUint32(&numErr, 1) + } + + wg.Done() + }() + + wg.Wait() + + require.Zero(t, atomic.LoadUint32(&numErr), "iteration %d out of %d", i, numKeys) + } + + _ = ldb.Close() +}