]> git.saurik.com Git - redis.git/blame - tests/unit/basic.tcl
testhelp.h now exits with retcode 1 on failed tests.
[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
02a3e582 265 test {RENAME with volatile key, should move the TTL as well} {
266 r del mykey mykey2
267 r set mykey foo
268 r expire mykey 100
269 assert {[r ttl mykey] > 95 && [r ttl mykey] <= 100}
270 r rename mykey mykey2
271 assert {[r ttl mykey2] > 95 && [r ttl mykey2] <= 100}
272 }
273
274 test {RENAME with volatile key, should not inherit TTL of target key} {
275 r del mykey mykey2
276 r set mykey foo
277 r set mykey2 bar
278 r expire mykey2 100
279 assert {[r ttl mykey] == -1 && [r ttl mykey2] > 0}
280 r rename mykey mykey2
281 r ttl mykey2
282 } {-1}
283
98578b57
PN
284 test {DEL all keys again (DB 0)} {
285 foreach key [r keys *] {
286 r del $key
287 }
288 r dbsize
289 } {0}
290
291 test {DEL all keys again (DB 1)} {
292 r select 10
293 foreach key [r keys *] {
294 r del $key
295 }
296 set res [r dbsize]
297 r select 9
298 format $res
299 } {0}
300
301 test {MOVE basic usage} {
302 r set mykey foobar
303 r move mykey 10
304 set res {}
305 lappend res [r exists mykey]
306 lappend res [r dbsize]
307 r select 10
308 lappend res [r get mykey]
309 lappend res [r dbsize]
310 r select 9
311 format $res
312 } [list 0 0 foobar 1]
313
314 test {MOVE against key existing in the target DB} {
315 r set mykey hello
316 r move mykey 10
317 } {0}
318
319 test {SET/GET keys in different DBs} {
320 r set a hello
321 r set b world
322 r select 10
323 r set a foo
324 r set b bared
325 r select 9
326 set res {}
327 lappend res [r get a]
328 lappend res [r get b]
329 r select 10
330 lappend res [r get a]
331 lappend res [r get b]
332 r select 9
333 format $res
334 } {hello world foo bared}
335
336 test {MGET} {
337 r flushdb
338 r set foo BAR
339 r set bar FOO
340 r mget foo bar
341 } {BAR FOO}
342
343 test {MGET against non existing key} {
344 r mget foo baazz bar
345 } {BAR {} FOO}
346
347 test {MGET against non-string key} {
348 r sadd myset ciao
349 r sadd myset bau
350 r mget foo baazz bar myset
351 } {BAR {} FOO {}}
352
353 test {RANDOMKEY} {
354 r flushdb
355 r set foo x
356 r set bar y
357 set foo_seen 0
358 set bar_seen 0
359 for {set i 0} {$i < 100} {incr i} {
360 set rkey [r randomkey]
361 if {$rkey eq {foo}} {
362 set foo_seen 1
363 }
364 if {$rkey eq {bar}} {
365 set bar_seen 1
366 }
367 }
368 list $foo_seen $bar_seen
369 } {1 1}
370
371 test {RANDOMKEY against empty DB} {
372 r flushdb
373 r randomkey
374 } {}
375
376 test {RANDOMKEY regression 1} {
377 r flushdb
378 r set x 10
379 r del x
380 r randomkey
381 } {}
382
383 test {GETSET (set new value)} {
384 list [r getset foo xyz] [r get foo]
385 } {{} xyz}
386
387 test {GETSET (replace old value)} {
388 r set foo bar
389 list [r getset foo xyz] [r get foo]
390 } {bar xyz}
391
392 test {MSET base case} {
393 r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n"
394 r mget x y z
395 } [list 10 {foo bar} "x x x x x x x\n\n\r\n"]
396
397 test {MSET wrong number of args} {
398 catch {r mset x 10 y "foo bar" z} err
399 format $err
400 } {*wrong number*}
401
402 test {MSETNX with already existent key} {
403 list [r msetnx x1 xxx y2 yyy x 20] [r exists x1] [r exists y2]
404 } {0 0 0}
405
406 test {MSETNX with not existing keys} {
407 list [r msetnx x1 xxx y2 yyy] [r get x1] [r get y2]
408 } {1 xxx yyy}
409
7d5f5712
PN
410 test "STRLEN against non-existing key" {
411 assert_equal 0 [r strlen notakey]
412 }
80091bba 413
7d5f5712 414 test "STRLEN against integer-encoded value" {
80091bba 415 r set myinteger -555
7d5f5712
PN
416 assert_equal 4 [r strlen myinteger]
417 }
80091bba 418
7d5f5712 419 test "STRLEN against plain string" {
80091bba 420 r set mystring "foozzz0123456789 baz"
7d5f5712 421 assert_equal 20 [r strlen mystring]
80091bba 422 }
3c1bf495
PN
423
424 test "SETBIT against non-existing key" {
425 r del mykey
30407e1f
PN
426 assert_equal 0 [r setbit mykey 1 1]
427 assert_equal [binary format B* 01000000] [r get mykey]
3c1bf495
PN
428 }
429
430 test "SETBIT against string-encoded key" {
30407e1f 431 # Ascii "@" is integer 64 = 01 00 00 00
3c1bf495
PN
432 r set mykey "@"
433
30407e1f
PN
434 assert_equal 0 [r setbit mykey 2 1]
435 assert_equal [binary format B* 01100000] [r get mykey]
436 assert_equal 1 [r setbit mykey 1 0]
437 assert_equal [binary format B* 00100000] [r get mykey]
3c1bf495
PN
438 }
439
440 test "SETBIT against integer-encoded key" {
30407e1f 441 # Ascii "1" is integer 49 = 00 11 00 01
3c1bf495
PN
442 r set mykey 1
443 assert_encoding int mykey
444
30407e1f
PN
445 assert_equal 0 [r setbit mykey 6 1]
446 assert_equal [binary format B* 00110011] [r get mykey]
447 assert_equal 1 [r setbit mykey 2 0]
448 assert_equal [binary format B* 00010011] [r get mykey]
3c1bf495
PN
449 }
450
451 test "SETBIT against key with wrong type" {
452 r del mykey
453 r lpush mykey "foo"
454 assert_error "*wrong kind*" {r setbit mykey 0 1}
455 }
456
457 test "SETBIT with out of range bit offset" {
458 r del mykey
076f88d6 459 assert_error "*out of range*" {r setbit mykey [expr 4*1024*1024*1024] 1}
3c1bf495
PN
460 assert_error "*out of range*" {r setbit mykey -1 1}
461 }
462
463 test "SETBIT with non-bit argument" {
464 r del mykey
eae33c1c
PN
465 assert_error "*out of range*" {r setbit mykey 0 -1}
466 assert_error "*out of range*" {r setbit mykey 0 2}
467 assert_error "*out of range*" {r setbit mykey 0 10}
468 assert_error "*out of range*" {r setbit mykey 0 20}
3c1bf495
PN
469 }
470
e983cf34
PN
471 test "SETBIT fuzzing" {
472 set str ""
473 set len [expr 256*8]
474 r del mykey
475
476 for {set i 0} {$i < 2000} {incr i} {
477 set bitnum [randomInt $len]
478 set bitval [randomInt 2]
479 set fmt [format "%%-%ds%%d%%-s" $bitnum]
480 set head [string range $str 0 $bitnum-1]
481 set tail [string range $str $bitnum+1 end]
482 set str [string map {" " 0} [format $fmt $head $bitval $tail]]
483
484 r setbit mykey $bitnum $bitval
485 assert_equal [binary format B* $str] [r get mykey]
486 }
487 }
488
3c1bf495
PN
489 test "GETBIT against non-existing key" {
490 r del mykey
491 assert_equal 0 [r getbit mykey 0]
492 }
493
494 test "GETBIT against string-encoded key" {
495 # Single byte with 2nd and 3rd bit set
496 r set mykey "`"
497
498 # In-range
499 assert_equal 0 [r getbit mykey 0]
500 assert_equal 1 [r getbit mykey 1]
501 assert_equal 1 [r getbit mykey 2]
502 assert_equal 0 [r getbit mykey 3]
503
504 # Out-range
505 assert_equal 0 [r getbit mykey 8]
506 assert_equal 0 [r getbit mykey 100]
507 assert_equal 0 [r getbit mykey 10000]
508 }
509
510 test "GETBIT against integer-encoded key" {
511 r set mykey 1
512 assert_encoding int mykey
513
514 # Ascii "1" is integer 49 = 00 11 00 01
515 assert_equal 0 [r getbit mykey 0]
516 assert_equal 0 [r getbit mykey 1]
517 assert_equal 1 [r getbit mykey 2]
518 assert_equal 1 [r getbit mykey 3]
519
520 # Out-range
521 assert_equal 0 [r getbit mykey 8]
522 assert_equal 0 [r getbit mykey 100]
523 assert_equal 0 [r getbit mykey 10000]
524 }
9f9e1cea
PN
525
526 test "SETRANGE against non-existing key" {
527 r del mykey
528 assert_equal 3 [r setrange mykey 0 foo]
529 assert_equal "foo" [r get mykey]
530
531 r del mykey
532 assert_equal 0 [r setrange mykey 0 ""]
533 assert_equal 0 [r exists mykey]
534
535 r del mykey
536 assert_equal 4 [r setrange mykey 1 foo]
537 assert_equal "\000foo" [r get mykey]
9f9e1cea
PN
538 }
539
540 test "SETRANGE against string-encoded key" {
541 r set mykey "foo"
542 assert_equal 3 [r setrange mykey 0 b]
543 assert_equal "boo" [r get mykey]
544
545 r set mykey "foo"
546 assert_equal 3 [r setrange mykey 0 ""]
547 assert_equal "foo" [r get mykey]
548
549 r set mykey "foo"
550 assert_equal 3 [r setrange mykey 1 b]
551 assert_equal "fbo" [r get mykey]
552
9f9e1cea
PN
553 r set mykey "foo"
554 assert_equal 7 [r setrange mykey 4 bar]
555 assert_equal "foo\000bar" [r get mykey]
556 }
557
558 test "SETRANGE against integer-encoded key" {
559 r set mykey 1234
560 assert_encoding int mykey
561 assert_equal 4 [r setrange mykey 0 2]
562 assert_encoding raw mykey
563 assert_equal 2234 [r get mykey]
564
565 # Shouldn't change encoding when nothing is set
566 r set mykey 1234
567 assert_encoding int mykey
568 assert_equal 4 [r setrange mykey 0 ""]
569 assert_encoding int mykey
570 assert_equal 1234 [r get mykey]
571
572 r set mykey 1234
573 assert_encoding int mykey
574 assert_equal 4 [r setrange mykey 1 3]
575 assert_encoding raw mykey
576 assert_equal 1334 [r get mykey]
577
9f9e1cea
PN
578 r set mykey 1234
579 assert_encoding int mykey
580 assert_equal 6 [r setrange mykey 5 2]
581 assert_encoding raw mykey
582 assert_equal "1234\0002" [r get mykey]
583 }
584
585 test "SETRANGE against key with wrong type" {
586 r del mykey
587 r lpush mykey "foo"
588 assert_error "*wrong kind*" {r setrange mykey 0 bar}
589 }
590
591 test "SETRANGE with out of range offset" {
592 r del mykey
593 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
8f8eeffe 594
9f9e1cea 595 r set mykey "hello"
8f8eeffe 596 assert_error "*out of range*" {r setrange mykey -1 world}
9f9e1cea
PN
597 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
598 }
ef11bccc 599
d8f160a8
PN
600 test "GETRANGE against non-existing key" {
601 r del mykey
602 assert_equal "" [r getrange mykey 0 -1]
603 }
604
605 test "GETRANGE against string value" {
606 r set mykey "Hello World"
607 assert_equal "Hell" [r getrange mykey 0 3]
608 assert_equal "Hello World" [r getrange mykey 0 -1]
609 assert_equal "orld" [r getrange mykey -4 -1]
610 assert_equal "" [r getrange mykey 5 3]
611 assert_equal " World" [r getrange mykey 5 5000]
612 assert_equal "Hello World" [r getrange mykey -5000 10000]
613 }
614
615 test "GETRANGE against integer-encoded value" {
616 r set mykey 1234
617 assert_equal "123" [r getrange mykey 0 2]
618 assert_equal "1234" [r getrange mykey 0 -1]
619 assert_equal "234" [r getrange mykey -3 -1]
620 assert_equal "" [r getrange mykey 5 3]
621 assert_equal "4" [r getrange mykey 3 5000]
622 assert_equal "1234" [r getrange mykey -5000 10000]
623 }
624
625 test "GETRANGE fuzzing" {
ef11bccc 626 for {set i 0} {$i < 1000} {incr i} {
d8f160a8 627 r set bin [set bin [randstring 0 1024 binary]]
ef11bccc
PN
628 set _start [set start [randomInt 1500]]
629 set _end [set end [randomInt 1500]]
630 if {$_start < 0} {set _start "end-[abs($_start)-1]"}
631 if {$_end < 0} {set _end "end-[abs($_end)-1]"}
d8f160a8 632 assert_equal [string range $bin $_start $_end] [r getrange bin $start $end]
ef11bccc 633 }
d8f160a8 634 }
98578b57 635}