1start_server {tags {"string"}} { 2 test {SET and GET an item} { 3 r set x foobar 4 r get x 5 } {foobar} 6 7 test {SET and GET an empty item} { 8 r set x {} 9 r get x 10 } {} 11 12 test {Very big payload in GET/SET} { 13 set buf [string repeat "abcd" 1000000] 14 r set foo $buf 15 r get foo 16 } [string repeat "abcd" 1000000] 17 18 tags {"slow"} { 19 test {Very big payload random access} { 20 set err {} 21 array set payload {} 22 for {set j 0} {$j < 100} {incr j} { 23 set size [expr 1+[randomInt 100000]] 24 set buf [string repeat "pl-$j" $size] 25 set payload($j) $buf 26 r set bigpayload_$j $buf 27 } 28 for {set j 0} {$j < 1000} {incr j} { 29 set index [randomInt 100] 30 set buf [r get bigpayload_$index] 31 if {$buf != $payload($index)} { 32 set err "Values differ: I set '$payload($index)' but I read back '$buf'" 33 break 34 } 35 } 36 unset payload 37 set _ $err 38 } {} 39 40 test {SET 10000 numeric keys and access all them in reverse order} { 41 r flushdb 42 set err {} 43 for {set x 0} {$x < 10000} {incr x} { 44 r set $x $x 45 } 46 set sum 0 47 for {set x 9999} {$x >= 0} {incr x -1} { 48 set val [r get $x] 49 if {$val ne $x} { 50 set err "Element at position $x is $val instead of $x" 51 break 52 } 53 } 54 set _ $err 55 } {} 56 57 test {DBSIZE should be 10000 now} { 58 r dbsize 59 } {10000} 60 } 61 62 test "SETNX target key missing" { 63 r del novar 64 assert_equal 1 [r setnx novar foobared] 65 assert_equal "foobared" [r get novar] 66 } 67 68 test "SETNX target key exists" { 69 r set novar foobared 70 assert_equal 0 [r setnx novar blabla] 71 assert_equal "foobared" [r get novar] 72 } 73 74 test "SETNX against not-expired volatile key" { 75 r set x 10 76 r expire x 10000 77 assert_equal 0 [r setnx x 20] 78 assert_equal 10 [r get x] 79 } 80 81 test "SETNX against expired volatile key" { 82 # Make it very unlikely for the key this test uses to be expired by the 83 # active expiry cycle. This is tightly coupled to the implementation of 84 # active expiry and dbAdd() but currently the only way to test that 85 # SETNX expires a key when it should have been. 86 for {set x 0} {$x < 9999} {incr x} { 87 r setex key-$x 3600 value 88 } 89 90 # This will be one of 10000 expiring keys. A cycle is executed every 91 # 100ms, sampling 10 keys for being expired or not. This key will be 92 # expired for at most 1s when we wait 2s, resulting in a total sample 93 # of 100 keys. The probability of the success of this test being a 94 # false positive is therefore approx. 1%. 95 r set x 10 96 r expire x 1 97 98 # Wait for the key to expire 99 after 2000 100 101 assert_equal 1 [r setnx x 20] 102 assert_equal 20 [r get x] 103 } 104 105 test {MGET} { 106 r flushdb 107 r set foo BAR 108 r set bar FOO 109 r mget foo bar 110 } {BAR FOO} 111 112 test {MGET against non existing key} { 113 r mget foo baazz bar 114 } {BAR {} FOO} 115 116 test {MGET against non-string key} { 117 r sadd myset ciao 118 r sadd myset bau 119 r mget foo baazz bar myset 120 } {BAR {} FOO {}} 121 122 test {GETSET (set new value)} { 123 r del foo 124 list [r getset foo xyz] [r get foo] 125 } {{} xyz} 126 127 test {GETSET (replace old value)} { 128 r set foo bar 129 list [r getset foo xyz] [r get foo] 130 } {bar xyz} 131 132 test {MSET base case} { 133 r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n" 134 r mget x y z 135 } [list 10 {foo bar} "x x x x x x x\n\n\r\n"] 136 137 test {MSET wrong number of args} { 138 catch {r mset x 10 y "foo bar" z} err 139 format $err 140 } {*wrong number*} 141 142 test {MSETNX with already existent key} { 143 list [r msetnx x1 xxx y2 yyy x 20] [r exists x1] [r exists y2] 144 } {0 0 0} 145 146 test {MSETNX with not existing keys} { 147 list [r msetnx x1 xxx y2 yyy] [r get x1] [r get y2] 148 } {1 xxx yyy} 149 150 test "STRLEN against non-existing key" { 151 assert_equal 0 [r strlen notakey] 152 } 153 154 test "STRLEN against integer-encoded value" { 155 r set myinteger -555 156 assert_equal 4 [r strlen myinteger] 157 } 158 159 test "STRLEN against plain string" { 160 r set mystring "foozzz0123456789 baz" 161 assert_equal 20 [r strlen mystring] 162 } 163 164 test "SETBIT against non-existing key" { 165 r del mykey 166 assert_equal 0 [r setbit mykey 1 1] 167 assert_equal [binary format B* 01000000] [r get mykey] 168 } 169 170 test "SETBIT against string-encoded key" { 171 # Ascii "@" is integer 64 = 01 00 00 00 172 r set mykey "@" 173 174 assert_equal 0 [r setbit mykey 2 1] 175 assert_equal [binary format B* 01100000] [r get mykey] 176 assert_equal 1 [r setbit mykey 1 0] 177 assert_equal [binary format B* 00100000] [r get mykey] 178 } 179 180 test "SETBIT against integer-encoded key" { 181 # Ascii "1" is integer 49 = 00 11 00 01 182 r set mykey 1 183 assert_encoding int mykey 184 185 assert_equal 0 [r setbit mykey 6 1] 186 assert_equal [binary format B* 00110011] [r get mykey] 187 assert_equal 1 [r setbit mykey 2 0] 188 assert_equal [binary format B* 00010011] [r get mykey] 189 } 190 191 test "SETBIT against key with wrong type" { 192 r del mykey 193 r lpush mykey "foo" 194 assert_error "WRONGTYPE*" {r setbit mykey 0 1} 195 } 196 197 test "SETBIT with out of range bit offset" { 198 r del mykey 199 assert_error "*out of range*" {r setbit mykey [expr 4*1024*1024*1024] 1} 200 assert_error "*out of range*" {r setbit mykey -1 1} 201 } 202 203 test "SETBIT with non-bit argument" { 204 r del mykey 205 assert_error "*out of range*" {r setbit mykey 0 -1} 206 assert_error "*out of range*" {r setbit mykey 0 2} 207 assert_error "*out of range*" {r setbit mykey 0 10} 208 assert_error "*out of range*" {r setbit mykey 0 20} 209 } 210 211 test "SETBIT fuzzing" { 212 set str "" 213 set len [expr 256*8] 214 r del mykey 215 216 for {set i 0} {$i < 2000} {incr i} { 217 set bitnum [randomInt $len] 218 set bitval [randomInt 2] 219 set fmt [format "%%-%ds%%d%%-s" $bitnum] 220 set head [string range $str 0 $bitnum-1] 221 set tail [string range $str $bitnum+1 end] 222 set str [string map {" " 0} [format $fmt $head $bitval $tail]] 223 224 r setbit mykey $bitnum $bitval 225 assert_equal [binary format B* $str] [r get mykey] 226 } 227 } 228 229 test "GETBIT against non-existing key" { 230 r del mykey 231 assert_equal 0 [r getbit mykey 0] 232 } 233 234 test "GETBIT against string-encoded key" { 235 # Single byte with 2nd and 3rd bit set 236 r set mykey "`" 237 238 # In-range 239 assert_equal 0 [r getbit mykey 0] 240 assert_equal 1 [r getbit mykey 1] 241 assert_equal 1 [r getbit mykey 2] 242 assert_equal 0 [r getbit mykey 3] 243 244 # Out-range 245 assert_equal 0 [r getbit mykey 8] 246 assert_equal 0 [r getbit mykey 100] 247 assert_equal 0 [r getbit mykey 10000] 248 } 249 250 test "GETBIT against integer-encoded key" { 251 r set mykey 1 252 assert_encoding int mykey 253 254 # Ascii "1" is integer 49 = 00 11 00 01 255 assert_equal 0 [r getbit mykey 0] 256 assert_equal 0 [r getbit mykey 1] 257 assert_equal 1 [r getbit mykey 2] 258 assert_equal 1 [r getbit mykey 3] 259 260 # Out-range 261 assert_equal 0 [r getbit mykey 8] 262 assert_equal 0 [r getbit mykey 100] 263 assert_equal 0 [r getbit mykey 10000] 264 } 265 266 test "SETRANGE against non-existing key" { 267 r del mykey 268 assert_equal 3 [r setrange mykey 0 foo] 269 assert_equal "foo" [r get mykey] 270 271 r del mykey 272 assert_equal 0 [r setrange mykey 0 ""] 273 assert_equal 0 [r exists mykey] 274 275 r del mykey 276 assert_equal 4 [r setrange mykey 1 foo] 277 assert_equal "\000foo" [r get mykey] 278 } 279 280 test "SETRANGE against string-encoded key" { 281 r set mykey "foo" 282 assert_equal 3 [r setrange mykey 0 b] 283 assert_equal "boo" [r get mykey] 284 285 r set mykey "foo" 286 assert_equal 3 [r setrange mykey 0 ""] 287 assert_equal "foo" [r get mykey] 288 289 r set mykey "foo" 290 assert_equal 3 [r setrange mykey 1 b] 291 assert_equal "fbo" [r get mykey] 292 293 r set mykey "foo" 294 assert_equal 7 [r setrange mykey 4 bar] 295 assert_equal "foo\000bar" [r get mykey] 296 } 297 298 test "SETRANGE against integer-encoded key" { 299 r set mykey 1234 300 assert_encoding int mykey 301 assert_equal 4 [r setrange mykey 0 2] 302 assert_encoding raw mykey 303 assert_equal 2234 [r get mykey] 304 305 # Shouldn't change encoding when nothing is set 306 r set mykey 1234 307 assert_encoding int mykey 308 assert_equal 4 [r setrange mykey 0 ""] 309 assert_encoding int mykey 310 assert_equal 1234 [r get mykey] 311 312 r set mykey 1234 313 assert_encoding int mykey 314 assert_equal 4 [r setrange mykey 1 3] 315 assert_encoding raw mykey 316 assert_equal 1334 [r get mykey] 317 318 r set mykey 1234 319 assert_encoding int mykey 320 assert_equal 6 [r setrange mykey 5 2] 321 assert_encoding raw mykey 322 assert_equal "1234\0002" [r get mykey] 323 } 324 325 test "SETRANGE against key with wrong type" { 326 r del mykey 327 r lpush mykey "foo" 328 assert_error "WRONGTYPE*" {r setrange mykey 0 bar} 329 } 330 331 test "SETRANGE with out of range offset" { 332 r del mykey 333 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world} 334 335 r set mykey "hello" 336 assert_error "*out of range*" {r setrange mykey -1 world} 337 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world} 338 } 339 340 test "GETRANGE against non-existing key" { 341 r del mykey 342 assert_equal "" [r getrange mykey 0 -1] 343 } 344 345 test "GETRANGE against string value" { 346 r set mykey "Hello World" 347 assert_equal "Hell" [r getrange mykey 0 3] 348 assert_equal "Hello World" [r getrange mykey 0 -1] 349 assert_equal "orld" [r getrange mykey -4 -1] 350 assert_equal "" [r getrange mykey 5 3] 351 assert_equal " World" [r getrange mykey 5 5000] 352 assert_equal "Hello World" [r getrange mykey -5000 10000] 353 } 354 355 test "GETRANGE against integer-encoded value" { 356 r set mykey 1234 357 assert_equal "123" [r getrange mykey 0 2] 358 assert_equal "1234" [r getrange mykey 0 -1] 359 assert_equal "234" [r getrange mykey -3 -1] 360 assert_equal "" [r getrange mykey 5 3] 361 assert_equal "4" [r getrange mykey 3 5000] 362 assert_equal "1234" [r getrange mykey -5000 10000] 363 } 364 365 test "GETRANGE fuzzing" { 366 for {set i 0} {$i < 1000} {incr i} { 367 r set bin [set bin [randstring 0 1024 binary]] 368 set _start [set start [randomInt 1500]] 369 set _end [set end [randomInt 1500]] 370 if {$_start < 0} {set _start "end-[abs($_start)-1]"} 371 if {$_end < 0} {set _end "end-[abs($_end)-1]"} 372 assert_equal [string range $bin $_start $_end] [r getrange bin $start $end] 373 } 374 } 375 376 test {Extended SET can detect syntax errors} { 377 set e {} 378 catch {r set foo bar non-existing-option} e 379 set e 380 } {*syntax*} 381 382 test {Extended SET NX option} { 383 r del foo 384 set v1 [r set foo 1 nx] 385 set v2 [r set foo 2 nx] 386 list $v1 $v2 [r get foo] 387 } {OK {} 1} 388 389 test {Extended SET XX option} { 390 r del foo 391 set v1 [r set foo 1 xx] 392 r set foo bar 393 set v2 [r set foo 2 xx] 394 list $v1 $v2 [r get foo] 395 } {{} OK 2} 396 397 test {Extended SET EX option} { 398 r del foo 399 r set foo bar ex 10 400 set ttl [r ttl foo] 401 assert {$ttl <= 10 && $ttl > 5} 402 } 403 404 test {Extended SET PX option} { 405 r del foo 406 r set foo bar px 10000 407 set ttl [r ttl foo] 408 assert {$ttl <= 10 && $ttl > 5} 409 } 410 411 test {Extended SET using multiple options at once} { 412 r set foo val 413 assert {[r set foo bar xx px 10000] eq {OK}} 414 set ttl [r ttl foo] 415 assert {$ttl <= 10 && $ttl > 5} 416 } 417 418 test {GETRANGE with huge ranges, Github issue #1844} { 419 r set foo bar 420 r getrange foo 0 4294967297 421 } {bar} 422} 423