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