|
24 | 24 | ]
|
25 | 25 |
|
26 | 26 |
|
| 27 | +async def send_three_messages_with_delay(channel_name, channel_layer, delay): |
| 28 | + await channel_layer.send(channel_name, {"type": "test.message", "text": "First!"}) |
| 29 | + |
| 30 | + await asyncio.sleep(delay) |
| 31 | + |
| 32 | + await channel_layer.send(channel_name, {"type": "test.message", "text": "Second!"}) |
| 33 | + |
| 34 | + await asyncio.sleep(delay) |
| 35 | + |
| 36 | + await channel_layer.send(channel_name, {"type": "test.message", "text": "Third!"}) |
| 37 | + |
| 38 | + |
| 39 | +async def group_send_three_messages_with_delay(group_name, channel_layer, delay): |
| 40 | + await channel_layer.group_send( |
| 41 | + group_name, {"type": "test.message", "text": "First!"} |
| 42 | + ) |
| 43 | + |
| 44 | + await asyncio.sleep(delay) |
| 45 | + |
| 46 | + await channel_layer.group_send( |
| 47 | + group_name, {"type": "test.message", "text": "Second!"} |
| 48 | + ) |
| 49 | + |
| 50 | + await asyncio.sleep(delay) |
| 51 | + |
| 52 | + await channel_layer.group_send( |
| 53 | + group_name, {"type": "test.message", "text": "Third!"} |
| 54 | + ) |
| 55 | + |
| 56 | + |
27 | 57 | @pytest.fixture()
|
28 | 58 | @async_generator
|
29 | 59 | async def channel_layer():
|
@@ -445,3 +475,139 @@ async def test_random_reset__client_prefix(channel_layer):
|
445 | 475 | random.seed(1)
|
446 | 476 | channel_layer_2 = RedisChannelLayer()
|
447 | 477 | assert channel_layer_1.client_prefix != channel_layer_2.client_prefix
|
| 478 | + |
| 479 | + |
| 480 | +@pytest.mark.asyncio |
| 481 | +async def test_message_expiry__earliest_message_expires(channel_layer): |
| 482 | + expiry = 3 |
| 483 | + delay = 2 |
| 484 | + channel_layer = RedisChannelLayer(expiry=expiry) |
| 485 | + channel_name = await channel_layer.new_channel() |
| 486 | + |
| 487 | + task = asyncio.ensure_future( |
| 488 | + send_three_messages_with_delay(channel_name, channel_layer, delay) |
| 489 | + ) |
| 490 | + await asyncio.wait_for(task, None) |
| 491 | + |
| 492 | + # the first message should have expired, we should only see the second message and the third |
| 493 | + message = await channel_layer.receive(channel_name) |
| 494 | + assert message["type"] == "test.message" |
| 495 | + assert message["text"] == "Second!" |
| 496 | + |
| 497 | + message = await channel_layer.receive(channel_name) |
| 498 | + assert message["type"] == "test.message" |
| 499 | + assert message["text"] == "Third!" |
| 500 | + |
| 501 | + # Make sure there's no third message even out of order |
| 502 | + with pytest.raises(asyncio.TimeoutError): |
| 503 | + async with async_timeout.timeout(1): |
| 504 | + await channel_layer.receive(channel_name) |
| 505 | + |
| 506 | + |
| 507 | +@pytest.mark.asyncio |
| 508 | +async def test_message_expiry__all_messages_under_expiration_time(channel_layer): |
| 509 | + expiry = 3 |
| 510 | + delay = 1 |
| 511 | + channel_layer = RedisChannelLayer(expiry=expiry) |
| 512 | + channel_name = await channel_layer.new_channel() |
| 513 | + |
| 514 | + task = asyncio.ensure_future( |
| 515 | + send_three_messages_with_delay(channel_name, channel_layer, delay) |
| 516 | + ) |
| 517 | + await asyncio.wait_for(task, None) |
| 518 | + |
| 519 | + # expiry = 3, total delay under 3, all messages there |
| 520 | + message = await channel_layer.receive(channel_name) |
| 521 | + assert message["type"] == "test.message" |
| 522 | + assert message["text"] == "First!" |
| 523 | + |
| 524 | + message = await channel_layer.receive(channel_name) |
| 525 | + assert message["type"] == "test.message" |
| 526 | + assert message["text"] == "Second!" |
| 527 | + |
| 528 | + message = await channel_layer.receive(channel_name) |
| 529 | + assert message["type"] == "test.message" |
| 530 | + assert message["text"] == "Third!" |
| 531 | + |
| 532 | + |
| 533 | +@pytest.mark.asyncio |
| 534 | +async def test_message_expiry__group_send(channel_layer): |
| 535 | + expiry = 3 |
| 536 | + delay = 2 |
| 537 | + channel_layer = RedisChannelLayer(expiry=expiry) |
| 538 | + channel_name = await channel_layer.new_channel() |
| 539 | + |
| 540 | + await channel_layer.group_add("test-group", channel_name) |
| 541 | + |
| 542 | + task = asyncio.ensure_future( |
| 543 | + group_send_three_messages_with_delay("test-group", channel_layer, delay) |
| 544 | + ) |
| 545 | + await asyncio.wait_for(task, None) |
| 546 | + |
| 547 | + # the first message should have expired, we should only see the second message and the third |
| 548 | + message = await channel_layer.receive(channel_name) |
| 549 | + assert message["type"] == "test.message" |
| 550 | + assert message["text"] == "Second!" |
| 551 | + |
| 552 | + message = await channel_layer.receive(channel_name) |
| 553 | + assert message["type"] == "test.message" |
| 554 | + assert message["text"] == "Third!" |
| 555 | + |
| 556 | + # Make sure there's no third message even out of order |
| 557 | + with pytest.raises(asyncio.TimeoutError): |
| 558 | + async with async_timeout.timeout(1): |
| 559 | + await channel_layer.receive(channel_name) |
| 560 | + |
| 561 | + |
| 562 | +@pytest.mark.asyncio |
| 563 | +async def test_message_expiry__group_send__one_channel_expires_message(channel_layer): |
| 564 | + expiry = 3 |
| 565 | + delay = 1 |
| 566 | + |
| 567 | + channel_layer = RedisChannelLayer(expiry=expiry) |
| 568 | + channel_1 = await channel_layer.new_channel() |
| 569 | + channel_2 = await channel_layer.new_channel(prefix="channel_2") |
| 570 | + |
| 571 | + await channel_layer.group_add("test-group", channel_1) |
| 572 | + await channel_layer.group_add("test-group", channel_2) |
| 573 | + |
| 574 | + # Let's give channel_1 one additional message and then sleep |
| 575 | + await channel_layer.send(channel_1, {"type": "test.message", "text": "Zero!"}) |
| 576 | + await asyncio.sleep(2) |
| 577 | + |
| 578 | + task = asyncio.ensure_future( |
| 579 | + group_send_three_messages_with_delay("test-group", channel_layer, delay) |
| 580 | + ) |
| 581 | + await asyncio.wait_for(task, None) |
| 582 | + |
| 583 | + # message Zero! was sent about 2 + 1 + 1 seconds ago and it should have expired |
| 584 | + message = await channel_layer.receive(channel_1) |
| 585 | + assert message["type"] == "test.message" |
| 586 | + assert message["text"] == "First!" |
| 587 | + |
| 588 | + message = await channel_layer.receive(channel_1) |
| 589 | + assert message["type"] == "test.message" |
| 590 | + assert message["text"] == "Second!" |
| 591 | + |
| 592 | + message = await channel_layer.receive(channel_1) |
| 593 | + assert message["type"] == "test.message" |
| 594 | + assert message["text"] == "Third!" |
| 595 | + |
| 596 | + # Make sure there's no fourth message even out of order |
| 597 | + with pytest.raises(asyncio.TimeoutError): |
| 598 | + async with async_timeout.timeout(1): |
| 599 | + await channel_layer.receive(channel_1) |
| 600 | + |
| 601 | + # channel_2 should receive all three messages from group_send |
| 602 | + message = await channel_layer.receive(channel_2) |
| 603 | + assert message["type"] == "test.message" |
| 604 | + assert message["text"] == "First!" |
| 605 | + |
| 606 | + # the first message should have expired, we should only see the second message and the third |
| 607 | + message = await channel_layer.receive(channel_2) |
| 608 | + assert message["type"] == "test.message" |
| 609 | + assert message["text"] == "Second!" |
| 610 | + |
| 611 | + message = await channel_layer.receive(channel_2) |
| 612 | + assert message["type"] == "test.message" |
| 613 | + assert message["text"] == "Third!" |
0 commit comments