2 # Redis test suite. Copyright (C) 2009 Salvatore Sanfilippo antirez@gmail.com
3 # This softare is released under the BSD License. See the COPYING file for
13 proc test
{name code okpattern
} {
15 if {$::testnum < $::first ||
$::testnum > $::last} return
16 puts -nonewline [format "%-70s " "#$::testnum $name"]
18 set retval
[uplevel 1 $code]
19 if {$okpattern eq
$retval ||
[string match
$okpattern $retval]} {
23 puts "!! ERROR expected\n'$okpattern'\nbut got\n'$retval'"
28 proc randstring
{min max
{type
binary}} {
29 set len
[expr {$min+int
(rand
()*($max-$min+1))}]
31 if {$type eq
{binary}} {
34 } elseif
{$type eq
{alpha
}} {
37 } elseif
{$type eq
{compr
}} {
42 append output
[format "%c" [expr {$minval+int
(rand
()*($maxval-$minval+1))}]]
48 # Useful for some test
49 proc zlistAlikeSort
{a b
} {
50 if {[lindex $a 0] > [lindex $b 0]} {return 1}
51 if {[lindex $a 0] < [lindex $b 0]} {return -1}
52 string compare
[lindex $a 1] [lindex $b 1]
55 proc waitForBgsave r
{
58 if {[string match
{*bgsave_in_progress
:1*} $i]} {
59 puts -nonewline "\nWaiting for background save to finish... "
68 proc waitForBgrewriteaof r
{
71 if {[string match
{*bgrewriteaof_in_progress
:1*} $i]} {
72 puts -nonewline "\nWaiting for background AOF rewrite to finish... "
81 proc randomInt
{max
} {
82 expr {int
(rand
()*$max)}
86 set path
[expr {int
(rand
()*[llength $args])}]
87 uplevel 1 [lindex $args $path]
92 # Small enough to likely collide
95 # 32 bit compressible signed/unsigned
96 randpath
{randomInt
2000000000} {randomInt
4000000000}
99 randpath
{randomInt
1000000000000}
102 randpath
{randstring
0 256 alpha
} \
103 {randstring
0 256 compr
} \
104 {randstring
0 256 binary}
110 # Small enough to likely collide
113 # 32 bit compressible signed/unsigned
114 randpath
{randomInt
2000000000} {randomInt
4000000000}
117 randpath
{randomInt
1000000000000}
120 randpath
{randstring
1 256 alpha
} \
121 {randstring
1 256 compr
}
125 proc createComplexDataset
{r ops
} {
126 for {set j
0} {$j < $ops} {incr j
} {
130 set d
[expr {rand
()}]
132 set d
[expr {rand
()}]
134 set d
[expr {rand
()}]
136 set d
[expr {rand
()}]
138 set d
[expr {rand
()}]
140 randpath
{set d
+inf
} {set d
-inf}
162 randpath
{$r lpush
$k $v} \
169 randpath
{$r sadd
$k $v} \
173 randpath
{$r zadd
$k $d $v} \
180 proc datasetDigest r
{
181 set keys
[lsort [split [$r keys
*] " "]]
187 set aux
[::sha1::sha1 -hex [$r get
$k]]
189 if {[$r llen
$k] == 0} {
192 set aux
[::sha1::sha1 -hex [$r lrange $k 0 -1]]
195 if {[$r scard
$k] == 0} {
198 set aux
[::sha1::sha1 -hex [lsort [$r smembers
$k]]]
201 if {[$r zcard
$k] == 0} {
204 set aux
[::sha1::sha1 -hex [$r zrange
$k 0 -1]]
207 error "Type not supported"
210 if {$aux eq
{}} continue
211 set digest
[::sha1::sha1 -hex [join [list $aux $digest $k] "\n"]]
216 proc main
{server port
} {
217 set r
[redis
$server $port]
222 # The following AUTH test should be enabled only when requirepass
223 # <PASSWORD> is set in redis.conf and redis-server was started with
224 # redis.conf as the first argument.
226 #test {AUTH with requirepass in redis.conf} {
230 test
{DEL all keys to start with a clean DB
} {
231 foreach key
[$r keys
*] {$r del
$key}
235 test
{SET and GET an item
} {
240 test
{SET and GET an empty item
} {
245 test
{DEL against a single item
} {
254 list [$r del foo1 foo2 foo3 foo4
] [$r mget foo1 foo2 foo3
]
257 test
{KEYS with pattern
} {
258 foreach key
{key_x key_y key_z foo_a foo_b foo_c
} {
262 } {foo_a foo_b foo_c
}
264 test
{KEYS to get all keys
} {
266 } {foo_a foo_b foo_c key_x key_y key_z
}
272 test
{DEL all keys
} {
273 foreach key
[$r keys
*] {$r del
$key}
277 test
{Very big payload in GET
/SET
} {
278 set buf
[string repeat
"abcd" 1000000]
281 } [string repeat
"abcd" 1000000]
283 test
{Very big payload random access
} {
286 for {set j
0} {$j < 100} {incr j
} {
287 set size
[expr 1+[randomInt
100000]]
288 set buf
[string repeat
"abcd" $size]
290 $r set bigpayload_
$j $buf
292 for {set j
0} {$j < 1000} {incr j
} {
293 set index
[randomInt
100]
294 set buf
[$r get bigpayload_
$index]
295 if {$buf != $payload($index)} {
296 set err
"Values differ: I set '$buf' but I read back '$buf2'"
304 test
{SET
10000 numeric keys and access all them in reverse order
} {
306 for {set x
0} {$x < 10000} {incr x
} {
310 for {set x
9999} {$x >= 0} {incr x
-1} {
313 set err
"Eleemnt at position $x is $val instead of $x"
320 test
{DBSIZE should be
10001 now
} {
324 test
{INCR against non existing key
} {
326 append res
[$r incr novar
]
327 append res
[$r get novar
]
330 test
{INCR against key created by
incr itself
} {
334 test
{INCR against key originally
set with SET
} {
339 test
{INCR over
32bit value
} {
340 $r set novar
17179869184
344 test
{INCRBY over
32bit value with over
32bit increment
} {
345 $r set novar
17179869184
346 $r incrby novar
17179869184
349 test
{INCR against key with spaces
(no integer encoded
)} {
354 test
{DECRBY over
32bit value with over
32bit increment
, negative res
} {
355 $r set novar
17179869184
356 $r decrby novar
17179869185
359 test
{SETNX target key missing
} {
360 $r setnx novar2 foobared
364 test
{SETNX target key exists
} {
365 $r setnx novar2 blabla
369 test
{SETNX will overwrite EXPIREing key
} {
379 append res
[$r exists newkey
]
381 append res
[$r exists newkey
]
384 test
{Zero length value in key. SET
/GET
/EXISTS
} {
386 set res
[$r get emptykey
]
387 append res
[$r exists emptykey
]
389 append res
[$r exists emptykey
]
392 test
{Commands pipelining
} {
394 puts -nonewline $fd "SET k1 4\r\nxyzk\r\nGET k1\r\nPING\r\n"
397 append res
[string match OK
* [::redis::redis_read_reply $fd]]
398 append res
[::redis::redis_read_reply $fd]
399 append res
[string match PONG
* [::redis::redis_read_reply $fd]]
403 test
{Non existing command
} {
404 catch {$r foobaredcommand
} err
405 string match ERR
* $err
408 test
{Basic LPUSH
, RPUSH
, LLENGTH
, LINDEX
} {
412 set res
[$r llen mylist
]
413 append res
[$r lindex mylist
0]
414 append res
[$r lindex mylist
1]
415 append res
[$r lindex mylist
2]
416 list $res [$r lindex mylist
100]
424 test
{Create a long
list and check every single element with LINDEX
} {
426 for {set i
0} {$i < 1000} {incr i
} {
429 for {set i
0} {$i < 1000} {incr i
} {
430 if {[$r lindex mylist
$i] eq
$i} {incr ok
}
431 if {[$r lindex mylist
[expr (-$i)-1]] eq
[expr 999-$i]} {
438 test
{Test elements with LINDEX in random access
} {
440 for {set i
0} {$i < 1000} {incr i
} {
441 set rint
[expr int
(rand
()*1000)]
442 if {[$r lindex mylist
$rint] eq
$rint} {incr ok
}
443 if {[$r lindex mylist
[expr (-$rint)-1]] eq
[expr 999-$rint]} {
450 test
{Check
if the
list is still ok
after a DEBUG RELOAD
} {
453 for {set i
0} {$i < 1000} {incr i
} {
454 set rint
[expr int
(rand
()*1000)]
455 if {[$r lindex mylist
$rint] eq
$rint} {incr ok
}
456 if {[$r lindex mylist
[expr (-$rint)-1]] eq
[expr 999-$rint]} {
463 test
{LLEN against non-list value
error} {
466 catch {$r llen mylist
} err
470 test
{LLEN against non existing key
} {
474 test
{LINDEX against non-list value
error} {
475 catch {$r lindex mylist
0} err
479 test
{LINDEX against non existing key
} {
480 $r lindex not-a-key
10
483 test
{LPUSH against non-list value
error} {
484 catch {$r lpush mylist
0} err
488 test
{RPUSH against non-list value
error} {
489 catch {$r rpush mylist
0} err
493 test
{RPOPLPUSH base case
} {
499 set v1
[$r rpoplpush mylist newlist
]
500 set v2
[$r rpoplpush mylist newlist
]
501 set l1
[$r lrange mylist
0 -1]
502 set l2
[$r lrange newlist
0 -1]
506 test
{RPOPLPUSH with the same
list as src and dst
} {
511 set l1
[$r lrange mylist
0 -1]
512 set v
[$r rpoplpush mylist mylist
]
513 set l2
[$r lrange mylist
0 -1]
515 } {{a b c
} c
{c a b
}}
517 test
{RPOPLPUSH target
list already exists
} {
525 set v1
[$r rpoplpush mylist newlist
]
526 set v2
[$r rpoplpush mylist newlist
]
527 set l1
[$r lrange mylist
0 -1]
528 set l2
[$r lrange newlist
0 -1]
530 } {d c
{a b
} {c d x
}}
532 test
{RPOPLPUSH against non existing key
} {
535 set v1
[$r rpoplpush mylist newlist
]
536 list $v1 [$r exists mylist
] [$r exists newlist
]
539 test
{RPOPLPUSH against non
list src key
} {
543 catch {$r rpoplpush mylist newlist
} err
544 list [$r type mylist
] [$r exists newlist
] [string range
$err 0 2]
547 test
{RPOPLPUSH against non
list dst key
} {
555 catch {$r rpoplpush mylist newlist
} err
556 list [$r lrange mylist
0 -1] [$r type newlist
] [string range
$err 0 2]
557 } {{a b c d
} string ERR
}
559 test
{RPOPLPUSH against non existing src key
} {
562 $r rpoplpush mylist newlist
565 test
{RENAME basic usage
} {
567 $r rename mykey mykey1
568 $r rename mykey1 mykey2
572 test
{RENAME
source key should no longer exist
} {
576 test
{RENAME against already existing key
} {
579 $r rename mykey2 mykey
580 set res
[$r get mykey
]
581 append res
[$r exists mykey2
]
584 test
{RENAMENX basic usage
} {
588 $r renamenx mykey mykey2
589 set res
[$r get mykey2
]
590 append res
[$r exists mykey
]
593 test
{RENAMENX against already existing key
} {
596 $r renamenx mykey mykey2
599 test
{RENAMENX against already existing key
(2)} {
600 set res
[$r get mykey
]
601 append res
[$r get mykey2
]
604 test
{RENAME against non existing
source key
} {
605 catch {$r rename nokey foobar
} err
609 test
{RENAME where
source and dest key is the same
} {
610 catch {$r rename mykey mykey
} err
614 test
{DEL all keys again
(DB
0)} {
615 foreach key
[$r keys
*] {
621 test
{DEL all keys again
(DB
1)} {
623 foreach key
[$r keys
*] {
631 test
{MOVE basic usage
} {
635 lappend res
[$r exists mykey
]
636 lappend res
[$r dbsize
]
638 lappend res
[$r get mykey
]
639 lappend res
[$r dbsize
]
642 } [list 0 0 foobar
1]
644 test
{MOVE against key existing in the target DB
} {
649 test
{SET
/GET keys in different DBs
} {
657 lappend res
[$r get a
]
658 lappend res
[$r get b
]
660 lappend res
[$r get a
]
661 lappend res
[$r get b
]
664 } {hello world foo bared
}
666 test
{Basic LPOP
/RPOP
} {
671 list [$r lpop mylist
] [$r rpop mylist
] [$r lpop mylist
] [$r llen mylist
]
674 test
{LPOP
/RPOP against empty
list} {
678 test
{LPOP against non
list value
} {
680 catch {$r lpop notalist
} err
684 test
{Mass LPUSH
/LPOP
} {
686 for {set i
0} {$i < 1000} {incr i
} {
691 for {set i
0} {$i < 500} {incr i
} {
692 incr sum2
[$r lpop mylist
]
693 incr sum2
[$r rpop mylist
]
698 test
{LRANGE basics
} {
699 for {set i
0} {$i < 10} {incr i
} {
702 list [$r lrange mylist
1 -2] \
703 [$r lrange mylist
-3 -1] \
704 [$r lrange mylist
4 4]
705 } {{1 2 3 4 5 6 7 8} {7 8 9} 4}
707 test
{LRANGE inverted indexes
} {
711 test
{LRANGE out of range indexes including the full
list} {
712 $r lrange mylist
-1000 1000
713 } {0 1 2 3 4 5 6 7 8 9}
715 test
{LRANGE against non existing key
} {
716 $r lrange nosuchkey
0 1
719 test
{LTRIM basics
} {
721 for {set i
0} {$i < 100} {incr i
} {
725 $r lrange mylist
0 -1
728 test
{LTRIM stress testing
} {
731 for {set i
0} {$i < 20} {incr i
} {
735 for {set j
0} {$j < 100} {incr j
} {
738 for {set i
0} {$i < 20} {incr i
} {
744 $r ltrim mylist
$a $b
745 if {[$r lrange mylist
0 -1] ne
[lrange $mylist $a $b]} {
746 set err
"[$r lrange mylist 0 -1] != [lrange $mylist $a $b]"
755 foreach x
{99 98 97 96 95} {
759 $r lset mylist
-1 bar
760 $r lrange mylist
0 -1
763 test
{LSET out of range index
} {
764 catch {$r lset mylist
10 foo
} err
768 test
{LSET against non existing key
} {
769 catch {$r lset nosuchkey
10 foo
} err
773 test
{LSET against non
list value
} {
775 catch {$r lset nolist
0 foo
} err
779 test
{SADD
, SCARD
, SISMEMBER
, SMEMBERS basics
} {
782 list [$r scard myset
] [$r sismember myset foo
] \
783 [$r sismember myset bar
] [$r sismember myset bla
] \
784 [lsort [$r smembers myset
]]
785 } {2 1 1 0 {bar foo
}}
787 test
{SADD adding the same element multiple times
} {
794 test
{SADD against non
set} {
795 catch {$r sadd mylist foo
} err
802 lsort [$r smembers myset
]
805 test
{Mass SADD and SINTER with two sets
} {
806 for {set i
0} {$i < 1000} {incr i
} {
808 $r sadd set2
[expr $i+995]
810 lsort [$r sinter set1 set2
]
811 } {995 996 997 998 999}
813 test
{SUNION with two sets
} {
814 lsort [$r sunion set1 set2
]
815 } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
817 test
{SINTERSTORE with two sets
} {
818 $r sinterstore setres set1 set2
819 lsort [$r smembers setres
]
820 } {995 996 997 998 999}
822 test
{SINTERSTORE with two sets
, after a DEBUG RELOAD
} {
824 $r sinterstore setres set1 set2
825 lsort [$r smembers setres
]
826 } {995 996 997 998 999}
828 test
{SUNIONSTORE with two sets
} {
829 $r sunionstore setres set1 set2
830 lsort [$r smembers setres
]
831 } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
833 test
{SUNIONSTORE against non existing keys
} {
835 list [$r sunionstore setres foo111 bar222
] [$r exists xxx
]
838 test
{SINTER against three sets
} {
843 lsort [$r sinter set1 set2 set3
]
846 test
{SINTERSTORE with three sets
} {
847 $r sinterstore setres set1 set2 set3
848 lsort [$r smembers setres
]
851 test
{SUNION with non existing keys
} {
852 lsort [$r sunion nokey1 set1 set2 nokey2
]
853 } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
855 test
{SDIFF with two sets
} {
856 for {set i
5} {$i < 1000} {incr i
} {
859 lsort [$r sdiff set1 set4
]
862 test
{SDIFF with three sets
} {
864 lsort [$r sdiff set1 set4 set5
]
867 test
{SDIFFSTORE with three sets
} {
868 $r sdiffstore sres set1 set4 set5
869 lsort [$r smembers sres
]
877 list [lsort [list [$r spop myset
] [$r spop myset
] [$r spop myset
]]] [$r scard myset
]
880 test
{SAVE
- make sure there are all the types as values
} {
881 # Wait for a background saving in progress to terminate
883 $r lpush mysavelist hello
884 $r lpush mysavelist world
886 $r set mynormalkey
{blablablba
}
887 $r zadd mytestzset a
10
888 $r zadd mytestzset b
20
889 $r zadd mytestzset c
30
898 unset -nocomplain myset
900 for {set i
0} {$i < 100} {incr i
} {
901 set myset
([$r srandmember myset
]) 1
903 lsort [array names myset
]
906 test
{Create a random
list and a random
set} {
908 array set seenrand
{}
909 for {set i
0} {$i < 10000} {incr i
} {
911 # Make sure all the weights are different because
912 # Redis does not use a stable sort but Tcl does.
914 set rint
[expr int
(rand
()*1000000)]
916 set rint
[expr rand
()]
918 if {![info exists seenrand
($rint)]} break
920 set seenrand
($rint) x
922 $r sadd tosort-set
$i
923 $r set weight_
$i $rint
924 lappend tosort
[list $i $rint]
926 set sorted
[lsort -index 1 -real $tosort]
928 for {set i
0} {$i < 10000} {incr i
} {
929 lappend res
[lindex $sorted $i 0]
934 test
{SORT with BY against the newly created
list} {
935 $r sort tosort
{BY weight_
*}
938 test
{the same SORT with BY
, but against the newly created
set} {
939 $r sort tosort-set
{BY weight_
*}
942 test
{SORT with BY and STORE against the newly created
list} {
943 $r sort tosort
{BY weight_
*} store sort-res
944 $r lrange sort-res
0 -1
947 test
{SORT direct
, numeric
, against the newly created
list} {
949 } [lsort -integer $res]
951 test
{SORT decreasing sort
} {
952 $r sort tosort
{DESC
}
953 } [lsort -decreasing -integer $res]
955 test
{SORT speed
, sorting
10000 elements
list using BY
, 100 times
} {
956 set start
[clock clicks
-milliseconds]
957 for {set i
0} {$i < 100} {incr i
} {
958 set sorted
[$r sort tosort
{BY weight_
* LIMIT
0 10}]
960 set elapsed
[expr [clock clicks
-milliseconds]-$start]
961 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
966 test
{SORT speed
, sorting
10000 elements
list directly
, 100 times
} {
967 set start
[clock clicks
-milliseconds]
968 for {set i
0} {$i < 100} {incr i
} {
969 set sorted
[$r sort tosort
{LIMIT
0 10}]
971 set elapsed
[expr [clock clicks
-milliseconds]-$start]
972 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
977 test
{SORT speed
, pseudo-sorting
10000 elements
list, BY
<const
>, 100 times
} {
978 set start
[clock clicks
-milliseconds]
979 for {set i
0} {$i < 100} {incr i
} {
980 set sorted
[$r sort tosort
{BY nokey LIMIT
0 10}]
982 set elapsed
[expr [clock clicks
-milliseconds]-$start]
983 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
988 test
{SORT regression
for issue
#19, sorting floats} {
990 foreach x
{1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15} {
994 } [lsort -real {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15}]
996 test
{SORT with GET
#} {
1001 $r mset weight_1
10 weight_2
5 weight_3
30
1002 $r sort mylist BY weight_
* GET
#
1005 test
{SORT with constant GET
} {
1006 $r sort mylist GET foo
1009 test
{LREM
, remove all the occurrences
} {
1013 $r rpush mylist foobar
1014 $r rpush mylist foobared
1017 $r rpush mylist test
1019 set res
[$r lrem mylist
0 bar
]
1020 list [$r lrange mylist
0 -1] $res
1021 } {{foo foobar foobared zap test foo
} 2}
1023 test
{LREM
, remove the first occurrence
} {
1024 set res
[$r lrem mylist
1 foo
]
1025 list [$r lrange mylist
0 -1] $res
1026 } {{foobar foobared zap test foo
} 1}
1028 test
{LREM
, remove non existing element
} {
1029 set res
[$r lrem mylist
1 nosuchelement
]
1030 list [$r lrange mylist
0 -1] $res
1031 } {{foobar foobared zap test foo
} 0}
1033 test
{LREM
, starting from tail with negative count
} {
1037 $r rpush mylist foobar
1038 $r rpush mylist foobared
1041 $r rpush mylist test
1044 set res
[$r lrem mylist
-1 bar
]
1045 list [$r lrange mylist
0 -1] $res
1046 } {{foo bar foobar foobared zap test foo foo
} 1}
1048 test
{LREM
, starting from tail with negative count
(2)} {
1049 set res
[$r lrem mylist
-2 foo
]
1050 list [$r lrange mylist
0 -1] $res
1051 } {{foo bar foobar foobared zap test
} 2}
1053 test
{LREM
, deleting objects that may be encoded as integers
} {
1054 $r lpush myotherlist
1
1055 $r lpush myotherlist
2
1056 $r lpush myotherlist
3
1057 $r lrem myotherlist
1 2
1068 test
{MGET against non existing key
} {
1069 $r mget foo baazz bar
1072 test
{MGET against non-string key
} {
1075 $r mget foo baazz bar myset
1084 for {set i
0} {$i < 100} {incr i
} {
1085 set rkey
[$r randomkey
]
1086 if {$rkey eq
{foo
}} {
1089 if {$rkey eq
{bar
}} {
1093 list $foo_seen $bar_seen
1096 test
{RANDOMKEY against empty DB
} {
1101 test
{RANDOMKEY regression
1} {
1108 test
{GETSET
(set new value
)} {
1109 list [$r getset foo xyz
] [$r get foo
]
1112 test
{GETSET
(replace old value
)} {
1114 list [$r getset foo xyz
] [$r get foo
]
1117 test
{SMOVE basics
} {
1124 $r smove myset1 myset2 a
1125 list [lsort [$r smembers myset2
]] [lsort [$r smembers myset1
]]
1128 test
{SMOVE non existing key
} {
1129 list [$r smove myset1 myset2 foo
] [lsort [$r smembers myset2
]] [lsort [$r smembers myset1
]]
1130 } {0 {a x y z
} {b c
}}
1132 test
{SMOVE non existing src
set} {
1133 list [$r smove noset myset2 foo
] [lsort [$r smembers myset2
]]
1136 test
{SMOVE non existing dst
set} {
1137 list [$r smove myset2 myset3 y
] [lsort [$r smembers myset2
]] [lsort [$r smembers myset3
]]
1140 test
{SMOVE wrong src key type
} {
1142 catch {$r smove x myset2 foo
} err
1146 test
{SMOVE wrong dst key type
} {
1148 catch {$r smove myset2 x foo
} err
1152 test
{MSET base case
} {
1153 $r mset x
10 y
"foo bar" z
"x x x x x x x\n\n\r\n"
1155 } [list 10 {foo bar
} "x x x x x x x\n\n\r\n"]
1157 test
{MSET wrong number of args
} {
1158 catch {$r mset x
10 y
"foo bar" z
} err
1162 test
{MSETNX with already existent key
} {
1163 list [$r msetnx x1 xxx y2 yyy x
20] [$r exists x1
] [$r exists y2
]
1166 test
{MSETNX with not existing keys
} {
1167 list [$r msetnx x1 xxx y2 yyy
] [$r get x1
] [$r get y2
]
1170 test
{MSETNX should remove all the volatile keys even on
failure} {
1174 list [$r msetnx x A y B z C
] [$r mget x y z
]
1177 test
{ZSET basic ZADD and score
update} {
1181 set aux1
[$r zrange ztmp
0 -1]
1183 set aux2
[$r zrange ztmp
0 -1]
1187 test
{ZCARD basics
} {
1191 test
{ZCARD non existing key
} {
1192 $r zcard ztmp-blabla
1198 for {set i
0} {$i < 1000} {incr i
} {
1199 set score
[expr rand
()]
1201 $r zadd zscoretest
$score $i
1203 for {set i
0} {$i < 1000} {incr i
} {
1204 if {[$r zscore zscoretest
$i] != [lindex $aux $i]} {
1205 set err
"Expected score was [lindex $aux $i] but got [$r zscore zscoretest $i] for element $i"
1212 test
{ZSCORE
after a DEBUG RELOAD
} {
1216 for {set i
0} {$i < 1000} {incr i
} {
1217 set score
[expr rand
()]
1219 $r zadd zscoretest
$score $i
1222 for {set i
0} {$i < 1000} {incr i
} {
1223 if {[$r zscore zscoretest
$i] != [lindex $aux $i]} {
1224 set err
"Expected score was [lindex $aux $i] but got [$r zscore zscoretest $i] for element $i"
1231 test
{ZRANGE and ZREVRANGE basics
} {
1232 list [$r zrange ztmp
0 -1] [$r zrevrange ztmp
0 -1] \
1233 [$r zrange ztmp
1 -1] [$r zrevrange ztmp
1 -1]
1234 } {{y x z
} {z x y
} {x z
} {x y
}}
1236 test
{ZRANGE WITHSCORES
} {
1237 $r zrange ztmp
0 -1 withscores
1240 test
{ZSETs stress tester
- sorting is working well?
} {
1242 for {set test
0} {$test < 2} {incr test
} {
1243 unset -nocomplain auxarray
1244 array set auxarray
{}
1247 for {set i
0} {$i < 1000} {incr i
} {
1249 set score
[expr rand
()]
1251 set score
[expr int
(rand
()*10)]
1253 set auxarray
($i) $score
1254 $r zadd myzset
$score $i
1256 if {[expr rand
()] < .2} {
1257 set j
[expr int
(rand
()*1000)]
1259 set score
[expr rand
()]
1261 set score
[expr int
(rand
()*10)]
1263 set auxarray
($j) $score
1264 $r zadd myzset
$score $j
1267 foreach {item score
} [array get auxarray
] {
1268 lappend auxlist
[list $score $item]
1270 set sorted
[lsort -command zlistAlikeSort
$auxlist]
1273 lappend auxlist
[lindex $x 1]
1275 set fromredis
[$r zrange myzset
0 -1]
1277 for {set i
0} {$i < [llength $fromredis]} {incr i
} {
1278 if {[lindex $fromredis $i] != [lindex $auxlist $i]} {
1286 test
{ZINCRBY
- can create a new sorted
set} {
1288 $r zincrby zset
1 foo
1289 list [$r zrange zset
0 -1] [$r zscore zset foo
]
1292 test
{ZINCRBY
- increment and decrement
} {
1293 $r zincrby zset
2 foo
1294 $r zincrby zset
1 bar
1295 set v1
[$r zrange zset
0 -1]
1296 $r zincrby zset
10 bar
1297 $r zincrby zset
-5 foo
1298 $r zincrby zset
-5 bar
1299 set v2
[$r zrange zset
0 -1]
1300 list $v1 $v2 [$r zscore zset foo
] [$r zscore zset bar
]
1301 } {{bar foo
} {foo bar
} -2 6}
1303 test
{ZRANGEBYSCORE basics
} {
1310 $r zrangebyscore zset
2 4
1313 test
{ZRANGEBYSCORE fuzzy test
, 100 ranges in
1000 elements sorted
set} {
1316 for {set i
0} {$i < 1000} {incr i
} {
1317 $r zadd zset
[expr rand
()] $i
1319 for {set i
0} {$i < 100} {incr i
} {
1320 set min
[expr rand
()]
1321 set max
[expr rand
()]
1327 set low
[$r zrangebyscore zset
-inf $min]
1328 set ok
[$r zrangebyscore zset
$min $max]
1329 set high
[$r zrangebyscore zset
$max +inf
]
1331 set score
[$r zscore zset
$x]
1332 if {$score > $min} {
1333 append err
"Error, score for $x is $score > $min\n"
1337 set score
[$r zscore zset
$x]
1338 if {$score < $min ||
$score > $max} {
1339 append err
"Error, score for $x is $score outside $min-$max range\n"
1343 set score
[$r zscore zset
$x]
1344 if {$score < $max} {
1345 append err
"Error, score for $x is $score < $max\n"
1352 test
{ZRANGEBYSCORE with LIMIT
} {
1360 [$r zrangebyscore zset
0 10 LIMIT
0 2] \
1361 [$r zrangebyscore zset
0 10 LIMIT
2 3] \
1362 [$r zrangebyscore zset
0 10 LIMIT
2 10] \
1363 [$r zrangebyscore zset
0 10 LIMIT
20 10]
1364 } {{a b
} {c d e
} {c d e
} {}}
1366 test
{ZREMRANGE basics
} {
1373 list [$r zremrangebyscore zset
2 4] [$r zrange zset
0 -1]
1376 test
{ZREMRANGE from
-inf to
+inf
} {
1383 list [$r zremrangebyscore zset
-inf +inf
] [$r zrange zset
0 -1]
1386 test
{SORT against sorted sets
} {
1393 $r sort zset alpha desc
1396 test
{Sorted sets
+inf and
-inf handling
} {
1401 $r zadd zset
1000000 d
1402 $r zadd zset
+inf max
1403 $r zadd zset
-inf min
1407 test
{EXPIRE
- don't
set timeouts multiple times
} {
1409 set v1
[$r expire x
5]
1411 set v3
[$r expire x
10]
1413 list $v1 $v2 $v3 $v4
1416 test
{EXPIRE
- It should be still possible to
read 'x'
} {
1420 test
{EXPIRE
- After
6 seconds the key should no longer be here
} {
1422 list [$r get x
] [$r exists x
]
1425 test
{EXPIRE
- Delete on write policy
} {
1433 test
{EXPIREAT
- Check
for EXPIRE alike behavior
} {
1436 $r expireat x
[expr [clock seconds
]+15]
1440 test
{ZSETs skiplist implementation backlink consistency test
} {
1443 for {set j
0} {$j < $elements} {incr j
} {
1444 $r zadd myzset
[expr rand
()] "Element-$j"
1445 $r zrem myzset
"Element-[expr int(rand()*$elements)]"
1447 set l1
[$r zrange myzset
0 -1]
1448 set l2
[$r zrevrange myzset
0 -1]
1449 for {set j
0} {$j < [llength $l1]} {incr j
} {
1450 if {[lindex $l1 $j] ne
[lindex $l2 end-
$j]} {
1457 foreach fuzztype
{binary alpha compr
} {
1458 test
"FUZZ stresser with data model $fuzztype" {
1460 for {set i
0} {$i < 10000} {incr i
} {
1461 set fuzz
[randstring
0 512 $fuzztype]
1463 set got
[$r get foo
]
1464 if {$got ne
$fuzz} {
1465 set err
[list $fuzz $got]
1483 test
{Handle an empty query well
} {
1485 puts -nonewline $fd "\r\n"
1490 test
{Negative multi bulk command does not create problems
} {
1492 puts -nonewline $fd "*-10\r\n"
1497 test
{Negative multi bulk payload
} {
1499 puts -nonewline $fd "SET x -10\r\n"
1504 test
{Too big bulk payload
} {
1506 puts -nonewline $fd "SET x 2000000000\r\n"
1509 } {*invalid bulk
*count
*}
1511 test
{Multi bulk request not followed by bulk args
} {
1513 puts -nonewline $fd "*1\r\nfoo\r\n"
1516 } {*protocol
error*}
1518 test
{Generic wrong number of args
} {
1519 catch {$r ping x y z
} err
1521 } {*wrong
*arguments
*ping
*}
1523 test
{SELECT an out of range DB
} {
1524 catch {$r select
1000000} err
1528 if {![catch {package require sha1
}]} {
1529 test
{Check consistency of different data types
after a reload
} {
1531 createComplexDataset
$r 10000
1532 set sha1
[datasetDigest
$r]
1534 set sha1_after
[datasetDigest
$r]
1535 expr {$sha1 eq
$sha1_after}
1538 test
{Same dataset digest
if saving
/reloading as AOF?
} {
1540 waitForBgrewriteaof
$r
1542 set sha1_after
[datasetDigest
$r]
1543 expr {$sha1 eq
$sha1_after}
1547 test
{EXPIRES
after a reload
(snapshot
+ append only
file)} {
1554 set e1
[expr {$ttl > 900 && $ttl <= 1000}]
1556 waitForBgrewriteaof
$r
1558 set e2
[expr {$ttl > 900 && $ttl <= 1000}]
1562 test
{PIPELINING stresser
(also a regression
for the old epoll bug
)} {
1563 set fd2
[socket 127.0.0.1 6379]
1564 fconfigure $fd2 -encoding binary -translation binary
1565 puts -nonewline $fd2 "SELECT 9\r\n"
1569 for {set i
0} {$i < 100000} {incr i
} {
1571 set val
"0000${i}0000"
1572 append q
"SET key:$i [string length $val]\r\n$val\r\n"
1573 puts -nonewline $fd2 $q
1575 append q
"GET key:$i\r\n"
1576 puts -nonewline $fd2 $q
1580 for {set i
0} {$i < 100000} {incr i
} {
1583 set count
[string range
$count 1 end
]
1584 set val
[read $fd2 $count]
1591 test
{MUTLI
/ EXEC basics
} {
1597 set v1
[$r lrange mylist
0 -1]
1601 } {QUEUED QUEUED
{{a b c
} PONG
}}
1603 # Leave the user with a clean DB before to exit
1608 lappend aux
[$r dbsize
]
1611 lappend aux
[$r dbsize
]
1614 test
{Perform a final SAVE to leave a clean DB on disk
} {
1619 if {[string match
{*Darwin
*} [exec uname
-a]]} {
1620 test
{Check
for memory leaks
} {
1621 exec leaks redis-server
1626 puts "\n[expr $::passed+$::failed] tests, $::passed passed, $::failed failed"
1627 if {$::failed > 0} {
1628 puts "\n*** WARNING!!! $::failed FAILED TESTS ***\n"
1637 set randkey
[expr int
(rand
()*10000)]
1638 set randval
[expr int
(rand
()*10000)]
1639 set randidx0
[expr int
(rand
()*10)]
1640 set randidx1
[expr int
(rand
()*10)]
1641 set cmd
[expr int
(rand
()*20)]
1643 if {$cmd == 0} {$r set $randkey $randval}
1644 if {$cmd == 1} {$r get
$randkey}
1645 if {$cmd == 2} {$r incr $randkey}
1646 if {$cmd == 3} {$r lpush
$randkey $randval}
1647 if {$cmd == 4} {$r rpop
$randkey}
1648 if {$cmd == 5} {$r del
$randkey}
1649 if {$cmd == 6} {$r llen
$randkey}
1650 if {$cmd == 7} {$r lrange $randkey $randidx0 $randidx1}
1651 if {$cmd == 8} {$r ltrim
$randkey $randidx0 $randidx1}
1652 if {$cmd == 9} {$r lindex $randkey $randidx0}
1653 if {$cmd == 10} {$r lset $randkey $randidx0 $randval}
1654 if {$cmd == 11} {$r sadd
$randkey $randval}
1655 if {$cmd == 12} {$r srem
$randkey $randval}
1656 if {$cmd == 13} {$r smove
$randkey $randval}
1657 if {$cmd == 14} {$r scard
$randkey}
1658 if {$cmd == 15} {$r expire
$randkey [expr $randval%60]}
1666 # Set a few configuration defaults
1667 set ::host 127.0.0.1
1675 for {set j
0} {$j < [llength $argv]} {incr j
} {
1676 set opt
[lindex $argv $j]
1677 set arg
[lindex $argv [expr $j+1]]
1678 set lastarg
[expr {$arg eq
{}}]
1679 if {$opt eq
{-h} && !$lastarg} {
1682 } elseif
{$opt eq
{-p} && !$lastarg} {
1685 } elseif
{$opt eq
{-stress}} {
1687 } elseif
{$opt eq
{--flush}} {
1689 } elseif
{$opt eq
{--first} && !$lastarg} {
1692 } elseif
{$opt eq
{--last} && !$lastarg} {
1696 puts "Wrong argument: $opt"
1701 # Before to run the test check if DB 9 and DB 10 are empty
1709 set db9size
[$r dbsize
]
1711 set db10size
[$r dbsize
]
1712 if {$db9size != 0 ||
$db10size != 0} {
1713 puts "Can't run the tests against DB 9 and 10: DBs are not empty."
1724 main
$::host $::port