X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/ef11bccccac22a001e2d0a6f440dddf69c401954..0bd6d68e34bc41cd80cd7fc44aab9cf3884de8dc:/tests/unit/basic.tcl diff --git a/tests/unit/basic.tcl b/tests/unit/basic.tcl index f082b05d..4210f48b 100644 --- a/tests/unit/basic.tcl +++ b/tests/unit/basic.tcl @@ -120,7 +120,19 @@ start_server {tags {"basic"}} { r incrby novar 17179869184 } {34359738368} - test {INCR fails against key with spaces (no integer encoded)} { + test {INCR fails against key with spaces (left)} { + r set novar " 11" + catch {r incr novar} err + format $err + } {ERR*} + + test {INCR fails against key with spaces (right)} { + r set novar "11 " + catch {r incr novar} err + format $err + } {ERR*} + + test {INCR fails against key with spaces (both)} { r set novar " 11 " catch {r incr novar} err format $err @@ -138,21 +150,116 @@ start_server {tags {"basic"}} { r decrby novar 17179869185 } {-1} - test {SETNX target key missing} { - r setnx novar2 foobared - r get novar2 - } {foobared} + test {INCRBYFLOAT against non existing key} { + r del novar + list [roundFloat [r incrbyfloat novar 1]] \ + [roundFloat [r get novar]] \ + [roundFloat [r incrbyfloat novar 0.25]] \ + [roundFloat [r get novar]] + } {1 1 1.25 1.25} + + test {INCRBYFLOAT against key originally set with SET} { + r set novar 1.5 + roundFloat [r incrbyfloat novar 1.5] + } {3} + + test {INCRBYFLOAT over 32bit value} { + r set novar 17179869184 + r incrbyfloat novar 1.5 + } {17179869185.5} + + test {INCRBYFLOAT over 32bit value with over 32bit increment} { + r set novar 17179869184 + r incrbyfloat novar 17179869184 + } {34359738368} + + test {INCRBYFLOAT fails against key with spaces (left)} { + set err {} + r set novar " 11" + catch {r incrbyfloat novar 1.0} err + format $err + } {ERR*valid*} + + test {INCRBYFLOAT fails against key with spaces (right)} { + set err {} + r set novar "11 " + catch {r incrbyfloat novar 1.0} err + format $err + } {ERR*valid*} + + test {INCRBYFLOAT fails against key with spaces (both)} { + set err {} + r set novar " 11 " + catch {r incrbyfloat novar 1.0} err + format $err + } {ERR*valid*} + + test {INCRBYFLOAT fails against a key holding a list} { + r del mylist + set err {} + r rpush mylist 1 + catch {r incrbyfloat mylist 1.0} err + r del mylist + format $err + } {ERR*kind*} + + test {INCRBYFLOAT does not allow NaN or Infinity} { + r set foo 0 + set err {} + catch {r incrbyfloat foo +inf} err + set err + # p.s. no way I can force NaN to test it from the API because + # there is no way to increment / decrement by infinity nor to + # perform divisions. + } {ERR*would produce*} + + test {INCRBYFLOAT decrement} { + r set foo 1 + roundFloat [r incrbyfloat foo -1.1] + } {-0.1} + + test "SETNX target key missing" { + r del novar + assert_equal 1 [r setnx novar foobared] + assert_equal "foobared" [r get novar] + } - test {SETNX target key exists} { - r setnx novar2 blabla - r get novar2 - } {foobared} + test "SETNX target key exists" { + r set novar foobared + assert_equal 0 [r setnx novar blabla] + assert_equal "foobared" [r get novar] + } - test {SETNX against volatile key} { + test "SETNX against not-expired volatile key" { r set x 10 r expire x 10000 - list [r setnx x 20] [r get x] - } {0 10} + assert_equal 0 [r setnx x 20] + assert_equal 10 [r get x] + } + + test "SETNX against expired volatile key" { + # Make it very unlikely for the key this test uses to be expired by the + # active expiry cycle. This is tightly coupled to the implementation of + # active expiry and dbAdd() but currently the only way to test that + # SETNX expires a key when it should have been. + for {set x 0} {$x < 9999} {incr x} { + r setex key-$x 3600 value + } + + # This will be one of 10000 expiring keys. A cycle is executed every + # 100ms, sampling 10 keys for being expired or not. This key will be + # expired for at most 1s when we wait 2s, resulting in a total sample + # of 100 keys. The probability of the success of this test being a + # false positive is therefore approx. 1%. + r set x 10 + r expire x 1 + + # Wait for the key to expire + after 2000 + + assert_equal 1 [r setnx x 20] + assert_equal 20 [r get x] + } test {EXISTS} { set res {} @@ -235,6 +342,25 @@ start_server {tags {"basic"}} { format $err } {ERR*} + test {RENAME with volatile key, should move the TTL as well} { + r del mykey mykey2 + r set mykey foo + r expire mykey 100 + assert {[r ttl mykey] > 95 && [r ttl mykey] <= 100} + r rename mykey mykey2 + assert {[r ttl mykey2] > 95 && [r ttl mykey2] <= 100} + } + + test {RENAME with volatile key, should not inherit TTL of target key} { + r del mykey mykey2 + r set mykey foo + r set mykey2 bar + r expire mykey2 100 + assert {[r ttl mykey] == -1 && [r ttl mykey2] > 0} + r rename mykey mykey2 + r ttl mykey2 + } {-1} + test {DEL all keys again (DB 0)} { foreach key [r keys *] { r del $key @@ -361,45 +487,45 @@ start_server {tags {"basic"}} { list [r msetnx x1 xxx y2 yyy] [r get x1] [r get y2] } {1 xxx yyy} - test {STRLEN against non existing key} { - r strlen notakey - } {0} + test "STRLEN against non-existing key" { + assert_equal 0 [r strlen notakey] + } - test {STRLEN against integer} { + test "STRLEN against integer-encoded value" { r set myinteger -555 - r strlen myinteger - } {4} + assert_equal 4 [r strlen myinteger] + } - test {STRLEN against plain string} { + test "STRLEN against plain string" { r set mystring "foozzz0123456789 baz" - r strlen mystring + assert_equal 20 [r strlen mystring] } test "SETBIT against non-existing key" { r del mykey - - # Setting 2nd bit to on is integer 64, ascii "@" - assert_equal 1 [r setbit mykey 1 1] - assert_equal "@" [r get mykey] + assert_equal 0 [r setbit mykey 1 1] + assert_equal [binary format B* 01000000] [r get mykey] } test "SETBIT against string-encoded key" { - # Single byte with 2nd bit set + # Ascii "@" is integer 64 = 01 00 00 00 r set mykey "@" - # 64 + 32 = 96 => ascii "`" (backtick) - assert_equal 1 [r setbit mykey 2 1] - assert_equal "`" [r get mykey] + assert_equal 0 [r setbit mykey 2 1] + assert_equal [binary format B* 01100000] [r get mykey] + assert_equal 1 [r setbit mykey 1 0] + assert_equal [binary format B* 00100000] [r get mykey] } test "SETBIT against integer-encoded key" { + # Ascii "1" is integer 49 = 00 11 00 01 r set mykey 1 assert_encoding int mykey - # Ascii "1" is integer 49 = 00 11 00 01 - # Setting 7th bit = 51 => ascii "3" - assert_equal 1 [r setbit mykey 6 1] - assert_equal "3" [r get mykey] + assert_equal 0 [r setbit mykey 6 1] + assert_equal [binary format B* 00110011] [r get mykey] + assert_equal 1 [r setbit mykey 2 0] + assert_equal [binary format B* 00010011] [r get mykey] } test "SETBIT against key with wrong type" { @@ -422,6 +548,24 @@ start_server {tags {"basic"}} { assert_error "*out of range*" {r setbit mykey 0 20} } + test "SETBIT fuzzing" { + set str "" + set len [expr 256*8] + r del mykey + + for {set i 0} {$i < 2000} {incr i} { + set bitnum [randomInt $len] + set bitval [randomInt 2] + set fmt [format "%%-%ds%%d%%-s" $bitnum] + set head [string range $str 0 $bitnum-1] + set tail [string range $str $bitnum+1 end] + set str [string map {" " 0} [format $fmt $head $bitval $tail]] + + r setbit mykey $bitnum $bitval + assert_equal [binary format B* $str] [r get mykey] + } + } + test "GETBIT against non-existing key" { r del mykey assert_equal 0 [r getbit mykey 0] @@ -471,14 +615,6 @@ start_server {tags {"basic"}} { r del mykey assert_equal 4 [r setrange mykey 1 foo] assert_equal "\000foo" [r get mykey] - - r del mykey - assert_equal 3 [r setrange mykey -1 foo] - assert_equal "foo" [r get mykey] - - r del mykey - assert_equal 3 [r setrange mykey -100 foo] - assert_equal "foo" [r get mykey] } test "SETRANGE against string-encoded key" { @@ -494,18 +630,6 @@ start_server {tags {"basic"}} { assert_equal 3 [r setrange mykey 1 b] assert_equal "fbo" [r get mykey] - r set mykey "foo" - assert_equal 6 [r setrange mykey -1 bar] - assert_equal "foobar" [r get mykey] - - r set mykey "foo" - assert_equal 5 [r setrange mykey -2 bar] - assert_equal "fobar" [r get mykey] - - r set mykey "foo" - assert_equal 3 [r setrange mykey -20 bar] - assert_equal "bar" [r get mykey] - r set mykey "foo" assert_equal 7 [r setrange mykey 4 bar] assert_equal "foo\000bar" [r get mykey] @@ -531,18 +655,6 @@ start_server {tags {"basic"}} { assert_encoding raw mykey assert_equal 1334 [r get mykey] - r set mykey 1234 - assert_encoding int mykey - assert_equal 5 [r setrange mykey -1 5] - assert_encoding raw mykey - assert_equal 12345 [r get mykey] - - r set mykey 1234 - assert_encoding int mykey - assert_equal 4 [r setrange mykey -2 5] - assert_encoding raw mykey - assert_equal 1235 [r get mykey] - r set mykey 1234 assert_encoding int mykey assert_equal 6 [r setrange mykey 5 2] @@ -559,43 +671,45 @@ start_server {tags {"basic"}} { test "SETRANGE with out of range offset" { r del mykey assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world} + r set mykey "hello" + assert_error "*out of range*" {r setrange mykey -1 world} assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world} } - test {SUBSTR basics} { - set res {} - r set foo "Hello World" - lappend res [r substr foo 0 3] - lappend res [r substr foo 0 -1] - lappend res [r substr foo -4 -1] - lappend res [r substr foo 5 3] - lappend res [r substr foo 5 5000] - lappend res [r substr foo -5000 10000] - set _ $res - } {Hell {Hello World} orld {} { World} {Hello World}} - - test {SUBSTR against integer encoded values} { - r set foo 123 - r substr foo 0 -2 - } {12} - - test {SUBSTR fuzzing} { - set err {} + test "GETRANGE against non-existing key" { + r del mykey + assert_equal "" [r getrange mykey 0 -1] + } + + test "GETRANGE against string value" { + r set mykey "Hello World" + assert_equal "Hell" [r getrange mykey 0 3] + assert_equal "Hello World" [r getrange mykey 0 -1] + assert_equal "orld" [r getrange mykey -4 -1] + assert_equal "" [r getrange mykey 5 3] + assert_equal " World" [r getrange mykey 5 5000] + assert_equal "Hello World" [r getrange mykey -5000 10000] + } + + test "GETRANGE against integer-encoded value" { + r set mykey 1234 + assert_equal "123" [r getrange mykey 0 2] + assert_equal "1234" [r getrange mykey 0 -1] + assert_equal "234" [r getrange mykey -3 -1] + assert_equal "" [r getrange mykey 5 3] + assert_equal "4" [r getrange mykey 3 5000] + assert_equal "1234" [r getrange mykey -5000 10000] + } + + test "GETRANGE fuzzing" { for {set i 0} {$i < 1000} {incr i} { - set bin [randstring 0 1024 binary] + r set bin [set bin [randstring 0 1024 binary]] set _start [set start [randomInt 1500]] set _end [set end [randomInt 1500]] if {$_start < 0} {set _start "end-[abs($_start)-1]"} if {$_end < 0} {set _end "end-[abs($_end)-1]"} - set s1 [string range $bin $_start $_end] - r set bin $bin - set s2 [r substr bin $start $end] - if {$s1 != $s2} { - set err "String mismatch" - break - } + assert_equal [string range $bin $_start $_end] [r getrange bin $start $end] } - set _ $err - } {} + } }