From 7298c16f35781c29d863470ec74ff304c33ca573 Mon Sep 17 00:00:00 2001 From: Yehor Butko Date: Tue, 31 Jul 2018 18:23:55 +0300 Subject: [PATCH] storage/redis covered with unit tests (#157) * storage/redis covered with unit tests * updated tests for redis --- storage/redis/client_test.go | 252 +++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) diff --git a/storage/redis/client_test.go b/storage/redis/client_test.go index 4255e7ec7..cfab131de 100644 --- a/storage/redis/client_test.go +++ b/storage/redis/client_test.go @@ -4,8 +4,14 @@ package redis import ( + "fmt" + "os" + "os/exec" "testing" + "time" + "github.com/go-redis/redis" + "github.com/stretchr/testify/assert" "storj.io/storj/internal/test" "storj.io/storj/storage" ) @@ -81,3 +87,249 @@ func TestListWithStartKey(t *testing.T) { rt.HandleErr(err, "Failed to list") } } + +var ( + validConnection = "127.0.0.1:6379" + unexistingKey = "unexistingKey" + validKey = "validKey" + validValue = "validValue" + keysList = []string{"key1", "key2", "key3"} + dbTest = 1 +) + +type TestFunc func(t *testing.T, st storage.KeyValueStore) + +func testWithRedis(t *testing.T, testFunc TestFunc) { + st, err := NewClient(validConnection, "", dbTest) + assert.NoError(t, err) + assert.NotNil(t, st) + + defer func() { + st.Close() + }() + + testFunc(t, st) +} + +func testWithInvalidConnection(t *testing.T, testFunc TestFunc) { + st := &redisClient{ + db: redis.NewClient(&redis.Options{ + Addr: "", + Password: "", + DB: dbTest, + }), + TTL: defaultNodeExpiration, + } + + testFunc(t, st) +} + +func TestCloseRedis(t *testing.T) { + testWithRedis(t, func(t *testing.T, st storage.KeyValueStore) { + err := st.Close() + assert.NoError(t, err) + }) +} + +func TestNewClient(t *testing.T) { + cases := []struct { + testName, address string + testFunc func(storage.KeyValueStore, error) + }{ + { + "NotValidConnection", + "", + func(st storage.KeyValueStore, err error) { + assert.Error(t, err) + assert.Nil(t, st) + }, + }, + { + "ValidConnection", + validConnection, + func(st storage.KeyValueStore, err error) { + assert.NoError(t, err) + assert.NotNil(t, st) + }, + }, + } + + for _, c := range cases { + t.Run(c.testName, func(t *testing.T) { + storage, err := NewClient(c.address, "", dbTest) + + defer func() { + if err == nil { + storage.Close() + } + }() + + c.testFunc(storage, err) + }) + } +} + +func TestCrudValidConnection(t *testing.T) { + cases := []struct { + testName string + testFunc TestFunc + }{ + { + "GetUnexistingKey", + func(t *testing.T, st storage.KeyValueStore) { + err := st.Delete(storage.Key(unexistingKey)) + assert.NoError(t, err) + + value, err := st.Get(storage.Key(unexistingKey)) + assert.NoError(t, err) + assert.Nil(t, value) + }, + }, + { + "GetValidKey", + func(t *testing.T, st storage.KeyValueStore) { + key := storage.Key(validKey) + orgValue := storage.Value(validValue) + + err := st.Put(key, orgValue) + assert.NoError(t, err) + + value, err := st.Get(key) + assert.NoError(t, err) + assert.Equal(t, orgValue, value) + + err = st.Delete(key) + assert.NoError(t, err) + }, + }, + { + "UpdateKey", + func(t *testing.T, st storage.KeyValueStore) { + key := storage.Key(validKey) + orgValue := storage.Value(validValue) + + err := st.Put(key, orgValue) + assert.NoError(t, err) + err = st.Put(key, orgValue) + assert.NoError(t, err) + + err = st.Delete(key) + assert.NoError(t, err) + }, + }, + { + "GetKeysList", + func(t *testing.T, st storage.KeyValueStore) { + orgValue := storage.Value(validValue) + + list := storage.Keys{} + for _, key := range keysList { + list = append(list, storage.Key(key)) + } + + for _, key := range list { + err := st.Put(key, orgValue) + assert.NoError(t, err) + } + + keys, err := st.List(list[0], storage.Limit(len(keysList))) + + assert.NoError(t, err) + assert.ElementsMatch(t, list, keys) + assert.Equal(t, len(list), len(keys)) + + for _, key := range list { + err := st.Delete(key) + assert.NoError(t, err) + } + }, + }, + { + "GetKeysListWithFirstArgNil", + func(t *testing.T, st storage.KeyValueStore) { + keys, err := st.List(nil, storage.Limit(len(keysList))) + assert.NoError(t, err) + assert.Equal(t, len(keys), 0) + }, + }, + } + + for _, c := range cases { + t.Run(c.testName, func(t *testing.T) { + testWithRedis(t, c.testFunc) + }) + } +} + +func TestCrudInvalidConnection(t *testing.T) { + cases := []struct { + testName string + testFunc TestFunc + }{ + { + "Get", + func(t *testing.T, st storage.KeyValueStore) { + _, err := st.Get(storage.Key(validKey)) + assert.Error(t, err) + }, + }, + { + "Put", + func(t *testing.T, st storage.KeyValueStore) { + err := st.Put(storage.Key(validKey), storage.Value(validValue)) + assert.Error(t, err) + }, + }, + { + "Delete", + func(t *testing.T, st storage.KeyValueStore) { + err := st.Delete(storage.Key(validKey)) + assert.Error(t, err) + }, + }, + { + "ListArgValid", + func(t *testing.T, st storage.KeyValueStore) { + keys, err := st.List(storage.Key(validKey), 1) + assert.Error(t, err) + assert.Nil(t, keys) + }, + }, + { + "ListArgInvalid", + func(t *testing.T, st storage.KeyValueStore) { + keys, err := st.List(nil, 1) + assert.Error(t, err) + assert.Nil(t, keys) + }, + }, + } + + for _, c := range cases { + t.Run(c.testName, func(t *testing.T) { + testWithInvalidConnection(t, c.testFunc) + }) + } +} + +func TestMain(m *testing.M) { + cmd := exec.Command("redis-server") + + err := cmd.Start() + + if err != nil { + fmt.Println(err) + return + } + //waiting for "redis-server command" to start + time.Sleep(time.Second) + + retCode := m.Run() + + err = cmd.Process.Kill() + if err != nil { + fmt.Print(err) + } + + os.Exit(retCode) +}