]> git.saurik.com Git - redis.git/blob - test-redis.tcl
a6e36db43a1e1d62cd95cb74a7f43d83344c1ae3
[redis.git] / test-redis.tcl
1 # TODO # test pipelining
2
3 source redis.tcl
4
5 set ::passed 0
6 set ::failed 0
7
8 proc test {name code okpattern} {
9 puts -nonewline [format "%-70s " $name]
10 flush stdout
11 set retval [uplevel 1 $code]
12 if {$okpattern eq $retval || [string match $okpattern $retval]} {
13 puts "PASSED"
14 incr ::passed
15 } else {
16 puts "!! ERROR expected\n'$okpattern'\nbut got\n'$retval'"
17 incr ::failed
18 }
19 }
20
21 proc randstring {min max {type binary}} {
22 set len [expr {$min+int(rand()*($max-$min+1))}]
23 set output {}
24 if {$type eq {binary}} {
25 set minval 0
26 set maxval 255
27 } elseif {$type eq {alpha}} {
28 set minval 48
29 set maxval 122
30 } elseif {$type eq {compr}} {
31 set minval 48
32 set maxval 52
33 }
34 while {$len} {
35 append output [format "%c" [expr {$minval+int(rand()*($maxval-$minval+1))}]]
36 incr len -1
37 }
38 return $output
39 }
40
41 # Useful for some test
42 proc zlistAlikeSort {a b} {
43 if {[lindex $a 0] > [lindex $b 0]} {return 1}
44 if {[lindex $a 0] < [lindex $b 0]} {return -1}
45 string compare [lindex $a 1] [lindex $b 1]
46 }
47
48 proc main {server port} {
49 set r [redis $server $port]
50 set err ""
51
52 # The following AUTH test should be enabled only when requirepass
53 # <PASSWORD> is set in redis.conf and redis-server was started with
54 # redis.conf as the first argument.
55
56 #test {AUTH with requirepass in redis.conf} {
57 # $r auth foobared
58 #} {OK}
59
60 test {DEL all keys to start with a clean DB} {
61 foreach key [$r keys *] {$r del $key}
62 $r dbsize
63 } {0}
64
65 test {SET and GET an item} {
66 $r set x foobar
67 $r get x
68 } {foobar}
69
70 test {DEL against a single item} {
71 $r del x
72 $r get x
73 } {}
74
75 test {Vararg DEL} {
76 $r set foo1 a
77 $r set foo2 b
78 $r set foo3 c
79 list [$r del foo1 foo2 foo3 foo4] [$r mget foo1 foo2 foo3]
80 } {3 {{} {} {}}}
81
82 test {KEYS with pattern} {
83 foreach key {key_x key_y key_z foo_a foo_b foo_c} {
84 $r set $key hello
85 }
86 lsort [$r keys foo*]
87 } {foo_a foo_b foo_c}
88
89 test {KEYS to get all keys} {
90 lsort [$r keys *]
91 } {foo_a foo_b foo_c key_x key_y key_z}
92
93 test {DBSIZE} {
94 $r dbsize
95 } {6}
96
97 test {DEL all keys} {
98 foreach key [$r keys *] {$r del $key}
99 $r dbsize
100 } {0}
101
102 test {Very big payload in GET/SET} {
103 set buf [string repeat "abcd" 1000000]
104 $r set foo $buf
105 $r get foo
106 } [string repeat "abcd" 1000000]
107
108 test {SET 10000 numeric keys and access all them in reverse order} {
109 for {set x 0} {$x < 10000} {incr x} {
110 $r set $x $x
111 }
112 set sum 0
113 for {set x 9999} {$x >= 0} {incr x -1} {
114 incr sum [$r get $x]
115 }
116 format $sum
117 } {49995000}
118
119 test {DBSIZE should be 10001 now} {
120 $r dbsize
121 } {10001}
122
123 test {INCR against non existing key} {
124 set res {}
125 append res [$r incr novar]
126 append res [$r get novar]
127 } {11}
128
129 test {INCR against key created by incr itself} {
130 $r incr novar
131 } {2}
132
133 test {INCR against key originally set with SET} {
134 $r set novar 100
135 $r incr novar
136 } {101}
137
138 test {INCR over 32bit value} {
139 $r set novar 17179869184
140 $r incr novar
141 } {17179869185}
142
143 test {INCRBY over 32bit value with over 32bit increment} {
144 $r set novar 17179869184
145 $r incrby novar 17179869184
146 } {34359738368}
147
148 test {DECRBY over 32bit value with over 32bit increment, negative res} {
149 $r set novar 17179869184
150 $r decrby novar 17179869185
151 } {-1}
152
153 test {SETNX target key missing} {
154 $r setnx novar2 foobared
155 $r get novar2
156 } {foobared}
157
158 test {SETNX target key exists} {
159 $r setnx novar2 blabla
160 $r get novar2
161 } {foobared}
162
163 test {EXISTS} {
164 set res {}
165 $r set newkey test
166 append res [$r exists newkey]
167 $r del newkey
168 append res [$r exists newkey]
169 } {10}
170
171 test {Zero length value in key. SET/GET/EXISTS} {
172 $r set emptykey {}
173 set res [$r get emptykey]
174 append res [$r exists emptykey]
175 $r del emptykey
176 append res [$r exists emptykey]
177 } {10}
178
179 test {Commands pipelining} {
180 set fd [$r channel]
181 puts -nonewline $fd "SET k1 4\r\nxyzk\r\nGET k1\r\nPING\r\n"
182 flush $fd
183 set res {}
184 append res [string match OK* [::redis::redis_read_reply $fd]]
185 append res [::redis::redis_read_reply $fd]
186 append res [string match PONG* [::redis::redis_read_reply $fd]]
187 format $res
188 } {1xyzk1}
189
190 test {Non existing command} {
191 catch {$r foobaredcommand} err
192 string match ERR* $err
193 } {1}
194
195 test {Basic LPUSH, RPUSH, LLENGTH, LINDEX} {
196 $r lpush mylist a
197 $r lpush mylist b
198 $r rpush mylist c
199 set res [$r llen mylist]
200 append res [$r lindex mylist 0]
201 append res [$r lindex mylist 1]
202 append res [$r lindex mylist 2]
203 } {3bac}
204
205 test {DEL a list} {
206 $r del mylist
207 $r exists mylist
208 } {0}
209
210 test {Create a long list and check every single element with LINDEX} {
211 set ok 0
212 for {set i 0} {$i < 1000} {incr i} {
213 $r rpush mylist $i
214 }
215 for {set i 0} {$i < 1000} {incr i} {
216 if {[$r lindex mylist $i] eq $i} {incr ok}
217 if {[$r lindex mylist [expr (-$i)-1]] eq [expr 999-$i]} {
218 incr ok
219 }
220 }
221 format $ok
222 } {2000}
223
224 test {Test elements with LINDEX in random access} {
225 set ok 0
226 for {set i 0} {$i < 1000} {incr i} {
227 set rint [expr int(rand()*1000)]
228 if {[$r lindex mylist $rint] eq $rint} {incr ok}
229 if {[$r lindex mylist [expr (-$rint)-1]] eq [expr 999-$rint]} {
230 incr ok
231 }
232 }
233 format $ok
234 } {2000}
235
236 test {LLEN against non-list value error} {
237 $r del mylist
238 $r set mylist foobar
239 catch {$r llen mylist} err
240 format $err
241 } {ERR*}
242
243 test {LINDEX against non-list value error} {
244 catch {$r lindex mylist 0} err
245 format $err
246 } {ERR*}
247
248 test {LPUSH against non-list value error} {
249 catch {$r lpush mylist 0} err
250 format $err
251 } {ERR*}
252
253 test {RPUSH against non-list value error} {
254 catch {$r rpush mylist 0} err
255 format $err
256 } {ERR*}
257
258 test {RENAME basic usage} {
259 $r set mykey hello
260 $r rename mykey mykey1
261 $r rename mykey1 mykey2
262 $r get mykey2
263 } {hello}
264
265 test {RENAME source key should no longer exist} {
266 $r exists mykey
267 } {0}
268
269 test {RENAME against already existing key} {
270 $r set mykey a
271 $r set mykey2 b
272 $r rename mykey2 mykey
273 set res [$r get mykey]
274 append res [$r exists mykey2]
275 } {b0}
276
277 test {RENAMENX basic usage} {
278 $r del mykey
279 $r del mykey2
280 $r set mykey foobar
281 $r renamenx mykey mykey2
282 set res [$r get mykey2]
283 append res [$r exists mykey]
284 } {foobar0}
285
286 test {RENAMENX against already existing key} {
287 $r set mykey foo
288 $r set mykey2 bar
289 $r renamenx mykey mykey2
290 } {0}
291
292 test {RENAMENX against already existing key (2)} {
293 set res [$r get mykey]
294 append res [$r get mykey2]
295 } {foobar}
296
297 test {RENAME against non existing source key} {
298 catch {$r rename nokey foobar} err
299 format $err
300 } {ERR*}
301
302 test {RENAME where source and dest key is the same} {
303 catch {$r rename mykey mykey} err
304 format $err
305 } {ERR*}
306
307 test {DEL all keys again (DB 0)} {
308 foreach key [$r keys *] {
309 $r del $key
310 }
311 $r dbsize
312 } {0}
313
314 test {DEL all keys again (DB 1)} {
315 $r select 1
316 foreach key [$r keys *] {
317 $r del $key
318 }
319 set res [$r dbsize]
320 $r select 0
321 format $res
322 } {0}
323
324 test {MOVE basic usage} {
325 $r set mykey foobar
326 $r move mykey 1
327 set res {}
328 lappend res [$r exists mykey]
329 lappend res [$r dbsize]
330 $r select 1
331 lappend res [$r get mykey]
332 lappend res [$r dbsize]
333 $r select 0
334 format $res
335 } [list 0 0 foobar 1]
336
337 test {MOVE against key existing in the target DB} {
338 $r set mykey hello
339 $r move mykey 1
340 } {0}
341
342 test {SET/GET keys in different DBs} {
343 $r set a hello
344 $r set b world
345 $r select 1
346 $r set a foo
347 $r set b bared
348 $r select 0
349 set res {}
350 lappend res [$r get a]
351 lappend res [$r get b]
352 $r select 1
353 lappend res [$r get a]
354 lappend res [$r get b]
355 $r select 0
356 format $res
357 } {hello world foo bared}
358
359 test {Basic LPOP/RPOP} {
360 $r del mylist
361 $r rpush mylist 1
362 $r rpush mylist 2
363 $r lpush mylist 0
364 list [$r lpop mylist] [$r rpop mylist] [$r lpop mylist] [$r llen mylist]
365 } [list 0 2 1 0]
366
367 test {LPOP/RPOP against empty list} {
368 $r lpop mylist
369 } {}
370
371 test {LPOP against non list value} {
372 $r set notalist foo
373 catch {$r lpop notalist} err
374 format $err
375 } {ERR*kind*}
376
377 test {Mass LPUSH/LPOP} {
378 set sum 0
379 for {set i 0} {$i < 1000} {incr i} {
380 $r lpush mylist $i
381 incr sum $i
382 }
383 set sum2 0
384 for {set i 0} {$i < 500} {incr i} {
385 incr sum2 [$r lpop mylist]
386 incr sum2 [$r rpop mylist]
387 }
388 expr $sum == $sum2
389 } {1}
390
391 test {LRANGE basics} {
392 for {set i 0} {$i < 10} {incr i} {
393 $r rpush mylist $i
394 }
395 list [$r lrange mylist 1 -2] \
396 [$r lrange mylist -3 -1] \
397 [$r lrange mylist 4 4]
398 } {{1 2 3 4 5 6 7 8} {7 8 9} 4}
399
400 test {LRANGE inverted indexes} {
401 $r lrange mylist 6 2
402 } {}
403
404 test {LRANGE out of range indexes including the full list} {
405 $r lrange mylist -1000 1000
406 } {0 1 2 3 4 5 6 7 8 9}
407
408 test {LRANGE against non existing key} {
409 $r lrange nosuchkey 0 1
410 } {}
411
412 test {LTRIM basics} {
413 $r del mylist
414 for {set i 0} {$i < 100} {incr i} {
415 $r lpush mylist $i
416 $r ltrim mylist 0 4
417 }
418 $r lrange mylist 0 -1
419 } {99 98 97 96 95}
420
421 test {LSET} {
422 $r lset mylist 1 foo
423 $r lset mylist -1 bar
424 $r lrange mylist 0 -1
425 } {99 foo 97 96 bar}
426
427 test {LSET out of range index} {
428 catch {$r lset mylist 10 foo} err
429 format $err
430 } {ERR*range*}
431
432 test {LSET against non existing key} {
433 catch {$r lset nosuchkey 10 foo} err
434 format $err
435 } {ERR*key*}
436
437 test {LSET against non list value} {
438 $r set nolist foobar
439 catch {$r lset nolist 0 foo} err
440 format $err
441 } {ERR*value*}
442
443 test {SADD, SCARD, SISMEMBER, SMEMBERS basics} {
444 $r sadd myset foo
445 $r sadd myset bar
446 list [$r scard myset] [$r sismember myset foo] \
447 [$r sismember myset bar] [$r sismember myset bla] \
448 [lsort [$r smembers myset]]
449 } {2 1 1 0 {bar foo}}
450
451 test {SADD adding the same element multiple times} {
452 $r sadd myset foo
453 $r sadd myset foo
454 $r sadd myset foo
455 $r scard myset
456 } {2}
457
458 test {SADD against non set} {
459 catch {$r sadd mylist foo} err
460 format $err
461 } {ERR*kind*}
462
463 test {SREM basics} {
464 $r sadd myset ciao
465 $r srem myset foo
466 lsort [$r smembers myset]
467 } {bar ciao}
468
469 test {Mass SADD and SINTER with two sets} {
470 for {set i 0} {$i < 1000} {incr i} {
471 $r sadd set1 $i
472 $r sadd set2 [expr $i+995]
473 }
474 lsort [$r sinter set1 set2]
475 } {995 996 997 998 999}
476
477 test {SUNION with two sets} {
478 lsort [$r sunion set1 set2]
479 } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
480
481 test {SINTERSTORE with two sets} {
482 $r sinterstore setres set1 set2
483 lsort [$r smembers setres]
484 } {995 996 997 998 999}
485
486 test {SUNIONSTORE with two sets} {
487 $r sunionstore setres set1 set2
488 lsort [$r smembers setres]
489 } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
490
491 test {SINTER against three sets} {
492 $r sadd set3 999
493 $r sadd set3 995
494 $r sadd set3 1000
495 $r sadd set3 2000
496 lsort [$r sinter set1 set2 set3]
497 } {995 999}
498
499 test {SINTERSTORE with three sets} {
500 $r sinterstore setres set1 set2 set3
501 lsort [$r smembers setres]
502 } {995 999}
503
504 test {SUNION with non existing keys} {
505 lsort [$r sunion nokey1 set1 set2 nokey2]
506 } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
507
508 test {SDIFF with two sets} {
509 for {set i 5} {$i < 1000} {incr i} {
510 $r sadd set4 $i
511 }
512 lsort [$r sdiff set1 set4]
513 } {0 1 2 3 4}
514
515 test {SDIFF with three sets} {
516 $r sadd set5 0
517 lsort [$r sdiff set1 set4 set5]
518 } {1 2 3 4}
519
520 test {SDIFFSTORE with three sets} {
521 $r sdiffstore sres set1 set4 set5
522 lsort [$r smembers sres]
523 } {1 2 3 4}
524
525 test {SPOP basics} {
526 $r del myset
527 $r sadd myset 1
528 $r sadd myset 2
529 $r sadd myset 3
530 list [lsort [list [$r spop myset] [$r spop myset] [$r spop myset]]] [$r scard myset]
531 } {{1 2 3} 0}
532
533 test {SAVE - make sure there are all the types as values} {
534 $r lpush mysavelist hello
535 $r lpush mysavelist world
536 $r set myemptykey {}
537 $r set mynormalkey {blablablba}
538 $r zadd mytestzset a 10
539 $r zadd mytestzset b 20
540 $r zadd mytestzset c 30
541 $r save
542 } {OK}
543
544 test {Create a random list} {
545 set tosort {}
546 array set seenrand {}
547 for {set i 0} {$i < 10000} {incr i} {
548 while 1 {
549 # Make sure all the weights are different because
550 # Redis does not use a stable sort but Tcl does.
551 set rint [expr int(rand()*1000000)]
552 if {![info exists seenrand($rint)]} break
553 }
554 set seenrand($rint) x
555 $r lpush tosort $i
556 $r set weight_$i $rint
557 lappend tosort [list $i $rint]
558 }
559 set sorted [lsort -index 1 -real $tosort]
560 set res {}
561 for {set i 0} {$i < 10000} {incr i} {
562 lappend res [lindex $sorted $i 0]
563 }
564 format {}
565 } {}
566
567 test {SORT with BY against the newly created list} {
568 $r sort tosort {BY weight_*}
569 } $res
570
571 test {SORT direct, numeric, against the newly created list} {
572 $r sort tosort
573 } [lsort -integer $res]
574
575 test {SORT decreasing sort} {
576 $r sort tosort {DESC}
577 } [lsort -decreasing -integer $res]
578
579 test {SORT speed, sorting 10000 elements list using BY, 100 times} {
580 set start [clock clicks -milliseconds]
581 for {set i 0} {$i < 100} {incr i} {
582 set sorted [$r sort tosort {BY weight_* LIMIT 0 10}]
583 }
584 set elapsed [expr [clock clicks -milliseconds]-$start]
585 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
586 flush stdout
587 format {}
588 } {}
589
590 test {SORT speed, sorting 10000 elements list directly, 100 times} {
591 set start [clock clicks -milliseconds]
592 for {set i 0} {$i < 100} {incr i} {
593 set sorted [$r sort tosort {LIMIT 0 10}]
594 }
595 set elapsed [expr [clock clicks -milliseconds]-$start]
596 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
597 flush stdout
598 format {}
599 } {}
600
601 test {SORT speed, pseudo-sorting 10000 elements list, BY <const>, 100 times} {
602 set start [clock clicks -milliseconds]
603 for {set i 0} {$i < 100} {incr i} {
604 set sorted [$r sort tosort {BY nokey LIMIT 0 10}]
605 }
606 set elapsed [expr [clock clicks -milliseconds]-$start]
607 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
608 flush stdout
609 format {}
610 } {}
611
612 test {SORT regression for issue #19, sorting floats} {
613 $r flushdb
614 foreach x {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15} {
615 $r lpush mylist $x
616 }
617 $r sort mylist
618 } [lsort -real {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15}]
619
620 test {LREM, remove all the occurrences} {
621 $r flushall
622 $r rpush mylist foo
623 $r rpush mylist bar
624 $r rpush mylist foobar
625 $r rpush mylist foobared
626 $r rpush mylist zap
627 $r rpush mylist bar
628 $r rpush mylist test
629 $r rpush mylist foo
630 set res [$r lrem mylist 0 bar]
631 list [$r lrange mylist 0 -1] $res
632 } {{foo foobar foobared zap test foo} 2}
633
634 test {LREM, remove the first occurrence} {
635 set res [$r lrem mylist 1 foo]
636 list [$r lrange mylist 0 -1] $res
637 } {{foobar foobared zap test foo} 1}
638
639 test {LREM, remove non existing element} {
640 set res [$r lrem mylist 1 nosuchelement]
641 list [$r lrange mylist 0 -1] $res
642 } {{foobar foobared zap test foo} 0}
643
644 test {LREM, starting from tail with negative count} {
645 $r flushall
646 $r rpush mylist foo
647 $r rpush mylist bar
648 $r rpush mylist foobar
649 $r rpush mylist foobared
650 $r rpush mylist zap
651 $r rpush mylist bar
652 $r rpush mylist test
653 $r rpush mylist foo
654 $r rpush mylist foo
655 set res [$r lrem mylist -1 bar]
656 list [$r lrange mylist 0 -1] $res
657 } {{foo bar foobar foobared zap test foo foo} 1}
658
659 test {LREM, starting from tail with negative count (2)} {
660 set res [$r lrem mylist -2 foo]
661 list [$r lrange mylist 0 -1] $res
662 } {{foo bar foobar foobared zap test} 2}
663
664 test {LREM, deleting objects that may be encoded as integers} {
665 $r lpush myotherlist 1
666 $r lpush myotherlist 2
667 $r lpush myotherlist 3
668 $r lrem myotherlist 1 2
669 $r llen myotherlist
670 } {2}
671
672 test {MGET} {
673 $r flushall
674 $r set foo BAR
675 $r set bar FOO
676 $r mget foo bar
677 } {BAR FOO}
678
679 test {MGET against non existing key} {
680 $r mget foo baazz bar
681 } {BAR {} FOO}
682
683 test {MGET against non-string key} {
684 $r sadd myset ciao
685 $r sadd myset bau
686 $r mget foo baazz bar myset
687 } {BAR {} FOO {}}
688
689 test {RANDOMKEY} {
690 $r flushall
691 $r set foo x
692 $r set bar y
693 set foo_seen 0
694 set bar_seen 0
695 for {set i 0} {$i < 100} {incr i} {
696 set rkey [$r randomkey]
697 if {$rkey eq {foo}} {
698 set foo_seen 1
699 }
700 if {$rkey eq {bar}} {
701 set bar_seen 1
702 }
703 }
704 list $foo_seen $bar_seen
705 } {1 1}
706
707 test {RANDOMKEY against empty DB} {
708 $r flushall
709 $r randomkey
710 } {}
711
712 test {RANDOMKEY regression 1} {
713 $r flushall
714 $r set x 10
715 $r del x
716 $r randomkey
717 } {}
718
719 test {GETSET (set new value)} {
720 list [$r getset foo xyz] [$r get foo]
721 } {{} xyz}
722
723 test {GETSET (replace old value)} {
724 $r set foo bar
725 list [$r getset foo xyz] [$r get foo]
726 } {bar xyz}
727
728 test {SMOVE basics} {
729 $r sadd myset1 a
730 $r sadd myset1 b
731 $r sadd myset1 c
732 $r sadd myset2 x
733 $r sadd myset2 y
734 $r sadd myset2 z
735 $r smove myset1 myset2 a
736 list [lsort [$r smembers myset2]] [lsort [$r smembers myset1]]
737 } {{a x y z} {b c}}
738
739 test {SMOVE non existing key} {
740 list [$r smove myset1 myset2 foo] [lsort [$r smembers myset2]] [lsort [$r smembers myset1]]
741 } {0 {a x y z} {b c}}
742
743 test {SMOVE non existing src set} {
744 list [$r smove noset myset2 foo] [lsort [$r smembers myset2]]
745 } {0 {a x y z}}
746
747 test {SMOVE non existing dst set} {
748 list [$r smove myset2 myset3 y] [lsort [$r smembers myset2]] [lsort [$r smembers myset3]]
749 } {1 {a x z} y}
750
751 test {SMOVE wrong src key type} {
752 $r set x 10
753 catch {$r smove x myset2 foo} err
754 format $err
755 } {ERR*}
756
757 test {SMOVE wrong dst key type} {
758 $r set x 10
759 catch {$r smove myset2 x foo} err
760 format $err
761 } {ERR*}
762
763 test {MSET base case} {
764 $r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n"
765 $r mget x y z
766 } [list 10 {foo bar} "x x x x x x x\n\n\r\n"]
767
768 test {MSET wrong number of args} {
769 catch {$r mset x 10 y "foo bar" z} err
770 format $err
771 } {*wrong number*}
772
773 test {MSETNX with already existent key} {
774 list [$r msetnx x1 xxx y2 yyy x 20] [$r exists x1] [$r exists y2]
775 } {0 0 0}
776
777 test {MSETNX with not existing keys} {
778 list [$r msetnx x1 xxx y2 yyy] [$r get x1] [$r get y2]
779 } {1 xxx yyy}
780
781 test {ZSET basic ZADD and score update} {
782 $r zadd ztmp 10 x
783 $r zadd ztmp 20 y
784 $r zadd ztmp 30 z
785 set aux1 [$r zrange ztmp 0 -1]
786 $r zadd ztmp 1 y
787 set aux2 [$r zrange ztmp 0 -1]
788 list $aux1 $aux2
789 } {{x y z} {y x z}}
790
791 test {ZSCORE} {
792 list [$r zscore ztmp x] [$r zscore ztmp y] [$r zscore ztmp z]
793 } {10 1 30}
794
795 test {ZRANGE and ZREVRANGE} {
796 list [$r zrange ztmp 0 -1] [$r zrevrange ztmp 0 -1]
797 } {{y x z} {z x y}}
798
799 test {ZSETs stress tester - sorting is working well?} {
800 set delta 0
801 for {set test 0} {$test < 2} {incr test} {
802 unset -nocomplain auxarray
803 array set auxarray {}
804 set auxlist {}
805 $r del myzset
806 for {set i 0} {$i < 1000} {incr i} {
807 if {$test == 0} {
808 set score [expr rand()]
809 } else {
810 set score [expr int(rand()*10)]
811 }
812 set auxarray($i) $score
813 $r zadd myzset $score $i
814 # Random update
815 if {[expr rand()] < .2} {
816 set j [expr int(rand()*1000)]
817 if {$test == 0} {
818 set score [expr rand()]
819 } else {
820 set score [expr int(rand()*10)]
821 }
822 set auxarray($j) $score
823 $r zadd myzset $score $j
824 }
825 }
826 foreach {item score} [array get auxarray] {
827 lappend auxlist [list $score $item]
828 }
829 set sorted [lsort -command zlistAlikeSort $auxlist]
830 set auxlist {}
831 foreach x $sorted {
832 lappend auxlist [lindex $x 1]
833 }
834 set fromredis [$r zrange myzset 0 -1]
835 set delta 0
836 for {set i 0} {$i < [llength $fromredis]} {incr i} {
837 if {[lindex $fromredis $i] != [lindex $auxlist $i]} {
838 incr delta
839 }
840 }
841 }
842 format $delta
843 } {0}
844
845 test {ZSETs skiplist implementation backlink consistency test} {
846 set diff 0
847 set elements 10000
848 for {set j 0} {$j < $elements} {incr j} {
849 $r zadd myzset [expr rand()] "Element-$j"
850 $r zrem myzset "Element-[expr int(rand()*$elements)]"
851 }
852 set l1 [$r zrange myzset 0 -1]
853 set l2 [$r zrevrange myzset 0 -1]
854 for {set j 0} {$j < [llength $l1]} {incr j} {
855 if {[lindex $l1 $j] ne [lindex $l2 end-$j]} {
856 incr diff
857 }
858 }
859 format $diff
860 } {0}
861
862 foreach fuzztype {binary alpha compr} {
863 test "FUZZ stresser with data model $fuzztype" {
864 set err 0
865 for {set i 0} {$i < 10000} {incr i} {
866 set fuzz [randstring 0 512 $fuzztype]
867 $r set foo $fuzz
868 set got [$r get foo]
869 if {$got ne $fuzz} {
870 set err [list $fuzz $got]
871 break
872 }
873 }
874 set _ $err
875 } {0}
876 }
877
878 # Leave the user with a clean DB before to exit
879 test {FLUSHALL} {
880 $r flushall
881 $r dbsize
882 } {0}
883
884 puts "\n[expr $::passed+$::failed] tests, $::passed passed, $::failed failed"
885 if {$::failed > 0} {
886 puts "\n*** WARNING!!! $::failed FAILED TESTS ***\n"
887 }
888 close $fd
889 }
890
891 proc stress {} {
892 set r [redis]
893 $r flushall
894 while 1 {
895 set randkey [expr int(rand()*10000)]
896 set randval [expr int(rand()*10000)]
897 set randidx0 [expr int(rand()*10)]
898 set randidx1 [expr int(rand()*10)]
899 set cmd [expr int(rand()*10)]
900 catch {
901 if {$cmd == 0} {$r set $randkey $randval}
902 if {$cmd == 1} {$r get $randkey}
903 if {$cmd == 2} {$r incr $randkey}
904 if {$cmd == 3} {$r lpush $randkey $randval}
905 if {$cmd == 4} {$r rpop $randkey}
906 if {$cmd == 5} {$r del $randkey}
907 if {$cmd == 6} {$r lrange $randkey $randidx0 $randidx1}
908 if {$cmd == 7} {$r ltrim $randkey $randidx0 $randidx1}
909 if {$cmd == 8} {$r lindex $randkey $randidx0}
910 if {$cmd == 9} {$r lset $randkey $randidx0 $randval}
911 }
912 flush stdout
913 }
914 $r close
915 }
916
917 if {[llength $argv] == 0} {
918 main 127.0.0.1 6379
919 } elseif {[llength $argv] == 1 && [lindex $argv 0] eq {stress}} {
920 stress
921 } else {
922 main [lindex $argv 0] [lindex $argv 1]
923 }