]> git.saurik.com Git - redis.git/blame - tests/unit/basic.tcl
Merge pull request #74 from kmerenkov/issue_620
[redis.git] / tests / unit / basic.tcl
CommitLineData
7f7499ee 1start_server {tags {"basic"}} {
98578b57
PN
2 test {DEL all keys to start with a clean DB} {
3 foreach key [r keys *] {r del $key}
4 r dbsize
5 } {0}
6
7 test {SET and GET an item} {
8 r set x foobar
9 r get x
10 } {foobar}
11
12 test {SET and GET an empty item} {
13 r set x {}
14 r get x
15 } {}
16
17 test {DEL against a single item} {
18 r del x
19 r get x
20 } {}
21
22 test {Vararg DEL} {
23 r set foo1 a
24 r set foo2 b
25 r set foo3 c
26 list [r del foo1 foo2 foo3 foo4] [r mget foo1 foo2 foo3]
27 } {3 {{} {} {}}}
28
29 test {KEYS with pattern} {
30 foreach key {key_x key_y key_z foo_a foo_b foo_c} {
31 r set $key hello
32 }
33 lsort [r keys foo*]
34 } {foo_a foo_b foo_c}
35
36 test {KEYS to get all keys} {
37 lsort [r keys *]
38 } {foo_a foo_b foo_c key_x key_y key_z}
39
40 test {DBSIZE} {
41 r dbsize
42 } {6}
43
44 test {DEL all keys} {
45 foreach key [r keys *] {r del $key}
46 r dbsize
47 } {0}
48
49 test {Very big payload in GET/SET} {
50 set buf [string repeat "abcd" 1000000]
51 r set foo $buf
52 r get foo
53 } [string repeat "abcd" 1000000]
54
7f7499ee
PN
55 tags {"slow"} {
56 test {Very big payload random access} {
57 set err {}
58 array set payload {}
59 for {set j 0} {$j < 100} {incr j} {
60 set size [expr 1+[randomInt 100000]]
61 set buf [string repeat "pl-$j" $size]
62 set payload($j) $buf
63 r set bigpayload_$j $buf
98578b57 64 }
7f7499ee
PN
65 for {set j 0} {$j < 1000} {incr j} {
66 set index [randomInt 100]
67 set buf [r get bigpayload_$index]
68 if {$buf != $payload($index)} {
69 set err "Values differ: I set '$payload($index)' but I read back '$buf'"
70 break
71 }
98578b57 72 }
7f7499ee
PN
73 unset payload
74 set _ $err
75 } {}
76
77 test {SET 10000 numeric keys and access all them in reverse order} {
78 set err {}
79 for {set x 0} {$x < 10000} {incr x} {
80 r set $x $x
81 }
82 set sum 0
83 for {set x 9999} {$x >= 0} {incr x -1} {
84 set val [r get $x]
85 if {$val ne $x} {
86 set err "Eleemnt at position $x is $val instead of $x"
87 break
88 }
89 }
90 set _ $err
91 } {}
98578b57 92
7f7499ee
PN
93 test {DBSIZE should be 10101 now} {
94 r dbsize
95 } {10101}
6e0e5bed 96 }
98578b57
PN
97
98 test {INCR against non existing key} {
99 set res {}
100 append res [r incr novar]
101 append res [r get novar]
102 } {11}
103
104 test {INCR against key created by incr itself} {
105 r incr novar
106 } {2}
107
108 test {INCR against key originally set with SET} {
109 r set novar 100
110 r incr novar
111 } {101}
112
113 test {INCR over 32bit value} {
114 r set novar 17179869184
115 r incr novar
116 } {17179869185}
117
118 test {INCRBY over 32bit value with over 32bit increment} {
119 r set novar 17179869184
120 r incrby novar 17179869184
121 } {34359738368}
122
123 test {INCR fails against key with spaces (no integer encoded)} {
124 r set novar " 11 "
125 catch {r incr novar} err
126 format $err
127 } {ERR*}
128
129 test {INCR fails against a key holding a list} {
130 r rpush mylist 1
131 catch {r incr mylist} err
132 r rpop mylist
133 format $err
134 } {ERR*}
135
136 test {DECRBY over 32bit value with over 32bit increment, negative res} {
137 r set novar 17179869184
138 r decrby novar 17179869185
139 } {-1}
140
b0d1d268
PN
141 test "SETNX target key missing" {
142 r del novar
143 assert_equal 1 [r setnx novar foobared]
144 assert_equal "foobared" [r get novar]
145 }
98578b57 146
b0d1d268
PN
147 test "SETNX target key exists" {
148 r set novar foobared
149 assert_equal 0 [r setnx novar blabla]
150 assert_equal "foobared" [r get novar]
151 }
98578b57 152
b0d1d268 153 test "SETNX against not-expired volatile key" {
98578b57
PN
154 r set x 10
155 r expire x 10000
b0d1d268
PN
156 assert_equal 0 [r setnx x 20]
157 assert_equal 10 [r get x]
158 }
159
160 test "SETNX against expired volatile key" {
161 # Make it very unlikely for the key this test uses to be expired by the
162 # active expiry cycle. This is tightly coupled to the implementation of
163 # active expiry and dbAdd() but currently the only way to test that
164 # SETNX expires a key when it should have been.
165 for {set x 0} {$x < 9999} {incr x} {
166 r setex key-$x 3600 value
167 }
168
169 # This will be one of 10000 expiring keys. A cycle is executed every
170 # 100ms, sampling 10 keys for being expired or not. This key will be
171 # expired for at most 1s when we wait 2s, resulting in a total sample
172 # of 100 keys. The probability of the success of this test being a
173 # false positive is therefore approx. 1%.
174 r set x 10
175 r expire x 1
176
177 # Wait for the key to expire
178 after 2000
179
180 assert_equal 1 [r setnx x 20]
181 assert_equal 20 [r get x]
182 }
98578b57
PN
183
184 test {EXISTS} {
185 set res {}
186 r set newkey test
187 append res [r exists newkey]
188 r del newkey
189 append res [r exists newkey]
190 } {10}
191
192 test {Zero length value in key. SET/GET/EXISTS} {
193 r set emptykey {}
194 set res [r get emptykey]
195 append res [r exists emptykey]
196 r del emptykey
197 append res [r exists emptykey]
198 } {10}
199
200 test {Commands pipelining} {
201 set fd [r channel]
dc11daf3 202 puts -nonewline $fd "SET k1 xyzk\r\nGET k1\r\nPING\r\n"
98578b57
PN
203 flush $fd
204 set res {}
205 append res [string match OK* [::redis::redis_read_reply $fd]]
206 append res [::redis::redis_read_reply $fd]
207 append res [string match PONG* [::redis::redis_read_reply $fd]]
208 format $res
209 } {1xyzk1}
210
211 test {Non existing command} {
212 catch {r foobaredcommand} err
213 string match ERR* $err
214 } {1}
215
216 test {RENAME basic usage} {
217 r set mykey hello
218 r rename mykey mykey1
219 r rename mykey1 mykey2
220 r get mykey2
221 } {hello}
222
223 test {RENAME source key should no longer exist} {
224 r exists mykey
225 } {0}
226
227 test {RENAME against already existing key} {
228 r set mykey a
229 r set mykey2 b
230 r rename mykey2 mykey
231 set res [r get mykey]
232 append res [r exists mykey2]
233 } {b0}
234
235 test {RENAMENX basic usage} {
236 r del mykey
237 r del mykey2
238 r set mykey foobar
239 r renamenx mykey mykey2
240 set res [r get mykey2]
241 append res [r exists mykey]
242 } {foobar0}
243
244 test {RENAMENX against already existing key} {
245 r set mykey foo
246 r set mykey2 bar
247 r renamenx mykey mykey2
248 } {0}
249
250 test {RENAMENX against already existing key (2)} {
251 set res [r get mykey]
252 append res [r get mykey2]
253 } {foobar}
254
255 test {RENAME against non existing source key} {
256 catch {r rename nokey foobar} err
257 format $err
258 } {ERR*}
259
260 test {RENAME where source and dest key is the same} {
261 catch {r rename mykey mykey} err
262 format $err
263 } {ERR*}
264
265 test {DEL all keys again (DB 0)} {
266 foreach key [r keys *] {
267 r del $key
268 }
269 r dbsize
270 } {0}
271
272 test {DEL all keys again (DB 1)} {
273 r select 10
274 foreach key [r keys *] {
275 r del $key
276 }
277 set res [r dbsize]
278 r select 9
279 format $res
280 } {0}
281
282 test {MOVE basic usage} {
283 r set mykey foobar
284 r move mykey 10
285 set res {}
286 lappend res [r exists mykey]
287 lappend res [r dbsize]
288 r select 10
289 lappend res [r get mykey]
290 lappend res [r dbsize]
291 r select 9
292 format $res
293 } [list 0 0 foobar 1]
294
295 test {MOVE against key existing in the target DB} {
296 r set mykey hello
297 r move mykey 10
298 } {0}
299
300 test {SET/GET keys in different DBs} {
301 r set a hello
302 r set b world
303 r select 10
304 r set a foo
305 r set b bared
306 r select 9
307 set res {}
308 lappend res [r get a]
309 lappend res [r get b]
310 r select 10
311 lappend res [r get a]
312 lappend res [r get b]
313 r select 9
314 format $res
315 } {hello world foo bared}
316
317 test {MGET} {
318 r flushdb
319 r set foo BAR
320 r set bar FOO
321 r mget foo bar
322 } {BAR FOO}
323
324 test {MGET against non existing key} {
325 r mget foo baazz bar
326 } {BAR {} FOO}
327
328 test {MGET against non-string key} {
329 r sadd myset ciao
330 r sadd myset bau
331 r mget foo baazz bar myset
332 } {BAR {} FOO {}}
333
334 test {RANDOMKEY} {
335 r flushdb
336 r set foo x
337 r set bar y
338 set foo_seen 0
339 set bar_seen 0
340 for {set i 0} {$i < 100} {incr i} {
341 set rkey [r randomkey]
342 if {$rkey eq {foo}} {
343 set foo_seen 1
344 }
345 if {$rkey eq {bar}} {
346 set bar_seen 1
347 }
348 }
349 list $foo_seen $bar_seen
350 } {1 1}
351
352 test {RANDOMKEY against empty DB} {
353 r flushdb
354 r randomkey
355 } {}
356
357 test {RANDOMKEY regression 1} {
358 r flushdb
359 r set x 10
360 r del x
361 r randomkey
362 } {}
363
364 test {GETSET (set new value)} {
365 list [r getset foo xyz] [r get foo]
366 } {{} xyz}
367
368 test {GETSET (replace old value)} {
369 r set foo bar
370 list [r getset foo xyz] [r get foo]
371 } {bar xyz}
372
373 test {MSET base case} {
374 r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n"
375 r mget x y z
376 } [list 10 {foo bar} "x x x x x x x\n\n\r\n"]
377
378 test {MSET wrong number of args} {
379 catch {r mset x 10 y "foo bar" z} err
380 format $err
381 } {*wrong number*}
382
383 test {MSETNX with already existent key} {
384 list [r msetnx x1 xxx y2 yyy x 20] [r exists x1] [r exists y2]
385 } {0 0 0}
386
387 test {MSETNX with not existing keys} {
388 list [r msetnx x1 xxx y2 yyy] [r get x1] [r get y2]
389 } {1 xxx yyy}
390
7d5f5712
PN
391 test "STRLEN against non-existing key" {
392 assert_equal 0 [r strlen notakey]
393 }
80091bba 394
7d5f5712 395 test "STRLEN against integer-encoded value" {
80091bba 396 r set myinteger -555
7d5f5712
PN
397 assert_equal 4 [r strlen myinteger]
398 }
80091bba 399
7d5f5712 400 test "STRLEN against plain string" {
80091bba 401 r set mystring "foozzz0123456789 baz"
7d5f5712 402 assert_equal 20 [r strlen mystring]
80091bba 403 }
3c1bf495
PN
404
405 test "SETBIT against non-existing key" {
406 r del mykey
30407e1f
PN
407 assert_equal 0 [r setbit mykey 1 1]
408 assert_equal [binary format B* 01000000] [r get mykey]
3c1bf495
PN
409 }
410
411 test "SETBIT against string-encoded key" {
30407e1f 412 # Ascii "@" is integer 64 = 01 00 00 00
3c1bf495
PN
413 r set mykey "@"
414
30407e1f
PN
415 assert_equal 0 [r setbit mykey 2 1]
416 assert_equal [binary format B* 01100000] [r get mykey]
417 assert_equal 1 [r setbit mykey 1 0]
418 assert_equal [binary format B* 00100000] [r get mykey]
3c1bf495
PN
419 }
420
421 test "SETBIT against integer-encoded key" {
30407e1f 422 # Ascii "1" is integer 49 = 00 11 00 01
3c1bf495
PN
423 r set mykey 1
424 assert_encoding int mykey
425
30407e1f
PN
426 assert_equal 0 [r setbit mykey 6 1]
427 assert_equal [binary format B* 00110011] [r get mykey]
428 assert_equal 1 [r setbit mykey 2 0]
429 assert_equal [binary format B* 00010011] [r get mykey]
3c1bf495
PN
430 }
431
432 test "SETBIT against key with wrong type" {
433 r del mykey
434 r lpush mykey "foo"
435 assert_error "*wrong kind*" {r setbit mykey 0 1}
436 }
437
438 test "SETBIT with out of range bit offset" {
439 r del mykey
076f88d6 440 assert_error "*out of range*" {r setbit mykey [expr 4*1024*1024*1024] 1}
3c1bf495
PN
441 assert_error "*out of range*" {r setbit mykey -1 1}
442 }
443
444 test "SETBIT with non-bit argument" {
445 r del mykey
eae33c1c
PN
446 assert_error "*out of range*" {r setbit mykey 0 -1}
447 assert_error "*out of range*" {r setbit mykey 0 2}
448 assert_error "*out of range*" {r setbit mykey 0 10}
449 assert_error "*out of range*" {r setbit mykey 0 20}
3c1bf495
PN
450 }
451
e983cf34
PN
452 test "SETBIT fuzzing" {
453 set str ""
454 set len [expr 256*8]
455 r del mykey
456
457 for {set i 0} {$i < 2000} {incr i} {
458 set bitnum [randomInt $len]
459 set bitval [randomInt 2]
460 set fmt [format "%%-%ds%%d%%-s" $bitnum]
461 set head [string range $str 0 $bitnum-1]
462 set tail [string range $str $bitnum+1 end]
463 set str [string map {" " 0} [format $fmt $head $bitval $tail]]
464
465 r setbit mykey $bitnum $bitval
466 assert_equal [binary format B* $str] [r get mykey]
467 }
468 }
469
3c1bf495
PN
470 test "GETBIT against non-existing key" {
471 r del mykey
472 assert_equal 0 [r getbit mykey 0]
473 }
474
475 test "GETBIT against string-encoded key" {
476 # Single byte with 2nd and 3rd bit set
477 r set mykey "`"
478
479 # In-range
480 assert_equal 0 [r getbit mykey 0]
481 assert_equal 1 [r getbit mykey 1]
482 assert_equal 1 [r getbit mykey 2]
483 assert_equal 0 [r getbit mykey 3]
484
485 # Out-range
486 assert_equal 0 [r getbit mykey 8]
487 assert_equal 0 [r getbit mykey 100]
488 assert_equal 0 [r getbit mykey 10000]
489 }
490
491 test "GETBIT against integer-encoded key" {
492 r set mykey 1
493 assert_encoding int mykey
494
495 # Ascii "1" is integer 49 = 00 11 00 01
496 assert_equal 0 [r getbit mykey 0]
497 assert_equal 0 [r getbit mykey 1]
498 assert_equal 1 [r getbit mykey 2]
499 assert_equal 1 [r getbit mykey 3]
500
501 # Out-range
502 assert_equal 0 [r getbit mykey 8]
503 assert_equal 0 [r getbit mykey 100]
504 assert_equal 0 [r getbit mykey 10000]
505 }
9f9e1cea
PN
506
507 test "SETRANGE against non-existing key" {
508 r del mykey
509 assert_equal 3 [r setrange mykey 0 foo]
510 assert_equal "foo" [r get mykey]
511
512 r del mykey
513 assert_equal 0 [r setrange mykey 0 ""]
514 assert_equal 0 [r exists mykey]
515
516 r del mykey
517 assert_equal 4 [r setrange mykey 1 foo]
518 assert_equal "\000foo" [r get mykey]
9f9e1cea
PN
519 }
520
521 test "SETRANGE against string-encoded key" {
522 r set mykey "foo"
523 assert_equal 3 [r setrange mykey 0 b]
524 assert_equal "boo" [r get mykey]
525
526 r set mykey "foo"
527 assert_equal 3 [r setrange mykey 0 ""]
528 assert_equal "foo" [r get mykey]
529
530 r set mykey "foo"
531 assert_equal 3 [r setrange mykey 1 b]
532 assert_equal "fbo" [r get mykey]
533
9f9e1cea
PN
534 r set mykey "foo"
535 assert_equal 7 [r setrange mykey 4 bar]
536 assert_equal "foo\000bar" [r get mykey]
537 }
538
539 test "SETRANGE against integer-encoded key" {
540 r set mykey 1234
541 assert_encoding int mykey
542 assert_equal 4 [r setrange mykey 0 2]
543 assert_encoding raw mykey
544 assert_equal 2234 [r get mykey]
545
546 # Shouldn't change encoding when nothing is set
547 r set mykey 1234
548 assert_encoding int mykey
549 assert_equal 4 [r setrange mykey 0 ""]
550 assert_encoding int mykey
551 assert_equal 1234 [r get mykey]
552
553 r set mykey 1234
554 assert_encoding int mykey
555 assert_equal 4 [r setrange mykey 1 3]
556 assert_encoding raw mykey
557 assert_equal 1334 [r get mykey]
558
9f9e1cea
PN
559 r set mykey 1234
560 assert_encoding int mykey
561 assert_equal 6 [r setrange mykey 5 2]
562 assert_encoding raw mykey
563 assert_equal "1234\0002" [r get mykey]
564 }
565
566 test "SETRANGE against key with wrong type" {
567 r del mykey
568 r lpush mykey "foo"
569 assert_error "*wrong kind*" {r setrange mykey 0 bar}
570 }
571
572 test "SETRANGE with out of range offset" {
573 r del mykey
574 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
8f8eeffe 575
9f9e1cea 576 r set mykey "hello"
8f8eeffe 577 assert_error "*out of range*" {r setrange mykey -1 world}
9f9e1cea
PN
578 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
579 }
ef11bccc 580
d8f160a8
PN
581 test "GETRANGE against non-existing key" {
582 r del mykey
583 assert_equal "" [r getrange mykey 0 -1]
584 }
585
586 test "GETRANGE against string value" {
587 r set mykey "Hello World"
588 assert_equal "Hell" [r getrange mykey 0 3]
589 assert_equal "Hello World" [r getrange mykey 0 -1]
590 assert_equal "orld" [r getrange mykey -4 -1]
591 assert_equal "" [r getrange mykey 5 3]
592 assert_equal " World" [r getrange mykey 5 5000]
593 assert_equal "Hello World" [r getrange mykey -5000 10000]
594 }
595
596 test "GETRANGE against integer-encoded value" {
597 r set mykey 1234
598 assert_equal "123" [r getrange mykey 0 2]
599 assert_equal "1234" [r getrange mykey 0 -1]
600 assert_equal "234" [r getrange mykey -3 -1]
601 assert_equal "" [r getrange mykey 5 3]
602 assert_equal "4" [r getrange mykey 3 5000]
603 assert_equal "1234" [r getrange mykey -5000 10000]
604 }
605
606 test "GETRANGE fuzzing" {
ef11bccc 607 for {set i 0} {$i < 1000} {incr i} {
d8f160a8 608 r set bin [set bin [randstring 0 1024 binary]]
ef11bccc
PN
609 set _start [set start [randomInt 1500]]
610 set _end [set end [randomInt 1500]]
611 if {$_start < 0} {set _start "end-[abs($_start)-1]"}
612 if {$_end < 0} {set _end "end-[abs($_end)-1]"}
d8f160a8 613 assert_equal [string range $bin $_start $_end] [r getrange bin $start $end]
ef11bccc 614 }
d8f160a8 615 }
98578b57 616}