From f302818d221cc526793749eab74952641b7be22f Mon Sep 17 00:00:00 2001 From: liyaojie Date: Thu, 24 Aug 2023 20:07:55 +0800 Subject: [PATCH] =?UTF-8?q?=20add=20the=20test=20for=20TairString=E3=80=81?= =?UTF-8?q?TairHash=20and=20TairSzset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liyaojie --- .github/workflows/ci.yml | 40 +++++++++++++++++++ internal/commands/table.go | 22 +++++------ scripts/table.json | 55 +++++++++++++++++++++++++++ tests/helpers/commands/__init__.py | 3 ++ tests/helpers/commands/tair_hash.py | 55 +++++++++++++++++++++++++++ tests/helpers/commands/tair_string.py | 43 +++++++++++++++++++++ tests/helpers/commands/tair_zset.py | 47 +++++++++++++++++++++++ tests/helpers/data_inserter.py | 7 +++- tests/helpers/redis.py | 12 +++++- 9 files changed, 270 insertions(+), 14 deletions(-) create mode 100644 tests/helpers/commands/tair_hash.py create mode 100644 tests/helpers/commands/tair_string.py create mode 100644 tests/helpers/commands/tair_zset.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34c20b19..8c98d5db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,7 @@ jobs: strategy: matrix: redis-version: [ "2.8", "3.0", "4.0", "5.0", "6.0", "7.0" ] + fail-fast: false container: ubuntu:latest steps: - name: Git checkout @@ -30,6 +31,45 @@ jobs: cp src/redis-server bin/redis-server echo "$GITHUB_WORKSPACE/redis/bin" >> $GITHUB_PATH + - name: clone and make TairString Module + if: contains( '5.0, 6.0, 7.0', matrix.redis-version) + run: | + cd $GITHUB_WORKSPACE + apt-get install -y cmake + git clone https://github.com/tair-opensource/TairString.git + cd TairString + mkdir build + cd build + cmake ../ && make -j + cp $GITHUB_WORKSPACE/TairString/lib/tairstring_module.so /lib + + + + - name: clone and make TairHash Module + if: contains( '5.0, 6.0, 7.0', matrix.redis-version) + run: | + cd $GITHUB_WORKSPACE + git clone https://github.com/tair-opensource/TairHash.git + cd TairHash + mkdir build + cd build + cmake ../ && make -j + cp $GITHUB_WORKSPACE/TairHash/lib/tairhash_module.so /lib + + + + - name: clone and make TairZset Module + if: contains( '5.0, 6.0, 7.0', matrix.redis-version) + run: | + cd $GITHUB_WORKSPACE + git clone https://github.com/tair-opensource/TairZset.git + cd TairZset + mkdir build + cd build + cmake ../ && make -j + cp $GITHUB_WORKSPACE/TairZset/lib/tairzset_module.so /lib + + - name: Setup Python uses: actions/setup-python@v4 with: diff --git a/internal/commands/table.go b/internal/commands/table.go index 8457f102..6053b778 100644 --- a/internal/commands/table.go +++ b/internal/commands/table.go @@ -1,22 +1,22 @@ package commands var containers = map[string]bool{ - "MODULE": true, - "CLUSTER": true, - "XGROUP": true, + "XINFO": true, "COMMAND": true, - "SLOWLOG": true, - "OBJECT": true, - "MEMORY": true, - "CONFIG": true, "FUNCTION": true, + "CONFIG": true, + "MODULE": true, + "MEMORY": true, "LATENCY": true, - "XINFO": true, - "CLIENT": true, - "SENTINEL": true, - "PUBSUB": true, "SCRIPT": true, "ACL": true, + "CLUSTER": true, + "CLIENT": true, + "XGROUP": true, + "PUBSUB": true, + "OBJECT": true, + "SENTINEL": true, + "SLOWLOG": true, } var redisCommands = map[string]redisCommand{ "LLEN": { diff --git a/scripts/table.json b/scripts/table.json index 11987b5c..86835529 100644 --- a/scripts/table.json +++ b/scripts/table.json @@ -3582,7 +3582,62 @@ } } ] + }, + "TairHash": { + "EXHSET": [ + { + "begin_search": { + "index": { + "pos": 1 + } + }, + "find_keys": { + "range": { + "lastkey": 0, + "step": 1, + "limit": 0 + } + } + } + ] + }, + "TairString": { + "EXSET": [ + { + "begin_search": { + "index": { + "pos": 1 + } + }, + "find_keys": { + "range": { + "lastkey": 0, + "step": 1, + "limit": 0 + } + } + } + ] + }, + "TairZset": { + "EXZADD ": [ + { + "begin_search": { + "index": { + "pos": 1 + } + }, + "find_keys": { + "range": { + "lastkey": 0, + "step": 1, + "limit": 0 + } + } + } + ] } + }, "container": [ "MODULE", diff --git a/tests/helpers/commands/__init__.py b/tests/helpers/commands/__init__.py index a1027747..b8a42486 100644 --- a/tests/helpers/commands/__init__.py +++ b/tests/helpers/commands/__init__.py @@ -1,2 +1,5 @@ from .select import SelectChecker from .string import StringChecker +from .tair_string import TairStringChecker +from .tair_hash import TairHashChecker +from .tair_zset import TairZsetChecker \ No newline at end of file diff --git a/tests/helpers/commands/tair_hash.py b/tests/helpers/commands/tair_hash.py new file mode 100644 index 00000000..d47abcf2 --- /dev/null +++ b/tests/helpers/commands/tair_hash.py @@ -0,0 +1,55 @@ +import pybbt + +from helpers.commands.checker import Checker +from helpers.redis import Redis +from helpers.constant import REDIS_SERVER_VERSION + + +class TairHashChecker(Checker): + PREFIX = "tairHash" + + def __init__(self): + self.cnt = 0 + + def add_data(self, r: Redis, cross_slots_cmd: bool): + if REDIS_SERVER_VERSION < 5.0: + return + p = r.pipeline() + # different parameters type + p.execute_command("EXHSET",f"{self.PREFIX}_{self.cnt}", "field", "value") + p.execute_command("EXHSET",f"{self.PREFIX}_{self.cnt}_ABS", "field_abs", "value_abs", "ABS", 2) + p.execute_command("EXHSET",f"{self.PREFIX}_{self.cnt}_EX", "field_ex", "value_ex", "EX", 20000) + + # different key + # different field + p.execute_command("EXHSET",f"{self.PREFIX}_{self.cnt}_ALL_01", "field_all_01", "value_all_01", "EX", 20000, "ABS", 2) + p.execute_command("EXHSET",f"{self.PREFIX}_{self.cnt}_ALL_01", "field_all_02", "value_all_02", "EX", 20000, "ABS", 3) + + p.execute_command("EXHSET",f"{self.PREFIX}_{self.cnt}_ALL_02", "field_all_01", "value_all_01", "EX", 20000, "ABS", 2) + p.execute_command("EXHSET",f"{self.PREFIX}_{self.cnt}_ALL_02", "field_all_02", "value_all_02", "EX", 20000, "ABS", 3) + + ret = p.execute() + # pybbt.ASSERT_EQ(ret, [b"1", b"1", b"1", b"1",b"1", b"1",b"1"]) + pybbt.ASSERT_EQ(ret, [1, 1, 1, 1, 1, 1, 1]) + + self.cnt += 1 + + def check_data(self, r: Redis, cross_slots_cmd: bool): + if REDIS_SERVER_VERSION < 5.0: + return + for i in range(self.cnt): + p = r.pipeline() + + p.execute_command("EXHGET",f"{self.PREFIX}_{i}", "field") + p.execute_command("EXHGET",f"{self.PREFIX}_{i}_ABS", "field_abs") + p.execute_command("EXHGET",f"{self.PREFIX}_{i}_EX", "field_ex") + + p.execute_command("EXHGET",f"{self.PREFIX}_{i}_ALL_01", "field_all_01") + p.execute_command("EXHGET",f"{self.PREFIX}_{i}_ALL_01", "field_all_02") + + p.execute_command("EXHGET",f"{self.PREFIX}_{i}_ALL_02", "field_all_01") + p.execute_command("EXHGET",f"{self.PREFIX}_{i}_ALL_02", "field_all_02") + + ret = p.execute() + # 需要确定一下如果一个命令返回多个值是如何封装的 + pybbt.ASSERT_EQ(ret, [b"value", b"value_abs", b"value_ex", b"value_all_01", b"value_all_02", b"value_all_01", b"value_all_02",]) \ No newline at end of file diff --git a/tests/helpers/commands/tair_string.py b/tests/helpers/commands/tair_string.py new file mode 100644 index 00000000..821d5a34 --- /dev/null +++ b/tests/helpers/commands/tair_string.py @@ -0,0 +1,43 @@ +import pybbt + +from helpers.commands.checker import Checker +from helpers.redis import Redis +from helpers.constant import REDIS_SERVER_VERSION + + +class TairStringChecker(Checker): + PREFIX = "tairString" + + def __init__(self): + self.cnt = 0 + + def add_data(self, r: Redis, cross_slots_cmd: bool): + if REDIS_SERVER_VERSION < 5.0: + return + p = r.pipeline() + # different parameters type + p.execute_command("EXSET",f"{self.PREFIX}_{self.cnt}_ABS", "abs_value", "VER",2) + p.execute_command("EXSET",f"{self.PREFIX}_{self.cnt}_FLAGS", "flags_value", "FLAGS", 2) + p.execute_command("Exset",f"{self.PREFIX}_{self.cnt}_EX", "ex_value", "EX", 20000) + + # different key + p.execute_command("Exset",f"{self.PREFIX}_{self.cnt}_ALL_01", "all_value_01", "EX", 20000, "ABS", 3, "FLAGS", 4) + p.execute_command("Exset",f"{self.PREFIX}_{self.cnt}_ALL_02", "all_value_02", "EX", 20000, "ABS", 4, "FLAGS", 5) + ret = p.execute() + pybbt.ASSERT_EQ(ret, [b"OK", b"OK", b"OK", b"OK", b"OK"]) + self.cnt += 1 + + def check_data(self, r: Redis, cross_slots_cmd: bool): + if REDIS_SERVER_VERSION < 5.0: + return + for i in range(self.cnt): + p = r.pipeline() + + p.execute_command("EXGET",f"{self.PREFIX}_{i}_ABS") + p.execute_command("EXGET",f"{self.PREFIX}_{i}_FLAGS", "WITHFLAGS") + p.execute_command("EXGET",f"{self.PREFIX}_{i}_EX") + p.execute_command("EXGET",f"{self.PREFIX}_{i}_ALL_01", "WITHFLAGS") + p.execute_command("EXGET",f"{self.PREFIX}_{i}_ALL_02", "WITHFLAGS") + + ret = p.execute() + pybbt.ASSERT_EQ(ret, [[b"abs_value", 1], [b"flags_value", 1, 2], [b"ex_value", 1], [b"all_value_01", 3, 4], [b"all_value_02", 4, 5]]) diff --git a/tests/helpers/commands/tair_zset.py b/tests/helpers/commands/tair_zset.py new file mode 100644 index 00000000..fff80c4c --- /dev/null +++ b/tests/helpers/commands/tair_zset.py @@ -0,0 +1,47 @@ +import pybbt + +from helpers.commands.checker import Checker +from helpers.redis import Redis +from helpers.constant import REDIS_SERVER_VERSION + + +class TairZsetChecker(Checker): + PREFIX = "tairZset" + + def __init__(self): + self.cnt = 0 + + def add_data(self, r: Redis, cross_slots_cmd: bool): + if REDIS_SERVER_VERSION < 5.0: + return + p = r.pipeline() + + # different key + # int or float + p.execute_command("EXZADD",f"{self.PREFIX}_{self.cnt}_key01", "1.1#1.2", "mem01","2.2#2.3", "mem02") + p.execute_command("EXZADD",f"{self.PREFIX}_{self.cnt}_key01", "3.3#3.4", "mem03","4.4#4.5", "mem04") + p.execute_command("EXZADD",f"{self.PREFIX}_{self.cnt}_key02", "1.1#1.2", "mem01") + p.execute_command("EXZADD",f"{self.PREFIX}_{self.cnt}_key02", "2.2#2.3", "mem02") + ret = p.execute() + pybbt.ASSERT_EQ(ret, [2, 2, 1, 1]) + + self.cnt += 1 + + def check_data(self, r: Redis, cross_slots_cmd: bool): + if REDIS_SERVER_VERSION < 5.0: + return + for i in range(self.cnt): + p = r.pipeline() + p.execute_command("EXZSCORE",f"{self.PREFIX}_{i}_key01", "mem01") + p.execute_command("EXZSCORE",f"{self.PREFIX}_{i}_key01", "mem02") + p.execute_command("EXZSCORE",f"{self.PREFIX}_{i}_key01", "mem03") + p.execute_command("EXZSCORE",f"{self.PREFIX}_{i}_key01", "mem04") + p.execute_command("EXZSCORE",f"{self.PREFIX}_{i}_key02", "mem01") + p.execute_command("EXZSCORE",f"{self.PREFIX}_{i}_key02", "mem02") + + ret = p.execute() + pybbt.ASSERT_EQ(ret, + [b'1.1000000000000001#1.2', + b'2.2000000000000002#2.2999999999999998', b'3.2999999999999998#3.3999999999999999', + b'4.4000000000000004#4.5', b'1.1000000000000001#1.2', + b'2.2000000000000002#2.2999999999999998'] ) diff --git a/tests/helpers/data_inserter.py b/tests/helpers/data_inserter.py index d513205f..504ed1e1 100644 --- a/tests/helpers/data_inserter.py +++ b/tests/helpers/data_inserter.py @@ -1,5 +1,6 @@ -from helpers.commands import SelectChecker, StringChecker +from helpers.commands import SelectChecker, StringChecker, TairStringChecker, TairHashChecker, TairZsetChecker from helpers.redis import Redis +from helpers.constant import PATH_REDIS_SERVER, REDIS_SERVER_VERSION class DataInserter: @@ -7,8 +8,12 @@ def __init__(self, ): self.checkers = [ StringChecker(), SelectChecker(), + TairStringChecker(), + TairHashChecker(), + TairZsetChecker(), ] + def add_data(self, r: Redis, cross_slots_cmd: bool): for checker in self.checkers: checker.add_data(r, cross_slots_cmd) diff --git a/tests/helpers/redis.py b/tests/helpers/redis.py index 3452f521..b90cf7b9 100644 --- a/tests/helpers/redis.py +++ b/tests/helpers/redis.py @@ -17,7 +17,15 @@ def __init__(self, args=None): self.port = get_free_port() self.dir = f"{self.case_ctx.dir}/redis_{self.port}" args.extend(["--port", str(self.port)]) - self.server = pybbt.Launcher(args=[PATH_REDIS_SERVER] + args, work_dir=self.dir) + + if REDIS_SERVER_VERSION > 4.0: + args.extend(["--loadmodule", "tairstring_module.so"]) + args.extend(["--loadmodule", "tairhash_module.so"]) + args.extend(["--loadmodule", "tairzset_module.so"]) + self.server = pybbt.Launcher(args=[PATH_REDIS_SERVER] + args, work_dir=self.dir) + else: + self.server = pybbt.Launcher(args=[PATH_REDIS_SERVER] + args, work_dir=self.dir) + self._wait_start() self.client = redis.Redis(host=self.host, port=self.port) self.case_ctx.add_exit_hook(lambda: self.server.stop()) @@ -58,4 +66,4 @@ def is_cluster(self): return self.client.info()["cluster_enabled"] def dbsize(self): - return self.client.dbsize() + return self.client.dbsize() \ No newline at end of file