mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -05:00
e5227aab89
interestingly the latency monitor test fails because valgrind is slow enough so that the time inside PEXPIREAT command from the moment of the first mstime() call to get the basetime until checkAlreadyExpired calls mstime() again is more than 1ms, and that test was too sensitive. using this opportunity to speed up the test (unrelated to the failure) the fix is just the longer time passed to PEXPIRE.
289 lines
8.1 KiB
Tcl
289 lines
8.1 KiB
Tcl
source tests/support/cli.tcl
|
|
|
|
start_server {tags {"cli"}} {
|
|
proc open_cli {{opts "-n 9"}} {
|
|
set ::env(TERM) dumb
|
|
set cmdline [rediscli [srv port] $opts]
|
|
set fd [open "|$cmdline" "r+"]
|
|
fconfigure $fd -buffering none
|
|
fconfigure $fd -blocking false
|
|
fconfigure $fd -translation binary
|
|
set _ $fd
|
|
}
|
|
|
|
proc close_cli {fd} {
|
|
close $fd
|
|
}
|
|
|
|
proc read_cli {fd} {
|
|
set buf [read $fd]
|
|
while {[string length $buf] == 0} {
|
|
# wait some time and try again
|
|
after 10
|
|
set buf [read $fd]
|
|
}
|
|
set _ $buf
|
|
}
|
|
|
|
proc write_cli {fd buf} {
|
|
puts $fd $buf
|
|
flush $fd
|
|
}
|
|
|
|
# Helpers to run tests in interactive mode
|
|
|
|
proc format_output {output} {
|
|
set _ [string trimright [regsub -all "\r" $output ""] "\n"]
|
|
}
|
|
|
|
proc run_command {fd cmd} {
|
|
write_cli $fd $cmd
|
|
set _ [format_output [read_cli $fd]]
|
|
}
|
|
|
|
proc test_interactive_cli {name code} {
|
|
set ::env(FAKETTY) 1
|
|
set fd [open_cli]
|
|
test "Interactive CLI: $name" $code
|
|
close_cli $fd
|
|
unset ::env(FAKETTY)
|
|
}
|
|
|
|
# Helpers to run tests where stdout is not a tty
|
|
proc write_tmpfile {contents} {
|
|
set tmp [tmpfile "cli"]
|
|
set tmpfd [open $tmp "w"]
|
|
puts -nonewline $tmpfd $contents
|
|
close $tmpfd
|
|
set _ $tmp
|
|
}
|
|
|
|
proc _run_cli {opts args} {
|
|
set cmd [rediscli [srv port] [list -n 9 {*}$args]]
|
|
foreach {key value} $opts {
|
|
if {$key eq "pipe"} {
|
|
set cmd "sh -c \"$value | $cmd\""
|
|
}
|
|
if {$key eq "path"} {
|
|
set cmd "$cmd < $value"
|
|
}
|
|
}
|
|
|
|
set fd [open "|$cmd" "r"]
|
|
fconfigure $fd -buffering none
|
|
fconfigure $fd -translation binary
|
|
set resp [read $fd 1048576]
|
|
close $fd
|
|
set _ [format_output $resp]
|
|
}
|
|
|
|
proc run_cli {args} {
|
|
_run_cli {} {*}$args
|
|
}
|
|
|
|
proc run_cli_with_input_pipe {cmd args} {
|
|
_run_cli [list pipe $cmd] -x {*}$args
|
|
}
|
|
|
|
proc run_cli_with_input_file {path args} {
|
|
_run_cli [list path $path] -x {*}$args
|
|
}
|
|
|
|
proc test_nontty_cli {name code} {
|
|
test "Non-interactive non-TTY CLI: $name" $code
|
|
}
|
|
|
|
# Helpers to run tests where stdout is a tty (fake it)
|
|
proc test_tty_cli {name code} {
|
|
set ::env(FAKETTY) 1
|
|
test "Non-interactive TTY CLI: $name" $code
|
|
unset ::env(FAKETTY)
|
|
}
|
|
|
|
test_interactive_cli "INFO response should be printed raw" {
|
|
set lines [split [run_command $fd info] "\n"]
|
|
foreach line $lines {
|
|
assert [regexp {^$|^#|^[a-z0-9_]+:.+} $line]
|
|
}
|
|
}
|
|
|
|
test_interactive_cli "Status reply" {
|
|
assert_equal "OK" [run_command $fd "set key foo"]
|
|
}
|
|
|
|
test_interactive_cli "Integer reply" {
|
|
assert_equal "(integer) 1" [run_command $fd "incr counter"]
|
|
}
|
|
|
|
test_interactive_cli "Bulk reply" {
|
|
r set key foo
|
|
assert_equal "\"foo\"" [run_command $fd "get key"]
|
|
}
|
|
|
|
test_interactive_cli "Multi-bulk reply" {
|
|
r rpush list foo
|
|
r rpush list bar
|
|
assert_equal "1) \"foo\"\n2) \"bar\"" [run_command $fd "lrange list 0 -1"]
|
|
}
|
|
|
|
test_interactive_cli "Parsing quotes" {
|
|
assert_equal "OK" [run_command $fd "set key \"bar\""]
|
|
assert_equal "bar" [r get key]
|
|
assert_equal "OK" [run_command $fd "set key \" bar \""]
|
|
assert_equal " bar " [r get key]
|
|
assert_equal "OK" [run_command $fd "set key \"\\\"bar\\\"\""]
|
|
assert_equal "\"bar\"" [r get key]
|
|
assert_equal "OK" [run_command $fd "set key \"\tbar\t\""]
|
|
assert_equal "\tbar\t" [r get key]
|
|
|
|
# invalid quotation
|
|
assert_equal "Invalid argument(s)" [run_command $fd "get \"\"key"]
|
|
assert_equal "Invalid argument(s)" [run_command $fd "get \"key\"x"]
|
|
|
|
# quotes after the argument are weird, but should be allowed
|
|
assert_equal "OK" [run_command $fd "set key\"\" bar"]
|
|
assert_equal "bar" [r get key]
|
|
}
|
|
|
|
test_tty_cli "Status reply" {
|
|
assert_equal "OK" [run_cli set key bar]
|
|
assert_equal "bar" [r get key]
|
|
}
|
|
|
|
test_tty_cli "Integer reply" {
|
|
r del counter
|
|
assert_equal "(integer) 1" [run_cli incr counter]
|
|
}
|
|
|
|
test_tty_cli "Bulk reply" {
|
|
r set key "tab\tnewline\n"
|
|
assert_equal "\"tab\\tnewline\\n\"" [run_cli get key]
|
|
}
|
|
|
|
test_tty_cli "Multi-bulk reply" {
|
|
r del list
|
|
r rpush list foo
|
|
r rpush list bar
|
|
assert_equal "1) \"foo\"\n2) \"bar\"" [run_cli lrange list 0 -1]
|
|
}
|
|
|
|
test_tty_cli "Read last argument from pipe" {
|
|
assert_equal "OK" [run_cli_with_input_pipe "echo foo" set key]
|
|
assert_equal "foo\n" [r get key]
|
|
}
|
|
|
|
test_tty_cli "Read last argument from file" {
|
|
set tmpfile [write_tmpfile "from file"]
|
|
assert_equal "OK" [run_cli_with_input_file $tmpfile set key]
|
|
assert_equal "from file" [r get key]
|
|
}
|
|
|
|
test_nontty_cli "Status reply" {
|
|
assert_equal "OK" [run_cli set key bar]
|
|
assert_equal "bar" [r get key]
|
|
}
|
|
|
|
test_nontty_cli "Integer reply" {
|
|
r del counter
|
|
assert_equal "1" [run_cli incr counter]
|
|
}
|
|
|
|
test_nontty_cli "Bulk reply" {
|
|
r set key "tab\tnewline\n"
|
|
assert_equal "tab\tnewline" [run_cli get key]
|
|
}
|
|
|
|
test_nontty_cli "Multi-bulk reply" {
|
|
r del list
|
|
r rpush list foo
|
|
r rpush list bar
|
|
assert_equal "foo\nbar" [run_cli lrange list 0 -1]
|
|
}
|
|
|
|
test_nontty_cli "Read last argument from pipe" {
|
|
assert_equal "OK" [run_cli_with_input_pipe "echo foo" set key]
|
|
assert_equal "foo\n" [r get key]
|
|
}
|
|
|
|
test_nontty_cli "Read last argument from file" {
|
|
set tmpfile [write_tmpfile "from file"]
|
|
assert_equal "OK" [run_cli_with_input_file $tmpfile set key]
|
|
assert_equal "from file" [r get key]
|
|
}
|
|
|
|
proc test_redis_cli_rdb_dump {} {
|
|
r flushdb
|
|
|
|
set dir [lindex [r config get dir] 1]
|
|
|
|
assert_equal "OK" [r debug populate 100000 key 1000]
|
|
catch {run_cli --rdb "$dir/cli.rdb"} output
|
|
assert_match {*Transfer finished with success*} $output
|
|
|
|
file delete "$dir/dump.rdb"
|
|
file rename "$dir/cli.rdb" "$dir/dump.rdb"
|
|
|
|
assert_equal "OK" [r set should-not-exist 1]
|
|
assert_equal "OK" [r debug reload nosave]
|
|
assert_equal {} [r get should-not-exist]
|
|
}
|
|
|
|
test_nontty_cli "Dumping an RDB" {
|
|
# Disk-based master
|
|
assert_match "OK" [r config set repl-diskless-sync no]
|
|
test_redis_cli_rdb_dump
|
|
|
|
# Disk-less master
|
|
assert_match "OK" [r config set repl-diskless-sync yes]
|
|
assert_match "OK" [r config set repl-diskless-sync-delay 0]
|
|
test_redis_cli_rdb_dump
|
|
}
|
|
|
|
test_nontty_cli "Connecting as a replica" {
|
|
set fd [open_cli "--replica"]
|
|
wait_for_condition 200 500 {
|
|
[string match {*slave0:*state=online*} [r info]]
|
|
} else {
|
|
fail "redis-cli --replica did not connect"
|
|
}
|
|
|
|
for {set i 0} {$i < 100} {incr i} {
|
|
r set test-key test-value-$i
|
|
}
|
|
r client kill type slave
|
|
catch {
|
|
assert_match {*SET*key-a*} [read_cli $fd]
|
|
}
|
|
|
|
close_cli $fd
|
|
}
|
|
|
|
test_nontty_cli "Piping raw protocol" {
|
|
set fd [open_cli "--pipe"]
|
|
fconfigure $fd -blocking true
|
|
|
|
# Create a new deferring client and overwrite its fd
|
|
set client [redis [srv 0 "host"] [srv 0 "port"] 1 0]
|
|
set ::redis::fd($::redis::id) $fd
|
|
$client select 9
|
|
|
|
r del test-counter
|
|
for {set i 0} {$i < 10000} {incr i} {
|
|
$client incr test-counter
|
|
$client set large-key [string repeat "x" 20000]
|
|
}
|
|
|
|
for {set i 0} {$i < 1000} {incr i} {
|
|
$client set very-large-key [string repeat "x" 512000]
|
|
}
|
|
|
|
close $fd write
|
|
set output [read_cli $fd]
|
|
|
|
assert_equal {10000} [r get test-counter]
|
|
assert_match {*All data transferred*errors: 0*replies: 21001*} $output
|
|
|
|
close_cli $fd
|
|
}
|
|
}
|