You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kvrocks.apache.org by hu...@apache.org on 2022/09/11 04:04:05 UTC

[incubator-kvrocks] branch unstable updated: Move tcl keyspace test cases to Go (#846)

This is an automated email from the ASF dual-hosted git repository.

hulk pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/incubator-kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new 38ca47a  Move tcl keyspace test cases to Go (#846)
38ca47a is described below

commit 38ca47a650f0fbf8c338c6535c0c953607391c27
Author: hulk <hu...@gmail.com>
AuthorDate: Sun Sep 11 12:03:59 2022 +0800

    Move tcl keyspace test cases to Go (#846)
---
 tests/gocase/unit/keyspace_test.go | 206 +++++++++++++++++++++++++++++++++++++
 tests/tcl/tests/test_helper.tcl    |   1 -
 tests/tcl/tests/unit/keyspace.tcl  | 168 ------------------------------
 3 files changed, 206 insertions(+), 169 deletions(-)

diff --git a/tests/gocase/unit/keyspace_test.go b/tests/gocase/unit/keyspace_test.go
new file mode 100644
index 0000000..c97d47e
--- /dev/null
+++ b/tests/gocase/unit/keyspace_test.go
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package unit
+
+import (
+	"context"
+	"sort"
+	"testing"
+	"time"
+
+	"github.com/apache/incubator-kvrocks/tests/gocase/util"
+	"github.com/stretchr/testify/require"
+)
+
+func TestKeyspace(t *testing.T) {
+	srv := util.StartServer(t, map[string]string{})
+	defer srv.Close()
+
+	ctx := context.Background()
+	rdb := srv.NewClient()
+	defer func() { require.NoError(t, rdb.Close()) }()
+
+	t.Run("DEL against a single item", func(t *testing.T) {
+		key := "x"
+		value := "foo"
+		require.NoError(t, rdb.Set(ctx, key, value, 0).Err())
+		require.Equal(t, value, rdb.Get(ctx, key).Val())
+		require.EqualValues(t, 1, rdb.Del(ctx, key).Val())
+		require.Equal(t, "", rdb.Get(ctx, key).Val())
+	})
+
+	t.Run("Vararg DEL", func(t *testing.T) {
+		require.NoError(t, rdb.Set(ctx, "foo1", "a", 0).Err())
+		require.NoError(t, rdb.Set(ctx, "foo2", "b", 0).Err())
+		require.NoError(t, rdb.Set(ctx, "foo3", "c", 0).Err())
+		require.EqualValues(t, 3, rdb.Del(ctx, "foo1", "foo2", "foo3").Val())
+		require.Equal(t, []interface{}{nil, nil, nil}, rdb.MGet(ctx, "foo1", "foo2", "foo3").Val())
+	})
+
+	t.Run("KEYS with pattern", func(t *testing.T) {
+		for _, key := range []string{"key_x", "key_y", "key_z", "foo_a", "foo_b", "foo_c"} {
+			require.NoError(t, rdb.Set(ctx, key, "hello", 0).Err())
+		}
+		keys := rdb.Keys(ctx, "foo*").Val()
+		sort.Slice(keys, func(i, j int) bool {
+			return keys[i] < keys[j]
+		})
+		require.Equal(t, []string{"foo_a", "foo_b", "foo_c"}, keys)
+	})
+
+	t.Run("KEYS to get all keys", func(t *testing.T) {
+		keys := rdb.Keys(ctx, "*").Val()
+		sort.Slice(keys, func(i, j int) bool {
+			return keys[i] < keys[j]
+		})
+		require.Equal(t, []string{"foo_a", "foo_b", "foo_c", "key_x", "key_y", "key_z"}, keys)
+	})
+
+	t.Run("DBSize", func(t *testing.T) {
+		require.NoError(t, rdb.Do(ctx, "dbsize", "scan").Err())
+		time.Sleep(100 * time.Millisecond)
+		require.EqualValues(t, 6, rdb.Do(ctx, "dbsize").Val())
+	})
+
+	t.Run("DEL all keys", func(t *testing.T) {
+		vals := rdb.Keys(ctx, "*").Val()
+		require.EqualValues(t, len(vals), rdb.Del(ctx, vals...).Val())
+		require.NoError(t, rdb.Do(ctx, "dbsize", "scan").Err())
+		time.Sleep(100 * time.Millisecond)
+		require.EqualValues(t, 0, rdb.Do(ctx, "dbsize").Val())
+	})
+
+	t.Run("EXISTS", func(t *testing.T) {
+		newKey := "newkey"
+		require.NoError(t, rdb.Set(ctx, newKey, "test", 0).Err())
+		require.EqualValues(t, 1, rdb.Exists(ctx, newKey).Val())
+		require.EqualValues(t, 1, rdb.Del(ctx, newKey).Val())
+		require.EqualValues(t, 0, rdb.Exists(ctx, newKey).Val())
+	})
+
+	t.Run("Zero length value in key. SET/GET/EXISTS", func(t *testing.T) {
+		emptyKey := "emptykey"
+		require.NoError(t, rdb.Set(ctx, emptyKey, nil, 0).Err())
+		require.EqualValues(t, 1, rdb.Exists(ctx, emptyKey).Val())
+		require.EqualValues(t, 1, rdb.Del(ctx, emptyKey).Val())
+		require.EqualValues(t, 0, rdb.Exists(ctx, emptyKey).Val())
+	})
+
+	t.Run("Commands pipelining", func(t *testing.T) {
+		c := srv.NewTCPClient()
+		defer func() { require.NoError(t, c.Close()) }()
+		require.NoError(t, c.Write("SET k1 xyzk\r\nGET k1\r\nPING\r\n"))
+		r, err := c.ReadLine()
+		require.NoError(t, err)
+		require.Equal(t, "+OK", r)
+		r, err = c.ReadLine()
+		require.NoError(t, err)
+		require.Equal(t, "$4", r)
+		r, err = c.ReadLine()
+		require.NoError(t, err)
+		require.Equal(t, "xyzk", r)
+		r, err = c.ReadLine()
+		require.NoError(t, err)
+		require.Equal(t, "+PONG", r)
+	})
+
+	t.Run("Non existing command", func(t *testing.T) {
+		util.ErrorRegexp(t, rdb.Do(ctx, "foobaredcommand").Err(), "ERR.*")
+	})
+
+	t.Run("RANDOMKEY", func(t *testing.T) {
+		rdb.FlushDB(ctx)
+		require.NoError(t, rdb.Set(ctx, "foo", "x", 0).Err())
+		require.NoError(t, rdb.Set(ctx, "bar", "y", 0).Err())
+
+		for i := 0; i < 1000; i++ {
+			randomKey := rdb.RandomKey(ctx).Val()
+			switch randomKey {
+			case "foo", "bar":
+				return
+			}
+		}
+		require.Fail(t, "RANDOMKEY never hits foo or bar")
+	})
+
+	t.Run("RANDOMKEY against empty DB", func(t *testing.T) {
+		rdb.FlushDB(ctx)
+		require.Equal(t, "", rdb.RandomKey(ctx).Val())
+	})
+
+	t.Run("RANDOMKEY regression 1", func(t *testing.T) {
+		rdb.FlushDB(ctx)
+		require.NoError(t, rdb.Set(ctx, "x", 10, 0).Err())
+		require.EqualValues(t, 1, rdb.Del(ctx, "x").Val())
+		require.Equal(t, "", rdb.RandomKey(ctx).Val())
+	})
+
+	t.Run("KEYS * two times with long key - RedisGithub issue #1208", func(t *testing.T) {
+		rdb.FlushDB(ctx)
+		require.NoError(t, rdb.Set(ctx, "dlskeriewrioeuwqoirueioqwrueoqwrueqw", "test", 0).Err())
+		require.Equal(t, []string{"dlskeriewrioeuwqoirueioqwrueoqwrueqw"}, rdb.Keys(ctx, "*").Val())
+		require.Equal(t, []string{"dlskeriewrioeuwqoirueioqwrueoqwrueqw"}, rdb.Keys(ctx, "*").Val())
+	})
+
+	t.Run("KEYS with multi namespace", func(t *testing.T) {
+		rdb.FlushDB(ctx)
+		rdb.ConfigSet(ctx, "requirepass", "foobared")
+		rdb.Do(ctx, "namespace", "add", "test_ns1", "test_ns_token1")
+		rdb.Do(ctx, "namespace", "add", "test_ns2", "test_ns_token2")
+
+		ns1Keys := []string{"foo_a", "foo_b", "foo_c", "key_l"}
+		ns2Keys := []string{"foo_d", "foo_e", "foo_f", "key_m"}
+		ns1PrefixKeys := []string{"foo_a", "foo_b", "foo_c"}
+		ns2PrefixKeys := []string{"foo_d", "foo_e", "foo_f"}
+
+		tokenKeys := map[string][]string{
+			"test_ns_token1": ns1Keys,
+			"test_ns_token2": ns2Keys,
+		}
+		tokenPrefixKeys := map[string][]string{
+			"test_ns_token1": ns1PrefixKeys,
+			"test_ns_token2": ns2PrefixKeys,
+		}
+
+		for token, keys := range tokenKeys {
+			rdb.Do(ctx, "auth", token)
+			for _, key := range keys {
+				require.NoError(t, rdb.Set(ctx, key, "hello", 0).Err())
+			}
+		}
+		for token, keys := range tokenKeys {
+			rdb.Do(ctx, "auth", token)
+			gotKeys := rdb.Keys(ctx, "*").Val()
+			sort.Slice(gotKeys, func(i, j int) bool {
+				return gotKeys[i] < gotKeys[j]
+			})
+			require.Equal(t, keys, gotKeys)
+		}
+
+		for token, prefixKeys := range tokenPrefixKeys {
+			rdb.Do(ctx, "auth", token)
+			gotKeys := rdb.Keys(ctx, "foo*").Val()
+			sort.Slice(gotKeys, func(i, j int) bool {
+				return gotKeys[i] < gotKeys[j]
+			})
+			require.Equal(t, prefixKeys, gotKeys)
+		}
+	})
+}
diff --git a/tests/tcl/tests/test_helper.tcl b/tests/tcl/tests/test_helper.tcl
index 8b1a521..82c577b 100644
--- a/tests/tcl/tests/test_helper.tcl
+++ b/tests/tcl/tests/test_helper.tcl
@@ -33,7 +33,6 @@ source tests/support/test.tcl
 source tests/support/util.tcl
 
 set ::all_tests {
-    unit/keyspace
     unit/scan
     unit/type/string
     unit/type/list
diff --git a/tests/tcl/tests/unit/keyspace.tcl b/tests/tcl/tests/unit/keyspace.tcl
deleted file mode 100644
index 079afe3..0000000
--- a/tests/tcl/tests/unit/keyspace.tcl
+++ /dev/null
@@ -1,168 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# Copyright (c) 2006-2020, Salvatore Sanfilippo
-# See bundled license file licenses/LICENSE.redis for details.
-
-# This file is copied and modified from the Redis project,
-# which started out as: https://github.com/redis/redis/blob/dbcc0a8/tests/unit/keyspace.tcl
-
-start_server {tags {"keyspace"}} {
-    test {DEL against a single item} {
-        r set x foo
-        assert {[r get x] eq "foo"}
-        r del x
-        r get x
-    } {}
-
-    test {Vararg DEL} {
-        r set foo1 a
-        r set foo2 b
-        r set foo3 c
-        list [r del foo1 foo2 foo3 foo4] [r mget foo1 foo2 foo3]
-    } {3 {{} {} {}}}
-
-    test {KEYS with pattern} {
-        foreach key {key_x key_y key_z foo_a foo_b foo_c} {
-            r set $key hello
-        }
-        lsort [r keys foo*]
-    } {foo_a foo_b foo_c}
-
-    test {KEYS to get all keys} {
-        lsort [r keys *]
-    } {foo_a foo_b foo_c key_x key_y key_z}
-
-    test {DBSIZE} {
-        r dbsize scan
-        after 100
-        r dbsize
-    } {6}
-
-    test {DEL all keys} {
-        foreach key [r keys *] {r del $key}
-        r dbsize scan
-        after 100
-        r dbsize
-    } {0}
-
-    test {EXISTS} {
-        set res {}
-        r set newkey test
-        append res [r exists newkey]
-        r del newkey
-        append res [r exists newkey]
-    } {10}
-
-    test {Zero length value in key. SET/GET/EXISTS} {
-        r set emptykey {}
-        set res [r get emptykey]
-        append res [r exists emptykey]
-        r del emptykey
-        append res [r exists emptykey]
-    } {10}
-
-    test {Commands pipelining} {
-        set fd [r channel]
-        puts -nonewline $fd "SET k1 xyzk\r\nGET k1\r\nPING\r\n"
-        flush $fd
-        set res {}
-        append res [string match OK* [r read]]
-        append res [r read]
-        append res [string match PONG* [r read]]
-        format $res
-    } {1xyzk1}
-
-    test {Non existing command} {
-        catch {r foobaredcommand} err
-        string match ERR* $err
-    } {1}
-
-    test {RANDOMKEY} {
-        r flushdb
-        r set foo x
-        r set bar y
-        set foo_seen 0
-        set bar_seen 0
-        for {set i 0} {$i < 1000} {incr i} {
-            set rkey [r randomkey]
-            if {$rkey eq {foo}} {
-                set foo_seen 1
-            }
-            if {$rkey eq {bar}} {
-                set bar_seen 1
-         
-            }
-        }
-        set sum [expr $foo_seen + $bar_seen]
-        assert {$sum > 0}
-    }
-
-    test {RANDOMKEY against empty DB} {
-        r flushdb
-        r randomkey
-    } {}
-
-    test {RANDOMKEY regression 1} {
-        r flushdb
-        r set x 10
-        r del x
-        r randomkey
-    } {}
-
-    test {KEYS * two times with long key, Github issue #1208} {
-        r flushdb
-        r set dlskeriewrioeuwqoirueioqwrueoqwrueqw test
-        r keys *
-        r keys *
-    } {dlskeriewrioeuwqoirueioqwrueoqwrueqw}
-
-    test {KEYS with multi namespace} {
-        r flushdb
-        r config set requirepass foobared
-
-        set namespaces {test_ns1 test_ns2}
-        set tokens {test_ns_token1 test_ns_token2}
-
-        set ns_keyspaces {{foo_a foo_b foo_c key_l} {foo_d foo_e foo_f key_m}}
-        set foo_prefix_keyspaces {{foo_a foo_b foo_c} {foo_d foo_e foo_f}}
-
-        # Add namespaces and write key
-        set index 0
-        foreach ns $namespaces {
-            r auth foobared
-            r namespace add $ns [lindex $tokens $index]
-
-            r auth [lindex $tokens $index]
-            foreach key [lindex $ns_keyspaces $index] {
-                r set $key hello
-            }
-
-            incr index
-        }
-
-        # Check KEYS and KEYS MATCH in different namespace
-        set index 0
-        foreach token $tokens {
-            r auth $token
-            assert_equal [lsort [r keys *]]  [lindex $ns_keyspaces $index]
-            assert_equal [lsort [r keys foo*]]  [lindex $foo_prefix_keyspaces $index]
-
-            incr index
-        }
-    }
-}