diff options
author | Valery Piashchynski <[email protected]> | 2021-04-22 14:41:50 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2021-04-22 14:41:50 +0300 |
commit | abf606afd6fd9fbb0fd374ab5da41a8ee8d5a15d (patch) | |
tree | b0cfdeb5c478463d853b8a7409e88cfa7219c3fa /tests/plugins | |
parent | e4d65a41ec90747a387cfe769f743327959f7105 (diff) |
- Implement tests for the KV
- Implement Storage interface for the boltdb,memory,memcached drivers
Signed-off-by: Valery Piashchynski <[email protected]>
Diffstat (limited to 'tests/plugins')
-rw-r--r-- | tests/plugins/kv/boltdb/configs/.rr-init.yaml | 45 | ||||
-rw-r--r-- | tests/plugins/kv/boltdb/plugin_test.go | 195 | ||||
-rw-r--r-- | tests/plugins/kv/configs/.rr-boltdb.yaml | 15 | ||||
-rw-r--r-- | tests/plugins/kv/configs/.rr-in-memory.yaml | 11 | ||||
-rw-r--r-- | tests/plugins/kv/configs/.rr-kv-init.yaml | 4 | ||||
-rw-r--r-- | tests/plugins/kv/configs/.rr-memcached.yaml | 12 | ||||
-rw-r--r-- | tests/plugins/kv/memcached/configs/.rr-init.yaml | 42 | ||||
-rw-r--r-- | tests/plugins/kv/memcached/plugin_test.go | 195 | ||||
-rw-r--r-- | tests/plugins/kv/memory/configs/.rr-init.yaml | 42 | ||||
-rw-r--r-- | tests/plugins/kv/memory/plugin_test.go | 195 | ||||
-rw-r--r-- | tests/plugins/kv/storage_plugin_test.go | 606 |
11 files changed, 644 insertions, 718 deletions
diff --git a/tests/plugins/kv/boltdb/configs/.rr-init.yaml b/tests/plugins/kv/boltdb/configs/.rr-init.yaml deleted file mode 100644 index e4644511..00000000 --- a/tests/plugins/kv/boltdb/configs/.rr-init.yaml +++ /dev/null @@ -1,45 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../../psr-worker-bench.php" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -logs: - mode: development - level: error - -http: - address: 127.0.0.1:44933 - max_request_size: 1024 - middleware: ["gzip", "headers"] - uploads: - forbid: [".php", ".exe", ".bat"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 6 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -# boltdb simple driver -boltdb: - dir: "." - file: "rr" - bucket: "test" - permissions: 777 - interval: 1 # seconds diff --git a/tests/plugins/kv/boltdb/plugin_test.go b/tests/plugins/kv/boltdb/plugin_test.go deleted file mode 100644 index fad7c7a3..00000000 --- a/tests/plugins/kv/boltdb/plugin_test.go +++ /dev/null @@ -1,195 +0,0 @@ -package boltdb_tests //nolint:golint,stylecheck - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/kv" - "github.com/spiral/roadrunner/v2/plugins/kv/drivers/boltdb" - "github.com/spiral/roadrunner/v2/plugins/logger" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/stretchr/testify/assert" -) - -func TestBoltDb(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &boltdb.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("testBoltDbRPCMethods", testRPCMethods) - stopCh <- struct{}{} - wg.Wait() - - _ = os.Remove("rr") -} - -func testRPCMethods(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - var setRes bool - items := make([]kv.Item, 0, 5) - items = append(items, kv.Item{ - Key: "a", - Value: "aa", - }) - items = append(items, kv.Item{ - Key: "b", - Value: "bb", - }) - // add 5 second ttl - tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) - items = append(items, kv.Item{ - Key: "c", - Value: "cc", - TTL: tt, - }) - - items = append(items, kv.Item{ - Key: "d", - Value: "dd", - }) - - items = append(items, kv.Item{ - Key: "e", - Value: "ee", - }) - - // Register 3 keys with values - err = client.Call("boltdb.Set", items, &setRes) - assert.NoError(t, err) - assert.True(t, setRes) - - ret := make(map[string]bool) - keys := []string{"a", "b", "c"} - err = client.Call("boltdb.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 3) // should be 3 - - // key "c" should be deleted - time.Sleep(time.Second * 7) - - ret = make(map[string]bool) - err = client.Call("boltdb.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 2) // should be 2 - - mGet := make(map[string]interface{}) - keys = []string{"a", "b", "c"} - err = client.Call("boltdb.MGet", keys, &mGet) - assert.NoError(t, err) - assert.Len(t, mGet, 2) // c is expired - assert.Equal(t, string("aa"), mGet["a"].(string)) - assert.Equal(t, string("bb"), mGet["b"].(string)) - - mExpKeys := make([]kv.Item, 0, 2) - tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) - mExpKeys = append(mExpKeys, kv.Item{Key: "a", TTL: tt2}) - mExpKeys = append(mExpKeys, kv.Item{Key: "b", TTL: tt2}) - mExpKeys = append(mExpKeys, kv.Item{Key: "d", TTL: tt2}) - - // MEXPIRE - var mExpRes bool - err = client.Call("boltdb.MExpire", mExpKeys, &mExpRes) - assert.NoError(t, err) - assert.True(t, mExpRes) - - // TTL - keys = []string{"a", "b", "d"} - ttlRes := make(map[string]interface{}) - err = client.Call("boltdb.TTL", keys, &ttlRes) - assert.NoError(t, err) - assert.Len(t, ttlRes, 3) - - // HAS AFTER TTL - time.Sleep(time.Second * 15) - ret = make(map[string]bool) - keys = []string{"a", "b", "d"} - err = client.Call("boltdb.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 0) - - // DELETE - keys = []string{"e"} - var delRet bool - err = client.Call("boltdb.Delete", keys, &delRet) - assert.NoError(t, err) - assert.True(t, delRet) - - // HAS AFTER DELETE - ret = make(map[string]bool) - keys = []string{"e"} - err = client.Call("boltdb.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 0) -} diff --git a/tests/plugins/kv/configs/.rr-boltdb.yaml b/tests/plugins/kv/configs/.rr-boltdb.yaml new file mode 100644 index 00000000..81b47715 --- /dev/null +++ b/tests/plugins/kv/configs/.rr-boltdb.yaml @@ -0,0 +1,15 @@ +rpc: + listen: tcp://127.0.0.1:6001 + +logs: + mode: development + level: error + +kv: + boltdb-rr: + driver: boltdb + dir: "." + file: "rr.db" + bucket: "test" + permissions: 0666 + interval: 1 # seconds diff --git a/tests/plugins/kv/configs/.rr-in-memory.yaml b/tests/plugins/kv/configs/.rr-in-memory.yaml new file mode 100644 index 00000000..c6c3f0f7 --- /dev/null +++ b/tests/plugins/kv/configs/.rr-in-memory.yaml @@ -0,0 +1,11 @@ +rpc: + listen: tcp://127.0.0.1:6001 + +logs: + mode: development + level: error + +kv: + default: + driver: memory + interval: 1 diff --git a/tests/plugins/kv/configs/.rr-kv-init.yaml b/tests/plugins/kv/configs/.rr-kv-init.yaml index 935b952d..34e22a4e 100644 --- a/tests/plugins/kv/configs/.rr-kv-init.yaml +++ b/tests/plugins/kv/configs/.rr-kv-init.yaml @@ -12,7 +12,7 @@ kv: file: "rr.db" bucket: "rr" permissions: 0666 - ttl: 40s + interval: 1 boltdb-africa: driver: boltdb @@ -20,7 +20,7 @@ kv: file: "africa.db" bucket: "rr" permissions: 0666 - ttl: 40 + interval: 1 memcached: driver: memcached diff --git a/tests/plugins/kv/configs/.rr-memcached.yaml b/tests/plugins/kv/configs/.rr-memcached.yaml new file mode 100644 index 00000000..68443bc4 --- /dev/null +++ b/tests/plugins/kv/configs/.rr-memcached.yaml @@ -0,0 +1,12 @@ +rpc: + listen: tcp://127.0.0.1:6001 + +logs: + mode: development + level: error + +kv: + memcached-rr: + driver: memcached + addr: + - "localhost:11211" diff --git a/tests/plugins/kv/memcached/configs/.rr-init.yaml b/tests/plugins/kv/memcached/configs/.rr-init.yaml deleted file mode 100644 index fbca3250..00000000 --- a/tests/plugins/kv/memcached/configs/.rr-init.yaml +++ /dev/null @@ -1,42 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../../psr-worker-bench.php" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -logs: - mode: development - level: error - -http: - address: 127.0.0.1:44933 - max_request_size: 1024 - middleware: ["gzip", "headers"] - uploads: - forbid: [".php", ".exe", ".bat"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 6 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -# boltdb simple driver -memcached: - addr: - - "localhost:11211"
\ No newline at end of file diff --git a/tests/plugins/kv/memcached/plugin_test.go b/tests/plugins/kv/memcached/plugin_test.go deleted file mode 100644 index ecbc7722..00000000 --- a/tests/plugins/kv/memcached/plugin_test.go +++ /dev/null @@ -1,195 +0,0 @@ -package memcached_test - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/kv" - "github.com/spiral/roadrunner/v2/plugins/kv/drivers/memcached" - "github.com/spiral/roadrunner/v2/plugins/logger" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/stretchr/testify/assert" -) - -func TestMemcache(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &memcached.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("testMemcachedRPCMethods", testRPCMethods) - stopCh <- struct{}{} - wg.Wait() - - _ = os.Remove("rr") -} - -func testRPCMethods(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - var setRes bool - items := make([]kv.Item, 0, 5) - items = append(items, kv.Item{ - Key: "a", - Value: "aa", - }) - items = append(items, kv.Item{ - Key: "b", - Value: "bb", - }) - // add 5 second ttl - tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) - items = append(items, kv.Item{ - Key: "c", - Value: "cc", - TTL: tt, - }) - - items = append(items, kv.Item{ - Key: "d", - Value: "dd", - }) - - items = append(items, kv.Item{ - Key: "e", - Value: "ee", - }) - - // Register 3 keys with values - err = client.Call("memcached.Set", items, &setRes) - assert.NoError(t, err) - assert.True(t, setRes) - - ret := make(map[string]bool) - keys := []string{"a", "b", "c"} - err = client.Call("memcached.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 3) // should be 3 - - // key "c" should be deleted - time.Sleep(time.Second * 7) - - ret = make(map[string]bool) - err = client.Call("memcached.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 2) // should be 2 - - mGet := make(map[string]interface{}) - keys = []string{"a", "b", "c"} - err = client.Call("memcached.MGet", keys, &mGet) - assert.NoError(t, err) - assert.Len(t, mGet, 2) // c is expired - assert.Equal(t, string("aa"), string(mGet["a"].([]byte))) - assert.Equal(t, string("bb"), string(mGet["b"].([]byte))) - - mExpKeys := make([]kv.Item, 0, 2) - tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) - mExpKeys = append(mExpKeys, kv.Item{Key: "a", TTL: tt2}) - mExpKeys = append(mExpKeys, kv.Item{Key: "b", TTL: tt2}) - mExpKeys = append(mExpKeys, kv.Item{Key: "d", TTL: tt2}) - - // MEXPIRE - var mExpRes bool - err = client.Call("memcached.MExpire", mExpKeys, &mExpRes) - assert.NoError(t, err) - assert.True(t, mExpRes) - - // TTL call is not supported for the memcached driver - keys = []string{"a", "b", "d"} - ttlRes := make(map[string]interface{}) - err = client.Call("memcached.TTL", keys, &ttlRes) - assert.Error(t, err) - assert.Len(t, ttlRes, 0) - - // HAS AFTER TTL - time.Sleep(time.Second * 15) - ret = make(map[string]bool) - keys = []string{"a", "b", "d"} - err = client.Call("memcached.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 0) - - // DELETE - keys = []string{"e"} - var delRet bool - err = client.Call("memcached.Delete", keys, &delRet) - assert.NoError(t, err) - assert.True(t, delRet) - - // HAS AFTER DELETE - ret = make(map[string]bool) - keys = []string{"e"} - err = client.Call("memcached.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 0) -} diff --git a/tests/plugins/kv/memory/configs/.rr-init.yaml b/tests/plugins/kv/memory/configs/.rr-init.yaml deleted file mode 100644 index 8780a622..00000000 --- a/tests/plugins/kv/memory/configs/.rr-init.yaml +++ /dev/null @@ -1,42 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../../psr-worker-bench.php" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -logs: - mode: development - level: error - -http: - address: 127.0.0.1:44933 - max_request_size: 1024 - middleware: ["gzip", "headers"] - uploads: - forbid: [".php", ".exe", ".bat"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 6 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -# in memory KV driver -memory: - # keys ttl check interval - interval: 1 diff --git a/tests/plugins/kv/memory/plugin_test.go b/tests/plugins/kv/memory/plugin_test.go deleted file mode 100644 index 23d23bc0..00000000 --- a/tests/plugins/kv/memory/plugin_test.go +++ /dev/null @@ -1,195 +0,0 @@ -package memory_test - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/kv" - "github.com/spiral/roadrunner/v2/plugins/kv/drivers/memory" - "github.com/spiral/roadrunner/v2/plugins/logger" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/stretchr/testify/assert" -) - -func TestInMemory(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &memory.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("testInMemoryRPCMethods", testRPCMethods) - stopCh <- struct{}{} - wg.Wait() - - _ = os.Remove("rr") -} - -func testRPCMethods(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - var setRes bool - items := make([]kv.Item, 0, 5) - items = append(items, kv.Item{ - Key: "a", - Value: "aa", - }) - items = append(items, kv.Item{ - Key: "b", - Value: "bb", - }) - // add 5 second ttl - tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) - items = append(items, kv.Item{ - Key: "c", - Value: "cc", - TTL: tt, - }) - - items = append(items, kv.Item{ - Key: "d", - Value: "dd", - }) - - items = append(items, kv.Item{ - Key: "e", - Value: "ee", - }) - - // Register 3 keys with values - err = client.Call("memory.Set", items, &setRes) - assert.NoError(t, err) - assert.True(t, setRes) - - ret := make(map[string]bool) - keys := []string{"a", "b", "c"} - err = client.Call("memory.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 3) // should be 3 - - // key "c" should be deleted - time.Sleep(time.Second * 7) - - ret = make(map[string]bool) - err = client.Call("memory.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 2) // should be 2 - - mGet := make(map[string]interface{}) - keys = []string{"a", "b", "c"} - err = client.Call("memory.MGet", keys, &mGet) - assert.NoError(t, err) - assert.Len(t, mGet, 2) // c is expired - assert.Equal(t, string("aa"), mGet["a"].(string)) - assert.Equal(t, string("bb"), mGet["b"].(string)) - - mExpKeys := make([]kv.Item, 0, 2) - tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) - mExpKeys = append(mExpKeys, kv.Item{Key: "a", TTL: tt2}) - mExpKeys = append(mExpKeys, kv.Item{Key: "b", TTL: tt2}) - mExpKeys = append(mExpKeys, kv.Item{Key: "d", TTL: tt2}) - - // MEXPIRE - var mExpRes bool - err = client.Call("memory.MExpire", mExpKeys, &mExpRes) - assert.NoError(t, err) - assert.True(t, mExpRes) - - // TTL - keys = []string{"a", "b", "d"} - ttlRes := make(map[string]interface{}) - err = client.Call("memory.TTL", keys, &ttlRes) - assert.NoError(t, err) - assert.Len(t, ttlRes, 3) - - // HAS AFTER TTL - time.Sleep(time.Second * 15) - ret = make(map[string]bool) - keys = []string{"a", "b", "d"} - err = client.Call("memory.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 0) - - // DELETE - keys = []string{"e"} - var delRet bool - err = client.Call("memory.Delete", keys, &delRet) - assert.NoError(t, err) - assert.True(t, delRet) - - // HAS AFTER DELETE - ret = make(map[string]bool) - keys = []string{"e"} - err = client.Call("memory.Has", keys, &ret) - assert.NoError(t, err) - assert.Len(t, ret, 0) -} diff --git a/tests/plugins/kv/storage_plugin_test.go b/tests/plugins/kv/storage_plugin_test.go index 6d270d3f..0b42e19d 100644 --- a/tests/plugins/kv/storage_plugin_test.go +++ b/tests/plugins/kv/storage_plugin_test.go @@ -30,7 +30,7 @@ func makePayload(b *flatbuffers.Builder, storage string, items []kv.Item) []byte storageOffset := b.CreateString(storage) - ////////////////////// ITEMS VECTOR //////////////////////////// + // //////////////////// ITEMS VECTOR //////////////////////////// offset := make([]flatbuffers.UOffsetT, len(items)) for i := len(items) - 1; i >= 0; i-- { offset[i] = serializeItems(b, items[i]) @@ -43,7 +43,7 @@ func makePayload(b *flatbuffers.Builder, storage string, items []kv.Item) []byte } itemsOffset := b.EndVector(len(offset)) - /////////////////////////////////////////////////////////////////// + // ///////////////////////////////////////////////////////////////// generated.PayloadStart(b) generated.PayloadAddItems(b, itemsOffset) @@ -187,3 +187,605 @@ func kvHasTest(t *testing.T) { err = client.Call("kv.Has", args, &ret) assert.NoError(t, err) } + +func TestBoltDb(t *testing.T) { + cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) + assert.NoError(t, err) + + cfg := &config.Viper{ + Path: "configs/.rr-boltdb.yaml", + Prefix: "rr", + } + + err = cont.RegisterAll( + cfg, + &kv.Plugin{}, + &boltdb.Plugin{}, + &rpcPlugin.Plugin{}, + &logger.ZapLogger{}, + ) + assert.NoError(t, err) + + err = cont.Init() + if err != nil { + t.Fatal(err) + } + + ch, err := cont.Serve() + assert.NoError(t, err) + + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + wg := &sync.WaitGroup{} + wg.Add(1) + + stopCh := make(chan struct{}, 1) + + go func() { + defer wg.Done() + for { + select { + case e := <-ch: + assert.Fail(t, "error", e.Error.Error()) + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + case <-sig: + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + case <-stopCh: + // timeout + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + } + } + }() + + time.Sleep(time.Second * 1) + t.Run("testBoltDbRPCMethods", testRPCMethods) + stopCh <- struct{}{} + wg.Wait() + + _ = os.Remove("rr.db") +} + +func testRPCMethods(t *testing.T) { + conn, err := net.Dial("tcp", "127.0.0.1:6001") + assert.NoError(t, err) + client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) + + // add 5 second ttl + tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) + keys := makePayload(flatbuffers.NewBuilder(100), "boltdb-rr", []kv.Item{ + { + Key: "a", + }, + { + Key: "b", + }, + { + Key: "c", + }, + }) + data := makePayload(flatbuffers.NewBuilder(100), "boltdb-rr", []kv.Item{ + { + Key: "a", + Value: "aa", + }, + { + Key: "b", + Value: "bb", + }, + { + Key: "c", + Value: "cc", + TTL: tt, + }, + { + Key: "d", + Value: "dd", + }, + { + Key: "e", + Value: "ee", + }, + }) + + var setRes bool + + // Register 3 keys with values + err = client.Call("kv.Set", data, &setRes) + assert.NoError(t, err) + assert.True(t, setRes) + + ret := make(map[string]bool) + err = client.Call("kv.Has", keys, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 3) // should be 3 + + // key "c" should be deleted + time.Sleep(time.Second * 7) + + ret = make(map[string]bool) + err = client.Call("kv.Has", keys, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 2) // should be 2 + + mGet := make(map[string]interface{}) + err = client.Call("kv.MGet", keys, &mGet) + assert.NoError(t, err) + assert.Len(t, mGet, 2) // c is expired + assert.Equal(t, "aa", mGet["a"].(string)) + assert.Equal(t, "bb", mGet["b"].(string)) + + tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) + data2 := makePayload(flatbuffers.NewBuilder(100), "boltdb-rr", []kv.Item{ + { + Key: "a", + TTL: tt2, + }, + { + Key: "b", + TTL: tt2, + }, + { + Key: "d", + TTL: tt2, + }, + }) + + // MEXPIRE + var mExpRes bool + err = client.Call("kv.MExpire", data2, &mExpRes) + assert.NoError(t, err) + assert.True(t, mExpRes) + + // TTL + keys2 := makePayload(flatbuffers.NewBuilder(100), "boltdb-rr", []kv.Item{ + { + Key: "a", + }, + { + Key: "b", + }, + { + Key: "d", + }, + }) + ttlRes := make(map[string]interface{}) + err = client.Call("kv.TTL", keys2, &ttlRes) + assert.NoError(t, err) + assert.Len(t, ttlRes, 3) + + // HAS AFTER TTL + time.Sleep(time.Second * 15) + ret = make(map[string]bool) + err = client.Call("kv.Has", keys2, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 0) + + // DELETE + keysDel := makePayload(flatbuffers.NewBuilder(100), "boltdb-rr", []kv.Item{ + { + Key: "e", + }, + }) + var delRet bool + err = client.Call("kv.Delete", keysDel, &delRet) + assert.NoError(t, err) + assert.True(t, delRet) + + // HAS AFTER DELETE + ret = make(map[string]bool) + err = client.Call("kv.Has", keysDel, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 0) +} + +func TestMemcached(t *testing.T) { + cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) + assert.NoError(t, err) + + cfg := &config.Viper{ + Path: "configs/.rr-memcached.yaml", + Prefix: "rr", + } + + err = cont.RegisterAll( + cfg, + &kv.Plugin{}, + &memcached.Plugin{}, + &rpcPlugin.Plugin{}, + &logger.ZapLogger{}, + ) + assert.NoError(t, err) + + err = cont.Init() + if err != nil { + t.Fatal(err) + } + + ch, err := cont.Serve() + assert.NoError(t, err) + + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + wg := &sync.WaitGroup{} + wg.Add(1) + + stopCh := make(chan struct{}, 1) + + go func() { + defer wg.Done() + for { + select { + case e := <-ch: + assert.Fail(t, "error", e.Error.Error()) + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + case <-sig: + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + case <-stopCh: + // timeout + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + } + } + }() + + time.Sleep(time.Second * 1) + t.Run("testMemcachedRPCMethods", testRPCMethodsMemcached) + stopCh <- struct{}{} + wg.Wait() +} + +func testRPCMethodsMemcached(t *testing.T) { + conn, err := net.Dial("tcp", "127.0.0.1:6001") + assert.NoError(t, err) + client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) + + // add 5 second ttl + tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) + keys := makePayload(flatbuffers.NewBuilder(100), "memcached-rr", []kv.Item{ + { + Key: "a", + }, + { + Key: "b", + }, + { + Key: "c", + }, + }) + data := makePayload(flatbuffers.NewBuilder(100), "memcached-rr", []kv.Item{ + { + Key: "a", + Value: "aa", + }, + { + Key: "b", + Value: "bb", + }, + { + Key: "c", + Value: "cc", + TTL: tt, + }, + { + Key: "d", + Value: "dd", + }, + { + Key: "e", + Value: "ee", + }, + }) + + var setRes bool + + // Register 3 keys with values + err = client.Call("kv.Set", data, &setRes) + assert.NoError(t, err) + assert.True(t, setRes) + + ret := make(map[string]bool) + err = client.Call("kv.Has", keys, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 3) // should be 3 + + // key "c" should be deleted + time.Sleep(time.Second * 7) + + ret = make(map[string]bool) + err = client.Call("kv.Has", keys, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 2) // should be 2 + + mGet := make(map[string]interface{}) + err = client.Call("kv.MGet", keys, &mGet) + assert.NoError(t, err) + assert.Len(t, mGet, 2) // c is expired + assert.Equal(t, string("aa"), string(mGet["a"].([]byte))) + assert.Equal(t, string("bb"), string(mGet["b"].([]byte))) + + tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) + data2 := makePayload(flatbuffers.NewBuilder(100), "memcached-rr", []kv.Item{ + { + Key: "a", + TTL: tt2, + }, + { + Key: "b", + TTL: tt2, + }, + { + Key: "d", + TTL: tt2, + }, + }) + + // MEXPIRE + var mExpRes bool + err = client.Call("kv.MExpire", data2, &mExpRes) + assert.NoError(t, err) + assert.True(t, mExpRes) + + // TTL call is not supported for the memcached driver + keys2 := makePayload(flatbuffers.NewBuilder(100), "memcached-rr", []kv.Item{ + { + Key: "a", + }, + { + Key: "b", + }, + { + Key: "d", + }, + }) + ttlRes := make(map[string]interface{}) + err = client.Call("kv.TTL", keys2, &ttlRes) + assert.Error(t, err) + assert.Len(t, ttlRes, 0) + + // HAS AFTER TTL + time.Sleep(time.Second * 15) + ret = make(map[string]bool) + err = client.Call("kv.Has", keys2, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 0) + + // DELETE + keysDel := makePayload(flatbuffers.NewBuilder(100), "memcached-rr", []kv.Item{ + { + Key: "e", + }, + }) + var delRet bool + err = client.Call("kv.Delete", keysDel, &delRet) + assert.NoError(t, err) + assert.True(t, delRet) + + // HAS AFTER DELETE + ret = make(map[string]bool) + err = client.Call("kv.Has", keysDel, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 0) +} + +func TestInMemory(t *testing.T) { + cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) + assert.NoError(t, err) + + cfg := &config.Viper{ + Path: "configs/.rr-in-memory.yaml", + Prefix: "rr", + } + + err = cont.RegisterAll( + cfg, + &kv.Plugin{}, + &memory.Plugin{}, + &rpcPlugin.Plugin{}, + &logger.ZapLogger{}, + ) + assert.NoError(t, err) + + err = cont.Init() + if err != nil { + t.Fatal(err) + } + + ch, err := cont.Serve() + assert.NoError(t, err) + + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + wg := &sync.WaitGroup{} + wg.Add(1) + + stopCh := make(chan struct{}, 1) + + go func() { + defer wg.Done() + for { + select { + case e := <-ch: + assert.Fail(t, "error", e.Error.Error()) + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + case <-sig: + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + case <-stopCh: + // timeout + err = cont.Stop() + if err != nil { + assert.FailNow(t, "error", err.Error()) + } + return + } + } + }() + + time.Sleep(time.Second * 1) + t.Run("testInMemoryRPCMethods", testRPCMethodsInMemory) + stopCh <- struct{}{} + wg.Wait() +} + +func testRPCMethodsInMemory(t *testing.T) { + conn, err := net.Dial("tcp", "127.0.0.1:6001") + assert.NoError(t, err) + client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) + + // add 5 second ttl + tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) + keys := makePayload(flatbuffers.NewBuilder(100), "default", []kv.Item{ + { + Key: "a", + }, + { + Key: "b", + }, + { + Key: "c", + }, + }) + data := makePayload(flatbuffers.NewBuilder(100), "default", []kv.Item{ + { + Key: "a", + Value: "aa", + }, + { + Key: "b", + Value: "bb", + }, + { + Key: "c", + Value: "cc", + TTL: tt, + }, + { + Key: "d", + Value: "dd", + }, + { + Key: "e", + Value: "ee", + }, + }) + + var setRes bool + + // Register 3 keys with values + err = client.Call("kv.Set", data, &setRes) + assert.NoError(t, err) + assert.True(t, setRes) + + ret := make(map[string]bool) + err = client.Call("kv.Has", keys, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 3) // should be 3 + + // key "c" should be deleted + time.Sleep(time.Second * 7) + + ret = make(map[string]bool) + err = client.Call("kv.Has", keys, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 2) // should be 2 + + mGet := make(map[string]interface{}) + err = client.Call("kv.MGet", keys, &mGet) + assert.NoError(t, err) + assert.Len(t, mGet, 2) // c is expired + assert.Equal(t, "aa", mGet["a"].(string)) + assert.Equal(t, "bb", mGet["b"].(string)) + + tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) + data2 := makePayload(flatbuffers.NewBuilder(100), "default", []kv.Item{ + { + Key: "a", + TTL: tt2, + }, + { + Key: "b", + TTL: tt2, + }, + { + Key: "d", + TTL: tt2, + }, + }) + + // MEXPIRE + var mExpRes bool + err = client.Call("kv.MExpire", data2, &mExpRes) + assert.NoError(t, err) + assert.True(t, mExpRes) + + // TTL + keys2 := makePayload(flatbuffers.NewBuilder(100), "default", []kv.Item{ + { + Key: "a", + }, + { + Key: "b", + }, + { + Key: "d", + }, + }) + ttlRes := make(map[string]interface{}) + err = client.Call("kv.TTL", keys2, &ttlRes) + assert.NoError(t, err) + assert.Len(t, ttlRes, 3) + + // HAS AFTER TTL + time.Sleep(time.Second * 15) + ret = make(map[string]bool) + err = client.Call("kv.Has", keys2, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 0) + + // DELETE + keysDel := makePayload(flatbuffers.NewBuilder(100), "default", []kv.Item{ + { + Key: "e", + }, + }) + var delRet bool + err = client.Call("kv.Delete", keysDel, &delRet) + assert.NoError(t, err) + assert.True(t, delRet) + + // HAS AFTER DELETE + ret = make(map[string]bool) + err = client.Call("kv.Has", keysDel, &ret) + assert.NoError(t, err) + assert.Len(t, ret, 0) +} |