4 "list-max-ziplist-value" 16
5 "list-max-ziplist-entries" 256
8 source "tests/unit/type/list-common.tcl"
10 test
{LPUSH
, RPUSH
, LLENGTH
, LINDEX
- ziplist
} {
11 # first lpush then rpush
12 assert_equal
1 [r lpush myziplist1 a
]
13 assert_equal
2 [r rpush myziplist1 b
]
14 assert_equal
3 [r rpush myziplist1 c
]
15 assert_equal
3 [r llen myziplist1
]
16 assert_equal a
[r
lindex myziplist1
0]
17 assert_equal b
[r
lindex myziplist1
1]
18 assert_equal c
[r
lindex myziplist1
2]
19 assert_encoding ziplist myziplist1
21 # first rpush then lpush
22 assert_equal
1 [r rpush myziplist2 a
]
23 assert_equal
2 [r lpush myziplist2 b
]
24 assert_equal
3 [r lpush myziplist2 c
]
25 assert_equal
3 [r llen myziplist2
]
26 assert_equal c
[r
lindex myziplist2
0]
27 assert_equal b
[r
lindex myziplist2
1]
28 assert_equal a
[r
lindex myziplist2
2]
29 assert_equal
{} [r
lindex myziplist2
3]
30 assert_encoding ziplist myziplist2
33 test
{LPUSH
, RPUSH
, LLENGTH
, LINDEX
- regular
list} {
34 # first lpush then rpush
35 assert_equal
1 [r lpush mylist1
$largevalue(linkedlist
)]
36 assert_encoding linkedlist mylist1
37 assert_equal
2 [r rpush mylist1 b
]
38 assert_equal
3 [r rpush mylist1 c
]
39 assert_equal
3 [r llen mylist1
]
40 assert_equal
$largevalue(linkedlist
) [r
lindex mylist1
0]
41 assert_equal b
[r
lindex mylist1
1]
42 assert_equal c
[r
lindex mylist1
2]
43 assert_equal
{} [r
lindex mylist1
3]
45 # first rpush then lpush
46 assert_equal
1 [r rpush mylist2
$largevalue(linkedlist
)]
47 assert_encoding linkedlist mylist2
48 assert_equal
2 [r lpush mylist2 b
]
49 assert_equal
3 [r lpush mylist2 c
]
50 assert_equal
3 [r llen mylist2
]
51 assert_equal c
[r
lindex mylist2
0]
52 assert_equal b
[r
lindex mylist2
1]
53 assert_equal
$largevalue(linkedlist
) [r
lindex mylist2
2]
54 assert_equal
{} [r
lindex mylist2
3]
57 test
{Variadic RPUSH
/LPUSH
} {
59 assert_equal
4 [r lpush mylist a b c d
]
60 assert_equal
8 [r rpush mylist
0 1 2 3]
61 assert_equal
{d c b a
0 1 2 3} [r
lrange mylist
0 -1]
64 test
{DEL a
list - ziplist
} {
65 assert_equal
1 [r del myziplist2
]
66 assert_equal
0 [r exists myziplist2
]
67 assert_equal
0 [r llen myziplist2
]
70 test
{DEL a
list - regular
list} {
71 assert_equal
1 [r del mylist2
]
72 assert_equal
0 [r exists mylist2
]
73 assert_equal
0 [r llen mylist2
]
76 proc create_ziplist
{key entries
} {
78 foreach entry $entries { r rpush
$key $entry }
79 assert_encoding ziplist
$key
82 proc create_linkedlist
{key entries
} {
84 foreach entry $entries { r rpush
$key $entry }
85 assert_encoding linkedlist
$key
88 foreach {type large
} [array get largevalue
] {
89 test
"BLPOP, BRPOP: single existing list - $type" {
90 set rd
[redis_deferring_client
]
91 create_
$type blist
"a b $large c d"
94 assert_equal
{blist a
} [$rd read]
96 assert_equal
{blist d
} [$rd read]
99 assert_equal
{blist b
} [$rd read]
101 assert_equal
{blist c
} [$rd read]
104 test
"BLPOP, BRPOP: multiple existing lists - $type" {
105 set rd
[redis_deferring_client
]
106 create_
$type blist1
"a $large c"
107 create_
$type blist2
"d $large f"
109 $rd blpop blist1 blist2
1
110 assert_equal
{blist1 a
} [$rd read]
111 $rd brpop blist1 blist2
1
112 assert_equal
{blist1 c
} [$rd read]
113 assert_equal
1 [r llen blist1
]
114 assert_equal
3 [r llen blist2
]
116 $rd blpop blist2 blist1
1
117 assert_equal
{blist2 d
} [$rd read]
118 $rd brpop blist2 blist1
1
119 assert_equal
{blist2 f
} [$rd read]
120 assert_equal
1 [r llen blist1
]
121 assert_equal
1 [r llen blist2
]
124 test
"BLPOP, BRPOP: second list has an entry - $type" {
125 set rd
[redis_deferring_client
]
127 create_
$type blist2
"d $large f"
129 $rd blpop blist1 blist2
1
130 assert_equal
{blist2 d
} [$rd read]
131 $rd brpop blist1 blist2
1
132 assert_equal
{blist2 f
} [$rd read]
133 assert_equal
0 [r llen blist1
]
134 assert_equal
1 [r llen blist2
]
137 test
"BRPOPLPUSH - $type" {
140 set rd
[redis_deferring_client
]
141 create_
$type blist
"a b $large c d"
143 $rd brpoplpush blist target
1
144 assert_equal d
[$rd read]
146 assert_equal d
[r rpop target
]
147 assert_equal
"a b $large c" [r
lrange blist
0 -1]
151 test
"BLPOP with variadic LPUSH" {
152 set rd
[redis_deferring_client
]
154 if {$::valgrind} {after 100}
156 if {$::valgrind} {after 100}
157 assert_equal
2 [r lpush blist foo bar
]
158 if {$::valgrind} {after 100}
159 assert_equal
{blist foo
} [$rd read]
160 assert_equal bar
[lindex [r
lrange blist
0 -1] 0]
163 test
"BRPOPLPUSH with zero timeout should block indefinitely" {
164 set rd
[redis_deferring_client
]
166 $rd brpoplpush blist target
0
169 assert_equal foo
[$rd read]
170 assert_equal
{foo
} [r
lrange target
0 -1]
173 test
"BRPOPLPUSH with a client BLPOPing the target list" {
174 set rd
[redis_deferring_client
]
175 set rd2
[redis_deferring_client
]
178 $rd brpoplpush blist target
0
181 assert_equal foo
[$rd read]
182 assert_equal
{target foo
} [$rd2 read]
183 assert_equal
0 [r exists target
]
186 test
"BRPOPLPUSH with wrong source type" {
187 set rd
[redis_deferring_client
]
190 $rd brpoplpush blist target
1
191 assert_error
"ERR*wrong kind*" {$rd read}
194 test
"BRPOPLPUSH with wrong destination type" {
195 set rd
[redis_deferring_client
]
199 $rd brpoplpush blist target
1
200 assert_error
"ERR*wrong kind*" {$rd read}
202 set rd
[redis_deferring_client
]
205 $rd brpoplpush blist target
0
208 assert_error
"ERR*wrong kind*" {$rd read}
209 assert_equal
{foo
} [r
lrange blist
0 -1]
212 test
"BRPOPLPUSH with multiple blocked clients" {
213 set rd1
[redis_deferring_client
]
214 set rd2
[redis_deferring_client
]
215 r del blist target1 target2
217 $rd1 brpoplpush blist target1
0
218 $rd2 brpoplpush blist target2
0
221 assert_error
"ERR*wrong kind*" {$rd1 read}
222 assert_equal
{foo
} [$rd2 read]
223 assert_equal
{foo
} [r
lrange target2
0 -1]
226 test
"Linked BRPOPLPUSH" {
227 set rd1
[redis_deferring_client
]
228 set rd2
[redis_deferring_client
]
230 r del list1 list2 list3
232 $rd1 brpoplpush list1 list2
0
233 $rd2 brpoplpush list2 list3
0
237 assert_equal
{} [r
lrange list1
0 -1]
238 assert_equal
{} [r
lrange list2
0 -1]
239 assert_equal
{foo
} [r
lrange list3
0 -1]
242 test
"Circular BRPOPLPUSH" {
243 set rd1
[redis_deferring_client
]
244 set rd2
[redis_deferring_client
]
248 $rd1 brpoplpush list1 list2
0
249 $rd2 brpoplpush list2 list1
0
253 assert_equal
{foo
} [r
lrange list1
0 -1]
254 assert_equal
{} [r
lrange list2
0 -1]
257 test
"Self-referential BRPOPLPUSH" {
258 set rd
[redis_deferring_client
]
262 $rd brpoplpush blist blist
0
266 assert_equal
{foo
} [r
lrange blist
0 -1]
269 test
"BRPOPLPUSH inside a transaction" {
275 r brpoplpush xlist target
0
276 r brpoplpush xlist target
0
277 r brpoplpush xlist target
0
281 } {foo bar
{} {} {bar foo
}}
283 test
{BRPOPLPUSH timeout
} {
284 set rd
[redis_deferring_client
]
286 $rd brpoplpush foo_list bar_list
1
291 foreach {pop
} {BLPOP BRPOP
} {
292 test
"$pop: with single empty list argument" {
293 set rd
[redis_deferring_client
]
297 assert_equal
{blist1 foo
} [$rd read]
298 assert_equal
0 [r exists blist1
]
301 test
"$pop: with negative timeout" {
302 set rd
[redis_deferring_client
]
304 assert_error
"ERR*is negative*" {$rd read}
307 test
"$pop: with non-integer timeout" {
308 set rd
[redis_deferring_client
]
310 assert_error
"ERR*not an integer*" {$rd read}
313 test
"$pop: with zero timeout should block indefinitely" {
314 # To test this, use a timeout of 0 and wait a second.
315 # The blocking pop should still be waiting for a push.
316 set rd
[redis_deferring_client
]
320 assert_equal
{blist1 foo
} [$rd read]
323 test
"$pop: second argument is not a list" {
324 set rd
[redis_deferring_client
]
327 $rd $pop blist1 blist2
1
328 assert_error
"ERR*wrong kind*" {$rd read}
331 test
"$pop: timeout" {
332 set rd
[redis_deferring_client
]
334 $rd $pop blist1 blist2
1
335 assert_equal
{} [$rd read]
338 test
"$pop: arguments are empty" {
339 set rd
[redis_deferring_client
]
342 $rd $pop blist1 blist2
1
344 assert_equal
{blist1 foo
} [$rd read]
345 assert_equal
0 [r exists blist1
]
346 assert_equal
0 [r exists blist2
]
348 $rd $pop blist1 blist2
1
350 assert_equal
{blist2 foo
} [$rd read]
351 assert_equal
0 [r exists blist1
]
352 assert_equal
0 [r exists blist2
]
356 test
{BLPOP inside a transaction
} {
365 } {{xlist bar
} {xlist foo
} {}}
367 test
{LPUSHX
, RPUSHX
- generic
} {
369 assert_equal
0 [r lpushx xlist a
]
370 assert_equal
0 [r llen xlist
]
371 assert_equal
0 [r rpushx xlist a
]
372 assert_equal
0 [r llen xlist
]
375 foreach {type large
} [array get largevalue
] {
376 test
"LPUSHX, RPUSHX - $type" {
377 create_
$type xlist
"$large c"
378 assert_equal
3 [r rpushx xlist d
]
379 assert_equal
4 [r lpushx xlist a
]
380 assert_equal
"a $large c d" [r
lrange xlist
0 -1]
383 test
"LINSERT - $type" {
384 create_
$type xlist
"a $large c d"
385 assert_equal
5 [r
linsert xlist before c zz
]
386 assert_equal
"a $large zz c d" [r
lrange xlist
0 10]
387 assert_equal
6 [r
linsert xlist
after c yy
]
388 assert_equal
"a $large zz c yy d" [r
lrange xlist
0 10]
389 assert_equal
7 [r
linsert xlist
after d dd
]
390 assert_equal
-1 [r
linsert xlist
after bad ddd
]
391 assert_equal
"a $large zz c yy d dd" [r
lrange xlist
0 10]
392 assert_equal
8 [r
linsert xlist before a aa
]
393 assert_equal
-1 [r
linsert xlist before bad aaa
]
394 assert_equal
"aa a $large zz c yy d dd" [r
lrange xlist
0 10]
396 # check inserting integer encoded value
397 assert_equal
9 [r
linsert xlist before aa
42]
398 assert_equal
42 [r
lrange xlist
0 0]
402 test
{LPUSHX
, RPUSHX convert from ziplist to
list} {
403 set large
$largevalue(linkedlist
)
405 # convert when a large value is pushed
406 create_ziplist xlist a
407 assert_equal
2 [r rpushx xlist
$large]
408 assert_encoding linkedlist xlist
409 create_ziplist xlist a
410 assert_equal
2 [r lpushx xlist
$large]
411 assert_encoding linkedlist xlist
413 # convert when the length threshold is exceeded
414 create_ziplist xlist
[lrepeat
256 a
]
415 assert_equal
257 [r rpushx xlist b
]
416 assert_encoding linkedlist xlist
417 create_ziplist xlist
[lrepeat
256 a
]
418 assert_equal
257 [r lpushx xlist b
]
419 assert_encoding linkedlist xlist
422 test
{LINSERT convert from ziplist to
list} {
423 set large
$largevalue(linkedlist
)
425 # convert when a large value is inserted
426 create_ziplist xlist a
427 assert_equal
2 [r
linsert xlist before a
$large]
428 assert_encoding linkedlist xlist
429 create_ziplist xlist a
430 assert_equal
2 [r
linsert xlist
after a
$large]
431 assert_encoding linkedlist xlist
433 # convert when the length threshold is exceeded
434 create_ziplist xlist
[lrepeat
256 a
]
435 assert_equal
257 [r
linsert xlist before a a
]
436 assert_encoding linkedlist xlist
437 create_ziplist xlist
[lrepeat
256 a
]
438 assert_equal
257 [r
linsert xlist
after a a
]
439 assert_encoding linkedlist xlist
441 # don't convert when the value could not be inserted
442 create_ziplist xlist
[lrepeat
256 a
]
443 assert_equal
-1 [r
linsert xlist before foo a
]
444 assert_encoding ziplist xlist
445 create_ziplist xlist
[lrepeat
256 a
]
446 assert_equal
-1 [r
linsert xlist
after foo a
]
447 assert_encoding ziplist xlist
450 foreach {type num
} {ziplist
250 linkedlist
500} {
451 proc check_numbered_list_consistency
{key
} {
452 set len
[r llen
$key]
453 for {set i
0} {$i < $len} {incr i
} {
454 assert_equal
$i [r
lindex $key $i]
455 assert_equal
[expr $len-1-$i] [r
lindex $key [expr (-$i)-1]]
459 proc check_random_access_consistency
{key
} {
460 set len
[r llen
$key]
461 for {set i
0} {$i < $len} {incr i
} {
462 set rint
[expr int
(rand
()*$len)]
463 assert_equal
$rint [r
lindex $key $rint]
464 assert_equal
[expr $len-1-$rint] [r
lindex $key [expr (-$rint)-1]]
468 test
"LINDEX consistency test - $type" {
470 for {set i
0} {$i < $num} {incr i
} {
473 assert_encoding
$type mylist
474 check_numbered_list_consistency mylist
477 test
"LINDEX random access - $type" {
478 assert_encoding
$type mylist
479 check_random_access_consistency mylist
482 test
"Check if list is still ok after a DEBUG RELOAD - $type" {
484 assert_encoding
$type mylist
485 check_numbered_list_consistency mylist
486 check_random_access_consistency mylist
490 test
{LLEN against non-list value
error} {
493 assert_error ERR
* {r llen mylist
}
496 test
{LLEN against non existing key
} {
497 assert_equal
0 [r llen not-a-key
]
500 test
{LINDEX against non-list value
error} {
501 assert_error ERR
* {r
lindex mylist
0}
504 test
{LINDEX against non existing key
} {
505 assert_equal
"" [r
lindex not-a-key
10]
508 test
{LPUSH against non-list value
error} {
509 assert_error ERR
* {r lpush mylist
0}
512 test
{RPUSH against non-list value
error} {
513 assert_error ERR
* {r rpush mylist
0}
516 foreach {type large
} [array get largevalue
] {
517 test
"RPOPLPUSH base case - $type" {
518 r del mylist1 mylist2
519 create_
$type mylist1
"a $large c d"
520 assert_equal d
[r rpoplpush mylist1 mylist2
]
521 assert_equal c
[r rpoplpush mylist1 mylist2
]
522 assert_equal
"a $large" [r
lrange mylist1
0 -1]
523 assert_equal
"c d" [r
lrange mylist2
0 -1]
524 assert_encoding ziplist mylist2
527 test
"RPOPLPUSH with the same list as src and dst - $type" {
528 create_
$type mylist
"a $large c"
529 assert_equal
"a $large c" [r
lrange mylist
0 -1]
530 assert_equal c
[r rpoplpush mylist mylist
]
531 assert_equal
"c a $large" [r
lrange mylist
0 -1]
534 foreach {othertype otherlarge
} [array get largevalue
] {
535 test
"RPOPLPUSH with $type source and existing target $othertype" {
536 create_
$type srclist
"a b c $large"
537 create_
$othertype dstlist
"$otherlarge"
538 assert_equal
$large [r rpoplpush srclist dstlist
]
539 assert_equal c
[r rpoplpush srclist dstlist
]
540 assert_equal
"a b" [r
lrange srclist
0 -1]
541 assert_equal
"c $large $otherlarge" [r
lrange dstlist
0 -1]
543 # When we rpoplpush'ed a large value, dstlist should be
544 # converted to the same encoding as srclist.
545 if {$type eq
"linkedlist"} {
546 assert_encoding linkedlist dstlist
552 test
{RPOPLPUSH against non existing key
} {
553 r del srclist dstlist
554 assert_equal
{} [r rpoplpush srclist dstlist
]
555 assert_equal
0 [r exists srclist
]
556 assert_equal
0 [r exists dstlist
]
559 test
{RPOPLPUSH against non
list src key
} {
560 r del srclist dstlist
562 assert_error ERR
* {r rpoplpush srclist dstlist
}
563 assert_type
string srclist
564 assert_equal
0 [r exists newlist
]
567 test
{RPOPLPUSH against non
list dst key
} {
568 create_ziplist srclist
{a b c d
}
570 assert_error ERR
* {r rpoplpush srclist dstlist
}
571 assert_type
string dstlist
572 assert_equal
{a b c d
} [r
lrange srclist
0 -1]
575 test
{RPOPLPUSH against non existing src key
} {
576 r del srclist dstlist
577 assert_equal
{} [r rpoplpush srclist dstlist
]
580 foreach {type large
} [array get largevalue
] {
581 test
"Basic LPOP/RPOP - $type" {
582 create_
$type mylist
"$large 1 2"
583 assert_equal
$large [r lpop mylist
]
584 assert_equal
2 [r rpop mylist
]
585 assert_equal
1 [r lpop mylist
]
586 assert_equal
0 [r llen mylist
]
589 assert_equal
{} [r lpop mylist
]
590 assert_equal
{} [r rpop mylist
]
594 test
{LPOP
/RPOP against non
list value
} {
596 assert_error ERR
*kind
* {r lpop notalist
}
597 assert_error ERR
*kind
* {r rpop notalist
}
600 foreach {type num
} {ziplist
250 linkedlist
500} {
601 test
"Mass RPOP/LPOP - $type" {
604 for {set i
0} {$i < $num} {incr i
} {
608 assert_encoding
$type mylist
610 for {set i
0} {$i < [expr $num/2]} {incr i
} {
611 incr sum2
[r lpop mylist
]
612 incr sum2
[r rpop mylist
]
614 assert_equal
$sum1 $sum2
618 foreach {type large
} [array get largevalue
] {
619 test
"LRANGE basics - $type" {
620 create_
$type mylist
"$large 1 2 3 4 5 6 7 8 9"
621 assert_equal
{1 2 3 4 5 6 7 8} [r
lrange mylist
1 -2]
622 assert_equal
{7 8 9} [r
lrange mylist
-3 -1]
623 assert_equal
{4} [r
lrange mylist
4 4]
626 test
"LRANGE inverted indexes - $type" {
627 create_
$type mylist
"$large 1 2 3 4 5 6 7 8 9"
628 assert_equal
{} [r
lrange mylist
6 2]
631 test
"LRANGE out of range indexes including the full list - $type" {
632 create_
$type mylist
"$large 1 2 3"
633 assert_equal
"$large 1 2 3" [r
lrange mylist
-1000 1000]
636 test
"LRANGE out of range negative end index - $type" {
637 create_
$type mylist
"$large 1 2 3"
638 assert_equal
$large [r
lrange mylist
0 -4]
639 assert_equal
{} [r
lrange mylist
0 -5]
643 test
{LRANGE against non existing key
} {
644 assert_equal
{} [r
lrange nosuchkey
0 1]
647 foreach {type large
} [array get largevalue
] {
648 proc trim_list
{type min max
} {
651 create_
$type mylist
"1 2 3 4 $large"
652 r ltrim mylist
$min $max
656 test
"LTRIM basics - $type" {
657 assert_equal
"1" [trim_list
$type 0 0]
658 assert_equal
"1 2" [trim_list
$type 0 1]
659 assert_equal
"1 2 3" [trim_list
$type 0 2]
660 assert_equal
"2 3" [trim_list
$type 1 2]
661 assert_equal
"2 3 4 $large" [trim_list
$type 1 -1]
662 assert_equal
"2 3 4" [trim_list
$type 1 -2]
663 assert_equal
"4 $large" [trim_list
$type -2 -1]
664 assert_equal
"$large" [trim_list
$type -1 -1]
665 assert_equal
"1 2 3 4 $large" [trim_list
$type -5 -1]
666 assert_equal
"1 2 3 4 $large" [trim_list
$type -10 10]
667 assert_equal
"1 2 3 4 $large" [trim_list
$type 0 5]
668 assert_equal
"1 2 3 4 $large" [trim_list
$type 0 10]
671 test
"LTRIM out of range negative end index - $type" {
672 assert_equal
{1} [trim_list
$type 0 -5]
673 assert_equal
{} [trim_list
$type 0 -6]
678 foreach {type large
} [array get largevalue
] {
679 test
"LSET - $type" {
680 create_
$type mylist
"99 98 $large 96 95"
683 assert_equal
"99 foo $large 96 bar" [r
lrange mylist
0 -1]
686 test
"LSET out of range index - $type" {
687 assert_error ERR
*range
* {r
lset mylist
10 foo
}
691 test
{LSET against non existing key
} {
692 assert_error ERR
*key
* {r
lset nosuchkey
10 foo
}
695 test
{LSET against non
list value
} {
697 assert_error ERR
*value
* {r
lset nolist
0 foo
}
700 foreach {type e
} [array get largevalue
] {
701 test
"LREM remove all the occurrences - $type" {
702 create_
$type mylist
"$e foo bar foobar foobared zap bar test foo"
703 assert_equal
2 [r lrem mylist
0 bar
]
704 assert_equal
"$e foo foobar foobared zap test foo" [r
lrange mylist
0 -1]
707 test
"LREM remove the first occurrence - $type" {
708 assert_equal
1 [r lrem mylist
1 foo
]
709 assert_equal
"$e foobar foobared zap test foo" [r
lrange mylist
0 -1]
712 test
"LREM remove non existing element - $type" {
713 assert_equal
0 [r lrem mylist
1 nosuchelement
]
714 assert_equal
"$e foobar foobared zap test foo" [r
lrange mylist
0 -1]
717 test
"LREM starting from tail with negative count - $type" {
718 create_
$type mylist
"$e foo bar foobar foobared zap bar test foo foo"
719 assert_equal
1 [r lrem mylist
-1 bar
]
720 assert_equal
"$e foo bar foobar foobared zap test foo foo" [r
lrange mylist
0 -1]
723 test
"LREM starting from tail with negative count (2) - $type" {
724 assert_equal
2 [r lrem mylist
-2 foo
]
725 assert_equal
"$e foo bar foobar foobared zap test" [r
lrange mylist
0 -1]
728 test
"LREM deleting objects that may be int encoded - $type" {
729 create_
$type myotherlist
"$e 1 2 3"
730 assert_equal
1 [r lrem myotherlist
1 2]
731 assert_equal
3 [r llen myotherlist
]
735 test
"Regression for bug 593 - chaining BRPOPLPUSH with other blocking cmds" {
736 set rd1
[redis_deferring_client
]
737 set rd2
[redis_deferring_client
]
739 $rd1 brpoplpush a b
0
740 $rd1 brpoplpush a b
0
741 $rd2 brpoplpush b c
0