1 # TODO # test pipelining 
   3 source client-libraries
/tcl
/redis.tcl
 
   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 main 
{server port
} { 
  22     set r 
[redis 
$server $port] 
  25     # The following AUTH test should be enabled only when requirepass 
  26     # <PASSWORD> is set in redis.conf and redis-server was started with 
  27     # redis.conf as the first argument.   
  29     #test {AUTH with requirepass in redis.conf} { 
  33     test 
{DEL all keys to start with a clean DB
} { 
  34         foreach key 
[$r keys 
*] {$r del 
$key} 
  38     test 
{SET and GET an item
} { 
  43     test 
{DEL against a single item
} { 
  48     test 
{KEYS with pattern
} { 
  49         foreach key 
{key_x key_y key_z foo_a foo_b foo_c
} { 
  55     test 
{KEYS to get all keys
} { 
  57     } {foo_a foo_b foo_c key_x key_y key_z
} 
  64         foreach key 
[$r keys 
*] {$r del 
$key} 
  68     test 
{Very big payload in GET
/SET
} { 
  69         set buf 
[string repeat 
"abcd" 1000000] 
  72     } [string repeat 
"abcd" 1000000] 
  74     test 
{SET 
10000 numeric keys and access all them in reverse order
} { 
  75         for {set x 
0} {$x < 10000} {incr x
} { 
  79         for {set x 
9999} {$x >= 0} {incr x 
-1} { 
  85     test 
{DBSIZE should be 
10001 now
} { 
  89     test 
{INCR against non existing key
} { 
  91         append res 
[$r incr novar
] 
  92         append res 
[$r get novar
] 
  95     test 
{INCR against key created by 
incr itself
} { 
  99     test 
{INCR against key originally 
set with SET
} { 
 104     test 
{SETNX target key missing
} { 
 105         $r setnx novar2 foobared
 
 109     test 
{SETNX target key exists
} { 
 110         $r setnx novar2 blabla
 
 117         append res 
[$r exists newkey
] 
 119         append res 
[$r exists newkey
] 
 122     test 
{Zero length value in key. SET
/GET
/EXISTS
} { 
 124         set res 
[$r get emptykey
] 
 125         append res 
[$r exists emptykey
] 
 127         append res 
[$r exists emptykey
] 
 130     test 
{Commands pipelining
} { 
 132         puts -nonewline $fd "SET k1 4\r\nxyzk\r\nGET k1\r\nPING\r\n" 
 135         append res 
[string match OK
* [::redis::redis_read_reply $fd]] 
 136         append res 
[::redis::redis_read_reply $fd] 
 137         append res 
[string match PONG
* [::redis::redis_read_reply $fd]] 
 141     test 
{Non existing command
} { 
 142         catch {$r foobaredcommand
} err
 
 143         string match ERR
* $err 
 146     test 
{Basic LPUSH
, RPUSH
, LLENGTH
, LINDEX
} { 
 150         set res 
[$r llen mylist
] 
 151         append res 
[$r lindex mylist 
0] 
 152         append res 
[$r lindex mylist 
1] 
 153         append res 
[$r lindex mylist 
2] 
 161     test 
{Create a long 
list and check every single element with LINDEX
} { 
 163         for {set i 
0} {$i < 1000} {incr i
} { 
 166         for {set i 
0} {$i < 1000} {incr i
} { 
 167             if {[$r lindex mylist 
$i] eq 
$i} {incr ok
} 
 168             if {[$r lindex mylist 
[expr (-$i)-1]] eq 
[expr 999-$i]} { 
 175     test 
{Test elements with LINDEX in random access
} { 
 177         for {set i 
0} {$i < 1000} {incr i
} { 
 178             set rint 
[expr int
(rand
()*1000)] 
 179             if {[$r lindex mylist 
$rint] eq 
$rint} {incr ok
} 
 180             if {[$r lindex mylist 
[expr (-$rint)-1]] eq 
[expr 999-$rint]} { 
 187     test 
{LLEN against non-list value 
error} { 
 190         catch {$r llen mylist
} err
 
 194     test 
{LINDEX against non-list value 
error} { 
 195         catch {$r lindex mylist 
0} err
 
 199     test 
{LPUSH against non-list value 
error} { 
 200         catch {$r lpush mylist 
0} err
 
 204     test 
{RPUSH against non-list value 
error} { 
 205         catch {$r rpush mylist 
0} err
 
 209     test 
{RENAME basic usage
} { 
 211         $r rename mykey mykey1
 
 212         $r rename mykey1 mykey2
 
 216     test 
{RENAME 
source key should no longer exist
} { 
 220     test 
{RENAME against already existing key
} { 
 223         $r rename mykey2 mykey
 
 224         set res 
[$r get mykey
] 
 225         append res 
[$r exists mykey2
] 
 228     test 
{RENAMENX basic usage
} { 
 232         $r renamenx mykey mykey2
 
 233         set res 
[$r get mykey2
] 
 234         append res 
[$r exists mykey
] 
 237     test 
{RENAMENX against already existing key
} { 
 240         $r renamenx mykey mykey2
 
 243     test 
{RENAMENX against already existing key 
(2)} { 
 244         set res 
[$r get mykey
] 
 245         append res 
[$r get mykey2
] 
 248     test 
{RENAME against non existing 
source key
} { 
 249         catch {$r rename nokey foobar
} err
 
 253     test 
{RENAME where 
source and dest key is the same
} { 
 254         catch {$r rename mykey mykey
} err
 
 258     test 
{DEL all keys again 
(DB 
0)} { 
 259         foreach key 
[$r keys 
*] { 
 265     test 
{DEL all keys again 
(DB 
1)} { 
 267         foreach key 
[$r keys 
*] { 
 275     test 
{MOVE basic usage
} { 
 279         lappend res 
[$r exists mykey
] 
 280         lappend res 
[$r dbsize
] 
 282         lappend res 
[$r get mykey
] 
 283         lappend res 
[$r dbsize
] 
 286     } [list 0 0 foobar 
1] 
 288     test 
{MOVE against key existing in the target DB
} { 
 293     test 
{SET
/GET keys in different DBs
} { 
 301         lappend res 
[$r get a
] 
 302         lappend res 
[$r get b
] 
 304         lappend res 
[$r get a
] 
 305         lappend res 
[$r get b
] 
 308     } {hello world foo bared
} 
 310     test 
{Basic LPOP
/RPOP
} { 
 315         list [$r lpop mylist
] [$r rpop mylist
] [$r lpop mylist
] [$r llen mylist
] 
 318     test 
{LPOP
/RPOP against empty 
list} { 
 322     test 
{LPOP against non 
list value
} { 
 324         catch {$r lpop notalist
} err
 
 328     test 
{Mass LPUSH
/LPOP
} { 
 330         for {set i 
0} {$i < 1000} {incr i
} { 
 335         for {set i 
0} {$i < 500} {incr i
} { 
 336             incr sum2 
[$r lpop mylist
] 
 337             incr sum2 
[$r rpop mylist
] 
 342     test 
{LRANGE basics
} { 
 343         for {set i 
0} {$i < 10} {incr i
} { 
 346         list [$r lrange mylist 
1 -2] \ 
 347                 [$r lrange mylist 
-3 -1] \ 
 348                 [$r lrange mylist 
4 4] 
 349     } {{1 2 3 4 5 6 7 8} {7 8 9} 4} 
 351     test 
{LRANGE inverted indexes
} { 
 355     test 
{LRANGE out of range indexes including the full 
list} { 
 356         $r lrange mylist 
-1000 1000 
 357     } {0 1 2 3 4 5 6 7 8 9} 
 359     test 
{LRANGE against non existing key
} { 
 360         $r lrange nosuchkey 
0 1 
 363     test 
{LTRIM basics
} { 
 365         for {set i 
0} {$i < 100} {incr i
} { 
 369         $r lrange mylist 
0 -1 
 374         $r lset mylist 
-1 bar
 
 375         $r lrange mylist 
0 -1 
 378     test 
{LSET out of range index
} { 
 379         catch {$r lset mylist 
10 foo
} err
 
 383     test 
{LSET against non existing key
} { 
 384         catch {$r lset nosuchkey 
10 foo
} err
 
 388     test 
{LSET against non 
list value
} { 
 390         catch {$r lset nolist 
0 foo
} err
 
 394     test 
{SADD
, SCARD
, SISMEMBER
, SMEMBERS basics
} { 
 397         list [$r scard myset
] [$r sismember myset foo
] \ 
 398             [$r sismember myset bar
] [$r sismember myset bla
] \ 
 399             [lsort [$r smembers myset
]] 
 400     } {2 1 1 0 {bar foo
}} 
 402     test 
{SADD adding the same element multiple times
} { 
 409     test 
{SADD against non 
set} { 
 410         catch {$r sadd mylist foo
} err
 
 417         lsort [$r smembers myset
] 
 420     test 
{Mass SADD and SINTER with two sets
} { 
 421         for {set i 
0} {$i < 1000} {incr i
} { 
 423             $r sadd set2 
[expr $i+995] 
 425         lsort [$r sinter set1 set2
] 
 426     } {995 996 997 998 999} 
 428     test 
{SINTERSTORE with two sets
} { 
 429         $r sinterstore setres set1 set2
 
 430         lsort [$r smembers setres
] 
 431     } {995 996 997 998 999} 
 433     test 
{SINTER against three sets
} { 
 438         lsort [$r sinter set1 set2 set3
] 
 441     test 
{SINTERSTORE with three sets
} { 
 442         $r sinterstore setres set1 set2 set3
 
 443         lsort [$r smembers setres
] 
 446     test 
{SAVE 
- make sure there are all the types as values
} { 
 447         $r lpush mysavelist hello
 
 448         $r lpush mysavelist world
 
 450         $r set mynormalkey 
{blablablba
} 
 454     test 
{Create a random 
list} { 
 456         array set seenrand 
{} 
 457         for {set i 
0} {$i < 10000} {incr i
} { 
 459                 # Make sure all the weights are different because 
 460                 # Redis does not use a stable sort but Tcl does. 
 461                 set rint 
[expr int
(rand
()*1000000)] 
 462                 if {![info exists seenrand
($rint)]} break 
 464             set seenrand
($rint) x
 
 466             $r set weight_
$i $rint 
 467             lappend tosort 
[list $i $rint] 
 469         set sorted 
[lsort -index 1 -real $tosort] 
 471         for {set i 
0} {$i < 10000} {incr i
} { 
 472             lappend res 
[lindex $sorted $i 0] 
 477     test 
{SORT with BY against the newly created 
list} { 
 478         $r sort tosort 
{BY weight_
*} 
 481     test 
{SORT direct
, numeric
, against the newly created 
list} { 
 483     } [lsort -integer $res] 
 485     test 
{SORT decreasing sort
} { 
 486         $r sort tosort 
{DESC
} 
 487     } [lsort -decreasing -integer $res] 
 489     test 
{SORT speed
, sorting 
10000 elements 
list using BY
, 100 times
} { 
 490         set start 
[clock clicks 
-milliseconds] 
 491         for {set i 
0} {$i < 100} {incr i
} { 
 492             set sorted 
[$r sort tosort 
{BY weight_
* LIMIT 
0 10}] 
 494         set elapsed 
[expr [clock clicks 
-milliseconds]-$start] 
 495         puts -nonewline "\n  Average time to sort: [expr double($elapsed)/100] milliseconds " 
 500     test 
{SORT speed
, sorting 
10000 elements 
list directly
, 100 times
} { 
 501         set start 
[clock clicks 
-milliseconds] 
 502         for {set i 
0} {$i < 100} {incr i
} { 
 503             set sorted 
[$r sort tosort 
{LIMIT 
0 10}] 
 505         set elapsed 
[expr [clock clicks 
-milliseconds]-$start] 
 506         puts -nonewline "\n  Average time to sort: [expr double($elapsed)/100] milliseconds " 
 511     test 
{SORT speed
, pseudo-sorting 
10000 elements 
list, BY 
<const
>, 100 times
} { 
 512         set start 
[clock clicks 
-milliseconds] 
 513         for {set i 
0} {$i < 100} {incr i
} { 
 514             set sorted 
[$r sort tosort 
{BY nokey LIMIT 
0 10}] 
 516         set elapsed 
[expr [clock clicks 
-milliseconds]-$start] 
 517         puts -nonewline "\n  Average time to sort: [expr double($elapsed)/100] milliseconds " 
 522     test 
{SORT regression 
for issue 
#19, sorting floats} { 
 524         foreach x 
{1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15} { 
 528     } [lsort -real {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15}] 
 530     test 
{LREM
, remove all the occurrences
} { 
 534         $r rpush mylist foobar
 
 535         $r rpush mylist foobared
 
 540         set res 
[$r lrem mylist 
0 bar
] 
 541         list [$r lrange mylist 
0 -1] $res 
 542     } {{foo foobar foobared zap test foo
} 2} 
 544     test 
{LREM
, remove the first occurrence
} { 
 545         set res 
[$r lrem mylist 
1 foo
] 
 546         list [$r lrange mylist 
0 -1] $res 
 547     } {{foobar foobared zap test foo
} 1} 
 549     test 
{LREM
, remove non existing element
} { 
 550         set res 
[$r lrem mylist 
1 nosuchelement
] 
 551         list [$r lrange mylist 
0 -1] $res 
 552     } {{foobar foobared zap test foo
} 0} 
 554     test 
{LREM
, starting from tail with negative count
} { 
 558         $r rpush mylist foobar
 
 559         $r rpush mylist foobared
 
 565         set res 
[$r lrem mylist 
-1 bar
] 
 566         list [$r lrange mylist 
0 -1] $res 
 567     } {{foo bar foobar foobared zap test foo foo
} 1} 
 569     test 
{LREM
, starting from tail with negative count 
(2)} { 
 570         set res 
[$r lrem mylist 
-2 foo
] 
 571         list [$r lrange mylist 
0 -1] $res 
 572     } {{foo bar foobar foobared zap test
} 2} 
 581     test 
{MGET against non existing key
} { 
 582         $r mget foo baazz bar
 
 585     test 
{MGET against non-string key
} { 
 588         $r mget foo baazz bar myset
 
 591     # Leave the user with a clean DB before to exit 
 597     puts "\n[expr $::passed+$::failed] tests, $::passed passed, $::failed failed" 
 599         puts "\n*** WARNING!!! $::failed FAILED TESTS ***\n" 
 608         set randkey 
[expr int
(rand
()*10000)] 
 609         set randval 
[expr int
(rand
()*10000)] 
 610         set randidx0 
[expr int
(rand
()*10)] 
 611         set randidx1 
[expr int
(rand
()*10)] 
 612         set cmd 
[expr int
(rand
()*10)] 
 614             if {$cmd == 0} {$r set $randkey $randval} 
 615             if {$cmd == 1} {$r get 
$randkey} 
 616             if {$cmd == 2} {$r incr $randkey} 
 617             if {$cmd == 3} {$r lpush 
$randkey $randval} 
 618             if {$cmd == 4} {$r rpop 
$randkey} 
 619             if {$cmd == 5} {$r del 
$randkey} 
 620             if {$cmd == 6} {$r lrange $randkey $randidx0 $randidx1} 
 621             if {$cmd == 7} {$r ltrim 
$randkey $randidx0 $randidx1} 
 622             if {$cmd == 8} {$r lindex $randkey $randidx0} 
 623             if {$cmd == 9} {$r lset $randkey $randidx0 $randval} 
 630 if {[llength $argv] == 0} { 
 632 } elseif 
{[llength $argv] == 1 && [lindex $argv 0] eq 
{stress
}} { 
 635     main 
[lindex $argv 0] [lindex $argv 1]