Skip to content

Commit

Permalink
Add test suite for storage interface
Browse files Browse the repository at this point in the history
  • Loading branch information
norbertklawikowski committed Nov 3, 2023
1 parent 7127616 commit 6da9de6
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 126 deletions.
78 changes: 18 additions & 60 deletions storage/leveldb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,24 @@ func TestLeveldbStorage(t *testing.T) {
require.NoError(t, err)
})

t.Run("has", func(t *testing.T) {
st := newStorage(true, t)

st.Open()
time.Sleep(1 * time.Second)

has, err := st.Has("key-1")
require.NoError(t, err)
require.False(t, has)

err = st.Set("key-1", []byte("content-1"))
require.NoError(t, err)

has, err = st.Has("key-1")
require.NoError(t, err)
require.True(t, has)
})

t.Run("set-reopen", func(t *testing.T) {
st := newStorage(true, t)

Expand Down Expand Up @@ -130,66 +148,6 @@ func TestLeveldbStorage(t *testing.T) {
})
}

func TestSetGet(t *testing.T) {
var (
err error
hasKey bool
)

tmpdir, err := os.MkdirTemp("", "goka_storage_TestSetGet")
require.NoError(t, err)

db, err := leveldb.OpenFile(tmpdir, nil)
require.NoError(t, err)

storage, err := New(db)
require.NoError(t, err)

hasKey, err = storage.Has("example1")
require.NoError(t, err)
require.False(t, hasKey)

value, err := storage.Get("example1")
require.True(t, value == nil)
require.NoError(t, err)

err = storage.Set("example1", []byte("example-message"))
require.NoError(t, err)

hasKey, err = storage.Has("example1")
require.NoError(t, err)
require.True(t, hasKey)

value, err = storage.Get("example1")
require.NoError(t, err)

require.NoError(t, storage.Delete("example1"))
hasKey, err = storage.Has("example1")
require.NoError(t, err)
require.False(t, hasKey)

// test iteration
require.NoError(t, storage.Set("key1", []byte("value1")))
require.NoError(t, storage.Set("key2", []byte("value2")))
iter, err := storage.Iterator()
require.NoError(t, err)
defer iter.Release()
messages := make(map[string]string)

for iter.Next() {
key := string(iter.Key())
val, err := iter.Value()
require.NoError(t, err)
messages[key] = string(val)
}
require.True(t, len(messages) == 2)
require.Equal(t, "value1", messages["key1"])
require.Equal(t, "value2", messages["key2"])

recoveredValue := string(value)
require.Equal(t, "example-message", recoveredValue)
}

func TestIterator(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "goka_storage_TestIterator")
require.Nil(t, err)
Expand Down
1 change: 1 addition & 0 deletions storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type Storage interface {

// Close closes the storage.
Close() error

// Has returns whether the given key exists in the database.
Has(key string) (bool, error)

Expand Down
66 changes: 0 additions & 66 deletions storage/storage_test.go

This file was deleted.

145 changes: 145 additions & 0 deletions storagetest/storagetest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package storagetest

import (
"testing"

"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"

"github.com/lovoo/goka/storage"
)

// TeardownFunc cleans up state after tests.
type TeardownFunc func() error

type StorageTestSuite struct {
suite.Suite

storageBuilder func(t *testing.T) (storage.Storage, TeardownFunc)
storage storage.Storage
teardownFn TeardownFunc
}

func NewStorageTestSuite(storageBuilder func(t *testing.T) (storage.Storage, TeardownFunc)) *StorageTestSuite {
return &StorageTestSuite{
storageBuilder: storageBuilder,
}
}

func (s *StorageTestSuite) SetupTest() {
storage, teardownFn := s.storageBuilder(s.T())
s.storage = storage
s.teardownFn = teardownFn
}

func (s *StorageTestSuite) TeardownTest() {
err := s.teardownFn()
require.NoError(s.T(), err)
s.teardownFn = nil
}

func (s *StorageTestSuite) TestHas() {
st := s.storage

var (
err error
hasKey bool
)

hasKey, err = st.Has("test-key")
require.NoError(s.T(), err)
require.False(s.T(), hasKey)

err = st.Set("test-key", []byte("test"))
require.NoError(s.T(), err)

hasKey, err = st.Has("test-key")
require.NoError(s.T(), err)
require.True(s.T(), hasKey)
}

func (s *StorageTestSuite) TestSetGet() {
st := s.storage

value, err := st.Get("example1")
require.NoError(s.T(), err)
require.Nil(s.T(), value)

err = st.Set("example1", []byte("example-message"))
require.NoError(s.T(), err)

value, err = st.Get("example1")
require.NoError(s.T(), err)
require.Equal(s.T(), []byte("example-message"), value)
}

func (s *StorageTestSuite) TestDelete() {
st := s.storage

err := st.Set("example1", []byte("example-message"))
require.NoError(s.T(), err)

require.NoError(s.T(), st.Delete("example1"))

hasKey, err := st.Has("example1")
require.NoError(s.T(), err)
require.False(s.T(), hasKey)

value, err := st.Get("example1")
require.NoError(s.T(), err)
require.Nil(s.T(), value)
}

func (s *StorageTestSuite) TestOffsetSetGet() {
st := s.storage

offset, err := st.GetOffset(0)
require.NoError(s.T(), err)
require.Equal(s.T(), int64(0), offset)

require.NoError(s.T(), st.SetOffset(100))

offset, err = st.GetOffset(0)
require.NoError(s.T(), err)
require.Equal(s.T(), int64(100), offset)
}

func (s *StorageTestSuite) TestIterator() {
st := s.storage

kv := map[string]string{
"key-1": "val-1",
"key-2": "val-2",
"key-3": "val-3",
}

for k, v := range kv {
require.Nil(s.T(), st.Set(k, []byte(v)))
}

require.Nil(s.T(), st.SetOffset(777))

iter, err := st.Iterator()
require.Nil(s.T(), err)
defer iter.Release()
count := 0

// accessing iterator before Next should only return nils
val, err := iter.Value()
require.True(s.T(), val == nil)
require.Nil(s.T(), err)

for iter.Next() {
count++
key := string(iter.Key())
expected, ok := kv[key]
if !ok {
s.T().Fatalf("unexpected key from iterator: %s", key)
}

val, err := iter.Value()
require.Nil(s.T(), err)
require.Equal(s.T(), expected, string(val))
}
require.Equal(s.T(), count, len(kv))
}

0 comments on commit 6da9de6

Please sign in to comment.