]> git.saurik.com Git - redis.git/blame - test-redis.tcl
zipmap fix for large values
[redis.git] / test-redis.tcl
CommitLineData
7a932b74 1# test-redis.tcl
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
4# more information.
ed9b544e 5
405b0a6a 6set tcl_precision 17
f89c3a35 7source redis.tcl
43c9dc7b 8
ed9b544e 9set ::passed 0
10set ::failed 0
fc77604c 11set ::testnum 0
ed9b544e 12
13proc test {name code okpattern} {
fc77604c 14 incr ::testnum
15 if {$::testnum < $::first || $::testnum > $::last} return
16 puts -nonewline [format "%-70s " "#$::testnum $name"]
ed9b544e 17 flush stdout
18 set retval [uplevel 1 $code]
19 if {$okpattern eq $retval || [string match $okpattern $retval]} {
20 puts "PASSED"
21 incr ::passed
22 } else {
23 puts "!! ERROR expected\n'$okpattern'\nbut got\n'$retval'"
24 incr ::failed
25 }
26}
27
75398fbc 28proc randstring {min max {type binary}} {
29 set len [expr {$min+int(rand()*($max-$min+1))}]
30 set output {}
31 if {$type eq {binary}} {
32 set minval 0
33 set maxval 255
34 } elseif {$type eq {alpha}} {
35 set minval 48
36 set maxval 122
37 } elseif {$type eq {compr}} {
38 set minval 48
39 set maxval 52
40 }
41 while {$len} {
42 append output [format "%c" [expr {$minval+int(rand()*($maxval-$minval+1))}]]
43 incr len -1
44 }
45 return $output
46}
47
d7f43c08 48# Useful for some test
49proc 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]
53}
54
0d36ded0 55proc waitForBgsave r {
56 while 1 {
57 set i [$r info]
58 if {[string match {*bgsave_in_progress:1*} $i]} {
59 puts -nonewline "\nWaiting for background save to finish... "
60 flush stdout
61 after 1000
62 } else {
63 break
64 }
65 }
66}
67
e96e4fbf 68proc waitForBgrewriteaof r {
69 while 1 {
70 set i [$r info]
71 if {[string match {*bgrewriteaof_in_progress:1*} $i]} {
72 puts -nonewline "\nWaiting for background AOF rewrite to finish... "
73 flush stdout
74 after 1000
75 } else {
76 break
77 }
78 }
79}
80
e054afda 81proc randomInt {max} {
82 expr {int(rand()*$max)}
83}
84
85proc randpath args {
86 set path [expr {int(rand()*[llength $args])}]
87 uplevel 1 [lindex $args $path]
88}
89
90proc randomValue {} {
91 randpath {
92 # Small enough to likely collide
93 randomInt 1000
94 } {
95 # 32 bit compressible signed/unsigned
96 randpath {randomInt 2000000000} {randomInt 4000000000}
97 } {
98 # 64 bit
99 randpath {randomInt 1000000000000}
100 } {
101 # Random string
102 randpath {randstring 0 256 alpha} \
103 {randstring 0 256 compr} \
104 {randstring 0 256 binary}
105 }
106}
107
108proc randomKey {} {
109 randpath {
110 # Small enough to likely collide
111 randomInt 1000
112 } {
113 # 32 bit compressible signed/unsigned
114 randpath {randomInt 2000000000} {randomInt 4000000000}
115 } {
116 # 64 bit
117 randpath {randomInt 1000000000000}
118 } {
119 # Random string
120 randpath {randstring 1 256 alpha} \
121 {randstring 1 256 compr}
122 }
123}
124
125proc createComplexDataset {r ops} {
126 for {set j 0} {$j < $ops} {incr j} {
127 set k [randomKey]
2a1198b4 128 set f [randomValue]
e054afda 129 set v [randomValue]
ab9d4cb1 130 randpath {
131 set d [expr {rand()}]
132 } {
133 set d [expr {rand()}]
134 } {
135 set d [expr {rand()}]
136 } {
137 set d [expr {rand()}]
138 } {
139 set d [expr {rand()}]
140 } {
141 randpath {set d +inf} {set d -inf}
142 }
e054afda 143 set t [$r type $k]
144
145 if {$t eq {none}} {
146 randpath {
147 $r set $k $v
148 } {
149 $r lpush $k $v
150 } {
151 $r sadd $k $v
152 } {
153 $r zadd $k $d $v
2a1198b4 154 } {
ad6de43c 155 puts "hset $k $f $v"
2a1198b4 156 $r hset $k $f $v
e054afda 157 }
158 set t [$r type $k]
159 }
160
161 switch $t {
162 {string} {
163 # Nothing to do
164 }
165 {list} {
166 randpath {$r lpush $k $v} \
167 {$r rpush $k $v} \
168 {$r lrem $k 0 $v} \
169 {$r rpop $k} \
170 {$r lpop $k}
171 }
172 {set} {
173 randpath {$r sadd $k $v} \
174 {$r srem $k $v}
175 }
176 {zset} {
177 randpath {$r zadd $k $d $v} \
178 {$r zrem $k $v}
179 }
2a1198b4 180 {hash} {
181 randpath {$r hset $k $f $v} \
ad6de43c 182 {puts "$r hdel $k $f"; $r hdel $k $f}
2a1198b4 183 }
e054afda 184 }
185 }
186}
187
188proc datasetDigest r {
a3f9eec2 189 set keys [lsort [$r keys *]]
e96e4fbf 190 set digest {}
e054afda 191 foreach k $keys {
192 set t [$r type $k]
e96e4fbf 193 switch $t {
194 {string} {
195 set aux [::sha1::sha1 -hex [$r get $k]]
196 } {list} {
197 if {[$r llen $k] == 0} {
198 set aux {}
199 } else {
200 set aux [::sha1::sha1 -hex [$r lrange $k 0 -1]]
201 }
202 } {set} {
203 if {[$r scard $k] == 0} {
204 set aux {}
205 } else {
206 set aux [::sha1::sha1 -hex [lsort [$r smembers $k]]]
207 }
208 } {zset} {
209 if {[$r zcard $k] == 0} {
210 set aux {}
211 } else {
212 set aux [::sha1::sha1 -hex [$r zrange $k 0 -1]]
213 }
214 } default {
a3f9eec2 215 error "Type not supported: $t"
e96e4fbf 216 }
e054afda 217 }
e96e4fbf 218 if {$aux eq {}} continue
219 set digest [::sha1::sha1 -hex [join [list $aux $digest $k] "\n"]]
e054afda 220 }
221 return $digest
222}
223
ed9b544e 224proc main {server port} {
43c9dc7b 225 set r [redis $server $port]
eea4baf7 226 $r select 9
43c9dc7b 227 set err ""
fc77604c 228 set res ""
ed9b544e 229
abcb223e
BH
230 # The following AUTH test should be enabled only when requirepass
231 # <PASSWORD> is set in redis.conf and redis-server was started with
232 # redis.conf as the first argument.
233
234 #test {AUTH with requirepass in redis.conf} {
235 # $r auth foobared
236 #} {OK}
237
ed9b544e 238 test {DEL all keys to start with a clean DB} {
43c9dc7b 239 foreach key [$r keys *] {$r del $key}
240 $r dbsize
ed9b544e 241 } {0}
242
243 test {SET and GET an item} {
43c9dc7b 244 $r set x foobar
245 $r get x
ed9b544e 246 } {foobar}
247
7c49733c 248 test {SET and GET an empty item} {
249 $r set x {}
250 $r get x
251 } {}
252
ed9b544e 253 test {DEL against a single item} {
43c9dc7b 254 $r del x
255 $r get x
ed9b544e 256 } {}
257
cc582a77 258 test {Vararg DEL} {
259 $r set foo1 a
260 $r set foo2 b
261 $r set foo3 c
262 list [$r del foo1 foo2 foo3 foo4] [$r mget foo1 foo2 foo3]
263 } {3 {{} {} {}}}
264
ed9b544e 265 test {KEYS with pattern} {
266 foreach key {key_x key_y key_z foo_a foo_b foo_c} {
43c9dc7b 267 $r set $key hello
ed9b544e 268 }
43c9dc7b 269 lsort [$r keys foo*]
ed9b544e 270 } {foo_a foo_b foo_c}
271
272 test {KEYS to get all keys} {
43c9dc7b 273 lsort [$r keys *]
ed9b544e 274 } {foo_a foo_b foo_c key_x key_y key_z}
275
276 test {DBSIZE} {
43c9dc7b 277 $r dbsize
ed9b544e 278 } {6}
279
280 test {DEL all keys} {
43c9dc7b 281 foreach key [$r keys *] {$r del $key}
282 $r dbsize
ed9b544e 283 } {0}
284
285 test {Very big payload in GET/SET} {
286 set buf [string repeat "abcd" 1000000]
43c9dc7b 287 $r set foo $buf
288 $r get foo
ed9b544e 289 } [string repeat "abcd" 1000000]
290
72766462 291 test {Very big payload random access} {
292 set err {}
293 array set payload {}
294 for {set j 0} {$j < 100} {incr j} {
295 set size [expr 1+[randomInt 100000]]
054e426d 296 set buf [string repeat "pl-$j" $size]
72766462 297 set payload($j) $buf
298 $r set bigpayload_$j $buf
299 }
300 for {set j 0} {$j < 1000} {incr j} {
301 set index [randomInt 100]
302 set buf [$r get bigpayload_$index]
303 if {$buf != $payload($index)} {
5f8e5d7c 304 set err "Values differ: I set '$payload($index)' but I read back '$buf'"
72766462 305 break
306 }
307 }
308 unset payload
309 set _ $err
310 } {}
311
ed9b544e 312 test {SET 10000 numeric keys and access all them in reverse order} {
25fd2cb2 313 set err {}
ed9b544e 314 for {set x 0} {$x < 10000} {incr x} {
43c9dc7b 315 $r set $x $x
ed9b544e 316 }
317 set sum 0
318 for {set x 9999} {$x >= 0} {incr x -1} {
25fd2cb2 319 set val [$r get $x]
320 if {$val ne $x} {
321 set err "Eleemnt at position $x is $val instead of $x"
322 break
323 }
ed9b544e 324 }
25fd2cb2 325 set _ $err
d663729a 326 } {}
ed9b544e 327
fefed597 328 test {DBSIZE should be 10101 now} {
43c9dc7b 329 $r dbsize
fefed597 330 } {10101}
ed9b544e 331
332 test {INCR against non existing key} {
333 set res {}
43c9dc7b 334 append res [$r incr novar]
335 append res [$r get novar]
ed9b544e 336 } {11}
337
338 test {INCR against key created by incr itself} {
43c9dc7b 339 $r incr novar
ed9b544e 340 } {2}
341
342 test {INCR against key originally set with SET} {
43c9dc7b 343 $r set novar 100
344 $r incr novar
ed9b544e 345 } {101}
346
d68ed120 347 test {INCR over 32bit value} {
348 $r set novar 17179869184
349 $r incr novar
350 } {17179869185}
351
352 test {INCRBY over 32bit value with over 32bit increment} {
353 $r set novar 17179869184
354 $r incrby novar 17179869184
355 } {34359738368}
356
ab9d4cb1 357 test {INCR against key with spaces (no integer encoded)} {
358 $r set novar " 11 "
359 $r incr novar
360 } {12}
361
d68ed120 362 test {DECRBY over 32bit value with over 32bit increment, negative res} {
363 $r set novar 17179869184
364 $r decrby novar 17179869185
365 } {-1}
366
ed9b544e 367 test {SETNX target key missing} {
43c9dc7b 368 $r setnx novar2 foobared
369 $r get novar2
ed9b544e 370 } {foobared}
371
372 test {SETNX target key exists} {
43c9dc7b 373 $r setnx novar2 blabla
374 $r get novar2
ed9b544e 375 } {foobared}
376
5acdc75d 377 test {SETNX will overwrite EXPIREing key} {
378 $r set x 10
379 $r expire x 10000
380 $r setnx x 20
381 $r get x
382 } {20}
383
ed9b544e 384 test {EXISTS} {
385 set res {}
43c9dc7b 386 $r set newkey test
387 append res [$r exists newkey]
388 $r del newkey
389 append res [$r exists newkey]
ed9b544e 390 } {10}
391
392 test {Zero length value in key. SET/GET/EXISTS} {
43c9dc7b 393 $r set emptykey {}
394 set res [$r get emptykey]
395 append res [$r exists emptykey]
396 $r del emptykey
397 append res [$r exists emptykey]
ed9b544e 398 } {10}
399
400 test {Commands pipelining} {
43c9dc7b 401 set fd [$r channel]
ed9b544e 402 puts -nonewline $fd "SET k1 4\r\nxyzk\r\nGET k1\r\nPING\r\n"
403 flush $fd
404 set res {}
43c9dc7b 405 append res [string match OK* [::redis::redis_read_reply $fd]]
406 append res [::redis::redis_read_reply $fd]
407 append res [string match PONG* [::redis::redis_read_reply $fd]]
ed9b544e 408 format $res
409 } {1xyzk1}
410
411 test {Non existing command} {
43c9dc7b 412 catch {$r foobaredcommand} err
413 string match ERR* $err
ed9b544e 414 } {1}
415
416 test {Basic LPUSH, RPUSH, LLENGTH, LINDEX} {
520b5a33 417 set res [$r lpush mylist a]
418 append res [$r lpush mylist b]
419 append res [$r rpush mylist c]
420 append res [$r llen mylist]
421 append res [$r rpush anotherlist d]
422 append res [$r lpush anotherlist e]
423 append res [$r llen anotherlist]
43c9dc7b 424 append res [$r lindex mylist 0]
425 append res [$r lindex mylist 1]
426 append res [$r lindex mylist 2]
520b5a33 427 append res [$r lindex anotherlist 0]
428 append res [$r lindex anotherlist 1]
ab9d4cb1 429 list $res [$r lindex mylist 100]
520b5a33 430 } {1233122baced {}}
ed9b544e 431
432 test {DEL a list} {
43c9dc7b 433 $r del mylist
434 $r exists mylist
ed9b544e 435 } {0}
436
437 test {Create a long list and check every single element with LINDEX} {
438 set ok 0
439 for {set i 0} {$i < 1000} {incr i} {
43c9dc7b 440 $r rpush mylist $i
ed9b544e 441 }
442 for {set i 0} {$i < 1000} {incr i} {
43c9dc7b 443 if {[$r lindex mylist $i] eq $i} {incr ok}
444 if {[$r lindex mylist [expr (-$i)-1]] eq [expr 999-$i]} {
ed9b544e 445 incr ok
446 }
447 }
448 format $ok
449 } {2000}
450
451 test {Test elements with LINDEX in random access} {
452 set ok 0
453 for {set i 0} {$i < 1000} {incr i} {
43c9dc7b 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]} {
ed9b544e 457 incr ok
458 }
459 }
460 format $ok
461 } {2000}
462
210e29f7 463 test {Check if the list is still ok after a DEBUG RELOAD} {
464 $r debug reload
465 set ok 0
466 for {set i 0} {$i < 1000} {incr i} {
467 set rint [expr int(rand()*1000)]
468 if {[$r lindex mylist $rint] eq $rint} {incr ok}
469 if {[$r lindex mylist [expr (-$rint)-1]] eq [expr 999-$rint]} {
470 incr ok
471 }
472 }
473 format $ok
474 } {2000}
475
ed9b544e 476 test {LLEN against non-list value error} {
43c9dc7b 477 $r del mylist
478 $r set mylist foobar
479 catch {$r llen mylist} err
480 format $err
c937aa89 481 } {ERR*}
ed9b544e 482
ab9d4cb1 483 test {LLEN against non existing key} {
484 $r llen not-a-key
485 } {0}
486
ed9b544e 487 test {LINDEX against non-list value error} {
43c9dc7b 488 catch {$r lindex mylist 0} err
489 format $err
c937aa89 490 } {ERR*}
ed9b544e 491
ab9d4cb1 492 test {LINDEX against non existing key} {
493 $r lindex not-a-key 10
494 } {}
495
ed9b544e 496 test {LPUSH against non-list value error} {
43c9dc7b 497 catch {$r lpush mylist 0} err
498 format $err
c937aa89 499 } {ERR*}
ed9b544e 500
501 test {RPUSH against non-list value error} {
43c9dc7b 502 catch {$r rpush mylist 0} err
503 format $err
c937aa89 504 } {ERR*}
ed9b544e 505
c08f1734 506 test {RPOPLPUSH base case} {
507 $r del mylist
508 $r rpush mylist a
509 $r rpush mylist b
510 $r rpush mylist c
511 $r rpush mylist d
512 set v1 [$r rpoplpush mylist newlist]
513 set v2 [$r rpoplpush mylist newlist]
514 set l1 [$r lrange mylist 0 -1]
515 set l2 [$r lrange newlist 0 -1]
516 list $v1 $v2 $l1 $l2
517 } {d c {a b} {c d}}
518
519 test {RPOPLPUSH with the same list as src and dst} {
520 $r del mylist
521 $r rpush mylist a
522 $r rpush mylist b
523 $r rpush mylist c
524 set l1 [$r lrange mylist 0 -1]
525 set v [$r rpoplpush mylist mylist]
526 set l2 [$r lrange mylist 0 -1]
527 list $l1 $v $l2
528 } {{a b c} c {c a b}}
529
530 test {RPOPLPUSH target list already exists} {
531 $r del mylist
532 $r del newlist
533 $r rpush mylist a
534 $r rpush mylist b
535 $r rpush mylist c
536 $r rpush mylist d
537 $r rpush newlist x
538 set v1 [$r rpoplpush mylist newlist]
539 set v2 [$r rpoplpush mylist newlist]
540 set l1 [$r lrange mylist 0 -1]
541 set l2 [$r lrange newlist 0 -1]
542 list $v1 $v2 $l1 $l2
543 } {d c {a b} {c d x}}
544
b9bb7ba2 545 test {RPOPLPUSH against non existing key} {
546 $r del mylist
547 $r del newlist
548 set v1 [$r rpoplpush mylist newlist]
549 list $v1 [$r exists mylist] [$r exists newlist]
550 } {{} 0 0}
551
552 test {RPOPLPUSH against non list src key} {
553 $r del mylist
554 $r del newlist
555 $r set mylist x
556 catch {$r rpoplpush mylist newlist} err
557 list [$r type mylist] [$r exists newlist] [string range $err 0 2]
558 } {string 0 ERR}
559
560 test {RPOPLPUSH against non list dst key} {
561 $r del mylist
562 $r del newlist
563 $r rpush mylist a
564 $r rpush mylist b
565 $r rpush mylist c
566 $r rpush mylist d
567 $r set newlist x
568 catch {$r rpoplpush mylist newlist} err
569 list [$r lrange mylist 0 -1] [$r type newlist] [string range $err 0 2]
570 } {{a b c d} string ERR}
571
fdcaae84 572 test {RPOPLPUSH against non existing src key} {
573 $r del mylist
574 $r del newlist
575 $r rpoplpush mylist newlist
576 } {}
577
ed9b544e 578 test {RENAME basic usage} {
43c9dc7b 579 $r set mykey hello
580 $r rename mykey mykey1
581 $r rename mykey1 mykey2
582 $r get mykey2
ed9b544e 583 } {hello}
584
585 test {RENAME source key should no longer exist} {
43c9dc7b 586 $r exists mykey
ed9b544e 587 } {0}
588
589 test {RENAME against already existing key} {
43c9dc7b 590 $r set mykey a
591 $r set mykey2 b
592 $r rename mykey2 mykey
593 set res [$r get mykey]
594 append res [$r exists mykey2]
ed9b544e 595 } {b0}
596
597 test {RENAMENX basic usage} {
43c9dc7b 598 $r del mykey
599 $r del mykey2
600 $r set mykey foobar
601 $r renamenx mykey mykey2
602 set res [$r get mykey2]
603 append res [$r exists mykey]
ed9b544e 604 } {foobar0}
605
606 test {RENAMENX against already existing key} {
43c9dc7b 607 $r set mykey foo
608 $r set mykey2 bar
609 $r renamenx mykey mykey2
ed9b544e 610 } {0}
611
612 test {RENAMENX against already existing key (2)} {
43c9dc7b 613 set res [$r get mykey]
614 append res [$r get mykey2]
ed9b544e 615 } {foobar}
616
617 test {RENAME against non existing source key} {
43c9dc7b 618 catch {$r rename nokey foobar} err
619 format $err
c937aa89 620 } {ERR*}
ed9b544e 621
622 test {RENAME where source and dest key is the same} {
43c9dc7b 623 catch {$r rename mykey mykey} err
624 format $err
c937aa89 625 } {ERR*}
ed9b544e 626
627 test {DEL all keys again (DB 0)} {
43c9dc7b 628 foreach key [$r keys *] {
629 $r del $key
ed9b544e 630 }
43c9dc7b 631 $r dbsize
ed9b544e 632 } {0}
633
634 test {DEL all keys again (DB 1)} {
eea4baf7 635 $r select 10
43c9dc7b 636 foreach key [$r keys *] {
637 $r del $key
ed9b544e 638 }
43c9dc7b 639 set res [$r dbsize]
eea4baf7 640 $r select 9
ed9b544e 641 format $res
642 } {0}
643
644 test {MOVE basic usage} {
43c9dc7b 645 $r set mykey foobar
eea4baf7 646 $r move mykey 10
ed9b544e 647 set res {}
43c9dc7b 648 lappend res [$r exists mykey]
649 lappend res [$r dbsize]
eea4baf7 650 $r select 10
43c9dc7b 651 lappend res [$r get mykey]
652 lappend res [$r dbsize]
eea4baf7 653 $r select 9
ed9b544e 654 format $res
655 } [list 0 0 foobar 1]
656
657 test {MOVE against key existing in the target DB} {
43c9dc7b 658 $r set mykey hello
eea4baf7 659 $r move mykey 10
ed9b544e 660 } {0}
661
662 test {SET/GET keys in different DBs} {
43c9dc7b 663 $r set a hello
664 $r set b world
eea4baf7 665 $r select 10
43c9dc7b 666 $r set a foo
667 $r set b bared
eea4baf7 668 $r select 9
ed9b544e 669 set res {}
43c9dc7b 670 lappend res [$r get a]
671 lappend res [$r get b]
eea4baf7 672 $r select 10
43c9dc7b 673 lappend res [$r get a]
674 lappend res [$r get b]
eea4baf7 675 $r select 9
ed9b544e 676 format $res
677 } {hello world foo bared}
678
679 test {Basic LPOP/RPOP} {
43c9dc7b 680 $r del mylist
681 $r rpush mylist 1
682 $r rpush mylist 2
683 $r lpush mylist 0
684 list [$r lpop mylist] [$r rpop mylist] [$r lpop mylist] [$r llen mylist]
ed9b544e 685 } [list 0 2 1 0]
686
687 test {LPOP/RPOP against empty list} {
43c9dc7b 688 $r lpop mylist
ed9b544e 689 } {}
690
691 test {LPOP against non list value} {
43c9dc7b 692 $r set notalist foo
693 catch {$r lpop notalist} err
694 format $err
c937aa89 695 } {ERR*kind*}
ed9b544e 696
697 test {Mass LPUSH/LPOP} {
698 set sum 0
699 for {set i 0} {$i < 1000} {incr i} {
43c9dc7b 700 $r lpush mylist $i
ed9b544e 701 incr sum $i
702 }
703 set sum2 0
704 for {set i 0} {$i < 500} {incr i} {
43c9dc7b 705 incr sum2 [$r lpop mylist]
706 incr sum2 [$r rpop mylist]
ed9b544e 707 }
708 expr $sum == $sum2
709 } {1}
710
711 test {LRANGE basics} {
712 for {set i 0} {$i < 10} {incr i} {
43c9dc7b 713 $r rpush mylist $i
ed9b544e 714 }
43c9dc7b 715 list [$r lrange mylist 1 -2] \
716 [$r lrange mylist -3 -1] \
717 [$r lrange mylist 4 4]
ed9b544e 718 } {{1 2 3 4 5 6 7 8} {7 8 9} 4}
719
720 test {LRANGE inverted indexes} {
43c9dc7b 721 $r lrange mylist 6 2
ed9b544e 722 } {}
723
724 test {LRANGE out of range indexes including the full list} {
43c9dc7b 725 $r lrange mylist -1000 1000
ed9b544e 726 } {0 1 2 3 4 5 6 7 8 9}
727
728 test {LRANGE against non existing key} {
43c9dc7b 729 $r lrange nosuchkey 0 1
ed9b544e 730 } {}
731
732 test {LTRIM basics} {
43c9dc7b 733 $r del mylist
ed9b544e 734 for {set i 0} {$i < 100} {incr i} {
43c9dc7b 735 $r lpush mylist $i
736 $r ltrim mylist 0 4
ed9b544e 737 }
43c9dc7b 738 $r lrange mylist 0 -1
ed9b544e 739 } {99 98 97 96 95}
740
c632369b 741 test {LTRIM stress testing} {
742 set mylist {}
743 set err {}
744 for {set i 0} {$i < 20} {incr i} {
745 lappend mylist $i
746 }
747
748 for {set j 0} {$j < 100} {incr j} {
749 # Fill the list
750 $r del mylist
751 for {set i 0} {$i < 20} {incr i} {
752 $r rpush mylist $i
753 }
754 # Trim at random
755 set a [randomInt 20]
756 set b [randomInt 20]
757 $r ltrim mylist $a $b
758 if {[$r lrange mylist 0 -1] ne [lrange $mylist $a $b]} {
759 set err "[$r lrange mylist 0 -1] != [lrange $mylist $a $b]"
760 break
761 }
762 }
763 set _ $err
764 } {}
765
ed9b544e 766 test {LSET} {
c632369b 767 $r del mylist
768 foreach x {99 98 97 96 95} {
769 $r rpush mylist $x
770 }
43c9dc7b 771 $r lset mylist 1 foo
772 $r lset mylist -1 bar
773 $r lrange mylist 0 -1
ed9b544e 774 } {99 foo 97 96 bar}
775
776 test {LSET out of range index} {
43c9dc7b 777 catch {$r lset mylist 10 foo} err
778 format $err
c937aa89 779 } {ERR*range*}
ed9b544e 780
781 test {LSET against non existing key} {
43c9dc7b 782 catch {$r lset nosuchkey 10 foo} err
783 format $err
c937aa89 784 } {ERR*key*}
ed9b544e 785
786 test {LSET against non list value} {
43c9dc7b 787 $r set nolist foobar
788 catch {$r lset nolist 0 foo} err
789 format $err
c937aa89 790 } {ERR*value*}
ed9b544e 791
792 test {SADD, SCARD, SISMEMBER, SMEMBERS basics} {
43c9dc7b 793 $r sadd myset foo
794 $r sadd myset bar
795 list [$r scard myset] [$r sismember myset foo] \
796 [$r sismember myset bar] [$r sismember myset bla] \
797 [lsort [$r smembers myset]]
ed9b544e 798 } {2 1 1 0 {bar foo}}
799
800 test {SADD adding the same element multiple times} {
43c9dc7b 801 $r sadd myset foo
802 $r sadd myset foo
803 $r sadd myset foo
804 $r scard myset
ed9b544e 805 } {2}
806
807 test {SADD against non set} {
43c9dc7b 808 catch {$r sadd mylist foo} err
809 format $err
c937aa89 810 } {ERR*kind*}
ed9b544e 811
812 test {SREM basics} {
43c9dc7b 813 $r sadd myset ciao
814 $r srem myset foo
815 lsort [$r smembers myset]
ed9b544e 816 } {bar ciao}
817
818 test {Mass SADD and SINTER with two sets} {
819 for {set i 0} {$i < 1000} {incr i} {
43c9dc7b 820 $r sadd set1 $i
821 $r sadd set2 [expr $i+995]
ed9b544e 822 }
43c9dc7b 823 lsort [$r sinter set1 set2]
ed9b544e 824 } {995 996 997 998 999}
40d224a9 825
826 test {SUNION with two sets} {
827 lsort [$r sunion set1 set2]
828 } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
ed9b544e 829
830 test {SINTERSTORE with two sets} {
43c9dc7b 831 $r sinterstore setres set1 set2
832 lsort [$r smembers setres]
ed9b544e 833 } {995 996 997 998 999}
834
210e29f7 835 test {SINTERSTORE with two sets, after a DEBUG RELOAD} {
836 $r debug reload
837 $r sinterstore setres set1 set2
838 lsort [$r smembers setres]
839 } {995 996 997 998 999}
840
40d224a9 841 test {SUNIONSTORE with two sets} {
842 $r sunionstore setres set1 set2
843 lsort [$r smembers setres]
844 } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
845
f4d9b3c6 846 test {SUNIONSTORE against non existing keys} {
847 $r set setres xxx
848 list [$r sunionstore setres foo111 bar222] [$r exists xxx]
849 } {0 0}
850
ed9b544e 851 test {SINTER against three sets} {
43c9dc7b 852 $r sadd set3 999
853 $r sadd set3 995
854 $r sadd set3 1000
855 $r sadd set3 2000
856 lsort [$r sinter set1 set2 set3]
ed9b544e 857 } {995 999}
858
859 test {SINTERSTORE with three sets} {
43c9dc7b 860 $r sinterstore setres set1 set2 set3
861 lsort [$r smembers setres]
ed9b544e 862 } {995 999}
40d224a9 863
864 test {SUNION with non existing keys} {
865 lsort [$r sunion nokey1 set1 set2 nokey2]
866 } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
867
f4f56e1d 868 test {SDIFF with two sets} {
869 for {set i 5} {$i < 1000} {incr i} {
870 $r sadd set4 $i
871 }
872 lsort [$r sdiff set1 set4]
873 } {0 1 2 3 4}
874
875 test {SDIFF with three sets} {
876 $r sadd set5 0
877 lsort [$r sdiff set1 set4 set5]
878 } {1 2 3 4}
879
880 test {SDIFFSTORE with three sets} {
881 $r sdiffstore sres set1 set4 set5
882 lsort [$r smembers sres]
883 } {1 2 3 4}
884
12fea928 885 test {SPOP basics} {
886 $r del myset
887 $r sadd myset 1
888 $r sadd myset 2
889 $r sadd myset 3
890 list [lsort [list [$r spop myset] [$r spop myset] [$r spop myset]]] [$r scard myset]
891 } {{1 2 3} 0}
892
ed9b544e 893 test {SAVE - make sure there are all the types as values} {
bbf44ecf 894 # Wait for a background saving in progress to terminate
0d36ded0 895 waitForBgsave $r
43c9dc7b 896 $r lpush mysavelist hello
897 $r lpush mysavelist world
898 $r set myemptykey {}
899 $r set mynormalkey {blablablba}
d7f43c08 900 $r zadd mytestzset a 10
901 $r zadd mytestzset b 20
902 $r zadd mytestzset c 30
43c9dc7b 903 $r save
c937aa89 904 } {OK}
6cbfd2b3 905
906 test {SRANDMEMBER} {
907 $r del myset
908 $r sadd myset a
909 $r sadd myset b
910 $r sadd myset c
911 unset -nocomplain myset
912 array set myset {}
913 for {set i 0} {$i < 100} {incr i} {
914 set myset([$r srandmember myset]) 1
915 }
916 lsort [array names myset]
917 } {a b c}
ed9b544e 918
98e1bb81 919 test {Create a random list and a random set} {
ed9b544e 920 set tosort {}
921 array set seenrand {}
922 for {set i 0} {$i < 10000} {incr i} {
923 while 1 {
924 # Make sure all the weights are different because
925 # Redis does not use a stable sort but Tcl does.
98e1bb81 926 randpath {
927 set rint [expr int(rand()*1000000)]
928 } {
929 set rint [expr rand()]
930 }
43c9dc7b 931 if {![info exists seenrand($rint)]} break
ed9b544e 932 }
43c9dc7b 933 set seenrand($rint) x
934 $r lpush tosort $i
98e1bb81 935 $r sadd tosort-set $i
43c9dc7b 936 $r set weight_$i $rint
937 lappend tosort [list $i $rint]
ed9b544e 938 }
939 set sorted [lsort -index 1 -real $tosort]
940 set res {}
941 for {set i 0} {$i < 10000} {incr i} {
942 lappend res [lindex $sorted $i 0]
943 }
944 format {}
945 } {}
946
947 test {SORT with BY against the newly created list} {
43c9dc7b 948 $r sort tosort {BY weight_*}
ed9b544e 949 } $res
950
98e1bb81 951 test {the same SORT with BY, but against the newly created set} {
952 $r sort tosort-set {BY weight_*}
953 } $res
954
5384a2d8 955 test {SORT with BY and STORE against the newly created list} {
956 $r sort tosort {BY weight_*} store sort-res
957 $r lrange sort-res 0 -1
958 } $res
959
ed9b544e 960 test {SORT direct, numeric, against the newly created list} {
43c9dc7b 961 $r sort tosort
ed9b544e 962 } [lsort -integer $res]
963
964 test {SORT decreasing sort} {
43c9dc7b 965 $r sort tosort {DESC}
ed9b544e 966 } [lsort -decreasing -integer $res]
967
968 test {SORT speed, sorting 10000 elements list using BY, 100 times} {
969 set start [clock clicks -milliseconds]
970 for {set i 0} {$i < 100} {incr i} {
43c9dc7b 971 set sorted [$r sort tosort {BY weight_* LIMIT 0 10}]
ed9b544e 972 }
973 set elapsed [expr [clock clicks -milliseconds]-$start]
974 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
975 flush stdout
976 format {}
977 } {}
c8c72447 978
ed9b544e 979 test {SORT speed, sorting 10000 elements list directly, 100 times} {
980 set start [clock clicks -milliseconds]
981 for {set i 0} {$i < 100} {incr i} {
43c9dc7b 982 set sorted [$r sort tosort {LIMIT 0 10}]
ed9b544e 983 }
984 set elapsed [expr [clock clicks -milliseconds]-$start]
985 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
986 flush stdout
987 format {}
988 } {}
989
990 test {SORT speed, pseudo-sorting 10000 elements list, BY <const>, 100 times} {
991 set start [clock clicks -milliseconds]
992 for {set i 0} {$i < 100} {incr i} {
43c9dc7b 993 set sorted [$r sort tosort {BY nokey LIMIT 0 10}]
ed9b544e 994 }
995 set elapsed [expr [clock clicks -milliseconds]-$start]
996 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
997 flush stdout
998 format {}
999 } {}
1000
1001 test {SORT regression for issue #19, sorting floats} {
43c9dc7b 1002 $r flushdb
ed9b544e 1003 foreach x {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15} {
43c9dc7b 1004 $r lpush mylist $x
ed9b544e 1005 }
43c9dc7b 1006 $r sort mylist
ed9b544e 1007 } [lsort -real {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15}]
1008
28173a49 1009 test {SORT with GET #} {
1010 $r del mylist
1011 $r lpush mylist 1
1012 $r lpush mylist 2
1013 $r lpush mylist 3
1014 $r mset weight_1 10 weight_2 5 weight_3 30
1015 $r sort mylist BY weight_* GET #
1016 } {2 1 3}
1017
d922ae65 1018 test {SORT with constant GET} {
1019 $r sort mylist GET foo
1020 } {{} {} {}}
1021
ed9b544e 1022 test {LREM, remove all the occurrences} {
eea4baf7 1023 $r flushdb
43c9dc7b 1024 $r rpush mylist foo
1025 $r rpush mylist bar
1026 $r rpush mylist foobar
1027 $r rpush mylist foobared
1028 $r rpush mylist zap
1029 $r rpush mylist bar
1030 $r rpush mylist test
1031 $r rpush mylist foo
1032 set res [$r lrem mylist 0 bar]
1033 list [$r lrange mylist 0 -1] $res
ed9b544e 1034 } {{foo foobar foobared zap test foo} 2}
1035
1036 test {LREM, remove the first occurrence} {
43c9dc7b 1037 set res [$r lrem mylist 1 foo]
1038 list [$r lrange mylist 0 -1] $res
ed9b544e 1039 } {{foobar foobared zap test foo} 1}
1040
1041 test {LREM, remove non existing element} {
43c9dc7b 1042 set res [$r lrem mylist 1 nosuchelement]
1043 list [$r lrange mylist 0 -1] $res
ed9b544e 1044 } {{foobar foobared zap test foo} 0}
1045
1046 test {LREM, starting from tail with negative count} {
eea4baf7 1047 $r flushdb
43c9dc7b 1048 $r rpush mylist foo
1049 $r rpush mylist bar
1050 $r rpush mylist foobar
1051 $r rpush mylist foobared
1052 $r rpush mylist zap
1053 $r rpush mylist bar
1054 $r rpush mylist test
1055 $r rpush mylist foo
1056 $r rpush mylist foo
1057 set res [$r lrem mylist -1 bar]
1058 list [$r lrange mylist 0 -1] $res
ed9b544e 1059 } {{foo bar foobar foobared zap test foo foo} 1}
1060
1061 test {LREM, starting from tail with negative count (2)} {
43c9dc7b 1062 set res [$r lrem mylist -2 foo]
1063 list [$r lrange mylist 0 -1] $res
ed9b544e 1064 } {{foo bar foobar foobared zap test} 2}
1065
724a51b1 1066 test {LREM, deleting objects that may be encoded as integers} {
1067 $r lpush myotherlist 1
1068 $r lpush myotherlist 2
1069 $r lpush myotherlist 3
1070 $r lrem myotherlist 1 2
1071 $r llen myotherlist
1072 } {2}
1073
5b19bd72 1074 test {MGET} {
eea4baf7 1075 $r flushdb
43c9dc7b 1076 $r set foo BAR
1077 $r set bar FOO
1078 $r mget foo bar
5b19bd72 1079 } {BAR FOO}
1080
1081 test {MGET against non existing key} {
43c9dc7b 1082 $r mget foo baazz bar
5b19bd72 1083 } {BAR {} FOO}
1084
1085 test {MGET against non-string key} {
43c9dc7b 1086 $r sadd myset ciao
1087 $r sadd myset bau
1088 $r mget foo baazz bar myset
5b19bd72 1089 } {BAR {} FOO {}}
1090
ce7bef07 1091 test {RANDOMKEY} {
eea4baf7 1092 $r flushdb
ce7bef07 1093 $r set foo x
1094 $r set bar y
1095 set foo_seen 0
1096 set bar_seen 0
1097 for {set i 0} {$i < 100} {incr i} {
1098 set rkey [$r randomkey]
1099 if {$rkey eq {foo}} {
1100 set foo_seen 1
1101 }
1102 if {$rkey eq {bar}} {
1103 set bar_seen 1
1104 }
1105 }
1106 list $foo_seen $bar_seen
1107 } {1 1}
1108
1109 test {RANDOMKEY against empty DB} {
eea4baf7 1110 $r flushdb
ce7bef07 1111 $r randomkey
1112 } {}
1113
f5785ae9 1114 test {RANDOMKEY regression 1} {
eea4baf7 1115 $r flushdb
f5785ae9 1116 $r set x 10
1117 $r del x
1118 $r randomkey
1119 } {}
1120
7ac6d461 1121 test {GETSET (set new value)} {
1122 list [$r getset foo xyz] [$r get foo]
1123 } {{} xyz}
1124
1125 test {GETSET (replace old value)} {
1126 $r set foo bar
1127 list [$r getset foo xyz] [$r get foo]
1128 } {bar xyz}
1129
0eeb2a4b 1130 test {SMOVE basics} {
1131 $r sadd myset1 a
1132 $r sadd myset1 b
1133 $r sadd myset1 c
1134 $r sadd myset2 x
1135 $r sadd myset2 y
1136 $r sadd myset2 z
1137 $r smove myset1 myset2 a
1138 list [lsort [$r smembers myset2]] [lsort [$r smembers myset1]]
1139 } {{a x y z} {b c}}
1140
1141 test {SMOVE non existing key} {
1142 list [$r smove myset1 myset2 foo] [lsort [$r smembers myset2]] [lsort [$r smembers myset1]]
1143 } {0 {a x y z} {b c}}
1144
1145 test {SMOVE non existing src set} {
1146 list [$r smove noset myset2 foo] [lsort [$r smembers myset2]]
1147 } {0 {a x y z}}
1148
1149 test {SMOVE non existing dst set} {
1150 list [$r smove myset2 myset3 y] [lsort [$r smembers myset2]] [lsort [$r smembers myset3]]
1151 } {1 {a x z} y}
1152
1153 test {SMOVE wrong src key type} {
1154 $r set x 10
1155 catch {$r smove x myset2 foo} err
1156 format $err
1157 } {ERR*}
1158
1159 test {SMOVE wrong dst key type} {
1160 $r set x 10
1161 catch {$r smove myset2 x foo} err
1162 format $err
1163 } {ERR*}
1164
f69f2cba 1165 test {MSET base case} {
1166 $r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n"
1167 $r mget x y z
1168 } [list 10 {foo bar} "x x x x x x x\n\n\r\n"]
1169
1170 test {MSET wrong number of args} {
1171 catch {$r mset x 10 y "foo bar" z} err
1172 format $err
1173 } {*wrong number*}
1174
1175 test {MSETNX with already existent key} {
1176 list [$r msetnx x1 xxx y2 yyy x 20] [$r exists x1] [$r exists y2]
1177 } {0 0 0}
1178
1179 test {MSETNX with not existing keys} {
1180 list [$r msetnx x1 xxx y2 yyy] [$r get x1] [$r get y2]
1181 } {1 xxx yyy}
1182
5acdc75d 1183 test {MSETNX should remove all the volatile keys even on failure} {
1184 $r mset x 1 y 2 z 3
1185 $r expire y 10000
1186 $r expire z 10000
1187 list [$r msetnx x A y B z C] [$r mget x y z]
1188 } {0 {1 {} {}}}
1189
d7f43c08 1190 test {ZSET basic ZADD and score update} {
1191 $r zadd ztmp 10 x
1192 $r zadd ztmp 20 y
1193 $r zadd ztmp 30 z
1194 set aux1 [$r zrange ztmp 0 -1]
1195 $r zadd ztmp 1 y
1196 set aux2 [$r zrange ztmp 0 -1]
1197 list $aux1 $aux2
1198 } {{x y z} {y x z}}
1199
fc77604c 1200 test {ZCARD basics} {
1201 $r zcard ztmp
1202 } {3}
1203
1204 test {ZCARD non existing key} {
1205 $r zcard ztmp-blabla
1206 } {0}
1207
69d95c3e
PN
1208 test {ZRANK basics} {
1209 $r zadd zranktmp 10 x
1210 $r zadd zranktmp 20 y
1211 $r zadd zranktmp 30 z
1212 list [$r zrank zranktmp x] [$r zrank zranktmp y] [$r zrank zranktmp z]
1213 } {0 1 2}
1214
798d9e55
PN
1215 test {ZREVRANK basics} {
1216 list [$r zrevrank zranktmp x] [$r zrevrank zranktmp y] [$r zrevrank zranktmp z]
1217 } {2 1 0}
1218
69d95c3e
PN
1219 test {ZRANK - after deletion} {
1220 $r zrem zranktmp y
1221 list [$r zrank zranktmp x] [$r zrank zranktmp z]
1222 } {0 1}
1223
d7f43c08 1224 test {ZSCORE} {
eaa256ad 1225 set aux {}
1226 set err {}
1227 for {set i 0} {$i < 1000} {incr i} {
1228 set score [expr rand()]
1229 lappend aux $score
1230 $r zadd zscoretest $score $i
1231 }
1232 for {set i 0} {$i < 1000} {incr i} {
1233 if {[$r zscore zscoretest $i] != [lindex $aux $i]} {
1234 set err "Expected score was [lindex $aux $i] but got [$r zscore zscoretest $i] for element $i"
1235 break
1236 }
1237 }
1238 set _ $err
1239 } {}
d7f43c08 1240
210e29f7 1241 test {ZSCORE after a DEBUG RELOAD} {
1242 set aux {}
1243 set err {}
1244 $r del zscoretest
1245 for {set i 0} {$i < 1000} {incr i} {
1246 set score [expr rand()]
1247 lappend aux $score
1248 $r zadd zscoretest $score $i
1249 }
1250 $r debug reload
1251 for {set i 0} {$i < 1000} {incr i} {
1252 if {[$r zscore zscoretest $i] != [lindex $aux $i]} {
1253 set err "Expected score was [lindex $aux $i] but got [$r zscore zscoretest $i] for element $i"
1254 break
1255 }
1256 }
1257 set _ $err
1258 } {}
1259
ac945e2d 1260 test {ZRANGE and ZREVRANGE basics} {
04c71068 1261 list [$r zrange ztmp 0 -1] [$r zrevrange ztmp 0 -1] \
1262 [$r zrange ztmp 1 -1] [$r zrevrange ztmp 1 -1]
1263 } {{y x z} {z x y} {x z} {x y}}
d7f43c08 1264
81d45645 1265 test {ZRANGE WITHSCORES} {
1266 $r zrange ztmp 0 -1 withscores
1267 } {y 1 x 10 z 30}
1268
d7f43c08 1269 test {ZSETs stress tester - sorting is working well?} {
1270 set delta 0
1271 for {set test 0} {$test < 2} {incr test} {
1272 unset -nocomplain auxarray
1273 array set auxarray {}
1274 set auxlist {}
1275 $r del myzset
1276 for {set i 0} {$i < 1000} {incr i} {
1277 if {$test == 0} {
1278 set score [expr rand()]
1279 } else {
1280 set score [expr int(rand()*10)]
1281 }
1282 set auxarray($i) $score
1283 $r zadd myzset $score $i
1284 # Random update
1285 if {[expr rand()] < .2} {
1286 set j [expr int(rand()*1000)]
1287 if {$test == 0} {
1288 set score [expr rand()]
1289 } else {
1290 set score [expr int(rand()*10)]
1291 }
1292 set auxarray($j) $score
1293 $r zadd myzset $score $j
1294 }
1295 }
1296 foreach {item score} [array get auxarray] {
1297 lappend auxlist [list $score $item]
1298 }
1299 set sorted [lsort -command zlistAlikeSort $auxlist]
1300 set auxlist {}
1301 foreach x $sorted {
1302 lappend auxlist [lindex $x 1]
1303 }
1304 set fromredis [$r zrange myzset 0 -1]
1305 set delta 0
1306 for {set i 0} {$i < [llength $fromredis]} {incr i} {
1307 if {[lindex $fromredis $i] != [lindex $auxlist $i]} {
1308 incr delta
1309 }
1310 }
1311 }
1312 format $delta
1313 } {0}
1314
28173a49 1315 test {ZINCRBY - can create a new sorted set} {
1316 $r del zset
1317 $r zincrby zset 1 foo
1318 list [$r zrange zset 0 -1] [$r zscore zset foo]
1319 } {foo 1}
1320
1321 test {ZINCRBY - increment and decrement} {
1322 $r zincrby zset 2 foo
1323 $r zincrby zset 1 bar
1324 set v1 [$r zrange zset 0 -1]
1325 $r zincrby zset 10 bar
1326 $r zincrby zset -5 foo
1327 $r zincrby zset -5 bar
1328 set v2 [$r zrange zset 0 -1]
1329 list $v1 $v2 [$r zscore zset foo] [$r zscore zset bar]
1330 } {{bar foo} {foo bar} -2 6}
1331
223a0591 1332 test {ZRANGEBYSCORE and ZCOUNT basics} {
c74e7c77 1333 $r del zset
1334 $r zadd zset 1 a
1335 $r zadd zset 2 b
1336 $r zadd zset 3 c
1337 $r zadd zset 4 d
1338 $r zadd zset 5 e
223a0591 1339 list [$r zrangebyscore zset 2 4] [$r zrangebyscore zset (2 (4] \
1340 [$r zcount zset 2 4] [$r zcount zset (2 (4]
1341 } {{b c d} c 3 1}
c74e7c77 1342
0500ef27
SH
1343 test {ZRANGEBYSCORE withscores} {
1344 $r del zset
1345 $r zadd zset 1 a
1346 $r zadd zset 2 b
1347 $r zadd zset 3 c
1348 $r zadd zset 4 d
1349 $r zadd zset 5 e
1350 $r zrangebyscore zset 2 4 withscores
1351 } {b 2 c 3 d 4}
1352
5b1207c6 1353 test {ZRANGEBYSCORE fuzzy test, 100 ranges in 1000 elements sorted set} {
1354 set err {}
1355 $r del zset
1356 for {set i 0} {$i < 1000} {incr i} {
1357 $r zadd zset [expr rand()] $i
1358 }
1359 for {set i 0} {$i < 100} {incr i} {
1360 set min [expr rand()]
1361 set max [expr rand()]
1362 if {$min > $max} {
1363 set aux $min
1364 set min $max
1365 set max $aux
1366 }
1367 set low [$r zrangebyscore zset -inf $min]
1368 set ok [$r zrangebyscore zset $min $max]
1369 set high [$r zrangebyscore zset $max +inf]
223a0591 1370 set lowx [$r zrangebyscore zset -inf ($min]
1371 set okx [$r zrangebyscore zset ($min ($max]
1372 set highx [$r zrangebyscore zset ($max +inf]
1373
1374 if {[$r zcount zset -inf $min] != [llength $low]} {
1375 append err "Error, len does not match zcount\n"
1376 }
1377 if {[$r zcount zset $min $max] != [llength $ok]} {
1378 append err "Error, len does not match zcount\n"
1379 }
1380 if {[$r zcount zset $max +inf] != [llength $high]} {
1381 append err "Error, len does not match zcount\n"
1382 }
1383 if {[$r zcount zset -inf ($min] != [llength $lowx]} {
1384 append err "Error, len does not match zcount\n"
1385 }
1386 if {[$r zcount zset ($min ($max] != [llength $okx]} {
1387 append err "Error, len does not match zcount\n"
1388 }
1389 if {[$r zcount zset ($max +inf] != [llength $highx]} {
1390 append err "Error, len does not match zcount\n"
1391 }
1392
5b1207c6 1393 foreach x $low {
1394 set score [$r zscore zset $x]
1395 if {$score > $min} {
1396 append err "Error, score for $x is $score > $min\n"
1397 }
1398 }
223a0591 1399 foreach x $lowx {
1400 set score [$r zscore zset $x]
1401 if {$score >= $min} {
1402 append err "Error, score for $x is $score >= $min\n"
1403 }
1404 }
5b1207c6 1405 foreach x $ok {
1406 set score [$r zscore zset $x]
1407 if {$score < $min || $score > $max} {
1408 append err "Error, score for $x is $score outside $min-$max range\n"
1409 }
1410 }
223a0591 1411 foreach x $okx {
1412 set score [$r zscore zset $x]
1413 if {$score <= $min || $score >= $max} {
1414 append err "Error, score for $x is $score outside $min-$max open range\n"
1415 }
1416 }
5b1207c6 1417 foreach x $high {
1418 set score [$r zscore zset $x]
1419 if {$score < $max} {
1420 append err "Error, score for $x is $score < $max\n"
1421 }
1422 }
223a0591 1423 foreach x $highx {
1424 set score [$r zscore zset $x]
1425 if {$score <= $max} {
1426 append err "Error, score for $x is $score <= $max\n"
1427 }
1428 }
5b1207c6 1429 }
1430 set _ $err
1431 } {}
1432
0b13687c 1433 test {ZRANGEBYSCORE with LIMIT} {
1434 $r del zset
1435 $r zadd zset 1 a
1436 $r zadd zset 2 b
1437 $r zadd zset 3 c
1438 $r zadd zset 4 d
1439 $r zadd zset 5 e
1440 list \
1441 [$r zrangebyscore zset 0 10 LIMIT 0 2] \
1442 [$r zrangebyscore zset 0 10 LIMIT 2 3] \
1443 [$r zrangebyscore zset 0 10 LIMIT 2 10] \
1444 [$r zrangebyscore zset 0 10 LIMIT 20 10]
1445 } {{a b} {c d e} {c d e} {}}
1446
0500ef27
SH
1447 test {ZRANGEBYSCORE with LIMIT and withscores} {
1448 $r del zset
1449 $r zadd zset 10 a
1450 $r zadd zset 20 b
1451 $r zadd zset 30 c
1452 $r zadd zset 40 d
1453 $r zadd zset 50 e
1454 $r zrangebyscore zset 20 50 LIMIT 2 3 withscores
1455 } {d 40 e 50}
1456
9212eafd 1457 test {ZREMRANGEBYSCORE basics} {
9c21a518 1458 $r del zset
1459 $r zadd zset 1 a
1460 $r zadd zset 2 b
1461 $r zadd zset 3 c
1462 $r zadd zset 4 d
1463 $r zadd zset 5 e
1464 list [$r zremrangebyscore zset 2 4] [$r zrange zset 0 -1]
1465 } {3 {a e}}
1466
9212eafd 1467 test {ZREMRANGEBYSCORE from -inf to +inf} {
9c21a518 1468 $r del zset
1469 $r zadd zset 1 a
1470 $r zadd zset 2 b
1471 $r zadd zset 3 c
1472 $r zadd zset 4 d
1473 $r zadd zset 5 e
1474 list [$r zremrangebyscore zset -inf +inf] [$r zrange zset 0 -1]
1475 } {5 {}}
1476
9212eafd
PN
1477 test {ZREMRANGEBYRANK basics} {
1478 $r del zset
1479 $r zadd zset 1 a
1480 $r zadd zset 2 b
1481 $r zadd zset 3 c
1482 $r zadd zset 4 d
1483 $r zadd zset 5 e
1484 list [$r zremrangebyrank zset 1 3] [$r zrange zset 0 -1]
1485 } {3 {a e}}
1486
2830ca53 1487 test {ZUNION basics} {
b287c9bb
PN
1488 $r del zseta zsetb zsetc
1489 $r zadd zseta 1 a
1490 $r zadd zseta 2 b
1491 $r zadd zseta 3 c
1492 $r zadd zsetb 1 b
1493 $r zadd zsetb 2 c
1494 $r zadd zsetb 3 d
2830ca53 1495 list [$r zunion zsetc 2 zseta zsetb] [$r zrange zsetc 0 -1 withscores]
b287c9bb
PN
1496 } {4 {a 1 b 3 d 3 c 5}}
1497
2830ca53
PN
1498 test {ZUNION with weights} {
1499 list [$r zunion zsetc 2 zseta zsetb weights 2 3] [$r zrange zsetc 0 -1 withscores]
b287c9bb
PN
1500 } {4 {a 2 b 7 d 9 c 12}}
1501
d2764cd6
PN
1502 test {ZUNION with AGGREGATE MIN} {
1503 list [$r zunion zsetc 2 zseta zsetb aggregate min] [$r zrange zsetc 0 -1 withscores]
1504 } {4 {a 1 b 1 c 2 d 3}}
1505
1506 test {ZUNION with AGGREGATE MAX} {
1507 list [$r zunion zsetc 2 zseta zsetb aggregate max] [$r zrange zsetc 0 -1 withscores]
1508 } {4 {a 1 b 2 c 3 d 3}}
1509
2830ca53
PN
1510 test {ZINTER basics} {
1511 list [$r zinter zsetc 2 zseta zsetb] [$r zrange zsetc 0 -1 withscores]
1512 } {2 {b 3 c 5}}
1513
1514 test {ZINTER with weights} {
1515 list [$r zinter zsetc 2 zseta zsetb weights 2 3] [$r zrange zsetc 0 -1 withscores]
1516 } {2 {b 7 c 12}}
1517
d2764cd6
PN
1518 test {ZINTER with AGGREGATE MIN} {
1519 list [$r zinter zsetc 2 zseta zsetb aggregate min] [$r zrange zsetc 0 -1 withscores]
1520 } {2 {b 1 c 2}}
1521
1522 test {ZINTER with AGGREGATE MAX} {
1523 list [$r zinter zsetc 2 zseta zsetb aggregate max] [$r zrange zsetc 0 -1 withscores]
1524 } {2 {b 2 c 3}}
1525
0b13687c 1526 test {SORT against sorted sets} {
1527 $r del zset
1528 $r zadd zset 1 a
1529 $r zadd zset 5 b
1530 $r zadd zset 2 c
1531 $r zadd zset 10 d
1532 $r zadd zset 3 e
1533 $r sort zset alpha desc
1534 } {e d c b a}
1535
c74e7c77 1536 test {Sorted sets +inf and -inf handling} {
1537 $r del zset
1538 $r zadd zset -100 a
1539 $r zadd zset 200 b
1540 $r zadd zset -300 c
1541 $r zadd zset 1000000 d
1542 $r zadd zset +inf max
1543 $r zadd zset -inf min
1544 $r zrange zset 0 -1
1545 } {min c a b d max}
1546
164ee595 1547 test {HSET/HLEN - Small hash creation} {
1548 array set smallhash {}
1549 for {set i 0} {$i < 8} {incr i} {
1550 set key [randstring 0 8 alpha]
1551 set val [randstring 0 8 alpha]
1552 if {[info exists smallhash($key)]} {
1553 incr i -1
1554 continue
1555 }
1556 $r hset smallhash $key $val
1557 set smallhash($key) $val
1558 }
1559 list [$r hlen smallhash]
1560 } {8}
1561
1562 test {Is the small hash encoded with a zipmap?} {
1563 $r debug object smallhash
1564 } {*zipmap*}
1565
1566 test {HSET/HLEN - Big hash creation} {
1567 array set bighash {}
1568 for {set i 0} {$i < 1024} {incr i} {
1569 set key [randstring 0 8 alpha]
1570 set val [randstring 0 8 alpha]
1571 if {[info exists bighash($key)]} {
1572 incr i -1
1573 continue
1574 }
1575 $r hset bighash $key $val
1576 set bighash($key) $val
1577 }
1578 list [$r hlen bighash]
1579 } {1024}
1580
1581 test {Is the big hash encoded with a zipmap?} {
1582 $r debug object bighash
1583 } {*hashtable*}
1584
1585 test {HGET against the small hash} {
1586 set err {}
1587 foreach k [array names smallhash *] {
1588 if {$smallhash($k) ne [$r hget smallhash $k]} {
1589 set err "$smallhash($k) != [$r hget smallhash $k]"
1590 break
1591 }
1592 }
1593 set _ $err
1594 } {}
1595
1596 test {HGET against the big hash} {
1597 set err {}
1598 foreach k [array names bighash *] {
1599 if {$bighash($k) ne [$r hget bighash $k]} {
1600 set err "$bighash($k) != [$r hget bighash $k]"
1601 break
1602 }
1603 }
1604 set _ $err
1605 } {}
1606
516977de 1607 test {HSET in update and insert mode} {
b1d9c91c 1608 set rv {}
1609 set k [lindex [array names smallhash *] 0]
516977de 1610 lappend rv [$r hset smallhash $k newval1]
11d9d1e3 1611 set smallhash($k) newval1
516977de 1612 lappend rv [$r hget smallhash $k]
b1d9c91c 1613 lappend rv [$r hset smallhash __foobar123__ newval]
1614 set k [lindex [array names bighash *] 0]
516977de 1615 lappend rv [$r hset bighash $k newval2]
11d9d1e3 1616 set bighash($k) newval2
516977de 1617 lappend rv [$r hget bighash $k]
b1d9c91c 1618 lappend rv [$r hset bighash __foobar123__ newval]
1619 lappend rv [$r hdel smallhash __foobar123__]
1620 lappend rv [$r hdel bighash __foobar123__]
1621 set _ $rv
516977de 1622 } {0 newval1 1 0 newval2 1 1 1}
b1d9c91c 1623
1624 test {HGET against non existing key} {
1625 set rv {}
1626 lappend rv [$r hget smallhash __123123123__]
1627 lappend rv [$r hget bighash __123123123__]
1628 set _ $rv
1629 } {{} {}}
1630
1631 test {HKEYS - small hash} {
1632 lsort [$r hkeys smallhash]
1633 } [lsort [array names smallhash *]]
1634
1635 test {HKEYS - big hash} {
1636 lsort [$r hkeys bighash]
1637 } [lsort [array names bighash *]]
1638
11d9d1e3 1639 test {HVALS - small hash} {
1640 set vals {}
1641 foreach {k v} [array get smallhash] {
1642 lappend vals $v
1643 }
1644 set _ [lsort $vals]
1645 } [lsort [$r hvals smallhash]]
1646
1647 test {HVALS - big hash} {
1648 set vals {}
1649 foreach {k v} [array get bighash] {
1650 lappend vals $v
1651 }
1652 set _ [lsort $vals]
1653 } [lsort [$r hvals bighash]]
1654
1655 test {HGETALL - small hash} {
1656 lsort [$r hgetall smallhash]
1657 } [lsort [array get smallhash]]
1658
1659 test {HGETALL - big hash} {
1660 lsort [$r hgetall bighash]
1661 } [lsort [array get bighash]]
1662
1663 test {HDEL and return value} {
1664 set rv {}
1665 lappend rv [$r hdel smallhash nokey]
1666 lappend rv [$r hdel bighash nokey]
1667 set k [lindex [array names smallhash *] 0]
1668 lappend rv [$r hdel smallhash $k]
1669 lappend rv [$r hdel smallhash $k]
1670 lappend rv [$r hget smallhash $k]
a86f14b1 1671 unset smallhash($k)
11d9d1e3 1672 set k [lindex [array names bighash *] 0]
1673 lappend rv [$r hdel bighash $k]
1674 lappend rv [$r hdel bighash $k]
1675 lappend rv [$r hget bighash $k]
a86f14b1 1676 unset bighash($k)
11d9d1e3 1677 set _ $rv
1678 } {0 0 1 0 {} 1 0 {}}
1679
a86f14b1 1680 test {HEXISTS} {
1681 set rv {}
1682 set k [lindex [array names smallhash *] 0]
1683 lappend rv [$r hexists smallhash $k]
1684 lappend rv [$r hexists smallhash nokey]
1685 set k [lindex [array names bighash *] 0]
1686 lappend rv [$r hexists bighash $k]
1687 lappend rv [$r hexists bighash nokey]
1688 } {1 0 1 0}
1689
11d9d1e3 1690 test {Is a zipmap encoded Hash promoted on big payload?} {
1691 $r hset smallhash foo [string repeat a 1024]
1692 $r debug object smallhash
1693 } {*hashtable*}
1694
b1d9c91c 1695 # TODO:
b1d9c91c 1696 # Randomized test, small and big
1697 # .rdb / AOF consistency test should include hashes
1698
b9febaab 1699 test {EXPIRE - don't set timeouts multiple times} {
1700 $r set x foobar
1701 set v1 [$r expire x 5]
1702 set v2 [$r ttl x]
1703 set v3 [$r expire x 10]
1704 set v4 [$r ttl x]
1705 list $v1 $v2 $v3 $v4
1706 } {1 5 0 5}
1707
1708 test {EXPIRE - It should be still possible to read 'x'} {
1709 $r get x
1710 } {foobar}
1711
1712 test {EXPIRE - After 6 seconds the key should no longer be here} {
1713 after 6000
1714 list [$r get x] [$r exists x]
1715 } {{} 0}
1716
1717 test {EXPIRE - Delete on write policy} {
1718 $r del x
1719 $r lpush x foo
1720 $r expire x 1000
1721 $r lpush x bar
1722 $r lrange x 0 -1
1723 } {bar}
1724
5446315f 1725 test {EXPIREAT - Check for EXPIRE alike behavior} {
1726 $r del x
1727 $r set x foo
1728 $r expireat x [expr [clock seconds]+15]
1729 $r ttl x
1730 } {1[345]}
1731
d7f43c08 1732 test {ZSETs skiplist implementation backlink consistency test} {
1733 set diff 0
1734 set elements 10000
1735 for {set j 0} {$j < $elements} {incr j} {
1736 $r zadd myzset [expr rand()] "Element-$j"
1737 $r zrem myzset "Element-[expr int(rand()*$elements)]"
1738 }
1739 set l1 [$r zrange myzset 0 -1]
1740 set l2 [$r zrevrange myzset 0 -1]
1741 for {set j 0} {$j < [llength $l1]} {incr j} {
1742 if {[lindex $l1 $j] ne [lindex $l2 end-$j]} {
1743 incr diff
1744 }
1745 }
1746 format $diff
1747 } {0}
1748
3589e1a7 1749 test {ZSETs ZRANK augmented skip list stress testing} {
1750 set err {}
1751 $r del myzset
1752 for {set k 0} {$k < 10000} {incr k} {
1753 set i [expr {$k%1000}]
1754 if {[expr rand()] < .2} {
1755 $r zrem myzset $i
1756 } else {
1757 set score [expr rand()]
1758 $r zadd myzset $score $i
1759 }
1760 set card [$r zcard myzset]
1761 if {$card > 0} {
1762 set index [randomInt $card]
1763 set ele [lindex [$r zrange myzset $index $index] 0]
1764 set rank [$r zrank myzset $ele]
1765 if {$rank != $index} {
67cac143 1766 set err "$ele RANK is wrong! ($rank != $index)"
3589e1a7 1767 break
1768 }
1769 }
1770 }
1771 set _ $err
1772 } {}
1773
75398fbc 1774 foreach fuzztype {binary alpha compr} {
1775 test "FUZZ stresser with data model $fuzztype" {
1776 set err 0
f69f2cba 1777 for {set i 0} {$i < 10000} {incr i} {
75398fbc 1778 set fuzz [randstring 0 512 $fuzztype]
1779 $r set foo $fuzz
1780 set got [$r get foo]
1781 if {$got ne $fuzz} {
f69f2cba 1782 set err [list $fuzz $got]
75398fbc 1783 break
1784 }
1785 }
f69f2cba 1786 set _ $err
75398fbc 1787 } {0}
1788 }
1789
0d36ded0 1790 test {BGSAVE} {
7c775e09 1791 waitForBgsave $r
0d36ded0 1792 $r flushdb
1793 $r save
1794 $r set x 10
1795 $r bgsave
1796 waitForBgsave $r
1797 $r debug reload
1798 $r get x
1799 } {10}
1800
7c49733c 1801 test {Handle an empty query well} {
1802 set fd [$r channel]
1803 puts -nonewline $fd "\r\n"
1804 flush $fd
1805 $r ping
1806 } {PONG}
1807
1808 test {Negative multi bulk command does not create problems} {
1809 set fd [$r channel]
1810 puts -nonewline $fd "*-10\r\n"
1811 flush $fd
1812 $r ping
1813 } {PONG}
1814
1815 test {Negative multi bulk payload} {
1816 set fd [$r channel]
1817 puts -nonewline $fd "SET x -10\r\n"
1818 flush $fd
1819 gets $fd
1820 } {*invalid bulk*}
1821
1822 test {Too big bulk payload} {
1823 set fd [$r channel]
1824 puts -nonewline $fd "SET x 2000000000\r\n"
1825 flush $fd
1826 gets $fd
1827 } {*invalid bulk*count*}
1828
1829 test {Multi bulk request not followed by bulk args} {
1830 set fd [$r channel]
1831 puts -nonewline $fd "*1\r\nfoo\r\n"
1832 flush $fd
1833 gets $fd
1834 } {*protocol error*}
1835
1836 test {Generic wrong number of args} {
1837 catch {$r ping x y z} err
1838 set _ $err
1839 } {*wrong*arguments*ping*}
1840
1841 test {SELECT an out of range DB} {
1842 catch {$r select 1000000} err
1843 set _ $err
1844 } {*invalid*}
1845
e054afda 1846 if {![catch {package require sha1}]} {
1847 test {Check consistency of different data types after a reload} {
1848 $r flushdb
1849 createComplexDataset $r 10000
1850 set sha1 [datasetDigest $r]
1851 $r debug reload
1852 set sha1_after [datasetDigest $r]
1853 expr {$sha1 eq $sha1_after}
1854 } {1}
e96e4fbf 1855
1856 test {Same dataset digest if saving/reloading as AOF?} {
1857 $r bgrewriteaof
1858 waitForBgrewriteaof $r
1859 $r debug loadaof
1860 set sha1_after [datasetDigest $r]
1861 expr {$sha1 eq $sha1_after}
1862 } {1}
e054afda 1863 }
1864
e96e4fbf 1865 test {EXPIRES after a reload (snapshot + append only file)} {
71c2b467 1866 $r flushdb
1867 $r set x 10
1868 $r expire x 1000
1869 $r save
1870 $r debug reload
1871 set ttl [$r ttl x]
e96e4fbf 1872 set e1 [expr {$ttl > 900 && $ttl <= 1000}]
1873 $r bgrewriteaof
1874 waitForBgrewriteaof $r
1875 set ttl [$r ttl x]
1876 set e2 [expr {$ttl > 900 && $ttl <= 1000}]
1877 list $e1 $e2
1878 } {1 1}
71c2b467 1879
483049a7 1880 test {PIPELINING stresser (also a regression for the old epoll bug)} {
1881 set fd2 [socket 127.0.0.1 6379]
1882 fconfigure $fd2 -encoding binary -translation binary
0447be2e 1883 puts -nonewline $fd2 "SELECT 9\r\n"
1884 flush $fd2
1885 gets $fd2
483049a7 1886
1887 for {set i 0} {$i < 100000} {incr i} {
1888 set q {}
1889 set val "0000${i}0000"
1890 append q "SET key:$i [string length $val]\r\n$val\r\n"
1891 puts -nonewline $fd2 $q
1892 set q {}
1893 append q "GET key:$i\r\n"
1894 puts -nonewline $fd2 $q
1895 }
1896 flush $fd2
1897
1898 for {set i 0} {$i < 100000} {incr i} {
1899 gets $fd2 line
1900 gets $fd2 count
1901 set count [string range $count 1 end]
1902 set val [read $fd2 $count]
1903 read $fd2 2
1904 }
1905 close $fd2
1906 set _ 1
1907 } {1}
1908
4409877e 1909 test {MUTLI / EXEC basics} {
1910 $r del mylist
1911 $r rpush mylist a
1912 $r rpush mylist b
1913 $r rpush mylist c
1914 $r multi
1915 set v1 [$r lrange mylist 0 -1]
1916 set v2 [$r ping]
1917 set v3 [$r exec]
1918 list $v1 $v2 $v3
1919 } {QUEUED QUEUED {{a b c} PONG}}
1920
18b6cb76
DJ
1921 test {DISCARD} {
1922 $r del mylist
1923 $r rpush mylist a
1924 $r rpush mylist b
1925 $r rpush mylist c
1926 $r multi
1927 set v1 [$r del mylist]
1928 set v2 [$r discard]
1929 set v3 [$r lrange mylist 0 -1]
1930 list $v1 $v2 $v3
1931 } {QUEUED OK {a b c}}
1932
3c290b9b 1933 test {APPEND basics} {
1934 list [$r append foo bar] [$r get foo] \
1935 [$r append foo 100] [$r get foo]
1936 } {3 bar 6 bar100}
1937
1938 test {APPEND fuzzing} {
1939 set err {}
1940 foreach type {binary alpha compr} {
1941 set buf {}
1942 $r del x
1943 for {set i 0} {$i < 1000} {incr i} {
1944 set bin [randstring 0 10 $type]
1945 append buf $bin
1946 $r append x $bin
1947 }
1948 if {$buf != [$r get x]} {
1949 set err "Expected '$buf' found '[$r get x]'"
1950 break
1951 }
1952 }
1953 set _ $err
1954 } {}
1955
ed9b544e 1956 # Leave the user with a clean DB before to exit
eea4baf7 1957 test {FLUSHDB} {
1958 set aux {}
1959 $r select 9
1960 $r flushdb
1961 lappend aux [$r dbsize]
1962 $r select 10
1963 $r flushdb
1964 lappend aux [$r dbsize]
1965 } {0 0}
ed9b544e 1966
c28b42ac 1967 test {Perform a final SAVE to leave a clean DB on disk} {
1968 $r save
1969 } {OK}
1970
17511391 1971 catch {
1972 if {[string match {*Darwin*} [exec uname -a]]} {
1973 test {Check for memory leaks} {
1974 exec leaks redis-server
1975 } {*0 leaks*}
1976 }
1977 }
1978
ed9b544e 1979 puts "\n[expr $::passed+$::failed] tests, $::passed passed, $::failed failed"
1980 if {$::failed > 0} {
1981 puts "\n*** WARNING!!! $::failed FAILED TESTS ***\n"
1982 }
ed9b544e 1983}
1984
5a6948fb 1985proc stress {} {
43c9dc7b 1986 set r [redis]
eea4baf7 1987 $r select 9
1988 $r flushdb
5a6948fb 1989 while 1 {
1990 set randkey [expr int(rand()*10000)]
1991 set randval [expr int(rand()*10000)]
1992 set randidx0 [expr int(rand()*10)]
1993 set randidx1 [expr int(rand()*10)]
12f9d551 1994 set cmd [expr int(rand()*20)]
43c9dc7b 1995 catch {
1996 if {$cmd == 0} {$r set $randkey $randval}
1997 if {$cmd == 1} {$r get $randkey}
1998 if {$cmd == 2} {$r incr $randkey}
1999 if {$cmd == 3} {$r lpush $randkey $randval}
2000 if {$cmd == 4} {$r rpop $randkey}
2001 if {$cmd == 5} {$r del $randkey}
12f9d551 2002 if {$cmd == 6} {$r llen $randkey}
2003 if {$cmd == 7} {$r lrange $randkey $randidx0 $randidx1}
2004 if {$cmd == 8} {$r ltrim $randkey $randidx0 $randidx1}
2005 if {$cmd == 9} {$r lindex $randkey $randidx0}
2006 if {$cmd == 10} {$r lset $randkey $randidx0 $randval}
2007 if {$cmd == 11} {$r sadd $randkey $randval}
2008 if {$cmd == 12} {$r srem $randkey $randval}
2009 if {$cmd == 13} {$r smove $randkey $randval}
2010 if {$cmd == 14} {$r scard $randkey}
2011 if {$cmd == 15} {$r expire $randkey [expr $randval%60]}
43c9dc7b 2012 }
5a6948fb 2013 flush stdout
2014 }
eea4baf7 2015 $r flushdb
43c9dc7b 2016 $r close
5a6948fb 2017}
2018
fc77604c 2019# Set a few configuration defaults
2020set ::host 127.0.0.1
2021set ::port 6379
2022set ::stress 0
2023set ::flush 0
2024set ::first 0
2025set ::last 1000000
2026
2027# Parse arguments
2028for {set j 0} {$j < [llength $argv]} {incr j} {
2029 set opt [lindex $argv $j]
2030 set arg [lindex $argv [expr $j+1]]
2031 set lastarg [expr {$arg eq {}}]
2032 if {$opt eq {-h} && !$lastarg} {
2033 set ::host $arg
2034 incr j
2035 } elseif {$opt eq {-p} && !$lastarg} {
2036 set ::port $arg
2037 incr j
2038 } elseif {$opt eq {-stress}} {
2039 set ::stress 1
2040 } elseif {$opt eq {--flush}} {
2041 set ::flush 1
2042 } elseif {$opt eq {--first} && !$lastarg} {
2043 set ::first $arg
2044 incr j
2045 } elseif {$opt eq {--last} && !$lastarg} {
2046 set ::last $arg
2047 incr j
2048 } else {
7c49733c 2049 puts "Wrong argument: $opt"
fc77604c 2050 exit 1
2051 }
2052}
2053
eea4baf7 2054# Before to run the test check if DB 9 and DB 10 are empty
2055set r [redis]
fc77604c 2056
2057if {$::flush} {
2058 $r flushall
2059}
2060
eea4baf7 2061$r select 9
2062set db9size [$r dbsize]
2063$r select 10
2064set db10size [$r dbsize]
2065if {$db9size != 0 || $db10size != 0} {
2066 puts "Can't run the tests against DB 9 and 10: DBs are not empty."
2067 exit 1
2068}
2069$r close
2070unset r
2071unset db9size
2072unset db10size
2073
fc77604c 2074if {$::stress} {
5a6948fb 2075 stress
ed9b544e 2076} else {
fc77604c 2077 main $::host $::port
ed9b544e 2078}