]> git.saurik.com Git - redis.git/blob - tests/unit/type/list.tcl
9a63d45137f628daed75782c6cfc84de724bcd84
[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 - 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
20
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
31 }
32
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]
44
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]
55 }
56
57 test {Variadic RPUSH/LPUSH} {
58 r del mylist
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]
62 }
63
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]
68 }
69
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]
74 }
75
76 proc create_ziplist {key entries} {
77 r del $key
78 foreach entry $entries { r rpush $key $entry }
79 assert_encoding ziplist $key
80 }
81
82 proc create_linkedlist {key entries} {
83 r del $key
84 foreach entry $entries { r rpush $key $entry }
85 assert_encoding linkedlist $key
86 }
87
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"
92
93 $rd blpop blist 1
94 assert_equal {blist a} [$rd read]
95 $rd brpop blist 1
96 assert_equal {blist d} [$rd read]
97
98 $rd blpop blist 1
99 assert_equal {blist b} [$rd read]
100 $rd brpop blist 1
101 assert_equal {blist c} [$rd read]
102 }
103
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"
108
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]
115
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]
122 }
123
124 test "BLPOP, BRPOP: second list has an entry - $type" {
125 set rd [redis_deferring_client]
126 r del blist1
127 create_$type blist2 "d $large f"
128
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]
135 }
136
137 test "BRPOPLPUSH - $type" {
138 r del target
139
140 set rd [redis_deferring_client]
141 create_$type blist "a b $large c d"
142
143 $rd brpoplpush blist target 1
144 assert_equal d [$rd read]
145
146 assert_equal d [r rpop target]
147 assert_equal "a b $large c" [r lrange blist 0 -1]
148 }
149 }
150
151 test "BLPOP with variadic LPUSH" {
152 set rd [redis_deferring_client]
153 r del blist target
154 if {$::valgrind} {after 100}
155 $rd blpop blist 0
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]
161 }
162
163 test "BRPOPLPUSH with zero timeout should block indefinitely" {
164 set rd [redis_deferring_client]
165 r del blist target
166 $rd brpoplpush blist target 0
167 after 1000
168 r rpush blist foo
169 assert_equal foo [$rd read]
170 assert_equal {foo} [r lrange target 0 -1]
171 }
172
173 test "BRPOPLPUSH with a client BLPOPing the target list" {
174 set rd [redis_deferring_client]
175 set rd2 [redis_deferring_client]
176 r del blist target
177 $rd2 blpop target 0
178 $rd brpoplpush blist target 0
179 after 1000
180 r rpush blist foo
181 assert_equal foo [$rd read]
182 assert_equal {target foo} [$rd2 read]
183 assert_equal 0 [r exists target]
184 }
185
186 test "BRPOPLPUSH with wrong source type" {
187 set rd [redis_deferring_client]
188 r del blist target
189 r set blist nolist
190 $rd brpoplpush blist target 1
191 assert_error "ERR*wrong kind*" {$rd read}
192 }
193
194 test "BRPOPLPUSH with wrong destination type" {
195 set rd [redis_deferring_client]
196 r del blist target
197 r set target nolist
198 r lpush blist foo
199 $rd brpoplpush blist target 1
200 assert_error "ERR*wrong kind*" {$rd read}
201
202 set rd [redis_deferring_client]
203 r del blist target
204 r set target nolist
205 $rd brpoplpush blist target 0
206 after 1000
207 r rpush blist foo
208 assert_error "ERR*wrong kind*" {$rd read}
209 assert_equal {foo} [r lrange blist 0 -1]
210 }
211
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
216 r set target1 nolist
217 $rd1 brpoplpush blist target1 0
218 $rd2 brpoplpush blist target2 0
219 r lpush blist foo
220
221 assert_error "ERR*wrong kind*" {$rd1 read}
222 assert_equal {foo} [$rd2 read]
223 assert_equal {foo} [r lrange target2 0 -1]
224 }
225
226 test "Linked BRPOPLPUSH" {
227 set rd1 [redis_deferring_client]
228 set rd2 [redis_deferring_client]
229
230 r del list1 list2 list3
231
232 $rd1 brpoplpush list1 list2 0
233 $rd2 brpoplpush list2 list3 0
234
235 r rpush list1 foo
236
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]
240 }
241
242 test "Circular BRPOPLPUSH" {
243 set rd1 [redis_deferring_client]
244 set rd2 [redis_deferring_client]
245
246 r del list1 list2
247
248 $rd1 brpoplpush list1 list2 0
249 $rd2 brpoplpush list2 list1 0
250
251 r rpush list1 foo
252
253 assert_equal {foo} [r lrange list1 0 -1]
254 assert_equal {} [r lrange list2 0 -1]
255 }
256
257 test "Self-referential BRPOPLPUSH" {
258 set rd [redis_deferring_client]
259
260 r del blist
261
262 $rd brpoplpush blist blist 0
263
264 r rpush blist foo
265
266 assert_equal {foo} [r lrange blist 0 -1]
267 }
268
269 test "BRPOPLPUSH inside a transaction" {
270 r del xlist target
271 r lpush xlist foo
272 r lpush xlist bar
273
274 r multi
275 r brpoplpush xlist target 0
276 r brpoplpush xlist target 0
277 r brpoplpush xlist target 0
278 r lrange xlist 0 -1
279 r lrange target 0 -1
280 r exec
281 } {foo bar {} {} {bar foo}}
282
283 test {BRPOPLPUSH timeout} {
284 set rd [redis_deferring_client]
285
286 $rd brpoplpush foo_list bar_list 1
287 after 2000
288 $rd read
289 } {}
290
291 foreach {pop} {BLPOP BRPOP} {
292 test "$pop: with single empty list argument" {
293 set rd [redis_deferring_client]
294 r del blist1
295 $rd $pop blist1 1
296 r rpush blist1 foo
297 assert_equal {blist1 foo} [$rd read]
298 assert_equal 0 [r exists blist1]
299 }
300
301 test "$pop: with negative timeout" {
302 set rd [redis_deferring_client]
303 $rd $pop blist1 -1
304 assert_error "ERR*is negative*" {$rd read}
305 }
306
307 test "$pop: with non-integer timeout" {
308 set rd [redis_deferring_client]
309 $rd $pop blist1 1.1
310 assert_error "ERR*not an integer*" {$rd read}
311 }
312
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]
317 $rd $pop blist1 0
318 after 1000
319 r rpush blist1 foo
320 assert_equal {blist1 foo} [$rd read]
321 }
322
323 test "$pop: second argument is not a list" {
324 set rd [redis_deferring_client]
325 r del blist1 blist2
326 r set blist2 nolist
327 $rd $pop blist1 blist2 1
328 assert_error "ERR*wrong kind*" {$rd read}
329 }
330
331 test "$pop: timeout" {
332 set rd [redis_deferring_client]
333 r del blist1 blist2
334 $rd $pop blist1 blist2 1
335 assert_equal {} [$rd read]
336 }
337
338 test "$pop: arguments are empty" {
339 set rd [redis_deferring_client]
340 r del blist1 blist2
341
342 $rd $pop blist1 blist2 1
343 r rpush blist1 foo
344 assert_equal {blist1 foo} [$rd read]
345 assert_equal 0 [r exists blist1]
346 assert_equal 0 [r exists blist2]
347
348 $rd $pop blist1 blist2 1
349 r rpush blist2 foo
350 assert_equal {blist2 foo} [$rd read]
351 assert_equal 0 [r exists blist1]
352 assert_equal 0 [r exists blist2]
353 }
354 }
355
356 test {BLPOP inside a transaction} {
357 r del xlist
358 r lpush xlist foo
359 r lpush xlist bar
360 r multi
361 r blpop xlist 0
362 r blpop xlist 0
363 r blpop xlist 0
364 r exec
365 } {{xlist bar} {xlist foo} {}}
366
367 test {LPUSHX, RPUSHX - generic} {
368 r del xlist
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]
373 }
374
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]
381 }
382
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]
395
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]
399 }
400 }
401
402 test {LPUSHX, RPUSHX convert from ziplist to list} {
403 set large $largevalue(linkedlist)
404
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
412
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
420 }
421
422 test {LINSERT convert from ziplist to list} {
423 set large $largevalue(linkedlist)
424
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
432
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
440
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
448 }
449
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]]
456 }
457 }
458
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]]
465 }
466 }
467
468 test "LINDEX consistency test - $type" {
469 r del mylist
470 for {set i 0} {$i < $num} {incr i} {
471 r rpush mylist $i
472 }
473 assert_encoding $type mylist
474 check_numbered_list_consistency mylist
475 }
476
477 test "LINDEX random access - $type" {
478 assert_encoding $type mylist
479 check_random_access_consistency mylist
480 }
481
482 test "Check if list is still ok after a DEBUG RELOAD - $type" {
483 r debug reload
484 assert_encoding $type mylist
485 check_numbered_list_consistency mylist
486 check_random_access_consistency mylist
487 }
488 }
489
490 test {LLEN against non-list value error} {
491 r del mylist
492 r set mylist foobar
493 assert_error ERR* {r llen mylist}
494 }
495
496 test {LLEN against non existing key} {
497 assert_equal 0 [r llen not-a-key]
498 }
499
500 test {LINDEX against non-list value error} {
501 assert_error ERR* {r lindex mylist 0}
502 }
503
504 test {LINDEX against non existing key} {
505 assert_equal "" [r lindex not-a-key 10]
506 }
507
508 test {LPUSH against non-list value error} {
509 assert_error ERR* {r lpush mylist 0}
510 }
511
512 test {RPUSH against non-list value error} {
513 assert_error ERR* {r rpush mylist 0}
514 }
515
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
525 }
526
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]
532 }
533
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]
542
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
547 }
548 }
549 }
550 }
551
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]
557 }
558
559 test {RPOPLPUSH against non list src key} {
560 r del srclist dstlist
561 r set srclist x
562 assert_error ERR* {r rpoplpush srclist dstlist}
563 assert_type string srclist
564 assert_equal 0 [r exists newlist]
565 }
566
567 test {RPOPLPUSH against non list dst key} {
568 create_ziplist srclist {a b c d}
569 r set dstlist x
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]
573 }
574
575 test {RPOPLPUSH against non existing src key} {
576 r del srclist dstlist
577 assert_equal {} [r rpoplpush srclist dstlist]
578 } {}
579
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]
587
588 # pop on empty list
589 assert_equal {} [r lpop mylist]
590 assert_equal {} [r rpop mylist]
591 }
592 }
593
594 test {LPOP/RPOP against non list value} {
595 r set notalist foo
596 assert_error ERR*kind* {r lpop notalist}
597 assert_error ERR*kind* {r rpop notalist}
598 }
599
600 foreach {type num} {ziplist 250 linkedlist 500} {
601 test "Mass RPOP/LPOP - $type" {
602 r del mylist
603 set sum1 0
604 for {set i 0} {$i < $num} {incr i} {
605 r lpush mylist $i
606 incr sum1 $i
607 }
608 assert_encoding $type mylist
609 set sum2 0
610 for {set i 0} {$i < [expr $num/2]} {incr i} {
611 incr sum2 [r lpop mylist]
612 incr sum2 [r rpop mylist]
613 }
614 assert_equal $sum1 $sum2
615 }
616 }
617
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]
624 }
625
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]
629 }
630
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]
634 }
635
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]
640 }
641 }
642
643 test {LRANGE against non existing key} {
644 assert_equal {} [r lrange nosuchkey 0 1]
645 }
646
647 foreach {type large} [array get largevalue] {
648 proc trim_list {type min max} {
649 upvar 1 large large
650 r del mylist
651 create_$type mylist "1 2 3 4 $large"
652 r ltrim mylist $min $max
653 r lrange mylist 0 -1
654 }
655
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]
669 }
670
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]
674 }
675
676 }
677
678 foreach {type large} [array get largevalue] {
679 test "LSET - $type" {
680 create_$type mylist "99 98 $large 96 95"
681 r lset mylist 1 foo
682 r lset mylist -1 bar
683 assert_equal "99 foo $large 96 bar" [r lrange mylist 0 -1]
684 }
685
686 test "LSET out of range index - $type" {
687 assert_error ERR*range* {r lset mylist 10 foo}
688 }
689 }
690
691 test {LSET against non existing key} {
692 assert_error ERR*key* {r lset nosuchkey 10 foo}
693 }
694
695 test {LSET against non list value} {
696 r set nolist foobar
697 assert_error ERR*value* {r lset nolist 0 foo}
698 }
699
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]
705 }
706
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]
710 }
711
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]
715 }
716
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]
721 }
722
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]
726 }
727
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]
732 }
733 }
734
735 test "Regression for bug 593 - chaining BRPOPLPUSH with other blocking cmds" {
736 set rd1 [redis_deferring_client]
737 set rd2 [redis_deferring_client]
738
739 $rd1 brpoplpush a b 0
740 $rd1 brpoplpush a b 0
741 $rd2 brpoplpush b c 0
742 after 1000
743 r lpush a data
744 $rd1 close
745 $rd2 close
746 r ping
747 } {PONG}
748 }