]> git.saurik.com Git - redis.git/blob - tests/unit/basic.tcl
Add test cases for GETRANGE against integer-encoded strings
[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 r strlen notakey
366 } {0}
367
368 test {STRLEN against integer} {
369 r set myinteger -555
370 r strlen myinteger
371 } {4}
372
373 test {STRLEN against plain string} {
374 r set mystring "foozzz0123456789 baz"
375 r strlen mystring
376 }
377
378 test "SETBIT against non-existing key" {
379 r del mykey
380
381 # Setting 2nd bit to on is integer 64, ascii "@"
382 assert_equal 1 [r setbit mykey 1 1]
383 assert_equal "@" [r get mykey]
384 }
385
386 test "SETBIT against string-encoded key" {
387 # Single byte with 2nd bit set
388 r set mykey "@"
389
390 # 64 + 32 = 96 => ascii "`" (backtick)
391 assert_equal 1 [r setbit mykey 2 1]
392 assert_equal "`" [r get mykey]
393 }
394
395 test "SETBIT against integer-encoded key" {
396 r set mykey 1
397 assert_encoding int mykey
398
399 # Ascii "1" is integer 49 = 00 11 00 01
400 # Setting 7th bit = 51 => ascii "3"
401 assert_equal 1 [r setbit mykey 6 1]
402 assert_equal "3" [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 "GETBIT against non-existing key" {
426 r del mykey
427 assert_equal 0 [r getbit mykey 0]
428 }
429
430 test "GETBIT against string-encoded key" {
431 # Single byte with 2nd and 3rd bit set
432 r set mykey "`"
433
434 # In-range
435 assert_equal 0 [r getbit mykey 0]
436 assert_equal 1 [r getbit mykey 1]
437 assert_equal 1 [r getbit mykey 2]
438 assert_equal 0 [r getbit mykey 3]
439
440 # Out-range
441 assert_equal 0 [r getbit mykey 8]
442 assert_equal 0 [r getbit mykey 100]
443 assert_equal 0 [r getbit mykey 10000]
444 }
445
446 test "GETBIT against integer-encoded key" {
447 r set mykey 1
448 assert_encoding int mykey
449
450 # Ascii "1" is integer 49 = 00 11 00 01
451 assert_equal 0 [r getbit mykey 0]
452 assert_equal 0 [r getbit mykey 1]
453 assert_equal 1 [r getbit mykey 2]
454 assert_equal 1 [r getbit mykey 3]
455
456 # Out-range
457 assert_equal 0 [r getbit mykey 8]
458 assert_equal 0 [r getbit mykey 100]
459 assert_equal 0 [r getbit mykey 10000]
460 }
461
462 test "SETRANGE against non-existing key" {
463 r del mykey
464 assert_equal 3 [r setrange mykey 0 foo]
465 assert_equal "foo" [r get mykey]
466
467 r del mykey
468 assert_equal 0 [r setrange mykey 0 ""]
469 assert_equal 0 [r exists mykey]
470
471 r del mykey
472 assert_equal 4 [r setrange mykey 1 foo]
473 assert_equal "\000foo" [r get mykey]
474
475 r del mykey
476 assert_equal 3 [r setrange mykey -1 foo]
477 assert_equal "foo" [r get mykey]
478
479 r del mykey
480 assert_equal 3 [r setrange mykey -100 foo]
481 assert_equal "foo" [r get mykey]
482 }
483
484 test "SETRANGE against string-encoded key" {
485 r set mykey "foo"
486 assert_equal 3 [r setrange mykey 0 b]
487 assert_equal "boo" [r get mykey]
488
489 r set mykey "foo"
490 assert_equal 3 [r setrange mykey 0 ""]
491 assert_equal "foo" [r get mykey]
492
493 r set mykey "foo"
494 assert_equal 3 [r setrange mykey 1 b]
495 assert_equal "fbo" [r get mykey]
496
497 r set mykey "foo"
498 assert_equal 6 [r setrange mykey -1 bar]
499 assert_equal "foobar" [r get mykey]
500
501 r set mykey "foo"
502 assert_equal 5 [r setrange mykey -2 bar]
503 assert_equal "fobar" [r get mykey]
504
505 r set mykey "foo"
506 assert_equal 3 [r setrange mykey -20 bar]
507 assert_equal "bar" [r get mykey]
508
509 r set mykey "foo"
510 assert_equal 7 [r setrange mykey 4 bar]
511 assert_equal "foo\000bar" [r get mykey]
512 }
513
514 test "SETRANGE against integer-encoded key" {
515 r set mykey 1234
516 assert_encoding int mykey
517 assert_equal 4 [r setrange mykey 0 2]
518 assert_encoding raw mykey
519 assert_equal 2234 [r get mykey]
520
521 # Shouldn't change encoding when nothing is set
522 r set mykey 1234
523 assert_encoding int mykey
524 assert_equal 4 [r setrange mykey 0 ""]
525 assert_encoding int mykey
526 assert_equal 1234 [r get mykey]
527
528 r set mykey 1234
529 assert_encoding int mykey
530 assert_equal 4 [r setrange mykey 1 3]
531 assert_encoding raw mykey
532 assert_equal 1334 [r get mykey]
533
534 r set mykey 1234
535 assert_encoding int mykey
536 assert_equal 5 [r setrange mykey -1 5]
537 assert_encoding raw mykey
538 assert_equal 12345 [r get mykey]
539
540 r set mykey 1234
541 assert_encoding int mykey
542 assert_equal 4 [r setrange mykey -2 5]
543 assert_encoding raw mykey
544 assert_equal 1235 [r get mykey]
545
546 r set mykey 1234
547 assert_encoding int mykey
548 assert_equal 6 [r setrange mykey 5 2]
549 assert_encoding raw mykey
550 assert_equal "1234\0002" [r get mykey]
551 }
552
553 test "SETRANGE against key with wrong type" {
554 r del mykey
555 r lpush mykey "foo"
556 assert_error "*wrong kind*" {r setrange mykey 0 bar}
557 }
558
559 test "SETRANGE with out of range offset" {
560 r del mykey
561 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
562 r set mykey "hello"
563 assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
564 }
565
566 test "GETRANGE against non-existing key" {
567 r del mykey
568 assert_equal "" [r getrange mykey 0 -1]
569 }
570
571 test "GETRANGE against string value" {
572 r set mykey "Hello World"
573 assert_equal "Hell" [r getrange mykey 0 3]
574 assert_equal "Hello World" [r getrange mykey 0 -1]
575 assert_equal "orld" [r getrange mykey -4 -1]
576 assert_equal "" [r getrange mykey 5 3]
577 assert_equal " World" [r getrange mykey 5 5000]
578 assert_equal "Hello World" [r getrange mykey -5000 10000]
579 }
580
581 test "GETRANGE against integer-encoded value" {
582 r set mykey 1234
583 assert_equal "123" [r getrange mykey 0 2]
584 assert_equal "1234" [r getrange mykey 0 -1]
585 assert_equal "234" [r getrange mykey -3 -1]
586 assert_equal "" [r getrange mykey 5 3]
587 assert_equal "4" [r getrange mykey 3 5000]
588 assert_equal "1234" [r getrange mykey -5000 10000]
589 }
590
591 test "GETRANGE fuzzing" {
592 for {set i 0} {$i < 1000} {incr i} {
593 r set bin [set bin [randstring 0 1024 binary]]
594 set _start [set start [randomInt 1500]]
595 set _end [set end [randomInt 1500]]
596 if {$_start < 0} {set _start "end-[abs($_start)-1]"}
597 if {$_end < 0} {set _end "end-[abs($_end)-1]"}
598 assert_equal [string range $bin $_start $_end] [r getrange bin $start $end]
599 }
600 }
601 }