Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
49816941
Unverified
Commit
49816941
authored
Feb 27, 2019
by
chendianqiang
Committed by
GitHub
Feb 27, 2019
Browse files
Merge pull request #2 from antirez/unstable
merge from redis
parents
68ceb466
f311a529
Changes
120
Show whitespace changes
Inline
Side-by-side
tests/support/server.tcl
View file @
49816941
...
...
@@ -4,7 +4,7 @@ set ::valgrind_errors {}
proc start_server_error
{
config_file error
}
{
set err
{}
append err
"Can
t
' start the Redis server
\n
"
append err
"Can'
t
start the Redis server
\n
"
append err
"CONFIGURATION:"
append err
[
exec cat $config_file
]
append err
"
\n
ERROR:"
...
...
tests/support/test.tcl
View file @
49816941
set ::num_tests 0
set ::num_passed 0
set ::num_failed 0
set ::num_skipped 0
set ::num_aborted 0
set ::tests_failed
{}
proc fail
{
msg
}
{
...
...
@@ -68,10 +70,26 @@ proc test {name code {okpattern undefined}} {
# abort if tagged with a tag to deny
foreach tag $::denytags
{
if
{[
lsearch $::tags $tag
]
>= 0
}
{
incr ::num_aborted
send_data_packet $::test_server_fd ignore $name
return
}
}
# abort if test name in skiptests
if
{[
lsearch $::skiptests $name
]
>= 0
}
{
incr ::num_skipped
send_data_packet $::test_server_fd skip $name
return
}
# abort if test name in skiptests
if
{[
llength $::only_tests
]
> 0 &&
[
lsearch $::only_tests $name
]
< 0
}
{
incr ::num_skipped
send_data_packet $::test_server_fd skip $name
return
}
# check if tagged with at least 1 tag to allow when there *is* a list
# of tags to allow, because default policy is to run everything
if
{[
llength $::allowtags
]
> 0
}
{
...
...
@@ -82,6 +100,8 @@ proc test {name code {okpattern undefined}} {
}
}
if
{
$matched
< 1
}
{
incr ::num_aborted
send_data_packet $::test_server_fd ignore $name
return
}
}
...
...
tests/support/util.tcl
View file @
49816941
...
...
@@ -91,6 +91,14 @@ proc wait_for_sync r {
}
}
proc wait_for_ofs_sync
{
r1 r2
}
{
wait_for_condition 50 100
{
[
status $r1 master_repl_offset
]
eq
[
status $r2 master_repl_offset
]
}
else
{
fail
"replica didn't sync in time"
}
}
# Random integer between 0 and max
(
excluded
)
.
proc randomInt
{
max
}
{
expr
{
int
(
rand
()
*$max
)}
...
...
tests/test_helper.tcl
View file @
49816941
...
...
@@ -34,6 +34,7 @@ set ::all_tests {
unit/multi
unit/quit
unit/aofrw
unit/acl
integration/block-repl
integration/replication
integration/replication-2
...
...
@@ -74,7 +75,11 @@ set ::stack_logging 0
set ::verbose 0
set ::quiet 0
set ::denytags
{}
set ::skiptests
{}
set ::allowtags
{}
set ::only_tests
{}
set ::single_tests
{}
set ::skip_till
""
set ::external 0
;
# If
"1"
this means, we are running against external instance
set ::file
""
;
# If set, runs only the tests in this comma separated list
set ::curfile
""
;
# Hold the filename of the current suite
...
...
@@ -85,6 +90,8 @@ set ::last_progress [clock seconds]
set ::active_servers
{}
;
# Pids of active Redis instances.
set ::dont_clean 0
set ::wait_server 0
set ::stop_on_failure 0
set ::loop 0
# Set to 1 when we are running in client mode. The Redis test uses a
# server-client model to run tests simultaneously. The server instance
...
...
@@ -255,6 +262,8 @@ proc accept_test_clients {fd addr port} {
# testing: just used to signal that a given test started.
# ok: a test was executed with success.
# err: a test was executed with an error.
# skip: a test was skipped by skipfile or individual test options.
# ignore: a test was skipped by a group tag.
# exception: there was a runtime exception while executing the test.
# done: all the specified test file was processed, this test client is
# ready to accept a new task.
...
...
@@ -283,11 +292,24 @@ proc read_from_test_client fd {
puts
"
\[
[
colorstr green $status
]
\]
:
$data
"
}
set ::active_clients_task
(
$fd
)
"(OK)
$data
"
}
elseif
{
$status
eq
{
skip
}}
{
if
{
!$::quiet
}
{
puts
"
\[
[
colorstr yellow $status
]
\]
:
$data
"
}
}
elseif
{
$status
eq
{
ignore
}}
{
if
{
!$::quiet
}
{
puts
"
\[
[
colorstr cyan $status
]
\]
:
$data
"
}
}
elseif
{
$status
eq
{
err
}}
{
set err
"
\[
[
colorstr red $status
]
\]
:
$data
"
puts $err
lappend ::failed_tests $err
set ::active_clients_task
(
$fd
)
"(ERR)
$data
"
if
{
$::stop
_on_failure
}
{
puts -nonewline
"(Test stopped, press enter to continue)"
flush stdout
gets stdin
}
}
elseif
{
$status
eq
{
exception
}}
{
puts
"
\[
[
colorstr red $status
]
\]
:
$data
"
kill_clients
...
...
@@ -350,6 +372,9 @@ proc signal_idle_client fd {
send_data_packet $fd run
[
lindex $::all_tests $::next_test
]
lappend ::active_clients $fd
incr ::next_test
if
{
$::loop
&& $::next_test ==
[
llength $::all_tests
]}
{
set ::next_test 0
}
}
else
{
lappend ::idle_clients $fd
if
{[
llength $::active_clients
]
== 0
}
{
...
...
@@ -412,13 +437,19 @@ proc print_help_screen {} {
"--stack-logging Enable OSX leaks/malloc stack logging."
"--accurate Run slow randomized tests for more iterations."
"--quiet Don't show individual tests."
"--single <unit> Just execute the specified unit (see next option)."
"--single <unit> Just execute the specified unit (see next option).
this option can be repeated.
"
"--list-tests List all the available test units."
"--only <test> Just execute the specified test by test name. this option can be repeated."
"--skip-till <unit> Skip all units until (and including) the specified one."
"--clients <num> Number of test clients (default 16)."
"--timeout <sec> Test timeout in seconds (default 10 min)."
"--force-failure Force the execution of a test that always fails."
"--dont-clean don't delete redis log files after the run"
"--wait-server wait after server is started (so that you can attach a debugger)"
"--config <k> <v> Extra config file argument."
"--skipfile <file> Name of a file containing test names that should be skipped (one per line)."
"--dont-clean Don't delete redis log files after the run."
"--stop Blocks once the first test fails."
"--loop Execute the specified set of tests forever."
"--wait-server Wait after server is started (so that you can attach a debugger)."
"--help Print this help screen."
}
"
\n
"
]
}
...
...
@@ -436,6 +467,17 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
}
}
incr j
}
elseif
{
$opt
eq
{
--config
}}
{
set arg2
[
lindex $argv
[
expr $j+2
]]
lappend ::global_overrides $arg
lappend ::global_overrides $arg2
incr j 2
}
elseif
{
$opt
eq
{
--skipfile
}}
{
incr j
set fp
[
open $arg r
]
set file_data
[
read $fp
]
close $fp
set ::skiptests
[
split $file_data
"
\n
"
]
}
elseif
{
$opt
eq
{
--valgrind
}}
{
set ::valgrind 1
}
elseif
{
$opt
eq
{
--stack-logging
}}
{
...
...
@@ -456,7 +498,13 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
}
elseif
{
$opt
eq
{
--force-failure
}}
{
set ::force_failure 1
}
elseif
{
$opt
eq
{
--single
}}
{
set ::all_tests $arg
lappend ::single_tests $arg
incr j
}
elseif
{
$opt
eq
{
--only
}}
{
lappend ::only_tests $arg
incr j
}
elseif
{
$opt
eq
{
--skiptill
}}
{
set ::skip_till $arg
incr j
}
elseif
{
$opt
eq
{
--list-tests
}}
{
foreach t $::all_tests
{
...
...
@@ -476,6 +524,10 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
set ::dont_clean 1
}
elseif
{
$opt
eq
{
--wait-server
}}
{
set ::wait_server 1
}
elseif
{
$opt
eq
{
--stop
}}
{
set ::stop_on_failure 1
}
elseif
{
$opt
eq
{
--loop
}}
{
set ::loop 1
}
elseif
{
$opt
eq
{
--timeout
}}
{
set ::timeout $arg
incr j
...
...
@@ -488,6 +540,30 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
}
}
# If --skil-till option was given, we populate the list of single tests
# to run with everything *after* the specified unit.
if
{
$::skip
_till !=
""
}
{
set skipping 1
foreach t $::all_tests
{
if
{
$skipping
== 0
}
{
lappend ::single_tests $t
}
if
{
$t
== $::skip_till
}
{
set skipping 0
}
}
if
{
$skipping
}
{
puts
"test
$::skip
_till not found"
exit 0
}
}
# Override the list of tests with the specific tests we want to run
# in case there was some filter, that is --single or --skip-till options.
if
{[
llength $::single_tests
]
> 0
}
{
set ::all_tests $::single_tests
}
proc attach_to_replication_stream
{}
{
set s
[
socket
[
srv 0
"host"
]
[
srv 0
"port"
]]
fconfigure $s -translation binary
...
...
tests/unit/acl.tcl
0 → 100644
View file @
49816941
start_server
{
tags
{
"acl"
}}
{
test
{
Connections start with the default user
}
{
r ACL WHOAMI
}
{
default
}
test
{
It is possible to create new users
}
{
r ACL setuser newuser
}
test
{
New users start disabled
}
{
r ACL setuser newuser >passwd1
catch
{
r AUTH newuser passwd1
}
err
set err
}
{
*WRONGPASS*
}
test
{
Enabling the user allows the login
}
{
r ACL setuser newuser on +acl
r AUTH newuser passwd1
r ACL WHOAMI
}
{
newuser
}
test
{
Only the set of correct passwords work
}
{
r ACL setuser newuser >passwd2
catch
{
r AUTH newuser passwd1
}
e
assert
{
$e
eq
"OK"
}
catch
{
r AUTH newuser passwd2
}
e
assert
{
$e
eq
"OK"
}
catch
{
r AUTH newuser passwd3
}
e
set e
}
{
*WRONGPASS*
}
test
{
It is possible to remove passwords from the set of valid ones
}
{
r ACL setuser newuser <passwd1
catch
{
r AUTH newuser passwd1
}
e
set e
}
{
*WRONGPASS*
}
test
{
By default users are not able to access any command
}
{
catch
{
r SET foo bar
}
e
set e
}
{
*NOPERM*
}
test
{
By default users are not able to access any key
}
{
r ACL setuser newuser +set
catch
{
r SET foo bar
}
e
set e
}
{
*NOPERM*key*
}
test
{
It's possible to allow the access of a subset of keys
}
{
r ACL setuser newuser allcommands ~foo:* ~bar:*
r SET foo:1 a
r SET bar:2 b
catch
{
r SET zap:3 c
}
e
r ACL setuser newuser allkeys
;
# Undo keys ACL
set e
}
{
*NOPERM*key*
}
test
{
Users can be configured to authenticate with any password
}
{
r ACL setuser newuser nopass
r AUTH newuser zipzapblabla
}
{
OK
}
test
{
ACLs can exclude single commands
}
{
r ACL setuser newuser -ping
r INCR mycounter
;
# Should not raise an error
catch
{
r PING
}
e
set e
}
{
*NOPERM*
}
test
{
ACLs can include or excluse whole classes of commands
}
{
r ACL setuser newuser -@all +@set +acl
r SADD myset a b c
;
# Should not raise an error
r ACL setuser newuser +@all -@string
r SADD myset a b c
;
# Again should not raise an error
# String commands instead should raise an error
catch
{
r SET foo bar
}
e
r ACL setuser newuser allcommands
;
# Undo commands ACL
set e
}
{
*NOPERM*
}
test
{
ACLs can include single subcommands
}
{
r ACL setuser newuser +@all -client
r ACL setuser newuser +client|id +client|setname
r CLIENT ID
;
# Should not fail
r CLIENT SETNAME foo
;
# Should not fail
catch
{
r CLIENT KILL type master
}
e
set e
}
{
*NOPERM*
}
# Note that the order of the generated ACL rules is not stable in Redis
# so we need to match the different parts and not as a whole string.
test
{
ACL GETUSER is able to translate back command permissions
}
{
# Subtractive
r ACL setuser newuser reset +@all ~* -@string +incr -debug +debug|digest
set cmdstr
[
dict get
[
r ACL getuser newuser
]
commands
]
assert_match
{
*+@all*
}
$cmdstr
assert_match
{
*-@string*
}
$cmdstr
assert_match
{
*+incr*
}
$cmdstr
assert_match
{
*-debug +debug|digest**
}
$cmdstr
# Additive
r ACL setuser newuser reset +@string -incr +acl +debug|digest +debug|segfault
set cmdstr
[
dict get
[
r ACL getuser newuser
]
commands
]
assert_match
{
*-@all*
}
$cmdstr
assert_match
{
*+@string*
}
$cmdstr
assert_match
{
*-incr*
}
$cmdstr
assert_match
{
*+debug|digest*
}
$cmdstr
assert_match
{
*+debug|segfault*
}
$cmdstr
assert_match
{
*+acl*
}
$cmdstr
}
}
tests/unit/auth.tcl
View file @
49816941
...
...
@@ -2,14 +2,14 @@ start_server {tags {"auth"}} {
test
{
AUTH fails if there is no password configured server side
}
{
catch
{
r auth foo
}
err
set _ $err
}
{
ERR*
no
password*
}
}
{
ERR*
any
password*
}
}
start_server
{
tags
{
"auth"
}
overrides
{
requirepass foobar
}}
{
test
{
AUTH fails when a wrong password is given
}
{
catch
{
r auth wrong!
}
err
set _ $err
}
{
ERR*invalid password
}
}
{
WRONGPASS*
}
test
{
Arbitrary command gives an error when AUTH is required
}
{
catch
{
r set foo bar
}
err
...
...
tests/unit/dump.tcl
View file @
49816941
...
...
@@ -33,7 +33,7 @@ start_server {tags {"dump"}} {
set now
[
clock milliseconds
]
r restore foo
[
expr $now+3000
]
$encoded absttl
set ttl
[
r pttl foo
]
assert
{
$ttl
>= 29
98
&& $ttl <= 3
0
00
}
assert
{
$ttl
>= 29
00
&& $ttl <= 3
1
00
}
r get foo
}
{
bar
}
...
...
@@ -44,7 +44,7 @@ start_server {tags {"dump"}} {
r config set maxmemory-policy allkeys-lru
r restore foo 0 $encoded idletime 1000
set idle
[
r object idletime foo
]
assert
{
$idle
>= 1000 && $idle <= 100
2
}
assert
{
$idle
>= 1000 && $idle <= 10
1
0
}
r get foo
}
{
bar
}
...
...
@@ -362,7 +362,7 @@ start_server {tags {"dump"}} {
r -1 lpush list a b c d
$second config set requirepass foobar2
catch
{
r -1 migrate $second_host $second_port list 9 5000 AUTH foobar
}
err
assert_match
{
*
invalid password
*
}
$err
assert_match
{
*
WRONGPASS
*
}
$err
}
}
}
tests/unit/introspection-2.tcl
View file @
49816941
proc cmdstat
{
cmd
}
{
if
{[
regexp
"
\r\n
cmdstat_
$cmd:
(.*?)
\r\n
"
[
r info commandstats
]
_ value
]}
{
set _ $value
}
}
start_server
{
tags
{
"introspection"
}}
{
test
{
TTL and TYPYE do not alter the last access time of a key
}
{
r set foo bar
...
...
@@ -20,4 +26,55 @@ start_server {tags {"introspection"}} {
r set key2 2
r touch key0 key1 key2 key3
}
2
test
{
command stats for GEOADD
}
{
r config resetstat
r GEOADD foo 0 0 bar
assert_match
{
*calls=1,*
}
[
cmdstat geoadd
]
assert_match
{}
[
cmdstat zadd
]
}
test
{
command stats for EXPIRE
}
{
r config resetstat
r SET foo bar
r EXPIRE foo 0
assert_match
{
*calls=1,*
}
[
cmdstat expire
]
assert_match
{}
[
cmdstat del
]
}
test
{
command stats for BRPOP
}
{
r config resetstat
r LPUSH list foo
r BRPOP list 0
assert_match
{
*calls=1,*
}
[
cmdstat brpop
]
assert_match
{}
[
cmdstat rpop
]
}
test
{
command stats for MULTI
}
{
r config resetstat
r MULTI
r set foo bar
r GEOADD foo2 0 0 bar
r EXPIRE foo2 0
r EXEC
assert_match
{
*calls=1,*
}
[
cmdstat multi
]
assert_match
{
*calls=1,*
}
[
cmdstat exec
]
assert_match
{
*calls=1,*
}
[
cmdstat set
]
assert_match
{
*calls=1,*
}
[
cmdstat expire
]
assert_match
{
*calls=1,*
}
[
cmdstat geoadd
]
}
test
{
command stats for scripts
}
{
r config resetstat
r set mykey myval
r eval
{
redis.call
(
'set', KEYS
[
1
]
, 0
)
redis.call
(
'expire', KEYS
[
1
]
, 0
)
redis.call
(
'geoadd', KEYS
[
1
]
, 0, 0,
"bar"
)
}
1 mykey
assert_match
{
*calls=1,*
}
[
cmdstat eval
]
assert_match
{
*calls=2,*
}
[
cmdstat set
]
assert_match
{
*calls=1,*
}
[
cmdstat expire
]
assert_match
{
*calls=1,*
}
[
cmdstat geoadd
]
}
}
tests/unit/introspection.tcl
View file @
49816941
start_server
{
tags
{
"introspection"
}}
{
test
{
CLIENT LIST
}
{
r client list
}
{
*addr=*:* fd=* age=* idle=* flags=N db=9 sub=0 psub=0 multi=-1 qbuf=
0
qbuf-free=* obl=0 oll=0 omem=0 events=r cmd=client*
}
}
{
*addr=*:* fd=* age=* idle=* flags=N db=9 sub=0 psub=0 multi=-1 qbuf=
26
qbuf-free=* obl=0 oll=0 omem=0 events=r cmd=client*
}
test
{
MONITOR can log executed commands
}
{
set rd
[
redis_deferring_client
]
...
...
tests/unit/maxmemory.tcl
View file @
49816941
...
...
@@ -143,9 +143,11 @@ start_server {tags {"maxmemory"}} {
}
}
proc test_slave_buffers
{
cmd_count payload_len limit_memory pipeline
}
{
proc test_slave_buffers
{
test_name
cmd_count payload_len limit_memory pipeline
}
{
start_server
{
tags
{
"maxmemory"
}}
{
start_server
{}
{
set slave_pid
[
s process_id
]
test
"
$test
_name"
{
set slave
[
srv 0 client
]
set slave_host
[
srv 0 host
]
set slave_port
[
srv 0 port
]
...
...
@@ -158,8 +160,10 @@ proc test_slave_buffers {cmd_count payload_len limit_memory pipeline} {
$master setrange
"key:
$j
"
100000 asdf
}
# make sure master doesn't disconnect slave because of timeout
$master config set repl-timeout 300
;
# 5 minutes
$master config set maxmemory-policy allkeys-random
$master config set client-output-buffer-limit
"
slave
100000000 100000000
6
0"
$master config set client-output-buffer-limit
"
replica
100000000 100000000
30
0"
$master config set repl-backlog-size
[
expr
{
10*1024
}]
$slave slaveof $master_host $master_port
...
...
@@ -182,9 +186,9 @@ proc test_slave_buffers {cmd_count payload_len limit_memory pipeline} {
# put the slave to sleep
set rd_slave
[
redis_deferring_client
]
$rd_slave debug sleep 60
exec kill -SIGSTOP $slave_pid
# send some 10mb woth of commands that don't increase the memory usage
# send some 10mb wo
r
th of commands that don't increase the memory usage
if
{
$pipeline
== 1
}
{
set rd_master
[
redis_deferring_client -1
]
for
{
set k 0
}
{
$k
< $cmd_count
}
{
incr k
}
{
...
...
@@ -218,19 +222,21 @@ proc test_slave_buffers {cmd_count payload_len limit_memory pipeline} {
set delta_no_repl
[
expr
{
$killed
_used_no_repl - $used_no_repl
}]
assert
{
$killed
_slave_buf == 0
}
assert
{
$delta
_no_repl > -50*1024 && $delta_no_repl < 50*1024
}
;
# 1 byte unaccounted for, with 1M commands will consume some 1MB
}
# unfreeze slave process
(
after the 'test' succeeded or failed, but before we attempt to terminate the server
exec kill -SIGCONT $slave_pid
}
}
}
test
{
slave buffer are counted correctly
}
{
# we wanna use many small commands, and we don't wanna wait long
# so we need to use a pipeline
(
redis_deferring_client
)
# that may cause query buffer to fill and induce eviction, so we disable it
test_slave_buffers 1000000 10 0 1
}
# test that slave buffer are counted correctly
# we wanna use many small commands, and we don't wanna wait long
# so we need to use a pipeline
(
redis_deferring_client
)
# that may cause query buffer to fill and induce eviction, so we disable it
test_slave_buffers
{
slave buffer are counted correctly
}
1000000 10 0 1
test
{
slave buffer don't induce eviction
}
{
# test again with fewer
(
and bigger
)
commands without pipeline, but with eviction
test_slave_buffers 100000 100 1 0
}
# test that slave buffer don't induce eviction
# test again with fewer
(
and bigger
)
commands without pipeline, but with eviction
test_slave_buffers
"replica buffer don't induce eviction"
100000 100 1 0
tests/unit/memefficiency.tcl
View file @
49816941
...
...
@@ -90,6 +90,7 @@ start_server {tags {"defrag"}} {
test
"Active defrag big keys"
{
r flushdb
r config resetstat
r config set save
""
;
# prevent bgsave from interfereing with save below
r config set activedefrag no
r config set active-defrag-max-scan-fields 1000
r config set active-defrag-threshold-lower 5
...
...
@@ -201,7 +202,7 @@ start_server {tags {"defrag"}} {
assert
{
$frag
< 1.1
}
# due to high fragmentation, 10hz, and active-defrag-cycle-max set to 75,
# we expect max latency to be not much higher than 75ms
assert
{
$max
_latency <=
8
0
}
assert
{
$max
_latency <=
12
0
}
}
# verify the data isn't corrupted or changed
set newdigest
[
r debug digest
]
...
...
tests/unit/pendingquerybuf.tcl
View file @
49816941
...
...
@@ -29,7 +29,7 @@ start_server {} {
set m_usedmemory
[
info_memory $master used_memory
]
set s_usedmemory
[
info_memory $slave used_memory
]
if
{
$s_usedmemory > $m_usedmemory + 10*1024*1024
}
{
fail
"the used_memory of
slave is too
larger than master.Master:
$m
_usedmemory
Slave
:
$s
_usedmemory"
fail
"the used_memory of
replica is much
larger than master.
Master:
$m
_usedmemory
Replica
:
$s
_usedmemory"
}
}
}}
tests/unit/scripting.tcl
View file @
49816941
...
...
@@ -148,9 +148,11 @@ start_server {tags {"scripting"}} {
test
{
EVAL - Scripts can't run certain commands
}
{
set e
{}
r debug lua-always-replicate-commands 0
catch
{
r eval
"redis.pcall('randomkey'); return redis.pcall('set','x','ciao')"
0
}
e
r debug lua-always-replicate-commands 1
set e
}
{
*not allowed after*
}
...
...
@@ -299,9 +301,12 @@ start_server {tags {"scripting"}} {
}
{
b534286061d4b9e4026607613b95c06c06015ae8 loaded
}
test
"In the context of Lua the output of random commands gets ordered"
{
r debug lua-always-replicate-commands 0
r del myset
r sadd myset a b c d e f g h i l m n o p q r s t u v z aa aaa azz
r eval
{
return redis.call
(
'smembers',KEYS
[
1
])}
1 myset
set res
[
r eval
{
return redis.call
(
'smembers',KEYS
[
1
])}
1 myset
]
r debug lua-always-replicate-commands 1
set res
}
{
a aa aaa azz b c d e f g h i l m n o p q r s t u v z
}
test
"SORT is normally not alpha re-ordered for the scripting engine"
{
...
...
@@ -537,7 +542,7 @@ foreach cmdrepl {0 1} {
r debug lua-always-replicate-commands 1
}
test
"Before the
slave
connects we issue two EVAL commands
$rt
"
{
test
"Before the
replica
connects we issue two EVAL commands
$rt
"
{
# One with an error, but still executing a command.
# SHA is: 67164fc43fa971f76fd1aaeeaf60c1c178d25876
catch
{
...
...
@@ -548,13 +553,13 @@ foreach cmdrepl {0 1} {
r eval
{
return redis.call
(
'incr',KEYS
[
1
])}
1 x
}
{
2
}
test
"Connect a
slave
to the master instance
$rt
"
{
test
"Connect a
replica
to the master instance
$rt
"
{
r -1 slaveof
[
srv 0 host
]
[
srv 0 port
]
wait_for_condition 50 100
{
[
s -1 role
]
eq
{
slave
}
&&
[
string match
{
*master_link_status:up*
}
[
r -1 info replication
]]
}
else
{
fail
"Can't turn the instance into a
slave
"
fail
"Can't turn the instance into a
replica
"
}
}
...
...
@@ -587,7 +592,7 @@ foreach cmdrepl {0 1} {
wait_for_condition 50 100
{
[
r -1 lrange a 0 -1
]
eq
[
r lrange a 0 -1
]
}
else
{
fail
"Expected list 'a' in
slave
and master to be the same, but they are respectively '
[
r -1 lrange a 0 -1
]
' and '
[
r lrange a 0 -1
]
'"
fail
"Expected list 'a' in
replica
and master to be the same, but they are respectively '
[
r -1 lrange a 0 -1
]
' and '
[
r lrange a 0 -1
]
'"
}
set res
}
{
a 1
}
...
...
@@ -622,7 +627,7 @@ foreach cmdrepl {0 1} {
wait_for_condition 50 100
{
[
r -1 debug digest
]
eq
[
r debug digest
]
}
else
{
fail
"Master-
Slave
desync after Lua script using SELECT."
fail
"Master-
Replica
desync after Lua script using SELECT."
}
}
}
...
...
@@ -631,13 +636,13 @@ foreach cmdrepl {0 1} {
start_server
{
tags
{
"scripting repl"
}}
{
start_server
{
overrides
{
appendonly yes aof-use-rdb-preamble no
}}
{
test
"Connect a
slave
to the master instance"
{
test
"Connect a
replica
to the master instance"
{
r -1 slaveof
[
srv 0 host
]
[
srv 0 port
]
wait_for_condition 50 100
{
[
s -1 role
]
eq
{
slave
}
&&
[
string match
{
*master_link_status:up*
}
[
r -1 info replication
]]
}
else
{
fail
"Can't turn the instance into a
slave
"
fail
"Can't turn the instance into a
replica
"
}
}
...
...
@@ -655,11 +660,13 @@ start_server {tags {"scripting repl"}} {
}
{
1
}
test
"Redis.set_repl() must be issued after replicate_commands()"
{
r debug lua-always-replicate-commands 0
catch
{
r eval
{
redis.set_repl
(
redis.REPL_ALL
);
}
0
}
e
r debug lua-always-replicate-commands 1
set e
}
{
*only after turning on*
}
...
...
@@ -689,7 +696,7 @@ start_server {tags {"scripting repl"}} {
wait_for_condition 50 100
{
[
r -1 mget a b c d
]
eq
{
1
{}
{}
4
}
}
else
{
fail
"Only a and c should be replicated to
slave
"
fail
"Only a and c should be replicated to
replica
"
}
# Master should have everything right now
...
...
@@ -728,7 +735,7 @@ start_server {tags {"scripting repl"}} {
wait_for_condition 50 100
{
[
r get time
]
eq
[
r -1 get time
]
}
else
{
fail
"Time key does not match between master and
slave
"
fail
"Time key does not match between master and
replica
"
}
}
}
...
...
tests/unit/type/stream-cgroups.tcl
View file @
49816941
...
...
@@ -9,6 +9,17 @@ start_server {
set err
}
{
BUSYGROUP*
}
test
{
XGROUP CREATE: automatic stream creation fails without MKSTREAM
}
{
r DEL mystream
catch
{
r XGROUP CREATE mystream mygroup $
}
err
set err
}
{
ERR*
}
test
{
XGROUP CREATE: automatic stream creation works with MKSTREAM
}
{
r DEL mystream
r XGROUP CREATE mystream mygroup $ MKSTREAM
}
{
OK
}
test
{
XREADGROUP will return only new elements
}
{
r XADD mystream * a 1
r XADD mystream * b 2
...
...
@@ -96,4 +107,142 @@ start_server {
set c
[
llength
[
lindex
[
r xreadgroup group g1 c2 streams events >
]
0 1
]]
assert
{
$c
== 5
}
}
test
{
XREADGROUP will not report data on empty history. Bug #5577
}
{
r del events
r xadd events * a 1
r xadd events * b 2
r xadd events * c 3
r xgroup create events mygroup 0
# Current local PEL should be empty
set res
[
r xpending events mygroup - + 10
]
assert
{[
llength $res
]
== 0
}
# So XREADGROUP should read an empty history as well
set res
[
r xreadgroup group mygroup myconsumer count 3 streams events 0
]
assert
{[
llength
[
lindex $res 0 1
]]
== 0
}
# We should fetch all the elements in the stream asking for >
set res
[
r xreadgroup group mygroup myconsumer count 3 streams events >
]
assert
{[
llength
[
lindex $res 0 1
]]
== 3
}
# Now the history is populated with three not acked entries
set res
[
r xreadgroup group mygroup myconsumer count 3 streams events 0
]
assert
{[
llength
[
lindex $res 0 1
]]
== 3
}
}
test
{
XREADGROUP history reporting of deleted entries. Bug #5570
}
{
r del mystream
r XGROUP CREATE mystream mygroup $ MKSTREAM
r XADD mystream 1 field1 A
r XREADGROUP GROUP mygroup myconsumer STREAMS mystream >
r XADD mystream MAXLEN 1 2 field1 B
r XREADGROUP GROUP mygroup myconsumer STREAMS mystream >
# Now we have two pending entries, however one should be deleted
# and one should be ok
(
we should only see
"B"
)
set res
[
r XREADGROUP GROUP mygroup myconsumer STREAMS mystream 0-1
]
assert
{[
lindex $res 0 1 0
]
==
{
1-0
{}}}
assert
{[
lindex $res 0 1 1
]
==
{
2-0
{
field1 B
}}}
}
test
{
XCLAIM can claim PEL items from another consumer
}
{
# Add 3 items into the stream, and create a consumer group
r del mystream
set id1
[
r XADD mystream * a 1
]
set id2
[
r XADD mystream * b 2
]
set id3
[
r XADD mystream * c 3
]
r XGROUP CREATE mystream mygroup 0
# Client 1 reads item 1 from the stream without acknowledgements.
# Client 2 then claims pending item 1 from the PEL of client 1
set reply
[
r XREADGROUP GROUP mygroup client1 count 1 STREAMS mystream >
]
assert
{[
llength
[
lindex $reply 0 1 0 1
]]
== 2
}
assert
{[
lindex $reply 0 1 0 1
]
eq
{
a 1
}}
r debug sleep 0.2
set reply
[
r XCLAIM mystream mygroup client2 10 $id1
]
assert
{[
llength
[
lindex $reply 0 1
]]
== 2
}
assert
{[
lindex $reply 0 1
]
eq
{
a 1
}}
# Client 1 reads another 2 items from stream
r XREADGROUP GROUP mygroup client1 count 2 STREAMS mystream >
r debug sleep 0.2
# Delete item 2 from the stream. Now client 1 has PEL that contains
# only item 3. Try to use client 2 to claim the deleted item 2
# from the PEL of client 1, this should return nil
r XDEL mystream $id2
set reply
[
r XCLAIM mystream mygroup client2 10 $id2
]
assert
{[
llength $reply
]
== 1
}
assert_equal
""
[
lindex $reply 0
]
# Delete item 3 from the stream. Now client 1 has PEL that is empty.
# Try to use client 2 to claim the deleted item 3 from the PEL
# of client 1, this should return nil
r debug sleep 0.2
r XDEL mystream $id3
set reply
[
r XCLAIM mystream mygroup client2 10 $id3
]
assert
{[
llength $reply
]
== 1
}
assert_equal
""
[
lindex $reply 0
]
}
start_server
{}
{
set master
[
srv -1 client
]
set master_host
[
srv -1 host
]
set master_port
[
srv -1 port
]
set slave
[
srv 0 client
]
foreach noack
{
0 1
}
{
test
"Consumer group last ID propagation to slave (NOACK=
$noack
)"
{
$slave slaveof $master_host $master_port
wait_for_condition 50 100
{
[
s 0 master_link_status
]
eq
{
up
}
}
else
{
fail
"Replication not started."
}
$master del stream
$master xadd stream * a 1
$master xadd stream * a 2
$master xadd stream * a 3
$master xgroup create stream mygroup 0
# Consume the first two items on the master
for
{
set j 0
}
{
$j
< 2
}
{
incr j
}
{
if
{
$noack
}
{
set item
[
$master
xreadgroup group mygroup
\
myconsumer COUNT 1 NOACK STREAMS stream >
]
}
else
{
set item
[
$master
xreadgroup group mygroup
\
myconsumer COUNT 1 STREAMS stream >
]
}
set id
[
lindex $item 0 1 0 0
]
if
{
$noack
== 0
}
{
assert
{[
$master
xack stream mygroup $id
]
eq
"1"
}
}
}
wait_for_ofs_sync $master $slave
# Turn slave into master
$slave slaveof no one
set item
[
$slave
xreadgroup group mygroup myconsumer
\
COUNT 1 STREAMS stream >
]
# The consumed enty should be the third
set myentry
[
lindex $item 0 1 0 1
]
assert
{
$myentry
eq
{
a 3
}}
}
}
}
}
tests/unit/type/stream.tcl
View file @
49816941
...
...
@@ -317,3 +317,97 @@ start_server {
assert_equal
[
r xrevrange teststream2 1234567891245 -
]
{{
1234567891240-0
{
key1 value2
}}
{
1234567891230-0
{
key1 value1
}}}
}
}
start_server
{
tags
{
"stream"
}
overrides
{
appendonly yes
}}
{
test
{
XADD with MAXLEN > xlen can propagate correctly
}
{
for
{
set j 0
}
{
$j
< 100
}
{
incr j
}
{
r XADD mystream * xitem v
}
r XADD mystream MAXLEN 200 * xitem v
incr j
assert
{[
r xlen mystream
]
== $j
}
r debug loadaof
r XADD mystream * xitem v
incr j
assert
{[
r xlen mystream
]
== $j
}
}
}
start_server
{
tags
{
"stream"
}
overrides
{
appendonly yes
}}
{
test
{
XADD with ~ MAXLEN can propagate correctly
}
{
for
{
set j 0
}
{
$j
< 100
}
{
incr j
}
{
r XADD mystream * xitem v
}
r XADD mystream MAXLEN ~ $j * xitem v
incr j
assert
{[
r xlen mystream
]
== $j
}
r config set stream-node-max-entries 1
r debug loadaof
r XADD mystream * xitem v
incr j
assert
{[
r xlen mystream
]
== $j
}
}
}
start_server
{
tags
{
"stream"
}
overrides
{
appendonly yes stream-node-max-entries 10
}}
{
test
{
XTRIM with ~ MAXLEN can propagate correctly
}
{
for
{
set j 0
}
{
$j
< 100
}
{
incr j
}
{
r XADD mystream * xitem v
}
r XTRIM mystream MAXLEN ~ 85
assert
{[
r xlen mystream
]
== 89
}
r config set stream-node-max-entries 1
r debug loadaof
r XADD mystream * xitem v
incr j
assert
{[
r xlen mystream
]
== 90
}
}
}
start_server
{
tags
{
"xsetid"
}}
{
test
{
XADD can CREATE an empty stream
}
{
r XADD mystream MAXLEN 0 * a b
assert
{[
dict get
[
r xinfo stream mystream
]
length
]
== 0
}
}
test
{
XSETID can set a specific ID
}
{
r XSETID mystream
"200-0"
assert
{[
dict get
[
r xinfo stream mystream
]
last-generated-id
]
==
"200-0"
}
}
test
{
XSETID cannot SETID with smaller ID
}
{
r XADD mystream * a b
catch
{
r XSETID mystream
"1-1"
}
err
r XADD mystream MAXLEN 0 * a b
set err
}
{
ERR*smaller*
}
test
{
XSETID cannot SETID on non-existent key
}
{
catch
{
r XSETID stream 1-1
}
err
set _ $err
}
{
ERR no such key
}
}
start_server
{
tags
{
"stream"
}
overrides
{
appendonly yes aof-use-rdb-preamble no
}}
{
test
{
Empty stream can be rewrite into AOF correctly
}
{
r XADD mystream MAXLEN 0 * a b
assert
{[
dict get
[
r xinfo stream mystream
]
length
]
== 0
}
r bgrewriteaof
waitForBgrewriteaof r
r debug loadaof
assert
{[
dict get
[
r xinfo stream mystream
]
length
]
== 0
}
}
test
{
Stream can be rewrite into AOF correctly after XDEL lastid
}
{
r XSETID mystream 0-0
r XADD mystream 1-1 a b
r XADD mystream 2-2 a b
assert
{[
dict get
[
r xinfo stream mystream
]
length
]
== 2
}
r XDEL mystream 2-2
r bgrewriteaof
waitForBgrewriteaof r
r debug loadaof
assert
{[
dict get
[
r xinfo stream mystream
]
length
]
== 1
}
assert
{[
dict get
[
r xinfo stream mystream
]
last-generated-id
]
==
"2-2"
}
}
}
tests/unit/type/zset.tcl
View file @
49816941
...
...
@@ -388,7 +388,7 @@ start_server {tags {"zset"}} {
0 omega
}
}
test
"ZRANGEBYLEX/ZREVRANGEBYLEX/ZCOUNT basics"
{
test
"ZRANGEBYLEX/ZREVRANGEBYLEX/Z
LEX
COUNT basics"
{
create_default_lex_zset
# inclusive range
...
...
@@ -417,6 +417,22 @@ start_server {tags {"zset"}} {
assert_equal
{}
[
r zrevrangebylex zset
(
hill
(
omega
]
}
test
"ZLEXCOUNT advanced"
{
create_default_lex_zset
assert_equal 9
[
r zlexcount zset - +
]
assert_equal 0
[
r zlexcount zset + -
]
assert_equal 0
[
r zlexcount zset +
\[
c
]
assert_equal 0
[
r zlexcount zset
\[
c -
]
assert_equal 8
[
r zlexcount zset
\[
bar +
]
assert_equal 5
[
r zlexcount zset
\[
bar
\[
foo
]
assert_equal 4
[
r zlexcount zset
\[
bar
(
foo
]
assert_equal 4
[
r zlexcount zset
(
bar
\[
foo
]
assert_equal 3
[
r zlexcount zset
(
bar
(
foo
]
assert_equal 5
[
r zlexcount zset -
(
foo
]
assert_equal 1
[
r zlexcount zset
(
maxstring +
]
}
test
"ZRANGEBYSLEX with LIMIT"
{
create_default_lex_zset
assert_equal
{
alpha bar
}
[
r zrangebylex zset -
\[
cool LIMIT 0 2
]
...
...
@@ -1185,4 +1201,30 @@ start_server {tags {"zset"}} {
stressers ziplist
stressers skiplist
}
test
{
ZSET skiplist order consistency when elements are moved
}
{
set original_max
[
lindex
[
r config get zset-max-ziplist-entries
]
1
]
r config set zset-max-ziplist-entries 0
for
{
set times 0
}
{
$times
< 10
}
{
incr times
}
{
r del zset
for
{
set j 0
}
{
$j
< 1000
}
{
incr j
}
{
r zadd zset
[
randomInt 50
]
ele-
[
randomInt 10
]
}
# Make sure that element ordering is correct
set prev_element
{}
set prev_score -1
foreach
{
element score
}
[
r zrange zset 0 -1 WITHSCORES
]
{
# Assert that elements are in increasing ordering
assert
{
$prev_score < $score ||
(
$prev
_score == $score &&
[
string compare $prev_element $element
]
== -1
)
}
set prev_element $element
set prev_score $score
}
}
r config set zset-max-ziplist-entries $original_max
}
}
utils/releasetools/changelog.tcl
View file @
49816941
#!/usr/bin/env tclsh
if
{[
llength $::argv
]
!= 2
}
{
puts
"Usage:
$::argv0
<branch> <version>"
if
{[
llength $::argv
]
!= 2
&&
[
llength $::argv
]
!= 3
}
{
puts
"Usage:
$::argv0
<branch> <version>
\[
<num-commits>
\]
"
exit 1
}
set branch
[
lindex $::argv 0
]
set ver
[
lindex $::argv 1
]
if
{[
llength $::argv
]
== 3
}
{
set count
[
lindex ::$argv 2
]
}
else
{
set count 100
}
set template
{
================================================================================
...
...
@@ -21,7 +26,7 @@ append template "\n\n"
set date
[
clock format
[
clock seconds
]]
set template
[
string map
[
list %ver% $ver %date% $date
]
$template
]
append template
[
exec git log $branch~
100
..$branch
"--format=format:%an in commit %h:%n %s"
--shortstat
]
append template
[
exec git log $branch~
$count
..$branch
"--format=format:%an in commit %h:%n %s"
--shortstat
]
#Older, more verbose version.
#
...
...
utils/srandmember/README.md
0 → 100644
View file @
49816941
The utilities in this directory plot the distribution of SRANDMEMBER to
evaluate how fair it is.
See http://theshfl.com/redis_sets for more information on the topic that lead
to such investigation fix.
showdist.rb -- shows the distribution of the frequency elements are returned.
The x axis is the number of times elements were returned, and
the y axis is how many elements were returned with such
frequency.
showfreq.rb -- shows the frequency each element was returned.
The x axis is the element number.
The y axis is the times it was returned.
utils/srandmember/showdist.rb
0 → 100644
View file @
49816941
require
'redis'
r
=
Redis
.
new
r
.
select
(
9
)
r
.
del
(
"myset"
);
r
.
sadd
(
"myset"
,(
0
..
999
).
to_a
)
freq
=
{}
100
.
times
{
res
=
r
.
pipelined
{
1000
.
times
{
r
.
srandmember
(
"myset"
)
}
}
res
.
each
{
|
ele
|
freq
[
ele
]
=
0
if
freq
[
ele
]
==
nil
freq
[
ele
]
+=
1
}
}
# Convert into frequency distribution
dist
=
{}
freq
.
each
{
|
item
,
count
|
dist
[
count
]
=
0
if
dist
[
count
]
==
nil
dist
[
count
]
+=
1
}
min
=
dist
.
keys
.
min
max
=
dist
.
keys
.
max
(
min
..
max
).
each
{
|
x
|
count
=
dist
[
x
]
count
=
0
if
count
==
nil
puts
"
#{
x
}
->
#{
"*"
*
count
}
"
}
utils/srandmember/showfreq.rb
0 → 100644
View file @
49816941
require
'redis'
r
=
Redis
.
new
r
.
select
(
9
)
r
.
del
(
"myset"
);
r
.
sadd
(
"myset"
,(
0
..
999
).
to_a
)
freq
=
{}
500
.
times
{
res
=
r
.
pipelined
{
1000
.
times
{
r
.
srandmember
(
"myset"
)
}
}
res
.
each
{
|
ele
|
freq
[
ele
]
=
0
if
freq
[
ele
]
==
nil
freq
[
ele
]
+=
1
}
}
# Print the frequency each element was yeld to process it with gnuplot
freq
.
each
{
|
item
,
count
|
puts
"
#{
item
}
#{
count
}
"
}
Prev
1
2
3
4
5
6
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment