def test_delay_queue_put_full(): eta = datetime(2020, 1, 1, second=0, tzinfo=timezone.utc) delay_queue = DelayQueue(max_size=1) delay_queue.put( DelayMessage(1, None, eta), ) with pytest.raises(Full): delay_queue.put( DelayMessage(2, None, eta), ) assert delay_queue.qsize() == 1 assert delay_queue.get().delivery_tag == 1
def test_delay_queue_get_ready(mocker): fake_put_now = datetime(2020, 1, 1, second=0, tzinfo=timezone.utc) mocker.patch('django.utils.timezone.now', return_value=fake_put_now) delay_queue = DelayQueue() delay_messages = [] for delay in (1, 0, 3600, 2): eta = fake_put_now + timedelta(seconds=delay) delay_message = DelayMessage(None, None, eta) delay_queue.put(delay_message) delay_messages.append(delay_message) mocker.stopall() fake_get_ready_now = datetime(2020, 1, 1, second=3, tzinfo=timezone.utc) mocker.patch('django.utils.timezone.now', return_value=fake_get_ready_now) ready_messages = list(delay_queue.get_ready()) assert len(ready_messages) == 3 sorted_expected = sorted(delay_messages, key=lambda x: x.eta) expected_not_ready = sorted_expected.pop() for expected, result in zip(sorted_expected, ready_messages): assert expected is result assert delay_queue.qsize() == 1 result_message = delay_queue.get() assert result_message is expected_not_ready
def test_delay_queue_put_same_eta(): eta = datetime(2020, 1, 1, second=0, tzinfo=timezone.utc) delay_messages = [DelayMessage(delivery_tag, None, eta) for delivery_tag in range(10)] delay_queue = DelayQueue() for delay_message in delay_messages: delay_queue.put(delay_message) assert delay_queue.qsize() == 10 assert delay_queue.get()
def test_delay_queue_put(): fake_now = datetime(2020, 1, 1, second=0, tzinfo=timezone.utc) delay_message = DelayMessage(1, {'test': 'data'}, fake_now) delay_queue = DelayQueue() delay_queue.put(delay_message) assert delay_queue.qsize() == 1 result_message = delay_queue.get() assert result_message is delay_message
def test_delay_message(mocker): fake_now = datetime(2020, 1, 1, second=0, tzinfo=timezone.utc) eta = fake_now + timedelta(seconds=10) mocker.patch('django.utils.timezone.now', return_value=fake_now) delay_message = DelayMessage(1, {'test': 'data'}, eta) assert delay_message.delivery_tag == 1 assert delay_message.payload == {'test': 'data'} expected_eta = datetime(2020, 1, 1, second=10, tzinfo=timezone.utc) assert delay_message.eta == expected_eta
def _delay_message(cls, channel, delivery_tag, payload, delay, delay_queue): if delay_queue.full(): # Memory limits handling, requeuing message with lowest ETA requeue_message = delay_queue.get() cls._requeue_message( channel, requeue_message.delivery_tag, requeue_message.payload, ) eta = timezone.now() + timedelta(seconds=delay) delay_message = DelayMessage(delivery_tag, payload, eta) delay_queue.put(delay_message) cls.log_delayed(payload, delay, delay_message.eta)
def test_delay_message_with_requeue(mocker, caplog): channel = mocker.MagicMock() requeue_message = mocker.patch( 'dj_cqrs.transport.rabbit_mq.RabbitMQTransport._requeue_message', ) delay_messages = [] for delay in (2, 1, 3): payload = TransportPayload(SignalType.SAVE, 'CQRS_ID', {'id': delay}, delay) eta = datetime.now(tz=timezone.utc) + timedelta(hours=delay) delay_message = DelayMessage(delivery_tag=delay, payload=payload, eta=eta) delay_messages.append(delay_message) delay_queue = DelayQueue(max_size=3) for delay_message in delay_messages: delay_queue.put(delay_message) exceeding_delay = 0 exceeding_payload = TransportPayload(SignalType.SAVE, 'CQRS_ID', {'id': 4}, 4) PublicRabbitMQTransport.delay_message( channel, 4, exceeding_payload, exceeding_delay, delay_queue, ) assert delay_queue.qsize() == 3 assert delay_queue.get().payload is exceeding_payload assert ( 'CQRS is delayed: pk = 4 (CQRS_ID), correlation_id = None, delay = 0 sec' in caplog.text) assert requeue_message.call_count == 1 requeue_payload = requeue_message.call_args[0][2] min_eta_delay_message = sorted(delay_messages, key=lambda x: x.eta)[0] assert requeue_payload is min_eta_delay_message.payload
def test_process_delay_messages(mocker, caplog): channel = mocker.MagicMock() produce = mocker.patch( 'dj_cqrs.transport.rabbit_mq.RabbitMQTransport.produce') payload = TransportPayload(SignalType.SAVE, 'CQRS_ID', {'id': 1}, 1) delay_queue = DelayQueue() delay_queue.put( DelayMessage(delivery_tag=1, payload=payload, eta=datetime.now(tz=timezone.utc)), ) PublicRabbitMQTransport.process_delay_messages(channel, delay_queue) assert delay_queue.qsize() == 0 assert channel.basic_nack.call_count == 1 assert produce.call_count == 1 produce_payload = produce.call_args[0][0] assert produce_payload is payload assert produce_payload.retries == 1 assert getattr(produce_payload, 'is_requeue', False) assert 'CQRS is requeued: pk = 1 (CQRS_ID)' in caplog.text