1 # TODO # test pipelining 
   8 proc test 
{name code okpattern
} { 
   9     puts -nonewline [format "%-70s " $name] 
  11     set retval 
[uplevel 1 $code] 
  12     if {$okpattern eq 
$retval || 
[string match 
$okpattern $retval]} { 
  16         puts "!! ERROR expected\n'$okpattern'\nbut got\n'$retval'" 
  21 proc randstring 
{min max 
{type 
binary}} { 
  22     set len 
[expr {$min+int
(rand
()*($max-$min+1))}] 
  24     if {$type eq 
{binary}} { 
  27     } elseif 
{$type eq 
{alpha
}} { 
  30     } elseif 
{$type eq 
{compr
}} { 
  35         append output 
[format "%c" [expr {$minval+int
(rand
()*($maxval-$minval+1))}]] 
  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] 
  48 proc main 
{server port
} { 
  49     set r 
[redis 
$server $port] 
  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.   
  56     #test {AUTH with requirepass in redis.conf} { 
  60     test 
{DEL all keys to start with a clean DB
} { 
  61         foreach key 
[$r keys 
*] {$r del 
$key} 
  65     test 
{SET and GET an item
} { 
  70     test 
{DEL against a single item
} { 
  79         list [$r del foo1 foo2 foo3 foo4
] [$r mget foo1 foo2 foo3
] 
  82     test 
{KEYS with pattern
} { 
  83         foreach key 
{key_x key_y key_z foo_a foo_b foo_c
} { 
  89     test 
{KEYS to get all keys
} { 
  91     } {foo_a foo_b foo_c key_x key_y key_z
} 
  98         foreach key 
[$r keys 
*] {$r del 
$key} 
 102     test 
{Very big payload in GET
/SET
} { 
 103         set buf 
[string repeat 
"abcd" 1000000] 
 106     } [string repeat 
"abcd" 1000000] 
 108     test 
{SET 
10000 numeric keys and access all them in reverse order
} { 
 109         for {set x 
0} {$x < 10000} {incr x
} { 
 113         for {set x 
9999} {$x >= 0} {incr x 
-1} { 
 119     test 
{DBSIZE should be 
10001 now
} { 
 123     test 
{INCR against non existing key
} { 
 125         append res 
[$r incr novar
] 
 126         append res 
[$r get novar
] 
 129     test 
{INCR against key created by 
incr itself
} { 
 133     test 
{INCR against key originally 
set with SET
} { 
 138     test 
{INCR over 
32bit value
} { 
 139         $r set novar 
17179869184 
 143     test 
{INCRBY over 
32bit value with over 
32bit increment
} { 
 144         $r set novar 
17179869184 
 145         $r incrby novar 
17179869184 
 148     test 
{DECRBY over 
32bit value with over 
32bit increment
, negative res
} { 
 149         $r set novar 
17179869184 
 150         $r decrby novar 
17179869185 
 153     test 
{SETNX target key missing
} { 
 154         $r setnx novar2 foobared
 
 158     test 
{SETNX target key exists
} { 
 159         $r setnx novar2 blabla
 
 166         append res 
[$r exists newkey
] 
 168         append res 
[$r exists newkey
] 
 171     test 
{Zero length value in key. SET
/GET
/EXISTS
} { 
 173         set res 
[$r get emptykey
] 
 174         append res 
[$r exists emptykey
] 
 176         append res 
[$r exists emptykey
] 
 179     test 
{Commands pipelining
} { 
 181         puts -nonewline $fd "SET k1 4\r\nxyzk\r\nGET k1\r\nPING\r\n" 
 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]] 
 190     test 
{Non existing command
} { 
 191         catch {$r foobaredcommand
} err
 
 192         string match ERR
* $err 
 195     test 
{Basic LPUSH
, RPUSH
, LLENGTH
, LINDEX
} { 
 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] 
 210     test 
{Create a long 
list and check every single element with LINDEX
} { 
 212         for {set i 
0} {$i < 1000} {incr i
} { 
 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]} { 
 224     test 
{Test elements with LINDEX in random access
} { 
 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]} { 
 236     test 
{LLEN against non-list value 
error} { 
 239         catch {$r llen mylist
} err
 
 243     test 
{LINDEX against non-list value 
error} { 
 244         catch {$r lindex mylist 
0} err
 
 248     test 
{LPUSH against non-list value 
error} { 
 249         catch {$r lpush mylist 
0} err
 
 253     test 
{RPUSH against non-list value 
error} { 
 254         catch {$r rpush mylist 
0} err
 
 258     test 
{RENAME basic usage
} { 
 260         $r rename mykey mykey1
 
 261         $r rename mykey1 mykey2
 
 265     test 
{RENAME 
source key should no longer exist
} { 
 269     test 
{RENAME against already existing key
} { 
 272         $r rename mykey2 mykey
 
 273         set res 
[$r get mykey
] 
 274         append res 
[$r exists mykey2
] 
 277     test 
{RENAMENX basic usage
} { 
 281         $r renamenx mykey mykey2
 
 282         set res 
[$r get mykey2
] 
 283         append res 
[$r exists mykey
] 
 286     test 
{RENAMENX against already existing key
} { 
 289         $r renamenx mykey mykey2
 
 292     test 
{RENAMENX against already existing key 
(2)} { 
 293         set res 
[$r get mykey
] 
 294         append res 
[$r get mykey2
] 
 297     test 
{RENAME against non existing 
source key
} { 
 298         catch {$r rename nokey foobar
} err
 
 302     test 
{RENAME where 
source and dest key is the same
} { 
 303         catch {$r rename mykey mykey
} err
 
 307     test 
{DEL all keys again 
(DB 
0)} { 
 308         foreach key 
[$r keys 
*] { 
 314     test 
{DEL all keys again 
(DB 
1)} { 
 316         foreach key 
[$r keys 
*] { 
 324     test 
{MOVE basic usage
} { 
 328         lappend res 
[$r exists mykey
] 
 329         lappend res 
[$r dbsize
] 
 331         lappend res 
[$r get mykey
] 
 332         lappend res 
[$r dbsize
] 
 335     } [list 0 0 foobar 
1] 
 337     test 
{MOVE against key existing in the target DB
} { 
 342     test 
{SET
/GET keys in different DBs
} { 
 350         lappend res 
[$r get a
] 
 351         lappend res 
[$r get b
] 
 353         lappend res 
[$r get a
] 
 354         lappend res 
[$r get b
] 
 357     } {hello world foo bared
} 
 359     test 
{Basic LPOP
/RPOP
} { 
 364         list [$r lpop mylist
] [$r rpop mylist
] [$r lpop mylist
] [$r llen mylist
] 
 367     test 
{LPOP
/RPOP against empty 
list} { 
 371     test 
{LPOP against non 
list value
} { 
 373         catch {$r lpop notalist
} err
 
 377     test 
{Mass LPUSH
/LPOP
} { 
 379         for {set i 
0} {$i < 1000} {incr i
} { 
 384         for {set i 
0} {$i < 500} {incr i
} { 
 385             incr sum2 
[$r lpop mylist
] 
 386             incr sum2 
[$r rpop mylist
] 
 391     test 
{LRANGE basics
} { 
 392         for {set i 
0} {$i < 10} {incr i
} { 
 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} 
 400     test 
{LRANGE inverted indexes
} { 
 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} 
 408     test 
{LRANGE against non existing key
} { 
 409         $r lrange nosuchkey 
0 1 
 412     test 
{LTRIM basics
} { 
 414         for {set i 
0} {$i < 100} {incr i
} { 
 418         $r lrange mylist 
0 -1 
 423         $r lset mylist 
-1 bar
 
 424         $r lrange mylist 
0 -1 
 427     test 
{LSET out of range index
} { 
 428         catch {$r lset mylist 
10 foo
} err
 
 432     test 
{LSET against non existing key
} { 
 433         catch {$r lset nosuchkey 
10 foo
} err
 
 437     test 
{LSET against non 
list value
} { 
 439         catch {$r lset nolist 
0 foo
} err
 
 443     test 
{SADD
, SCARD
, SISMEMBER
, SMEMBERS basics
} { 
 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
}} 
 451     test 
{SADD adding the same element multiple times
} { 
 458     test 
{SADD against non 
set} { 
 459         catch {$r sadd mylist foo
} err
 
 466         lsort [$r smembers myset
] 
 469     test 
{Mass SADD and SINTER with two sets
} { 
 470         for {set i 
0} {$i < 1000} {incr i
} { 
 472             $r sadd set2 
[expr $i+995] 
 474         lsort [$r sinter set1 set2
] 
 475     } {995 996 997 998 999} 
 477     test 
{SUNION with two sets
} { 
 478         lsort [$r sunion set1 set2
] 
 479     } [lsort -uniq "[$r smembers set1] [$r smembers set2]"] 
 481     test 
{SINTERSTORE with two sets
} { 
 482         $r sinterstore setres set1 set2
 
 483         lsort [$r smembers setres
] 
 484     } {995 996 997 998 999} 
 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]"] 
 491     test 
{SINTER against three sets
} { 
 496         lsort [$r sinter set1 set2 set3
] 
 499     test 
{SINTERSTORE with three sets
} { 
 500         $r sinterstore setres set1 set2 set3
 
 501         lsort [$r smembers setres
] 
 504     test 
{SUNION with non existing keys
} { 
 505         lsort [$r sunion nokey1 set1 set2 nokey2
] 
 506     } [lsort -uniq "[$r smembers set1] [$r smembers set2]"] 
 508     test 
{SDIFF with two sets
} { 
 509         for {set i 
5} {$i < 1000} {incr i
} { 
 512         lsort [$r sdiff set1 set4
] 
 515     test 
{SDIFF with three sets
} { 
 517         lsort [$r sdiff set1 set4 set5
] 
 520     test 
{SDIFFSTORE with three sets
} { 
 521         $r sdiffstore sres set1 set4 set5
 
 522         lsort [$r smembers sres
] 
 530         list [lsort [list [$r spop myset
] [$r spop myset
] [$r spop myset
]]] [$r scard myset
] 
 533     test 
{SAVE 
- make sure there are all the types as values
} { 
 534         $r lpush mysavelist hello
 
 535         $r lpush mysavelist world
 
 537         $r set mynormalkey 
{blablablba
} 
 538         $r zadd mytestzset a 
10 
 539         $r zadd mytestzset b 
20 
 540         $r zadd mytestzset c 
30 
 544     test 
{Create a random 
list} { 
 546         array set seenrand 
{} 
 547         for {set i 
0} {$i < 10000} {incr i
} { 
 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 
 554             set seenrand
($rint) x
 
 556             $r set weight_
$i $rint 
 557             lappend tosort 
[list $i $rint] 
 559         set sorted 
[lsort -index 1 -real $tosort] 
 561         for {set i 
0} {$i < 10000} {incr i
} { 
 562             lappend res 
[lindex $sorted $i 0] 
 567     test 
{SORT with BY against the newly created 
list} { 
 568         $r sort tosort 
{BY weight_
*} 
 571     test 
{SORT direct
, numeric
, against the newly created 
list} { 
 573     } [lsort -integer $res] 
 575     test 
{SORT decreasing sort
} { 
 576         $r sort tosort 
{DESC
} 
 577     } [lsort -decreasing -integer $res] 
 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}] 
 584         set elapsed 
[expr [clock clicks 
-milliseconds]-$start] 
 585         puts -nonewline "\n  Average time to sort: [expr double($elapsed)/100] milliseconds " 
 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}] 
 595         set elapsed 
[expr [clock clicks 
-milliseconds]-$start] 
 596         puts -nonewline "\n  Average time to sort: [expr double($elapsed)/100] milliseconds " 
 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}] 
 606         set elapsed 
[expr [clock clicks 
-milliseconds]-$start] 
 607         puts -nonewline "\n  Average time to sort: [expr double($elapsed)/100] milliseconds " 
 612     test 
{SORT regression 
for issue 
#19, sorting floats} { 
 614         foreach x 
{1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15} { 
 618     } [lsort -real {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15}] 
 620     test 
{LREM
, remove all the occurrences
} { 
 624         $r rpush mylist foobar
 
 625         $r rpush mylist foobared
 
 630         set res 
[$r lrem mylist 
0 bar
] 
 631         list [$r lrange mylist 
0 -1] $res 
 632     } {{foo foobar foobared zap test foo
} 2} 
 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} 
 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} 
 644     test 
{LREM
, starting from tail with negative count
} { 
 648         $r rpush mylist foobar
 
 649         $r rpush mylist foobared
 
 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} 
 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} 
 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 
 679     test 
{MGET against non existing key
} { 
 680         $r mget foo baazz bar
 
 683     test 
{MGET against non-string key
} { 
 686         $r mget foo baazz bar myset
 
 695         for {set i 
0} {$i < 100} {incr i
} { 
 696             set rkey 
[$r randomkey
] 
 697             if {$rkey eq 
{foo
}} { 
 700             if {$rkey eq 
{bar
}} { 
 704         list $foo_seen $bar_seen 
 707     test 
{RANDOMKEY against empty DB
} { 
 712     test 
{RANDOMKEY regression 
1} { 
 719     test 
{GETSET 
(set new value
)} { 
 720         list [$r getset foo xyz
] [$r get foo
] 
 723     test 
{GETSET 
(replace old value
)} { 
 725         list [$r getset foo xyz
] [$r get foo
] 
 728     test 
{SMOVE basics
} { 
 735         $r smove myset1 myset2 a
 
 736         list [lsort [$r smembers myset2
]] [lsort [$r smembers myset1
]] 
 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
}} 
 743     test 
{SMOVE non existing src 
set} { 
 744         list [$r smove noset myset2 foo
] [lsort [$r smembers myset2
]] 
 747     test 
{SMOVE non existing dst 
set} { 
 748         list [$r smove myset2 myset3 y
] [lsort [$r smembers myset2
]] [lsort [$r smembers myset3
]] 
 751     test 
{SMOVE wrong src key type
} { 
 753         catch {$r smove x myset2 foo
} err
 
 757     test 
{SMOVE wrong dst key type
} { 
 759         catch {$r smove myset2 x foo
} err
 
 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" 
 766     } [list 10 {foo bar
} "x x x x x x x\n\n\r\n"] 
 768     test 
{MSET wrong number of args
} { 
 769         catch {$r mset x 
10 y 
"foo bar" z
} err
 
 773     test 
{MSETNX with already existent key
} { 
 774         list [$r msetnx x1 xxx y2 yyy x 
20] [$r exists x1
] [$r exists y2
] 
 777     test 
{MSETNX with not existing keys
} { 
 778         list [$r msetnx x1 xxx y2 yyy
] [$r get x1
] [$r get y2
] 
 781     test 
{ZSET basic ZADD and score 
update} { 
 785         set aux1 
[$r zrange ztmp 
0 -1] 
 787         set aux2 
[$r zrange ztmp 
0 -1] 
 794         for {set i 
0} {$i < 1000} {incr i
} { 
 795             set score 
[expr rand
()] 
 797             $r zadd zscoretest 
$score $i 
 799         for {set i 
0} {$i < 1000} {incr i
} { 
 800             if {[$r zscore zscoretest 
$i] != [lindex $aux $i]} { 
 801                 set err 
"Expected score was [lindex $aux $i] but got [$r zscore zscoretest $i] for element $i" 
 808     test 
{ZRANGE and ZREVRANGE
} { 
 809         list [$r zrange ztmp 
0 -1] [$r zrevrange ztmp 
0 -1] 
 812     test 
{ZSETs stress tester 
- sorting is working well?
} { 
 814         for {set test 
0} {$test < 2} {incr test
} { 
 815             unset -nocomplain auxarray
 
 816             array set auxarray 
{} 
 819             for {set i 
0} {$i < 1000} {incr i
} { 
 821                     set score 
[expr rand
()] 
 823                     set score 
[expr int
(rand
()*10)] 
 825                 set auxarray
($i) $score 
 826                 $r zadd myzset 
$score $i 
 828                 if {[expr rand
()] < .2} { 
 829                     set j 
[expr int
(rand
()*1000)] 
 831                         set score 
[expr rand
()] 
 833                         set score 
[expr int
(rand
()*10)] 
 835                     set auxarray
($j) $score 
 836                     $r zadd myzset 
$score $j 
 839             foreach {item score
} [array get auxarray
] { 
 840                 lappend auxlist 
[list $score $item] 
 842             set sorted 
[lsort -command zlistAlikeSort 
$auxlist] 
 845                 lappend auxlist 
[lindex $x 1] 
 847             set fromredis 
[$r zrange myzset 
0 -1] 
 849             for {set i 
0} {$i < [llength $fromredis]} {incr i
} { 
 850                 if {[lindex $fromredis $i] != [lindex $auxlist $i]} { 
 858     test 
{ZSETs skiplist implementation backlink consistency test
} { 
 861         for {set j 
0} {$j < $elements} {incr j
} { 
 862             $r zadd myzset 
[expr rand
()] "Element-$j" 
 863             $r zrem myzset 
"Element-[expr int(rand()*$elements)]" 
 865         set l1 
[$r zrange myzset 
0 -1] 
 866         set l2 
[$r zrevrange myzset 
0 -1] 
 867         for {set j 
0} {$j < [llength $l1]} {incr j
} { 
 868             if {[lindex $l1 $j] ne 
[lindex $l2 end-
$j]} { 
 875     foreach fuzztype 
{binary alpha compr
} { 
 876         test 
"FUZZ stresser with data model $fuzztype" { 
 878             for {set i 
0} {$i < 10000} {incr i
} { 
 879                 set fuzz 
[randstring 
0 512 $fuzztype] 
 883                     set err 
[list $fuzz $got] 
 891     # Leave the user with a clean DB before to exit 
 897     puts "\n[expr $::passed+$::failed] tests, $::passed passed, $::failed failed" 
 899         puts "\n*** WARNING!!! $::failed FAILED TESTS ***\n" 
 908         set randkey 
[expr int
(rand
()*10000)] 
 909         set randval 
[expr int
(rand
()*10000)] 
 910         set randidx0 
[expr int
(rand
()*10)] 
 911         set randidx1 
[expr int
(rand
()*10)] 
 912         set cmd 
[expr int
(rand
()*10)] 
 914             if {$cmd == 0} {$r set $randkey $randval} 
 915             if {$cmd == 1} {$r get 
$randkey} 
 916             if {$cmd == 2} {$r incr $randkey} 
 917             if {$cmd == 3} {$r lpush 
$randkey $randval} 
 918             if {$cmd == 4} {$r rpop 
$randkey} 
 919             if {$cmd == 5} {$r del 
$randkey} 
 920             if {$cmd == 6} {$r lrange $randkey $randidx0 $randidx1} 
 921             if {$cmd == 7} {$r ltrim 
$randkey $randidx0 $randidx1} 
 922             if {$cmd == 8} {$r lindex $randkey $randidx0} 
 923             if {$cmd == 9} {$r lset $randkey $randidx0 $randval} 
 930 if {[llength $argv] == 0} { 
 932 } elseif 
{[llength $argv] == 1 && [lindex $argv 0] eq 
{stress
}} { 
 935     main 
[lindex $argv 0] [lindex $argv 1]