]> git.saurik.com Git - redis.git/blob - tests/unit/basic.tcl
Merge branch 'unstable' of github.com:antirez/redis into unstable
[redis.git] / tests / unit / basic.tcl
1 start_server {tags {"basic"}} {
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
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
64 }
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 }
72 }
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 } {}
92
93 test {DBSIZE should be 10101 now} {
94 r dbsize
95 } {10101}
96 }
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
141 test {SETNX target key missing} {
142 r setnx novar2 foobared
143 r get novar2
144 } {foobared}
145
146 test {SETNX target key exists} {
147 r setnx novar2 blabla
148 r get novar2
149 } {foobared}
150
151 test {SETNX against volatile key} {
152 r set x 10
153 r expire x 10000
154 list [r setnx x 20] [r get x]
155 } {0 10}
156
157 test {EXISTS} {
158 set res {}
159 r set newkey test
160 append res [r exists newkey]
161 r del newkey
162 append res [r exists newkey]
163 } {10}
164
165 test {Zero length value in key. SET/GET/EXISTS} {
166 r set emptykey {}
167 set res [r get emptykey]
168 append res [r exists emptykey]
169 r del emptykey
170 append res [r exists emptykey]
171 } {10}
172
173 test {Commands pipelining} {
174 set fd [r channel]
175 puts -nonewline $fd "SET k1 xyzk\r\nGET k1\r\nPING\r\n"
176 flush $fd
177 set res {}
178 append res [string match OK* [::redis::redis_read_reply $fd]]
179 append res [::redis::redis_read_reply $fd]
180 append res [string match PONG* [::redis::redis_read_reply $fd]]
181 format $res
182 } {1xyzk1}
183
184 test {Non existing command} {
185 catch {r foobaredcommand} err
186 string match ERR* $err
187 } {1}
188
189 test {RENAME basic usage} {
190 r set mykey hello
191 r rename mykey mykey1
192 r rename mykey1 mykey2
193 r get mykey2
194 } {hello}
195
196 test {RENAME source key should no longer exist} {
197 r exists mykey
198 } {0}
199
200 test {RENAME against already existing key} {
201 r set mykey a
202 r set mykey2 b
203 r rename mykey2 mykey
204 set res [r get mykey]
205 append res [r exists mykey2]
206 } {b0}
207
208 test {RENAMENX basic usage} {
209 r del mykey
210 r del mykey2
211 r set mykey foobar
212 r renamenx mykey mykey2
213 set res [r get mykey2]
214 append res [r exists mykey]
215 } {foobar0}
216
217 test {RENAMENX against already existing key} {
218 r set mykey foo
219 r set mykey2 bar
220 r renamenx mykey mykey2
221 } {0}
222
223 test {RENAMENX against already existing key (2)} {
224 set res [r get mykey]
225 append res [r get mykey2]
226 } {foobar}
227
228 test {RENAME against non existing source key} {
229 catch {r rename nokey foobar} err
230 format $err
231 } {ERR*}
232
233 test {RENAME where source and dest key is the same} {
234 catch {r rename mykey mykey} err
235 format $err
236 } {ERR*}
237
238 test {DEL all keys again (DB 0)} {
239 foreach key [r keys *] {
240 r del $key
241 }
242 r dbsize
243 } {0}
244
245 test {DEL all keys again (DB 1)} {
246 r select 10
247 foreach key [r keys *] {
248 r del $key
249 }
250 set res [r dbsize]
251 r select 9
252 format $res
253 } {0}
254
255 test {MOVE basic usage} {
256 r set mykey foobar
257 r move mykey 10
258 set res {}
259 lappend res [r exists mykey]
260 lappend res [r dbsize]
261 r select 10
262 lappend res [r get mykey]
263 lappend res [r dbsize]
264 r select 9
265 format $res
266 } [list 0 0 foobar 1]
267
268 test {MOVE against key existing in the target DB} {
269 r set mykey hello
270 r move mykey 10
271 } {0}
272
273 test {SET/GET keys in different DBs} {
274 r set a hello
275 r set b world
276 r select 10
277 r set a foo
278 r set b bared
279 r select 9
280 set res {}
281 lappend res [r get a]
282 lappend res [r get b]
283 r select 10
284 lappend res [r get a]
285 lappend res [r get b]
286 r select 9
287 format $res
288 } {hello world foo bared}
289
290 test {MGET} {
291 r flushdb
292 r set foo BAR
293 r set bar FOO
294 r mget foo bar
295 } {BAR FOO}
296
297 test {MGET against non existing key} {
298 r mget foo baazz bar
299 } {BAR {} FOO}
300
301 test {MGET against non-string key} {
302 r sadd myset ciao
303 r sadd myset bau
304 r mget foo baazz bar myset
305 } {BAR {} FOO {}}
306
307 test {RANDOMKEY} {
308 r flushdb
309 r set foo x
310 r set bar y
311 set foo_seen 0
312 set bar_seen 0
313 for {set i 0} {$i < 100} {incr i} {
314 set rkey [r randomkey]
315 if {$rkey eq {foo}} {
316 set foo_seen 1
317 }
318 if {$rkey eq {bar}} {
319 set bar_seen 1
320 }
321 }
322 list $foo_seen $bar_seen
323 } {1 1}
324
325 test {RANDOMKEY against empty DB} {
326 r flushdb
327 r randomkey
328 } {}
329
330 test {RANDOMKEY regression 1} {
331 r flushdb
332 r set x 10
333 r del x
334 r randomkey
335 } {}
336
337 test {GETSET (set new value)} {
338 list [r getset foo xyz] [r get foo]
339 } {{} xyz}
340
341 test {GETSET (replace old value)} {
342 r set foo bar
343 list [r getset foo xyz] [r get foo]
344 } {bar xyz}
345
346 test {MSET base case} {
347 r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n"
348 r mget x y z
349 } [list 10 {foo bar} "x x x x x x x\n\n\r\n"]
350
351 test {MSET wrong number of args} {
352 catch {r mset x 10 y "foo bar" z} err
353 format $err
354 } {*wrong number*}
355
356 test {MSETNX with already existent key} {
357 list [r msetnx x1 xxx y2 yyy x 20] [r exists x1] [r exists y2]
358 } {0 0 0}
359
360 test {MSETNX with not existing keys} {
361 list [r msetnx x1 xxx y2 yyy] [r get x1] [r get y2]
362 } {1 xxx yyy}
363
364 test "STRLEN against non-existing key" {
365 assert_equal 0 [r strlen notakey]
366 }
367
368 test "STRLEN against integer-encoded value" {
369 r set myinteger -555
370 assert_equal 4 [r strlen myinteger]
371 }
372
373 test "STRLEN against plain string" {
374 r set mystring "foozzz0123456789 baz"
375 assert_equal 20 [r strlen mystring]
376 }
377
378 test "SETBIT against non-existing key" {
379 r del mykey
380 assert_equal 0 [r setbit mykey 1 1]
381 assert_equal [binary format B* 01000000] [r get mykey]
382 }
383
384 test "SETBIT against string-encoded key" {
385 # Ascii "@" is integer 64 = 01 00 00 00
386 r set mykey "@"
387
388 assert_equal 0 [r setbit mykey 2 1]
389 assert_equal [binary format B* 01100000] [r get mykey]
390 assert_equal 1 [r setbit mykey 1 0]
391 assert_equal [binary format B* 00100000] [r get mykey]
392 }
393
394 test "SETBIT against integer-encoded key" {
395 # Ascii "1" is integer 49 = 00 11 00 01
396 r set mykey 1
397 assert_encoding int mykey
398
399 assert_equal 0 [r setbit mykey 6 1]
400 assert_equal [binary format B* 00110011] [r get mykey]
401 assert_equal 1 [r setbit mykey 2 0]
402 assert_equal [binary format B* 00010011] [r get mykey]
403 }
404
405 test "SETBIT against key with wrong type" {
406 r del mykey
407 r lpush mykey "foo"
408 assert_error "*wrong kind*" {r setbit mykey 0 1}
409 }
410
411 test "SETBIT with out of range bit offset" {
412 r del mykey
413 assert_error "*out of range*" {r setbit mykey [expr 4*1024*1024*1024] 1}
414 assert_error "*out of range*" {r setbit mykey -1 1}
415 }
416
417 test "SETBIT with non-bit argument" {
418 r del mykey
419 assert_error "*out of range*" {r setbit mykey 0 -1}
420 assert_error "*out of range*" {r setbit mykey 0 2}
421 assert_error "*out of range*" {r setbit mykey 0 10}
422 assert_error "*out of range*" {r setbit mykey 0 20}
423 }
424
425 test "SETBIT fuzzing" {
426 set str ""
427 set len [expr 256*8]
428 r del mykey
429
430 for {set i 0} {$i < 2000} {incr i} {
431 set bitnum [randomInt $len]
432 set bitval [randomInt 2]
433 set fmt [format "%%-%ds%%d%%-s" $bitnum]
434 set head [string range $str 0 $bitnum-1]
435 set tail [string range $str $bitnum+1 end]
436 set str [string map {" " 0} [format $fmt $head $bitval $tail]]
437
438 r setbit mykey $bitnum $bitval
439 assert_equal [binary format B* $str] [r get mykey]
440 }
441 }
442
443 test "GETBIT against non-existing key" {
444 r del mykey
445 assert_equal 0 [r getbit mykey 0]
446 }
447
448 test "GETBIT against string-encoded key" {
449 # Single byte with 2nd and 3rd bit set
450 r set mykey "`"
451
452 # In-range
453 assert_equal 0 [r getbit mykey 0]
454 assert_equal 1 [r getbit mykey 1]
455 assert_equal 1 [r getbit mykey 2]
456 assert_equal 0 [r getbit mykey 3]
457
458 # Out-range
459 assert_equal 0 [r getbit mykey 8]
460 assert_equal 0 [r getbit mykey 100]
461 assert_equal 0 [r getbit mykey 10000]
462 }
463
464 test "GETBIT against integer-encoded key" {
465 r set mykey 1
466 assert_encoding int mykey
467
468 # Ascii "1" is integer 49 = 00 11 00 01
469 assert_equal 0 [r getbit mykey 0]
470 assert_equal 0 [r getbit mykey 1]
471 assert_equal 1 [r getbit mykey 2]
472 assert_equal 1 [r getbit mykey 3]
473
474 # Out-range
475 assert_equal 0 [r getbit mykey 8]
476 assert_equal 0 [r getbit mykey 100]
477 assert_equal 0 [r getbit mykey 10000]
478 }
479
480 test "SETRANGE against non-existing key" {
481 r del mykey
482 assert_equal 3 [r setrange mykey 0 foo]
483 assert_equal "foo" [r get mykey]
484
485 r del mykey
486 assert_equal 0 [r setrange mykey 0 ""]
487 assert_equal 0 [r exists mykey]
488
489 r del mykey
490 assert_equal 4 [r setrange mykey 1 foo]
491 assert_equal "\000foo" [r get mykey]
492 }
493
494 test "SETRANGE against string-encoded key" {
495 r set mykey "foo"
496 assert_equal 3 [r setrange mykey 0 b]
497 assert_equal "boo" [r get mykey]
498
499 r set mykey "foo"
500 assert_equal 3 [r setrange mykey 0 ""]
501 assert_equal "foo" [r get mykey]
502
503 r set mykey "foo"
504 assert_equal 3 [r setrange mykey 1 b]
505 assert_equal "fbo" [r get mykey]
506
507 r set mykey "foo"
508 assert_equal 7 [r setrange mykey 4 bar]
509 assert_equal "foo\000bar" [r get mykey]
510 }
511
512 test "SETRANGE against integer-encoded key" {
513 r set mykey 1234
514 assert_encoding int mykey
515 assert_equal 4 [r setrange mykey 0 2]
516 assert_encoding raw mykey
517 assert_equal 2234 [r get mykey]
518
519 # Shouldn't change encoding when nothing is set
520 r set mykey 1234
521 assert_encoding int mykey
522 assert_equal 4 [r setrange mykey 0 ""]
523 assert_encoding int mykey
524 assert_equal 1234 [r get mykey]
525
526 r set mykey 1234
527 assert_encoding int mykey
528 assert_equal 4 [r setrange mykey 1 3]
529 assert_encoding raw mykey
530 assert_equal 1334 [r get mykey]
531
532 r set mykey 1234
533 assert_encoding int mykey
534 assert_equal 6 [r setrange mykey 5 2]
535 assert_encoding raw mykey
536 assert_equal "1234\0002" [r get mykey]
537 }
538
539 test "SETRANGE against key with wrong type" {
540 r del mykey
541 r lpush mykey "foo"
542 assert_error "*wrong kind*" {r setrange mykey 0 bar}
543 }
544
545 test "SETRANGE with out of range offset" {
546 r del mykey
547 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
548
549 r set mykey "hello"
550 assert_error "*out of range*" {r setrange mykey -1 world}
551 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
552 }
553
554 test "GETRANGE against non-existing key" {
555 r del mykey
556 assert_equal "" [r getrange mykey 0 -1]
557 }
558
559 test "GETRANGE against string value" {
560 r set mykey "Hello World"
561 assert_equal "Hell" [r getrange mykey 0 3]
562 assert_equal "Hello World" [r getrange mykey 0 -1]
563 assert_equal "orld" [r getrange mykey -4 -1]
564 assert_equal "" [r getrange mykey 5 3]
565 assert_equal " World" [r getrange mykey 5 5000]
566 assert_equal "Hello World" [r getrange mykey -5000 10000]
567 }
568
569 test "GETRANGE against integer-encoded value" {
570 r set mykey 1234
571 assert_equal "123" [r getrange mykey 0 2]
572 assert_equal "1234" [r getrange mykey 0 -1]
573 assert_equal "234" [r getrange mykey -3 -1]
574 assert_equal "" [r getrange mykey 5 3]
575 assert_equal "4" [r getrange mykey 3 5000]
576 assert_equal "1234" [r getrange mykey -5000 10000]
577 }
578
579 test "GETRANGE fuzzing" {
580 for {set i 0} {$i < 1000} {incr i} {
581 r set bin [set bin [randstring 0 1024 binary]]
582 set _start [set start [randomInt 1500]]
583 set _end [set end [randomInt 1500]]
584 if {$_start < 0} {set _start "end-[abs($_start)-1]"}
585 if {$_end < 0} {set _end "end-[abs($_end)-1]"}
586 assert_equal [string range $bin $_start $_end] [r getrange bin $start $end]
587 }
588 }
589 }