Commit 0681c5ad authored by antirez's avatar antirez
Browse files

master branch merged into scripting.

parents 15bc1cc1 34a8b517
start_server {tags {"repl"}} {
start_server {} {
test {First server should have role slave after SLAVEOF} {
r -1 slaveof [srv 0 host] [srv 0 port]
after 1000
s -1 role
} {slave}
if {$::accurate} {set numops 50000} else {set numops 5000}
test {MASTER and SLAVE consistency with expire} {
createComplexDataset r $numops useexpire
after 4000 ;# Make sure everything expired before taking the digest
r keys * ;# Force DEL syntesizing to slave
after 1000 ;# Wait another second. Now everything should be fine.
if {[r debug digest] ne [r -1 debug digest]} {
set csv1 [csvdump r]
set csv2 [csvdump {r -1}]
set fd [open /tmp/repldump1.txt w]
puts -nonewline $fd $csv1
close $fd
set fd [open /tmp/repldump2.txt w]
puts -nonewline $fd $csv2
close $fd
puts "Master - Slave inconsistency"
puts "Run diff -u against /tmp/repldump*.txt for more info"
}
assert_equal [r debug digest] [r -1 debug digest]
}
}
}
......@@ -23,44 +23,6 @@ start_server {tags {"repl"}} {
after 1000
assert_equal [r debug digest] [r -1 debug digest]
}
test {MASTER and SLAVE dataset should be identical after complex ops} {
createComplexDataset r 10000
after 500
if {[r debug digest] ne [r -1 debug digest]} {
set csv1 [csvdump r]
set csv2 [csvdump {r -1}]
set fd [open /tmp/repldump1.txt w]
puts -nonewline $fd $csv1
close $fd
set fd [open /tmp/repldump2.txt w]
puts -nonewline $fd $csv2
close $fd
puts "Master - Slave inconsistency"
puts "Run diff -u against /tmp/repldump*.txt for more info"
}
assert_equal [r debug digest] [r -1 debug digest]
}
test {MASTER and SLAVE consistency with expire} {
createComplexDataset r 50000 useexpire
after 4000 ;# Make sure everything expired before taking the digest
r keys * ;# Force DEL syntesizing to slave
after 1000 ;# Wait another second. Now everything should be fine.
if {[r debug digest] ne [r -1 debug digest]} {
set csv1 [csvdump r]
set csv2 [csvdump {r -1}]
set fd [open /tmp/repldump1.txt w]
puts -nonewline $fd $csv1
close $fd
set fd [open /tmp/repldump2.txt w]
puts -nonewline $fd $csv2
close $fd
puts "Master - Slave inconsistency"
puts "Run diff -u against /tmp/repldump*.txt for more info"
}
assert_equal [r debug digest] [r -1 debug digest]
}
}
}
......@@ -92,6 +54,7 @@ start_server {tags {"repl"}} {
test {SET on the master should immediately propagate} {
r -1 set mykey bar
if {$::valgrind} {after 2000}
r 0 get mykey
} {bar}
}
......
set ::global_overrides {}
set ::tags {}
set ::valgrind_errors {}
proc error_and_quit {config_file error} {
puts "!!COULD NOT START REDIS-SERVER\n"
......@@ -16,11 +17,9 @@ proc check_valgrind_errors stderr {
close $fd
if {![regexp -- {ERROR SUMMARY: 0 errors} $buf] ||
![regexp -- {definitely lost: 0 bytes} $buf]} {
puts "*** VALGRIND ERRORS ***"
puts $buf
puts "--- press enter to continue ---"
gets stdin
(![regexp -- {definitely lost: 0 bytes} $buf] &&
![regexp -- {no leaks are possible} $buf])} {
send_data_packet $::test_server_fd err "Valgrind error: $buf\n"
}
}
......@@ -182,7 +181,7 @@ proc start_server {options {code undefined}} {
# check that the server actually started
# ugly but tries to be as fast as possible...
set retrynum 20
set retrynum 100
set serverisup 0
if {$::verbose} {
......
......@@ -49,60 +49,28 @@ proc color_term {} {
expr {[info exists ::env(TERM)] && [string match *xterm* $::env(TERM)]}
}
# This is called before starting the test
proc announce_test {s} {
proc colorstr {color str} {
if {[color_term]} {
puts -nonewline "$s\033\[0K"
flush stdout
set ::backward_count [string length $s]
}
}
# This is called after the test finished
proc colored_dot {tags passed} {
if {[color_term]} {
# Go backward and delete what announc_test function printed.
puts -nonewline "\033\[${::backward_count}D\033\[0K\033\[J"
# Print a coloured char, accordingly to test outcome and tags.
if {[lsearch $tags list] != -1} {
set colorcode {31}
set ch L
} elseif {[lsearch $tags hash] != -1} {
set colorcode {32}
set ch H
} elseif {[lsearch $tags set] != -1} {
set colorcode {33}
set ch S
} elseif {[lsearch $tags zset] != -1} {
set colorcode {34}
set ch Z
} elseif {[lsearch $tags basic] != -1} {
set colorcode {35}
set ch B
} elseif {[lsearch $tags scripting] != -1} {
set colorcode {36}
set ch X
} else {
set colorcode {37}
set ch .
set b 0
if {[string range $color 0 4] eq {bold-}} {
set b 1
set color [string range $color 5 end]
}
switch $color {
red {set colorcode {31}}
green {set colorcode {32}}
yellow {set colorcode {33}}
blue {set colorcode {34}}
magenta {set colorcode {35}}
cyan {set colorcode {36}}
white {set colorcode {37}}
default {set colorcode {37}}
}
if {$colorcode ne {}} {
if {$passed} {
puts -nonewline "\033\[0;${colorcode};40m"
} else {
puts -nonewline "\033\[7;${colorcode};40m"
}
puts -nonewline $ch
puts -nonewline "\033\[0m"
flush stdout
return "\033\[$b;${colorcode};40m$str\033\[0m"
}
} else {
if {$passed} {
puts -nonewline .
} else {
puts -nonewline F
}
return $str
}
}
......@@ -130,16 +98,9 @@ proc test {name code {okpattern undefined}} {
incr ::num_tests
set details {}
lappend details $::curfile
lappend details $::tags
lappend details $name
lappend details "$name in $::curfile"
if {$::verbose} {
puts -nonewline [format "#%03d %-68s " $::num_tests $name]
flush stdout
} else {
announce_test $name
}
send_data_packet $::test_server_fd testing $name
if {[catch {set retval [uplevel 1 $code]} error]} {
if {[string match "assertion:*" $error]} {
......@@ -148,12 +109,7 @@ proc test {name code {okpattern undefined}} {
lappend ::tests_failed $details
incr ::num_failed
if {$::verbose} {
puts "FAILED"
puts "$msg\n"
} else {
colored_dot $::tags 0
}
send_data_packet $::test_server_fd err [join $details "\n"]
} else {
# Re-raise, let handler up the stack take care of this.
error $error $::errorInfo
......@@ -161,33 +117,21 @@ proc test {name code {okpattern undefined}} {
} else {
if {$okpattern eq "undefined" || $okpattern eq $retval || [string match $okpattern $retval]} {
incr ::num_passed
if {$::verbose} {
puts "PASSED"
} else {
colored_dot $::tags 1
}
send_data_packet $::test_server_fd ok $name
} else {
set msg "Expected '$okpattern' to equal or match '$retval'"
lappend details $msg
lappend ::tests_failed $details
incr ::num_failed
if {$::verbose} {
puts "FAILED"
puts "$msg\n"
} else {
colored_dot $::tags 0
}
send_data_packet $::test_server_fd err [join $details "\n"]
}
}
flush stdout
if {$::traceleaks} {
set output [exec leaks redis-server]
if {![string match {*0 leaks*} $output]} {
puts "--- Test \"$name\" leaked! ---"
puts $output
exit 1
send_data_packet $::test_server_fd err "Detected a memory leak in test '$name': $output"
}
}
}
......@@ -4,13 +4,7 @@ file mkdir $::tmproot
# returns a dirname unique to this process to write to
proc tmpdir {basename} {
if {$::diskstore} {
# For diskstore we want to use the same dir again and again
# otherwise everything is too slow.
set dir [file join $::tmproot $basename.diskstore]
} else {
set dir [file join $::tmproot $basename.[pid].[incr ::tmpcounter]]
}
set dir [file join $::tmproot $basename.[pid].[incr ::tmpcounter]]
file mkdir $dir
set _ $dir
}
......
......@@ -9,6 +9,33 @@ source tests/support/tmpfile.tcl
source tests/support/test.tcl
source tests/support/util.tcl
set ::all_tests {
unit/printver
unit/auth
unit/protocol
unit/basic
unit/type/list
unit/type/list-2
unit/type/list-3
unit/type/set
unit/type/zset
unit/type/hash
unit/sort
unit/expire
unit/other
unit/cas
unit/quit
integration/replication
integration/replication-2
integration/replication-3
integration/aof
unit/pubsub
unit/slowlog
unit/scripting
}
# Index to the next test to run in the ::all_tests list.
set ::next_test 0
set ::host 127.0.0.1
set ::port 16379
set ::traceleaks 0
......@@ -19,12 +46,22 @@ set ::allowtags {}
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
set ::diskstore 0; # Don't touch this by hand. The test itself will toggle it.
set ::accurate 0; # If true runs fuzz tests with more iterations
set ::force_failure 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
# runs the specified number of client instances that will actually run tests.
# The server is responsible of showing the result to the user, and exit with
# the appropriate exit code depending on the test outcome.
set ::client 0
set ::numclients 16
proc execute_tests name {
set path "tests/$name.tcl"
set ::curfile $path
source $path
send_data_packet $::test_server_fd done "$name"
}
# Setup a list to hold a stack of server configs. When calls to start_server
......@@ -104,93 +141,191 @@ proc s {args} {
}
proc cleanup {} {
puts "Cleanup: warning may take some time..."
puts -nonewline "Cleanup: may take some time... "
flush stdout
catch {exec rm -rf {*}[glob tests/tmp/redis.conf.*]}
catch {exec rm -rf {*}[glob tests/tmp/server.*]}
puts "OK"
}
proc execute_everything {} {
if 0 {
# Use this when hacking on new tests.
set ::verbose 1
execute_tests "unit/first"
return
}
execute_tests "unit/printver"
execute_tests "unit/auth"
execute_tests "unit/protocol"
execute_tests "unit/basic"
execute_tests "unit/type/list"
execute_tests "unit/type/set"
execute_tests "unit/type/zset"
execute_tests "unit/type/hash"
execute_tests "unit/sort"
execute_tests "unit/expire"
execute_tests "unit/other"
execute_tests "unit/cas"
execute_tests "unit/quit"
execute_tests "integration/replication"
execute_tests "integration/aof"
# execute_tests "integration/redis-cli"
execute_tests "unit/pubsub"
execute_tests "unit/scripting"
return; # No diskstore tests for now...
# run tests with diskstore enabled
puts "\nRunning diskstore tests... this is slow, press Ctrl+C if not interested.."
set ::diskstore 1
lappend ::denytags nodiskstore
set ::global_overrides {diskstore-enabled yes}
execute_tests "unit/protocol"
execute_tests "unit/basic"
execute_tests "unit/type/list"
execute_tests "unit/type/set"
execute_tests "unit/type/zset"
execute_tests "unit/type/hash"
execute_tests "unit/sort"
execute_tests "unit/expire"
execute_tests "unit/other"
execute_tests "unit/cas"
}
proc main {} {
proc test_server_main {} {
cleanup
# Open a listening socket, trying different ports in order to find a
# non busy one.
set port 11111
while 1 {
puts "Starting test server at port $port"
if {[catch {socket -server accept_test_clients $port} e]} {
if {[string match {*address already in use*} $e]} {
if {$port == 20000} {
puts "Can't find an available TCP port for test server."
exit 1
} else {
incr port
}
} else {
puts "Fatal error starting test server: $e"
exit 1
}
} else {
break
}
}
# Start the client instances
set ::clients_pids {}
for {set j 0} {$j < $::numclients} {incr j} {
set p [exec tclsh8.5 [info script] {*}$::argv \
--client $port --port [expr {$::port+($j*10)}] &]
lappend ::clients_pids $p
}
if {[string length $::file] > 0} {
foreach {file} [split $::file ,] {
execute_tests $file
# Setup global state for the test server
set ::idle_clients {}
set ::active_clients {}
array set ::clients_start_time {}
set ::clients_time_history {}
set ::failed_tests {}
# Enter the event loop to handle clients I/O
after 100 test_server_cron
vwait forever
}
# This function gets called 10 times per second, for now does nothing but
# may be used in the future in order to detect test clients taking too much
# time to execute the task.
proc test_server_cron {} {
}
proc accept_test_clients {fd addr port} {
fileevent $fd readable [list read_from_test_client $fd]
}
# This is the readable handler of our test server. Clients send us messages
# in the form of a status code such and additional data. Supported
# status types are:
#
# ready: the client is ready to execute the command. Only sent at client
# startup. The server will queue the client FD in the list of idle
# clients.
# 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.
# 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.
proc read_from_test_client fd {
set bytes [gets $fd]
set payload [read $fd $bytes]
foreach {status data} $payload break
if {$status eq {ready}} {
puts "\[$status\]: $data"
signal_idle_client $fd
} elseif {$status eq {done}} {
set elapsed [expr {[clock seconds]-$::clients_start_time($fd)}]
puts "\[[colorstr yellow $status]\]: $data ($elapsed seconds)"
puts "+++ [expr {[llength $::active_clients]-1}] units still in execution."
lappend ::clients_time_history $elapsed $data
signal_idle_client $fd
} elseif {$status eq {ok}} {
puts "\[[colorstr green $status]\]: $data"
} elseif {$status eq {err}} {
set err "\[[colorstr red $status]\]: $data"
puts $err
lappend ::failed_tests $err
} elseif {$status eq {exception}} {
puts "\[[colorstr red $status]\]: $data"
foreach p $::clients_pids {
catch {exec kill -9 $p}
}
exit 1
} elseif {$status eq {testing}} {
# No op
} else {
execute_everything
puts "\[$status\]: $data"
}
}
cleanup
puts "\n[expr $::num_tests] tests, $::num_passed passed, $::num_failed failed\n"
if {$::num_failed > 0} {
set curheader ""
puts "Failures:"
foreach {test} $::tests_failed {
set header [lindex $test 0]
append header " ("
append header [join [lindex $test 1] ","]
append header ")"
if {$curheader ne $header} {
set curheader $header
puts "\n$curheader:"
}
set name [lindex $test 2]
set msg [lindex $test 3]
puts "- $name: $msg"
# A new client is idle. Remove it from the list of active clients and
# if there are still test units to run, launch them.
proc signal_idle_client fd {
# Remove this fd from the list of active clients.
set ::active_clients \
[lsearch -all -inline -not -exact $::active_clients $fd]
# New unit to process?
if {$::next_test != [llength $::all_tests]} {
puts [colorstr bold-white "Testing [lindex $::all_tests $::next_test]"]
set ::clients_start_time($fd) [clock seconds]
send_data_packet $fd run [lindex $::all_tests $::next_test]
lappend ::active_clients $fd
incr ::next_test
} else {
lappend ::idle_clients $fd
if {[llength $::active_clients] == 0} {
the_end
}
}
}
puts ""
# The the_end funciton gets called when all the test units were already
# executed, so the test finished.
proc the_end {} {
# TODO: print the status, exit with the rigth exit code.
puts "\n The End\n"
puts "Execution time of different units:"
foreach {time name} $::clients_time_history {
puts " $time seconds - $name"
}
if {[llength $::failed_tests]} {
puts "\n[colorstr bold-red {!!! WARNING}] The following tests failed:\n"
foreach failed $::failed_tests {
puts "*** $failed"
}
cleanup
exit 1
} else {
puts "\n[colorstr bold-white {\o/}] [colorstr bold-green {All tests passed without errors!}]\n"
cleanup
exit 0
}
}
# The client is not even driven (the test server is instead) as we just need
# to read the command, execute, reply... all this in a loop.
proc test_client_main server_port {
set ::test_server_fd [socket localhost $server_port]
send_data_packet $::test_server_fd ready [pid]
while 1 {
set bytes [gets $::test_server_fd]
set payload [read $::test_server_fd $bytes]
foreach {cmd data} $payload break
if {$cmd eq {run}} {
execute_tests $data
} else {
error "Unknown test client command: $cmd"
}
}
}
proc send_data_packet {fd status data} {
set payload [list $status $data]
puts $fd [string length $payload]
puts -nonewline $fd $payload
flush $fd
}
proc print_help_screen {} {
puts [join {
"--valgrind Run the test over valgrind."
"--accurate Run slow randomized tests for more iterations."
"--single <unit> Just execute the specified unit (see next option)."
"--list-tests List all the available test units."
"--force-failure Force the execution of a test that always fails."
"--help Print this help screen."
} "\n"]
}
# parse arguments
for {set j 0} {$j < [llength $argv]} {incr j} {
set opt [lindex $argv $j]
......@@ -206,9 +341,6 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
incr j
} elseif {$opt eq {--valgrind}} {
set ::valgrind 1
} elseif {$opt eq {--file}} {
set ::file $arg
incr j
} elseif {$opt eq {--host}} {
set ::external 1
set ::host $arg
......@@ -216,20 +348,47 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
} elseif {$opt eq {--port}} {
set ::port $arg
incr j
} elseif {$opt eq {--verbose}} {
set ::verbose 1
} elseif {$opt eq {--accurate}} {
set ::accurate 1
} elseif {$opt eq {--force-failure}} {
set ::force_failure 1
} elseif {$opt eq {--single}} {
set ::all_tests $arg
incr j
} elseif {$opt eq {--list-tests}} {
foreach t $::all_tests {
puts $t
}
exit 0
} elseif {$opt eq {--client}} {
set ::client 1
set ::test_server_port $arg
incr j
} elseif {$opt eq {--help}} {
print_help_screen
exit 0
} else {
puts "Wrong argument: $opt"
exit 1
}
}
if {[catch { main } err]} {
if {[string length $err] > 0} {
# only display error when not generated by the test suite
if {$err ne "exception"} {
puts $::errorInfo
if {$::client} {
if {[catch { test_client_main $::test_server_port } err]} {
set estr "Executing test client: $err.\n$::errorInfo"
if {[catch {send_data_packet $::test_server_fd exception $estr}]} {
puts $estr
}
exit 1
}
} else {
if {[catch { test_server_main } err]} {
if {[string length $err] > 0} {
# only display error when not generated by the test suite
if {$err ne "exception"} {
puts $::errorInfo
}
exit 1
}
}
}
......@@ -7,7 +7,7 @@ start_server {tags {"expire"}} {
set v4 [r ttl x]
r expire x 4
list $v1 $v2 $v3 $v4
} {1 5 1 10}
} {1 [45] 1 10}
test {EXPIRE - It should be still possible to read 'x'} {
r get x
......
start_server {tags {"other"}} {
if {$::force_failure} {
# This is used just for test suite development purposes.
test {Failing test} {
format err
} {ok}
}
test {SAVE - make sure there are all the types as values} {
# Wait for a background saving in progress to terminate
waitForBgsave r
......@@ -12,11 +19,12 @@ start_server {tags {"other"}} {
r save
} {OK}
tags {slow nodiskstore} {
tags {slow} {
if {$::accurate} {set iterations 10000} else {set iterations 1000}
foreach fuzztype {binary alpha compr} {
test "FUZZ stresser with data model $fuzztype" {
set err 0
for {set i 0} {$i < 10000} {incr i} {
for {set i 0} {$i < $iterations} {incr i} {
set fuzz [randstring 0 512 $fuzztype]
r set foo $fuzz
set got [r get foo]
......@@ -46,11 +54,12 @@ start_server {tags {"other"}} {
set _ $err
} {*invalid*}
tags {consistency nodiskstore} {
tags {consistency} {
if {![catch {package require sha1}]} {
if {$::accurate} {set numops 10000} else {set numops 1000}
test {Check consistency of different data types after a reload} {
r flushdb
createComplexDataset r 10000
createComplexDataset r $numops
set dump [csvdump r]
set sha1 [r debug digest]
r debug reload
......@@ -102,25 +111,19 @@ start_server {tags {"other"}} {
r flushdb
r set x 10
r expire x 1000
if {$::diskstore} {
r debug flushcache
} else {
r save
r debug reload
}
r save
r debug reload
set ttl [r ttl x]
set e1 [expr {$ttl > 900 && $ttl <= 1000}]
if {!$::diskstore} {
r bgrewriteaof
waitForBgrewriteaof r
r debug loadaof
}
r bgrewriteaof
waitForBgrewriteaof r
r debug loadaof
set ttl [r ttl x]
set e2 [expr {$ttl > 900 && $ttl <= 1000}]
list $e1 $e2
} {1 1}
tags {protocol nodiskstore} {
tags {protocol} {
test {PIPELINING stresser (also a regression for the old epoll bug)} {
set fd2 [socket $::host $::port]
fconfigure $fd2 -encoding binary -translation binary
......@@ -244,6 +247,7 @@ start_server {tags {"other"}} {
} {0 0}
test {Perform a final SAVE to leave a clean DB on disk} {
waitForBgsave r
r save
} {OK}
}
start_server {tags {"slowlog"} overrides {slowlog-log-slower-than 1000000}} {
test {SLOWLOG - check that it starts with an empty log} {
r slowlog len
} {0}
test {SLOWLOG - only logs commands taking more time than specified} {
r config set slowlog-log-slower-than 100000
r ping
assert_equal [r slowlog len] 0
r debug sleep 0.2
assert_equal [r slowlog len] 1
}
test {SLOWLOG - max entries is correctly handled} {
r config set slowlog-log-slower-than 0
r config set slowlog-max-len 10
for {set i 0} {$i < 100} {incr i} {
r ping
}
r slowlog len
} {10}
test {SLOWLOG - GET optional argument to limit output len works} {
llength [r slowlog get 5]
} {5}
test {SLOWLOG - RESET subcommand works} {
r config set slowlog-log-slower-than 100000
r slowlog reset
r slowlog len
} {0}
test {SLOWLOG - logged entry sanity check} {
r debug sleep 0.2
set e [lindex [r slowlog get] 0]
assert_equal [llength $e] 4
assert_equal [lindex $e 0] 105
assert_equal [expr {[lindex $e 2] > 100000}] 1
assert_equal [lindex $e 3] {debug sleep 0.2}
}
}
start_server {
tags {"list"}
overrides {
"list-max-ziplist-value" 16
"list-max-ziplist-entries" 256
}
} {
source "tests/unit/type/list-common.tcl"
foreach {type large} [array get largevalue] {
tags {"slow"} {
test "LTRIM stress testing - $type" {
set mylist {}
set startlen 32
r del mylist
# Start with the large value to ensure the
# right encoding is used.
r rpush mylist $large
lappend mylist $large
for {set i 0} {$i < $startlen} {incr i} {
set str [randomInt 9223372036854775807]
r rpush mylist $str
lappend mylist $str
}
for {set i 0} {$i < 1000} {incr i} {
set min [expr {int(rand()*$startlen)}]
set max [expr {$min+int(rand()*$startlen)}]
set mylist [lrange $mylist $min $max]
r ltrim mylist $min $max
assert_equal $mylist [r lrange mylist 0 -1]
for {set j [r llen mylist]} {$j < $startlen} {incr j} {
set str [randomInt 9223372036854775807]
r rpush mylist $str
lappend mylist $str
}
}
}
}
}
}
start_server {
tags {list ziplist}
overrides {
"list-max-ziplist-value" 200000
"list-max-ziplist-entries" 256
}
} {
test {Explicit regression for a list bug} {
set mylist {49376042582 {BkG2o\pIC]4YYJa9cJ4GWZalG[4tin;1D2whSkCOW`mX;SFXGyS8sedcff3fQI^tgPCC@^Nu1J6o]meM@Lko]t_jRyo<xSJ1oObDYd`ppZuW6P@fS278YaOx=s6lvdFlMbP0[SbkI^Kr\HBXtuFaA^mDx:yzS4a[skiiPWhT<nNfAf=aQVfclcuwDrfe;iVuKdNvB9kbfq>tK?tH[\EvWqS]b`o2OCtjg:?nUTwdjpcUm]y:pg5q24q7LlCOwQE^}}
r del l
r rpush l [lindex $mylist 0]
r rpush l [lindex $mylist 1]
assert_equal [r lindex l 0] [lindex $mylist 0]
assert_equal [r lindex l 1] [lindex $mylist 1]
}
tags {slow} {
test {ziplist implementation: value encoding and backlink} {
if {$::accurate} {set iterations 100} else {set iterations 10}
for {set j 0} {$j < $iterations} {incr j} {
r del l
set l {}
for {set i 0} {$i < 200} {incr i} {
randpath {
set data [string repeat x [randomInt 100000]]
} {
set data [randomInt 65536]
} {
set data [randomInt 4294967296]
} {
set data [randomInt 18446744073709551616]
}
lappend l $data
r rpush l $data
}
assert_equal [llength $l] [r llen l]
# Traverse backward
for {set i 199} {$i >= 0} {incr i -1} {
if {[lindex $l $i] ne [r lindex l $i]} {
assert_equal [lindex $l $i] [r lindex l $i]
}
}
}
}
test {ziplist implementation: encoding stress testing} {
for {set j 0} {$j < 200} {incr j} {
r del l
set l {}
set len [randomInt 400]
for {set i 0} {$i < $len} {incr i} {
set rv [randomValue]
randpath {
lappend l $rv
r rpush l $rv
} {
set l [concat [list $rv] $l]
r lpush l $rv
}
}
assert_equal [llength $l] [r llen l]
for {set i 0} {$i < $len} {incr i} {
if {[lindex $l $i] ne [r lindex l $i]} {
assert_equal [lindex $l $i] [r lindex l $i]
}
}
}
}
}
}
# We need a value larger than list-max-ziplist-value to make sure
# the list has the right encoding when it is swapped in again.
array set largevalue {}
set largevalue(ziplist) "hello"
set largevalue(linkedlist) [string repeat "hello" 4]
......@@ -5,11 +5,7 @@ start_server {
"list-max-ziplist-entries" 256
}
} {
# We need a value larger than list-max-ziplist-value to make sure
# the list has the right encoding when it is swapped in again.
array set largevalue {}
set largevalue(ziplist) "hello"
set largevalue(linkedlist) [string repeat "hello" 4]
source "tests/unit/type/list-common.tcl"
test {LPUSH, RPUSH, LLENGTH, LINDEX - ziplist} {
# first lpush then rpush
......@@ -152,8 +148,11 @@ start_server {
test "BLPOP with variadic LPUSH" {
set rd [redis_deferring_client]
r del blist target
if {$::valgrind} {after 100}
$rd blpop blist 0
if {$::valgrind} {after 100}
assert_equal 2 [r lpush blist foo bar]
if {$::valgrind} {after 100}
assert_equal {blist foo} [$rd read]
assert_equal bar [lindex [r lrange blist 0 -1] 0]
}
......@@ -671,38 +670,6 @@ start_server {
assert_equal {} [trim_list $type 0 -6]
}
tags {"slow"} {
test "LTRIM stress testing - $type" {
set mylist {}
set startlen 32
r del mylist
# Start with the large value to ensure the
# right encoding is used.
r rpush mylist $large
lappend mylist $large
for {set i 0} {$i < $startlen} {incr i} {
set str [randomInt 9223372036854775807]
r rpush mylist $str
lappend mylist $str
}
for {set i 0} {$i < 1000} {incr i} {
set min [expr {int(rand()*$startlen)}]
set max [expr {$min+int(rand()*$startlen)}]
set mylist [lrange $mylist $min $max]
r ltrim mylist $min $max
assert_equal $mylist [r lrange mylist 0 -1]
for {set j [r llen mylist]} {$j < $startlen} {incr j} {
set str [randomInt 9223372036854775807]
r rpush mylist $str
lappend mylist $str
}
}
}
}
}
foreach {type large} [array get largevalue] {
......@@ -760,76 +727,5 @@ start_server {
assert_equal 1 [r lrem myotherlist 1 2]
assert_equal 3 [r llen myotherlist]
}
}
}
start_server {
tags {list ziplist}
overrides {
"list-max-ziplist-value" 200000
"list-max-ziplist-entries" 256
}
} {
test {Explicit regression for a list bug} {
set mylist {49376042582 {BkG2o\pIC]4YYJa9cJ4GWZalG[4tin;1D2whSkCOW`mX;SFXGyS8sedcff3fQI^tgPCC@^Nu1J6o]meM@Lko]t_jRyo<xSJ1oObDYd`ppZuW6P@fS278YaOx=s6lvdFlMbP0[SbkI^Kr\HBXtuFaA^mDx:yzS4a[skiiPWhT<nNfAf=aQVfclcuwDrfe;iVuKdNvB9kbfq>tK?tH[\EvWqS]b`o2OCtjg:?nUTwdjpcUm]y:pg5q24q7LlCOwQE^}}
r del l
r rpush l [lindex $mylist 0]
r rpush l [lindex $mylist 1]
assert_equal [r lindex l 0] [lindex $mylist 0]
assert_equal [r lindex l 1] [lindex $mylist 1]
}
tags {slow} {
test {ziplist implementation: value encoding and backlink} {
for {set j 0} {$j < 100} {incr j} {
r del l
set l {}
for {set i 0} {$i < 200} {incr i} {
randpath {
set data [string repeat x [randomInt 100000]]
} {
set data [randomInt 65536]
} {
set data [randomInt 4294967296]
} {
set data [randomInt 18446744073709551616]
}
lappend l $data
r rpush l $data
}
assert_equal [llength $l] [r llen l]
# Traverse backward
for {set i 199} {$i >= 0} {incr i -1} {
if {[lindex $l $i] ne [r lindex l $i]} {
assert_equal [lindex $l $i] [r lindex l $i]
}
}
}
}
test {ziplist implementation: encoding stress testing} {
for {set j 0} {$j < 200} {incr j} {
r del l
set l {}
set len [randomInt 400]
for {set i 0} {$i < $len} {incr i} {
set rv [randomValue]
randpath {
lappend l $rv
r rpush l $rv
} {
set l [concat [list $rv] $l]
r lpush l $rv
}
}
assert_equal [llength $l] [r llen l]
for {set i 0} {$i < 200} {incr i} {
if {[lindex $l $i] ne [r lindex l $i]} {
assert_equal [lindex $l $i] [r lindex l $i]
}
}
}
}
}
}
......@@ -527,7 +527,7 @@ start_server {tags {"zset"}} {
} elseif {$encoding == "skiplist"} {
r config set zset-max-ziplist-entries 0
r config set zset-max-ziplist-value 0
set elements 1000
if {$::accurate} {set elements 1000} else {set elements 100}
} else {
puts "Unknown sorted set encoding"
exit
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment