This is an automated email from the ASF dual-hosted git repository.
twice 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 8e3a0ae Move `runtest` to `x.py` with customized server/cli path
(#765)
8e3a0ae is described below
commit 8e3a0ae0b806546fa844b48282b02abdb41b4186
Author: Twice <[email protected]>
AuthorDate: Wed Aug 3 15:39:57 2022 +0800
Move `runtest` to `x.py` with customized server/cli path (#765)
---
.github/workflows/kvrocks.yaml | 4 +--
tests/tcl/runtest | 18 ----------
tests/tcl/tests/support/cli.tcl | 4 +--
tests/tcl/tests/support/server.tcl | 6 ++--
tests/tcl/tests/test_helper.tcl | 11 ++++++
x.py | 73 +++++++++++++++++++++++++++-----------
6 files changed, 70 insertions(+), 46 deletions(-)
diff --git a/.github/workflows/kvrocks.yaml b/.github/workflows/kvrocks.yaml
index 432e03e..a6106ff 100644
--- a/.github/workflows/kvrocks.yaml
+++ b/.github/workflows/kvrocks.yaml
@@ -163,9 +163,7 @@ jobs:
- name: Run Redis Tcl Test
run: |
export ${{ matrix.runtime_env_vars }}
- cp $HOME/local/bin/redis-cli tests/tcl/redis-cli
- cd tests/tcl
- ./runtest --dont-clean
+ ./x.py test tcl build --cli-path $HOME/local/bin/redis-cli
--dont-clean
SANITIZER_OUTPUT=$(grep "Sanitizer:" tests/tmp -r || true)
if [[ $SANITIZER_OUTPUT ]]; then
echo "$SANITIZER_OUTPUT"
diff --git a/tests/tcl/runtest b/tests/tcl/runtest
deleted file mode 100755
index 83bae7b..0000000
--- a/tests/tcl/runtest
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-TCL_VERSIONS="8.5 8.6"
-TCLSH=""
-
-for VERSION in $TCL_VERSIONS; do
- TCL=`which tclsh$VERSION 2>/dev/null` && TCLSH=$TCL
-done
-
-if [ -z $TCLSH ]
-then
- echo "You need tcl 8.5 or newer in order to run the Redis test"
- exit 1
-fi
-
-cp ../../build/kvrocks redis-server && $TCLSH tests/test_helper.tcl "${@}"
-status=$?
-rm ./redis-server
-exit $status
diff --git a/tests/tcl/tests/support/cli.tcl b/tests/tcl/tests/support/cli.tcl
index abf43d9..d6ebad8 100644
--- a/tests/tcl/tests/support/cli.tcl
+++ b/tests/tcl/tests/support/cli.tcl
@@ -36,7 +36,7 @@ proc rediscli_tls_config {testsdir} {
# Returns command line for executing redis-cli
proc rediscli {host port {opts {}}} {
- set cmd [list ./redis-cli -h $host -p $port]
+ set cmd [list $::redis_cli_path -h $host -p $port]
lappend cmd {*}[rediscli_tls_config "tests"]
lappend cmd {*}$opts
return $cmd
@@ -44,7 +44,7 @@ proc rediscli {host port {opts {}}} {
# Returns command line for executing redis-cli with a unix socket address
proc rediscli_unixsocket {unixsocket {opts {}}} {
- return [list ./redis-cli -s $unixsocket {*}$opts]
+ return [list $::redis_cli_path -s $unixsocket {*}$opts]
}
# Run redis-cli with specified args on the server of specified level.
diff --git a/tests/tcl/tests/support/server.tcl
b/tests/tcl/tests/support/server.tcl
index c4bb718..3e61084 100644
--- a/tests/tcl/tests/support/server.tcl
+++ b/tests/tcl/tests/support/server.tcl
@@ -235,11 +235,11 @@ proc create_server_config_file {filename config} {
proc spawn_server {config_file stdout stderr} {
if {$::valgrind} {
- set pid [exec valgrind --track-origins=yes --trace-children=yes
--suppressions=[pwd]/src/valgrind.sup --show-reachable=no
--show-possibly-lost=no --leak-check=full ./redis-server -c $config_file >>
$stdout 2>> $stderr &]
+ set pid [exec valgrind --track-origins=yes --trace-children=yes
--suppressions=[pwd]/src/valgrind.sup --show-reachable=no
--show-possibly-lost=no --leak-check=full $::redis_server_path -c $config_file
>> $stdout 2>> $stderr &]
} elseif ($::stack_logging) {
- set pid [exec /usr/bin/env MallocStackLogging=1
MallocLogFile=/tmp/malloc_log.txt ./redis-server -c $config_file >> $stdout 2>>
$stderr &]
+ set pid [exec /usr/bin/env MallocStackLogging=1
MallocLogFile=/tmp/malloc_log.txt $::redis_server_path -c $config_file >>
$stdout 2>> $stderr &]
} else {
- set pid [exec ./redis-server -c $config_file >> $stdout 2>> $stderr &]
+ set pid [exec $::redis_server_path -c $config_file >> $stdout 2>>
$stderr &]
}
if {$::wait_server} {
diff --git a/tests/tcl/tests/test_helper.tcl b/tests/tcl/tests/test_helper.tcl
index e550137..eea6b4f 100644
--- a/tests/tcl/tests/test_helper.tcl
+++ b/tests/tcl/tests/test_helper.tcl
@@ -551,10 +551,15 @@ proc print_help_screen {} {
"--port <port> TCP port to use against external host."
"--baseport <port> Initial port number for spawned redis servers."
"--portcount <num> Port range for spawned redis servers."
+ "--server-path <p> Path for redis server (default ./redis-server)."
+ "--cli-path <path> Path for redis CLI (default ./redis-cli)."
"--help Print this help screen."
} "\n"]
}
+set ::redis_server_path ./redis-server
+set ::redis_cli_path ./redis-cli
+
# parse arguments
for {set j 0} {$j < [llength $argv]} {incr j} {
set opt [lindex $argv $j]
@@ -655,6 +660,12 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
} elseif {$opt eq {--timeout}} {
set ::timeout $arg
incr j
+ } elseif {$opt eq {--server-path}} {
+ set ::redis_server_path $arg
+ incr j
+ } elseif {$opt eq {--cli-path}} {
+ set ::redis_cli_path $arg
+ incr j
} elseif {$opt eq {--help}} {
print_help_screen
exit 0
diff --git a/x.py b/x.py
index c0f8a3b..46c012e 100755
--- a/x.py
+++ b/x.py
@@ -17,17 +17,19 @@
# specific language governing permissions and limitations
# under the License.
-from argparse import Namespace, ArgumentParser, ArgumentDefaultsHelpFormatter
+from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, REMAINDER
from glob import glob
from os import makedirs
from pathlib import Path
import re
from subprocess import Popen, PIPE
import sys
-from typing import Callable, List, Any, Optional, TextIO
+from typing import List, Any, Optional, TextIO, Tuple
from shutil import copyfile
CMAKE_REQUIRE_VERSION = (3, 13, 0)
+TCL_REQUIRE_VERSION = (8, 5, 0)
+
SEMVER_REGEX = re.compile(
r"""
^
@@ -49,7 +51,7 @@ SEMVER_REGEX = re.compile(
re.VERBOSE,
)
-def run(*args: str, msg: Optional[str]=None, verbose: bool=False, **kwargs:
Any) -> Popen:
+def run(*args: str, msg: Optional[str]=None, verbose: bool=False, **kwargs:
Any) -> Popen[Any]:
sys.stdout.flush()
if verbose:
print(f"$ {' '.join(args)}")
@@ -57,11 +59,9 @@ def run(*args: str, msg: Optional[str]=None, verbose:
bool=False, **kwargs: Any)
p = Popen(args, **kwargs)
code = p.wait()
if code != 0:
- err = f"""
-failed to run: {args}
-exit with code: {code}
-error message: {msg}
-"""
+ err = f"\nfailed to run: {args}\nexit with code: {code}\n"
+ if msg:
+ err += f"error message: {msg}\n"
raise RuntimeError(err)
return p
@@ -70,9 +70,19 @@ def run_pipe(*args: str, msg: Optional[str]=None, verbose:
bool=False, **kwargs:
p = run(*args, msg=msg, verbose=verbose, stdout=PIPE, text=True, **kwargs)
return p.stdout # type: ignore
-def find_command(command: str, msg: Optional[str]=None):
+def find_command(command: str, msg: Optional[str]=None) -> str:
return run_pipe("which", command, msg=msg).read().strip()
+def check_version(current: str, required: Tuple[int, int, int], prog_name:
Optional[str] = None) -> None:
+ require_version = '.'.join(map(str, required))
+ semver_match = SEMVER_REGEX.match(current)
+ if semver_match is None:
+ raise RuntimeError(f"{prog_name} {require_version} or higher is
required, got: {current}")
+ semver_dict = semver_match.groupdict()
+ semver = (int(semver_dict["major"]), int(semver_dict["minor"]),
int(semver_dict["patch"]))
+ if semver < required:
+ raise RuntimeError(f"{prog_name} {require_version} or higher is
required, got: {current}")
+
def build(dir: str, jobs: int, ghproxy: bool, ninja: bool, unittest: bool,
compiler: str, cmake_path: str, D: List[str]) -> None:
basedir = Path(__file__).parent.absolute()
@@ -83,14 +93,7 @@ def build(dir: str, jobs: int, ghproxy: bool, ninja: bool,
unittest: bool, compi
output = run_pipe("head", "-n", "1", stdin=output)
output = run_pipe("sed", "s/[^0-9.]*//g", stdin=output)
cmake_version = output.read().strip()
- cmake_require_version = '.'.join(map(str, CMAKE_REQUIRE_VERSION))
- cmake_semver_match = SEMVER_REGEX.match(cmake_version)
- if cmake_semver_match is None:
- raise RuntimeError(f"CMake {cmake_require_version} or higher is
required, got: {cmake_version}")
- cmake_semver_dict = cmake_semver_match.groupdict()
- cmake_semver = (int(cmake_semver_dict["major"]),
int(cmake_semver_dict["minor"]), int(cmake_semver_dict["patch"]))
- if cmake_semver < CMAKE_REQUIRE_VERSION:
- raise RuntimeError(f"CMake {cmake_require_version} or higher is
required, got: {cmake_version}")
+ check_version(cmake_version, CMAKE_REQUIRE_VERSION, "CMake")
makedirs(dir, exist_ok=True)
@@ -116,7 +119,7 @@ def cpplint() -> None:
command = find_command("cpplint", msg="cpplint is required")
options = ["--linelength=120",
"--filter=-build/include_subdir,-legal/copyright,-build/c++11"]
sources = [*glob("src/*.h"), *glob("src/*.cc")]
- run(command, *options, *sources)
+ run(command, *options, *sources, verbose=True)
def cppcheck() -> None:
command = find_command("cppcheck", msg="cppcheck is required")
@@ -132,7 +135,7 @@ def cppcheck() -> None:
sources = ["src"]
- run(command, *options, *sources)
+ run(command, *options, *sources, verbose=True)
def write_version(release_version: str) -> str:
version = release_version.strip()
@@ -204,7 +207,20 @@ def package_fpm(package_type: str, release_version: str,
dir: str, jobs: int) ->
'--license', 'Apache-2.0'
]
- run(fpm, *fpm_opts)
+ run(fpm, *fpm_opts, verbose=True)
+
+def test_tcl(dir: str, rest: List[str]) -> None:
+ tclsh = find_command('tclsh', msg='TCL is required for testing')
+
+ output = run_pipe('echo', 'puts [info patchlevel];exit 0')
+ output = run_pipe(tclsh, stdin=output)
+ tcl_version = output.read().strip()
+ check_version(tcl_version, TCL_REQUIRE_VERSION, "tclsh")
+
+ tcldir = Path(__file__).parent.absolute() / 'tests' / 'tcl'
+ run(tclsh, 'tests/test_helper.tcl', '--server-path',
str(Path(dir).absolute() / 'kvrocks'), *rest,
+ cwd=str(tcldir), verbose=True
+ )
if __name__ == '__main__':
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
@@ -273,6 +289,23 @@ if __name__ == '__main__':
parser_package_fpm.add_argument('-j', '--jobs', default=4, metavar='N',
help='execute N build jobs concurrently')
parser_package_fpm.set_defaults(func=package_fpm)
+ parser_test = subparsers.add_parser(
+ 'test',
+ description="Test against a specific kvrocks build",
+ help="Test against a specific kvrocks build",
+ formatter_class=ArgumentDefaultsHelpFormatter,
+ )
+ parser_test.set_defaults(func=parser_test.print_help)
+ parser_test_subparsers = parser_test.add_subparsers()
+ parser_test_tcl = parser_test_subparsers.add_parser(
+ 'tcl',
+ description="Test kvrocks via TCL scripts",
+ help="Test kvrocks via TCL scripts",
+ )
+ parser_test_tcl.add_argument('dir', metavar='BUILD_DIR', nargs='?',
default='build', help="directory including kvrocks build files")
+ parser_test_tcl.add_argument('rest', nargs=REMAINDER, help="the rest of
arguments to forward to TCL scripts")
+ parser_test_tcl.set_defaults(func=test_tcl)
+
args = parser.parse_args()
arg_dict = dict(vars(args))