]> git.saurik.com Git - redis.git/blob - tests/unit/type/list.tcl
642762cff561ddf1df1a58241aad42ada38ac926
[redis.git] / tests / unit / type / list.tcl
1 start_server {
2 tags {"list"}
3 overrides {
4 "list-max-ziplist-value" 16
5 "list-max-ziplist-entries" 256
6 }
7 } {
8 source "tests/unit/type/list-common.tcl"
9
10 test {LPUSH, RPUSH, LLENGTH, LINDEX, LPOP - 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_equal {} [r lindex myziplist2 3]
20 assert_equal c [r rpop myziplist1]
21 assert_equal a [r lpop myziplist1]
22 assert_encoding ziplist myziplist1
23
24 # first rpush then lpush
25 assert_equal 1 [r rpush myziplist2 a]
26 assert_equal 2 [r lpush myziplist2 b]
27 assert_equal 3 [r lpush myziplist2 c]
28 assert_equal 3 [r llen myziplist2]
29 assert_equal c [r lindex myziplist2 0]
30 assert_equal b [r lindex myziplist2 1]
31 assert_equal a [r lindex myziplist2 2]
32 assert_equal {} [r lindex myziplist2 3]
33 assert_equal a [r rpop myziplist2]
34 assert_equal c [r lpop myziplist2]
35 assert_encoding ziplist myziplist2
36 }
37
38 test {LPUSH, RPUSH, LLENGTH, LINDEX, LPOP - regular list} {
39 # first lpush then rpush
40 assert_equal 1 [r lpush mylist1 $largevalue(linkedlist)]
41 assert_encoding linkedlist mylist1
42 assert_equal 2 [r rpush mylist1 b]
43 assert_equal 3 [r rpush mylist1 c]
44 assert_equal 3 [r llen mylist1]
45 assert_equal $largevalue(linkedlist) [r lindex mylist1 0]
46 assert_equal b [r lindex mylist1 1]
47 assert_equal c [r lindex mylist1 2]
48 assert_equal {} [r lindex mylist1 3]
49 assert_equal c [r rpop mylist1]
50 assert_equal $largevalue(linkedlist) [r lpop mylist1]
51
52 # first rpush then lpush
53 assert_equal 1 [r rpush mylist2 $largevalue(linkedlist)]
54 assert_encoding linkedlist mylist2
55 assert_equal 2 [r lpush mylist2 b]
56 assert_equal 3 [r lpush mylist2 c]
57 assert_equal 3 [r llen mylist2]
58 assert_equal c [r lindex mylist2 0]
59 assert_equal b [r lindex mylist2 1]
60 assert_equal $largevalue(linkedlist) [r lindex mylist2 2]
61 assert_equal {} [r lindex mylist2 3]
62 assert_equal $largevalue(linkedlist) [r rpop mylist2]
63 assert_equal c [r lpop mylist2]
64 }
65
66 test {R/LPOP against empty list} {
67 r lpop non-existing-list
68 } {}
69
70 test {Variadic RPUSH/LPUSH} {
71 r del mylist
72 assert_equal 4 [r lpush mylist a b c d]
73 assert_equal 8 [r rpush mylist 0 1 2 3]
74 assert_equal {d c b a 0 1 2 3} [r lrange mylist 0 -1]
75 }
76
77 test {DEL a list - ziplist} {
78 assert_equal 1 [r del myziplist2]
79 assert_equal 0 [r exists myziplist2]
80 assert_equal 0 [r llen myziplist2]
81 }
82
83 test {DEL a list - regular list} {
84 assert_equal 1 [r del mylist2]
85 assert_equal 0 [r exists mylist2]
86 assert_equal 0 [r llen mylist2]
87 }
88
89 proc create_ziplist {key entries} {
90 r del $key
91 foreach entry $entries { r rpush $key $entry }
92 assert_encoding ziplist $key
93 }
94
95 proc create_linkedlist {key entries} {
96 r del $key
97 foreach entry $entries { r rpush $key $entry }
98 assert_encoding linkedlist $key
99 }
100
101 foreach {type large} [array get largevalue] {
102 test "BLPOP, BRPOP: single existing list - $type" {
103 set rd [redis_deferring_client]
104 create_$type blist "a b $large c d"
105
106 $rd blpop blist 1
107 assert_equal {blist a} [$rd read]
108 $rd brpop blist 1
109 assert_equal {blist d} [$rd read]
110
111 $rd blpop blist 1
112 assert_equal {blist b} [$rd read]
113 $rd brpop blist 1
114 assert_equal {blist c} [$rd read]
115 }
116
117 test "BLPOP, BRPOP: multiple existing lists - $type" {
118 set rd [redis_deferring_client]
119 create_$type blist1 "a $large c"
120 create_$type blist2 "d $large f"
121
122 $rd blpop blist1 blist2 1
123 assert_equal {blist1 a} [$rd read]
124 $rd brpop blist1 blist2 1
125 assert_equal {blist1 c} [$rd read]
126 assert_equal 1 [r llen blist1]
127 assert_equal 3 [r llen blist2]
128
129 $rd blpop blist2 blist1 1
130 assert_equal {blist2 d} [$rd read]
131 $rd brpop blist2 blist1 1
132 assert_equal {blist2 f} [$rd read]
133 assert_equal 1 [r llen blist1]
134 assert_equal 1 [r llen blist2]
135 }
136
137 test "BLPOP, BRPOP: second list has an entry - $type" {
138 set rd [redis_deferring_client]
139 r del blist1
140 create_$type blist2 "d $large f"
141
142 $rd blpop blist1 blist2 1
143 assert_equal {blist2 d} [$rd read]
144 $rd brpop blist1 blist2 1
145 assert_equal {blist2 f} [$rd read]
146 assert_equal 0 [r llen blist1]
147 assert_equal 1 [r llen blist2]
148 }
149
150 test "BRPOPLPUSH - $type" {
151 r del target
152
153 set rd [redis_deferring_client]
154 create_$type blist "a b $large c d"
155
156 $rd brpoplpush blist target 1
157 assert_equal d [$rd read]
158
159 assert_equal d [r rpop target]
160 assert_equal "a b $large c" [r lrange blist 0 -1]
161 }
162 }
163
164 test "BLPOP, LPUSH + DEL should not awake blocked client" {
165 set rd [redis_deferring_client]
166 r del list
167
168 $rd blpop list 0
169 r multi
170 r lpush list a
171 r del list
172 r exec
173 r del list
174 r lpush list b
175 $rd read
176 } {list b}
177
178 test "BLPOP, LPUSH + DEL + SET should not awake blocked client" {
179 set rd [redis_deferring_client]
180 r del list
181
182 $rd blpop list 0
183 r multi
184 r lpush list a
185 r del list
186 r set list foo
187 r exec
188 r del list
189 r lpush list b
190 $rd read
191 } {list b}
192
193 test "MULTI/EXEC is isolated from the point of view of BLPOP" {
194 set rd [redis_deferring_client]
195 r del list
196 $rd blpop list 0
197 r multi
198 r lpush list a
199 r lpush list b
200 r lpush list c
201 r exec
202 $rd read
203 } {list c}
204
205 test "BLPOP with variadic LPUSH" {
206 set rd [redis_deferring_client]
207 r del blist target
208 if {$::valgrind} {after 100}
209 $rd blpop blist 0
210 if {$::valgrind} {after 100}
211 assert_equal 2 [r lpush blist foo bar]
212 if {$::valgrind} {after 100}
213 assert_equal {blist bar} [$rd read]
214 assert_equal foo [lindex [r lrange blist 0 -1] 0]
215 }
216
217 test "BRPOPLPUSH with zero timeout should block indefinitely" {
218 set rd [redis_deferring_client]
219 r del blist target
220 $rd brpoplpush blist target 0
221 after 1000
222 r rpush blist foo
223 assert_equal foo [$rd read]
224 assert_equal {foo} [r lrange target 0 -1]
225 }
226
227 test "BRPOPLPUSH with a client BLPOPing the target list" {
228 set rd [redis_deferring_client]
229 set rd2 [redis_deferring_client]
230 r del blist target
231 $rd2 blpop target 0
232 $rd brpoplpush blist target 0
233 after 1000
234 r rpush blist foo
235 assert_equal foo [$rd read]
236 assert_equal {target foo} [$rd2 read]
237 assert_equal 0 [r exists target]
238 }
239
240 test "BRPOPLPUSH with wrong source type" {
241 set rd [redis_deferring_client]
242 r del blist target
243 r set blist nolist
244 $rd brpoplpush blist target 1
245 assert_error "WRONGTYPE*" {$rd read}
246 }
247
248 test "BRPOPLPUSH with wrong destination type" {
249 set rd [redis_deferring_client]
250 r del blist target
251 r set target nolist
252 r lpush blist foo
253 $rd brpoplpush blist target 1
254 assert_error "WRONGTYPE*" {$rd read}
255
256 set rd [redis_deferring_client]
257 r del blist target
258 r set target nolist
259 $rd brpoplpush blist target 0
260 after 1000
261 r rpush blist foo
262 assert_error "WRONGTYPE*" {$rd read}
263 assert_equal {foo} [r lrange blist 0 -1]
264 }
265
266 test "BRPOPLPUSH maintains order of elements after failure" {
267 set rd [redis_deferring_client]
268 r del blist target
269 r set target nolist
270 $rd brpoplpush blist target 0
271 r rpush blist a b c
272 assert_error "WRONGTYPE*" {$rd read}
273 r lrange blist 0 -1
274 } {a b c}
275
276 test "BRPOPLPUSH with multiple blocked clients" {
277 set rd1 [redis_deferring_client]
278 set rd2 [redis_deferring_client]
279 r del blist target1 target2
280 r set target1 nolist
281 $rd1 brpoplpush blist target1 0
282 $rd2 brpoplpush blist target2 0
283 r lpush blist foo
284
285 assert_error "WRONGTYPE*" {$rd1 read}
286 assert_equal {foo} [$rd2 read]
287 assert_equal {foo} [r lrange target2 0 -1]
288 }
289
290 test "Linked BRPOPLPUSH" {
291 set rd1 [redis_deferring_client]
292 set rd2 [redis_deferring_client]
293
294 r del list1 list2 list3
295
296 $rd1 brpoplpush list1 list2 0
297 $rd2 brpoplpush list2 list3 0
298
299 r rpush list1 foo
300
301 assert_equal {} [r lrange list1 0 -1]
302 assert_equal {} [r lrange list2 0 -1]
303 assert_equal {foo} [r lrange list3 0 -1]
304 }
305
306 test "Circular BRPOPLPUSH" {
307 set rd1 [redis_deferring_client]
308 set rd2 [redis_deferring_client]
309
310 r del list1 list2
311
312 $rd1 brpoplpush list1 list2 0
313 $rd2 brpoplpush list2 list1 0
314
315 r rpush list1 foo
316
317 assert_equal {foo} [r lrange list1 0 -1]
318 assert_equal {} [r lrange list2 0 -1]
319 }
320
321 test "Self-referential BRPOPLPUSH" {
322 set rd [redis_deferring_client]
323
324 r del blist
325
326 $rd brpoplpush blist blist 0
327
328 r rpush blist foo
329
330 assert_equal {foo} [r lrange blist 0 -1]
331 }
332
333 test "BRPOPLPUSH inside a transaction" {
334 r del xlist target
335 r lpush xlist foo
336 r lpush xlist bar
337
338 r multi
339 r brpoplpush xlist target 0
340 r brpoplpush xlist target 0
341 r brpoplpush xlist target 0
342 r lrange xlist 0 -1
343 r lrange target 0 -1
344 r exec
345 } {foo bar {} {} {bar foo}}
346
347 test "PUSH resulting from BRPOPLPUSH affect WATCH" {
348 set blocked_client [redis_deferring_client]
349 set watching_client [redis_deferring_client]
350 r del srclist dstlist somekey
351 r set somekey somevalue
352 $blocked_client brpoplpush srclist dstlist 0
353 $watching_client watch dstlist
354 $watching_client read
355 $watching_client multi
356 $watching_client read
357 $watching_client get somekey
358 $watching_client read
359 r lpush srclist element
360 $watching_client exec
361 $watching_client read
362 } {}
363
364 test "BRPOPLPUSH does not affect WATCH while still blocked" {
365 set blocked_client [redis_deferring_client]
366 set watching_client [redis_deferring_client]
367 r del srclist dstlist somekey
368 r set somekey somevalue
369 $blocked_client brpoplpush srclist dstlist 0
370 $watching_client watch dstlist
371 $watching_client read
372 $watching_client multi
373 $watching_client read
374 $watching_client get somekey
375 $watching_client read
376 $watching_client exec
377 # Blocked BLPOPLPUSH may create problems, unblock it.
378 r lpush srclist element
379 $watching_client read
380 } {somevalue}
381
382 test {BRPOPLPUSH timeout} {
383 set rd [redis_deferring_client]
384
385 $rd brpoplpush foo_list bar_list 1
386 after 2000
387 $rd read
388 } {}
389
390 foreach {pop} {BLPOP BRPOP} {
391 test "$pop: with single empty list argument" {
392 set rd [redis_deferring_client]
393 r del blist1
394 $rd $pop blist1 1
395 r rpush blist1 foo
396 assert_equal {blist1 foo} [$rd read]
397 assert_equal 0 [r exists blist1]
398 }
399
400 test "$pop: with negative timeout" {
401 set rd [redis_deferring_client]
402 $rd $pop blist1 -1
403 assert_error "ERR*is negative*" {$rd read}
404 }
405
406 test "$pop: with non-integer timeout" {
407 set rd [redis_deferring_client]
408 $rd $pop blist1 1.1
409 assert_error "ERR*not an integer*" {$rd read}
410 }
411
412 test "$pop: with zero timeout should block indefinitely" {
413 # To test this, use a timeout of 0 and wait a second.
414 # The blocking pop should still be waiting for a push.
415 set rd [redis_deferring_client]
416 $rd $pop blist1 0
417 after 1000
418 r rpush blist1 foo
419 assert_equal {blist1 foo} [$rd read]
420 }
421
422 test "$pop: second argument is not a list" {
423 set rd [redis_deferring_client]
424 r del blist1 blist2
425 r set blist2 nolist
426 $rd $pop blist1 blist2 1
427 assert_error "WRONGTYPE*" {$rd read}
428 }
429
430 test "$pop: timeout" {
431 set rd [redis_deferring_client]
432 r del blist1 blist2
433 $rd $pop blist1 blist2 1
434 assert_equal {} [$rd read]
435 }
436
437 test "$pop: arguments are empty" {
438 set rd [redis_deferring_client]
439 r del blist1 blist2
440
441 $rd $pop blist1 blist2 1
442 r rpush blist1 foo
443 assert_equal {blist1 foo} [$rd read]
444 assert_equal 0 [r exists blist1]
445 assert_equal 0 [r exists blist2]
446
447 $rd $pop blist1 blist2 1
448 r rpush blist2 foo
449 assert_equal {blist2 foo} [$rd read]
450 assert_equal 0 [r exists blist1]
451 assert_equal 0 [r exists blist2]
452 }
453 }
454
455 test {BLPOP inside a transaction} {
456 r del xlist
457 r lpush xlist foo
458 r lpush xlist bar
459 r multi
460 r blpop xlist 0
461 r blpop xlist 0
462 r blpop xlist 0
463 r exec
464 } {{xlist bar} {xlist foo} {}}
465
466 test {LPUSHX, RPUSHX - generic} {
467 r del xlist
468 assert_equal 0 [r lpushx xlist a]
469 assert_equal 0 [r llen xlist]
470 assert_equal 0 [r rpushx xlist a]
471 assert_equal 0 [r llen xlist]
472 }
473
474 foreach {type large} [array get largevalue] {
475 test "LPUSHX, RPUSHX - $type" {
476 create_$type xlist "$large c"
477 assert_equal 3 [r rpushx xlist d]
478 assert_equal 4 [r lpushx xlist a]
479 assert_equal "a $large c d" [r lrange xlist 0 -1]
480 }
481
482 test "LINSERT - $type" {
483 create_$type xlist "a $large c d"
484 assert_equal 5 [r linsert xlist before c zz]
485 assert_equal "a $large zz c d" [r lrange xlist 0 10]
486 assert_equal 6 [r linsert xlist after c yy]
487 assert_equal "a $large zz c yy d" [r lrange xlist 0 10]
488 assert_equal 7 [r linsert xlist after d dd]
489 assert_equal -1 [r linsert xlist after bad ddd]
490 assert_equal "a $large zz c yy d dd" [r lrange xlist 0 10]
491 assert_equal 8 [r linsert xlist before a aa]
492 assert_equal -1 [r linsert xlist before bad aaa]
493 assert_equal "aa a $large zz c yy d dd" [r lrange xlist 0 10]
494
495 # check inserting integer encoded value
496 assert_equal 9 [r linsert xlist before aa 42]
497 assert_equal 42 [r lrange xlist 0 0]
498 }
499 }
500
501 test {LINSERT raise error on bad syntax} {
502 catch {[r linsert xlist aft3r aa 42]} e
503 set e
504 } {*ERR*syntax*error*}
505
506 test {LPUSHX, RPUSHX convert from ziplist to list} {
507 set large $largevalue(linkedlist)
508
509 # convert when a large value is pushed
510 create_ziplist xlist a
511 assert_equal 2 [r rpushx xlist $large]
512 assert_encoding linkedlist xlist
513 create_ziplist xlist a
514 assert_equal 2 [r lpushx xlist $large]
515 assert_encoding linkedlist xlist
516
517 # convert when the length threshold is exceeded
518 create_ziplist xlist [lrepeat 256 a]
519 assert_equal 257 [r rpushx xlist b]
520 assert_encoding linkedlist xlist
521 create_ziplist xlist [lrepeat 256 a]
522 assert_equal 257 [r lpushx xlist b]
523 assert_encoding linkedlist xlist
524 }
525
526 test {LINSERT convert from ziplist to list} {
527 set large $largevalue(linkedlist)
528
529 # convert when a large value is inserted
530 create_ziplist xlist a
531 assert_equal 2 [r linsert xlist before a $large]
532 assert_encoding linkedlist xlist
533 create_ziplist xlist a
534 assert_equal 2 [r linsert xlist after a $large]
535 assert_encoding linkedlist xlist
536
537 # convert when the length threshold is exceeded
538 create_ziplist xlist [lrepeat 256 a]
539 assert_equal 257 [r linsert xlist before a a]
540 assert_encoding linkedlist xlist
541 create_ziplist xlist [lrepeat 256 a]
542 assert_equal 257 [r linsert xlist after a a]
543 assert_encoding linkedlist xlist
544
545 # don't convert when the value could not be inserted
546 create_ziplist xlist [lrepeat 256 a]
547 assert_equal -1 [r linsert xlist before foo a]
548 assert_encoding ziplist xlist
549 create_ziplist xlist [lrepeat 256 a]
550 assert_equal -1 [r linsert xlist after foo a]
551 assert_encoding ziplist xlist
552 }
553
554 foreach {type num} {ziplist 250 linkedlist 500} {
555 proc check_numbered_list_consistency {key} {
556 set len [r llen $key]
557 for {set i 0} {$i < $len} {incr i} {
558 assert_equal $i [r lindex $key $i]
559 assert_equal [expr $len-1-$i] [r lindex $key [expr (-$i)-1]]
560 }
561 }
562
563 proc check_random_access_consistency {key} {
564 set len [r llen $key]
565 for {set i 0} {$i < $len} {incr i} {
566 set rint [expr int(rand()*$len)]
567 assert_equal $rint [r lindex $key $rint]
568 assert_equal [expr $len-1-$rint] [r lindex $key [expr (-$rint)-1]]
569 }
570 }
571
572 test "LINDEX consistency test - $type" {
573 r del mylist
574 for {set i 0} {$i < $num} {incr i} {
575 r rpush mylist $i
576 }
577 assert_encoding $type mylist
578 check_numbered_list_consistency mylist
579 }
580
581 test "LINDEX random access - $type" {
582 assert_encoding $type mylist
583 check_random_access_consistency mylist
584 }
585
586 test "Check if list is still ok after a DEBUG RELOAD - $type" {
587 r debug reload
588 assert_encoding $type mylist
589 check_numbered_list_consistency mylist
590 check_random_access_consistency mylist
591 }
592 }
593
594 test {LLEN against non-list value error} {
595 r del mylist
596 r set mylist foobar
597 assert_error WRONGTYPE* {r llen mylist}
598 }
599
600 test {LLEN against non existing key} {
601 assert_equal 0 [r llen not-a-key]
602 }
603
604 test {LINDEX against non-list value error} {
605 assert_error WRONGTYPE* {r lindex mylist 0}
606 }
607
608 test {LINDEX against non existing key} {
609 assert_equal "" [r lindex not-a-key 10]
610 }
611
612 test {LPUSH against non-list value error} {
613 assert_error WRONGTYPE* {r lpush mylist 0}
614 }
615
616 test {RPUSH against non-list value error} {
617 assert_error WRONGTYPE* {r rpush mylist 0}
618 }
619
620 foreach {type large} [array get largevalue] {
621 test "RPOPLPUSH base case - $type" {
622 r del mylist1 mylist2
623 create_$type mylist1 "a $large c d"
624 assert_equal d [r rpoplpush mylist1 mylist2]
625 assert_equal c [r rpoplpush mylist1 mylist2]
626 assert_equal "a $large" [r lrange mylist1 0 -1]
627 assert_equal "c d" [r lrange mylist2 0 -1]
628 assert_encoding ziplist mylist2
629 }
630
631 test "RPOPLPUSH with the same list as src and dst - $type" {
632 create_$type mylist "a $large c"
633 assert_equal "a $large c" [r lrange mylist 0 -1]
634 assert_equal c [r rpoplpush mylist mylist]
635 assert_equal "c a $large" [r lrange mylist 0 -1]
636 }
637
638 foreach {othertype otherlarge} [array get largevalue] {
639 test "RPOPLPUSH with $type source and existing target $othertype" {
640 create_$type srclist "a b c $large"
641 create_$othertype dstlist "$otherlarge"
642 assert_equal $large [r rpoplpush srclist dstlist]
643 assert_equal c [r rpoplpush srclist dstlist]
644 assert_equal "a b" [r lrange srclist 0 -1]
645 assert_equal "c $large $otherlarge" [r lrange dstlist 0 -1]
646
647 # When we rpoplpush'ed a large value, dstlist should be
648 # converted to the same encoding as srclist.
649 if {$type eq "linkedlist"} {
650 assert_encoding linkedlist dstlist
651 }
652 }
653 }
654 }
655
656 test {RPOPLPUSH against non existing key} {
657 r del srclist dstlist
658 assert_equal {} [r rpoplpush srclist dstlist]
659 assert_equal 0 [r exists srclist]
660 assert_equal 0 [r exists dstlist]
661 }
662
663 test {RPOPLPUSH against non list src key} {
664 r del srclist dstlist
665 r set srclist x
666 assert_error WRONGTYPE* {r rpoplpush srclist dstlist}
667 assert_type string srclist
668 assert_equal 0 [r exists newlist]
669 }
670
671 test {RPOPLPUSH against non list dst key} {
672 create_ziplist srclist {a b c d}
673 r set dstlist x
674 assert_error WRONGTYPE* {r rpoplpush srclist dstlist}
675 assert_type string dstlist
676 assert_equal {a b c d} [r lrange srclist 0 -1]
677 }
678
679 test {RPOPLPUSH against non existing src key} {
680 r del srclist dstlist
681 assert_equal {} [r rpoplpush srclist dstlist]
682 } {}
683
684 foreach {type large} [array get largevalue] {
685 test "Basic LPOP/RPOP - $type" {
686 create_$type mylist "$large 1 2"
687 assert_equal $large [r lpop mylist]
688 assert_equal 2 [r rpop mylist]
689 assert_equal 1 [r lpop mylist]
690 assert_equal 0 [r llen mylist]
691
692 # pop on empty list
693 assert_equal {} [r lpop mylist]
694 assert_equal {} [r rpop mylist]
695 }
696 }
697
698 test {LPOP/RPOP against non list value} {
699 r set notalist foo
700 assert_error WRONGTYPE* {r lpop notalist}
701 assert_error WRONGTYPE* {r rpop notalist}
702 }
703
704 foreach {type num} {ziplist 250 linkedlist 500} {
705 test "Mass RPOP/LPOP - $type" {
706 r del mylist
707 set sum1 0
708 for {set i 0} {$i < $num} {incr i} {
709 r lpush mylist $i
710 incr sum1 $i
711 }
712 assert_encoding $type mylist
713 set sum2 0
714 for {set i 0} {$i < [expr $num/2]} {incr i} {
715 incr sum2 [r lpop mylist]
716 incr sum2 [r rpop mylist]
717 }
718 assert_equal $sum1 $sum2
719 }
720 }
721
722 foreach {type large} [array get largevalue] {
723 test "LRANGE basics - $type" {
724 create_$type mylist "$large 1 2 3 4 5 6 7 8 9"
725 assert_equal {1 2 3 4 5 6 7 8} [r lrange mylist 1 -2]
726 assert_equal {7 8 9} [r lrange mylist -3 -1]
727 assert_equal {4} [r lrange mylist 4 4]
728 }
729
730 test "LRANGE inverted indexes - $type" {
731 create_$type mylist "$large 1 2 3 4 5 6 7 8 9"
732 assert_equal {} [r lrange mylist 6 2]
733 }
734
735 test "LRANGE out of range indexes including the full list - $type" {
736 create_$type mylist "$large 1 2 3"
737 assert_equal "$large 1 2 3" [r lrange mylist -1000 1000]
738 }
739
740 test "LRANGE out of range negative end index - $type" {
741 create_$type mylist "$large 1 2 3"
742 assert_equal $large [r lrange mylist 0 -4]
743 assert_equal {} [r lrange mylist 0 -5]
744 }
745 }
746
747 test {LRANGE against non existing key} {
748 assert_equal {} [r lrange nosuchkey 0 1]
749 }
750
751 foreach {type large} [array get largevalue] {
752 proc trim_list {type min max} {
753 upvar 1 large large
754 r del mylist
755 create_$type mylist "1 2 3 4 $large"
756 r ltrim mylist $min $max
757 r lrange mylist 0 -1
758 }
759
760 test "LTRIM basics - $type" {
761 assert_equal "1" [trim_list $type 0 0]
762 assert_equal "1 2" [trim_list $type 0 1]
763 assert_equal "1 2 3" [trim_list $type 0 2]
764 assert_equal "2 3" [trim_list $type 1 2]
765 assert_equal "2 3 4 $large" [trim_list $type 1 -1]
766 assert_equal "2 3 4" [trim_list $type 1 -2]
767 assert_equal "4 $large" [trim_list $type -2 -1]
768 assert_equal "$large" [trim_list $type -1 -1]
769 assert_equal "1 2 3 4 $large" [trim_list $type -5 -1]
770 assert_equal "1 2 3 4 $large" [trim_list $type -10 10]
771 assert_equal "1 2 3 4 $large" [trim_list $type 0 5]
772 assert_equal "1 2 3 4 $large" [trim_list $type 0 10]
773 }
774
775 test "LTRIM out of range negative end index - $type" {
776 assert_equal {1} [trim_list $type 0 -5]
777 assert_equal {} [trim_list $type 0 -6]
778 }
779
780 }
781
782 foreach {type large} [array get largevalue] {
783 test "LSET - $type" {
784 create_$type mylist "99 98 $large 96 95"
785 r lset mylist 1 foo
786 r lset mylist -1 bar
787 assert_equal "99 foo $large 96 bar" [r lrange mylist 0 -1]
788 }
789
790 test "LSET out of range index - $type" {
791 assert_error ERR*range* {r lset mylist 10 foo}
792 }
793 }
794
795 test {LSET against non existing key} {
796 assert_error ERR*key* {r lset nosuchkey 10 foo}
797 }
798
799 test {LSET against non list value} {
800 r set nolist foobar
801 assert_error WRONGTYPE* {r lset nolist 0 foo}
802 }
803
804 foreach {type e} [array get largevalue] {
805 test "LREM remove all the occurrences - $type" {
806 create_$type mylist "$e foo bar foobar foobared zap bar test foo"
807 assert_equal 2 [r lrem mylist 0 bar]
808 assert_equal "$e foo foobar foobared zap test foo" [r lrange mylist 0 -1]
809 }
810
811 test "LREM remove the first occurrence - $type" {
812 assert_equal 1 [r lrem mylist 1 foo]
813 assert_equal "$e foobar foobared zap test foo" [r lrange mylist 0 -1]
814 }
815
816 test "LREM remove non existing element - $type" {
817 assert_equal 0 [r lrem mylist 1 nosuchelement]
818 assert_equal "$e foobar foobared zap test foo" [r lrange mylist 0 -1]
819 }
820
821 test "LREM starting from tail with negative count - $type" {
822 create_$type mylist "$e foo bar foobar foobared zap bar test foo foo"
823 assert_equal 1 [r lrem mylist -1 bar]
824 assert_equal "$e foo bar foobar foobared zap test foo foo" [r lrange mylist 0 -1]
825 }
826
827 test "LREM starting from tail with negative count (2) - $type" {
828 assert_equal 2 [r lrem mylist -2 foo]
829 assert_equal "$e foo bar foobar foobared zap test" [r lrange mylist 0 -1]
830 }
831
832 test "LREM deleting objects that may be int encoded - $type" {
833 create_$type myotherlist "$e 1 2 3"
834 assert_equal 1 [r lrem myotherlist 1 2]
835 assert_equal 3 [r llen myotherlist]
836 }
837 }
838
839 test "Regression for bug 593 - chaining BRPOPLPUSH with other blocking cmds" {
840 set rd1 [redis_deferring_client]
841 set rd2 [redis_deferring_client]
842
843 $rd1 brpoplpush a b 0
844 $rd1 brpoplpush a b 0
845 $rd2 brpoplpush b c 0
846 after 1000
847 r lpush a data
848 $rd1 close
849 $rd2 close
850 r ping
851 } {PONG}
852 }