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