+ test {RANDOMKEY regression 1} {
+ $r flushdb
+ $r set x 10
+ $r del x
+ $r randomkey
+ } {}
+
+ test {GETSET (set new value)} {
+ list [$r getset foo xyz] [$r get foo]
+ } {{} xyz}
+
+ test {GETSET (replace old value)} {
+ $r set foo bar
+ list [$r getset foo xyz] [$r get foo]
+ } {bar xyz}
+
+ test {SMOVE basics} {
+ $r sadd myset1 a
+ $r sadd myset1 b
+ $r sadd myset1 c
+ $r sadd myset2 x
+ $r sadd myset2 y
+ $r sadd myset2 z
+ $r smove myset1 myset2 a
+ list [lsort [$r smembers myset2]] [lsort [$r smembers myset1]]
+ } {{a x y z} {b c}}
+
+ test {SMOVE non existing key} {
+ list [$r smove myset1 myset2 foo] [lsort [$r smembers myset2]] [lsort [$r smembers myset1]]
+ } {0 {a x y z} {b c}}
+
+ test {SMOVE non existing src set} {
+ list [$r smove noset myset2 foo] [lsort [$r smembers myset2]]
+ } {0 {a x y z}}
+
+ test {SMOVE non existing dst set} {
+ list [$r smove myset2 myset3 y] [lsort [$r smembers myset2]] [lsort [$r smembers myset3]]
+ } {1 {a x z} y}
+
+ test {SMOVE wrong src key type} {
+ $r set x 10
+ catch {$r smove x myset2 foo} err
+ format $err
+ } {ERR*}
+
+ test {SMOVE wrong dst key type} {
+ $r set x 10
+ catch {$r smove myset2 x foo} err
+ format $err
+ } {ERR*}
+
+ test {MSET base case} {
+ $r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n"
+ $r mget x y z
+ } [list 10 {foo bar} "x x x x x x x\n\n\r\n"]
+
+ test {MSET wrong number of args} {
+ catch {$r mset x 10 y "foo bar" z} err
+ format $err
+ } {*wrong number*}
+
+ test {MSETNX with already existent key} {
+ list [$r msetnx x1 xxx y2 yyy x 20] [$r exists x1] [$r exists y2]
+ } {0 0 0}
+
+ test {MSETNX with not existing keys} {
+ list [$r msetnx x1 xxx y2 yyy] [$r get x1] [$r get y2]
+ } {1 xxx yyy}
+
+ test {ZSET basic ZADD and score update} {
+ $r zadd ztmp 10 x
+ $r zadd ztmp 20 y
+ $r zadd ztmp 30 z
+ set aux1 [$r zrange ztmp 0 -1]
+ $r zadd ztmp 1 y
+ set aux2 [$r zrange ztmp 0 -1]
+ list $aux1 $aux2
+ } {{x y z} {y x z}}
+
+ test {ZSCORE} {
+ set aux {}
+ set err {}
+ for {set i 0} {$i < 1000} {incr i} {
+ set score [expr rand()]
+ lappend aux $score
+ $r zadd zscoretest $score $i
+ }
+ for {set i 0} {$i < 1000} {incr i} {
+ if {[$r zscore zscoretest $i] != [lindex $aux $i]} {
+ set err "Expected score was [lindex $aux $i] but got [$r zscore zscoretest $i] for element $i"
+ break
+ }
+ }
+ set _ $err
+ } {}
+
+ test {ZSCORE after a DEBUG RELOAD} {
+ set aux {}
+ set err {}
+ $r del zscoretest
+ for {set i 0} {$i < 1000} {incr i} {
+ set score [expr rand()]
+ lappend aux $score
+ $r zadd zscoretest $score $i
+ }
+ $r debug reload
+ for {set i 0} {$i < 1000} {incr i} {
+ if {[$r zscore zscoretest $i] != [lindex $aux $i]} {
+ set err "Expected score was [lindex $aux $i] but got [$r zscore zscoretest $i] for element $i"
+ break
+ }
+ }
+ set _ $err
+ } {}
+
+ test {ZRANGE and ZREVRANGE} {
+ list [$r zrange ztmp 0 -1] [$r zrevrange ztmp 0 -1]
+ } {{y x z} {z x y}}
+
+ test {ZSETs stress tester - sorting is working well?} {
+ set delta 0
+ for {set test 0} {$test < 2} {incr test} {
+ unset -nocomplain auxarray
+ array set auxarray {}
+ set auxlist {}
+ $r del myzset
+ for {set i 0} {$i < 1000} {incr i} {
+ if {$test == 0} {
+ set score [expr rand()]
+ } else {
+ set score [expr int(rand()*10)]
+ }
+ set auxarray($i) $score
+ $r zadd myzset $score $i
+ # Random update
+ if {[expr rand()] < .2} {
+ set j [expr int(rand()*1000)]
+ if {$test == 0} {
+ set score [expr rand()]
+ } else {
+ set score [expr int(rand()*10)]
+ }
+ set auxarray($j) $score
+ $r zadd myzset $score $j
+ }
+ }
+ foreach {item score} [array get auxarray] {
+ lappend auxlist [list $score $item]
+ }
+ set sorted [lsort -command zlistAlikeSort $auxlist]
+ set auxlist {}
+ foreach x $sorted {
+ lappend auxlist [lindex $x 1]
+ }
+ set fromredis [$r zrange myzset 0 -1]
+ set delta 0
+ for {set i 0} {$i < [llength $fromredis]} {incr i} {
+ if {[lindex $fromredis $i] != [lindex $auxlist $i]} {
+ incr delta
+ }
+ }
+ }
+ format $delta
+ } {0}
+
+ test {ZINCRBY - can create a new sorted set} {
+ $r del zset
+ $r zincrby zset 1 foo
+ list [$r zrange zset 0 -1] [$r zscore zset foo]
+ } {foo 1}
+
+ test {ZINCRBY - increment and decrement} {
+ $r zincrby zset 2 foo
+ $r zincrby zset 1 bar
+ set v1 [$r zrange zset 0 -1]
+ $r zincrby zset 10 bar
+ $r zincrby zset -5 foo
+ $r zincrby zset -5 bar
+ set v2 [$r zrange zset 0 -1]
+ list $v1 $v2 [$r zscore zset foo] [$r zscore zset bar]
+ } {{bar foo} {foo bar} -2 6}
+
+ test {EXPIRE - don't set timeouts multiple times} {
+ $r set x foobar
+ set v1 [$r expire x 5]
+ set v2 [$r ttl x]
+ set v3 [$r expire x 10]
+ set v4 [$r ttl x]
+ list $v1 $v2 $v3 $v4
+ } {1 5 0 5}
+
+ test {EXPIRE - It should be still possible to read 'x'} {
+ $r get x
+ } {foobar}
+
+ test {EXPIRE - After 6 seconds the key should no longer be here} {
+ after 6000
+ list [$r get x] [$r exists x]
+ } {{} 0}
+
+ test {EXPIRE - Delete on write policy} {
+ $r del x
+ $r lpush x foo
+ $r expire x 1000
+ $r lpush x bar
+ $r lrange x 0 -1
+ } {bar}
+
+ test {EXPIREAT - Check for EXPIRE alike behavior} {
+ $r del x
+ $r set x foo
+ $r expireat x [expr [clock seconds]+15]
+ $r ttl x
+ } {1[345]}
+
+ test {ZSETs skiplist implementation backlink consistency test} {
+ set diff 0
+ set elements 10000
+ for {set j 0} {$j < $elements} {incr j} {
+ $r zadd myzset [expr rand()] "Element-$j"
+ $r zrem myzset "Element-[expr int(rand()*$elements)]"
+ }
+ set l1 [$r zrange myzset 0 -1]
+ set l2 [$r zrevrange myzset 0 -1]
+ for {set j 0} {$j < [llength $l1]} {incr j} {
+ if {[lindex $l1 $j] ne [lindex $l2 end-$j]} {
+ incr diff
+ }
+ }
+ format $diff