Esempio n. 1
0
    async def test_on_receive_handles_gapfill(
        self, pipeline_with_messages, user_notification_message
    ):
        seq_num_app = SeqNumManagerApp(pipeline_with_messages)
        seq_num_app.startup_time = datetime.utcnow() - timedelta(
            seconds=10
        )  # Don't wait for resend requests

        seq_num_app.receive_seq_num = 5  # 5 Messages received so far
        user_notification_message.seq_num = 8  # Simulate missing messages 6 and 7

        try:
            await seq_num_app.on_receive(user_notification_message)
            assert pipeline_with_messages.send.call_count == 1  # Resend request sent
        except StopMessageProcessing:
            # Expected
            pass

        # Simulate resend of 6 and 7
        for seq_num in [6, 7]:
            message = user_notification_message.copy()
            message.seq_num = seq_num
            message.PossDupFlag = True
            await seq_num_app.on_receive(message)

        # Wait for separate 'send' tasks to complete
        tasks = asyncio.all_tasks()
        await asyncio.wait(tasks, timeout=0.1)

        assert (
            pipeline_with_messages.receive.call_count == 1
        )  # One queued message (with sequence number 8) processed
Esempio n. 2
0
    async def test_handle_resend_request_sends_resend_request(
        self, pipeline_with_messages
    ):
        seq_num_app = SeqNumManagerApp(pipeline_with_messages)
        seq_num_app.send_seq_num = 3  # 3 messages sent so far
        resend_begin_seq_num = 2  # Simulate resend request of 2 and 3

        await seq_num_app._handle_resend_request(
            admin.ResendRequestMessage(resend_begin_seq_num)
        )

        # Wait for separate 'send' tasks to complete
        tasks = asyncio.all_tasks()
        await asyncio.wait(tasks, timeout=0.1)

        assert pipeline_with_messages.send.call_count == 2

        for idx in range(pipeline_with_messages.send.call_count):
            message = pipeline_with_messages.send.mock_calls[idx][1][0]
            # Check sequence number
            assert message.seq_num == resend_begin_seq_num + idx
            # Check PossDup flag
            assert bool(message.PossDupFlag) is True
            # Check sending time
            assert str(message.OrigSendingTime) == str(message.SendingTime)
Esempio n. 3
0
    def test_handle_sequence_number_too_low_raises_exception_if_number_too_low(
            self, email_message):
        with pytest.raises(SessionError):
            pipeline_mock = MagicMock(BasePipeline)
            seq_num_app = SeqNumManagerApp(pipeline_mock)
            seq_num_app.receive_seq_num = 10

            email_message.MsgSeqNum = 1

            seq_num_app._handle_sequence_number_too_low(email_message)
Esempio n. 4
0
    async def test_send_resend_request_waits_for_target_before_doing_gapfill(
            self, pipeline_with_messages):

        seq_num_app = SeqNumManagerApp(pipeline_with_messages)
        seq_num_app.startup_time = datetime.utcnow() - timedelta(
            seconds=5)  # Don't wait
        assert not seq_num_app.waited_for_resend_request_event.is_set()

        await seq_num_app._send_resend_request([1, 2])

        assert seq_num_app.waited_for_resend_request_event.is_set()
Esempio n. 5
0
    def test_handle_sequence_number_too_low_skips_duplicates_with_low_sequence_numbers(
            self, email_message):
        with pytest.raises(StopMessageProcessing):
            pipeline_mock = MagicMock(BasePipeline)
            seq_num_app = SeqNumManagerApp(pipeline_mock)
            seq_num_app.receive_seq_num = 10

            email_message.MsgSeqNum = 1
            email_message.PossDupFlag = True

            seq_num_app._handle_sequence_number_too_low(email_message)
Esempio n. 6
0
    async def test_send_resend_request_sends_resend_request(
            self, pipeline_with_messages):
        seq_num_app = SeqNumManagerApp(pipeline_with_messages)
        seq_num_app.startup_time = datetime.utcnow() - timedelta(
            seconds=5)  # Don't wait

        await seq_num_app._send_resend_request([1, 2])

        # Wait for separate 'send' tasks to complete
        tasks = asyncio.all_tasks()
        await asyncio.wait(tasks, timeout=0.1)

        assert pipeline_with_messages.send.call_count == 1
Esempio n. 7
0
    async def test_handle_resend_request_converts_admin_messages_to_sequence_reset_messages(
        self, logon_message, pipeline_with_messages, messages
    ):
        seq_num_app = SeqNumManagerApp(pipeline_with_messages)

        admin_messages = [logon_message, HeartbeatMessage("test123")]

        # Inject admin messages
        messages = admin_messages + messages

        # Reset sequence numbers
        for idx, message in enumerate(messages):
            message.MsgSeqNum = idx + 1

        message_store_app = pipeline_with_messages.apps[MessageStoreApp.name]
        await message_store_app.initialize()
        message_store_app.store._store.clear()

        for message in messages:
            await message_store_app.set_sent(message)

        seq_num_app.send_seq_num = max(
            message.seq_num
            for message in pipeline_with_messages.apps[
                MessageStoreApp.name
            ].store._store.values()
        )

        resend_begin_seq_num = 1

        await seq_num_app._handle_resend_request(
            admin.ResendRequestMessage(resend_begin_seq_num)
        )

        # Wait for separate 'send' tasks to complete
        tasks = asyncio.all_tasks()
        await asyncio.wait(tasks, timeout=0.1)

        assert pipeline_with_messages.send.call_count == 6

        admin_messages_resend = pipeline_with_messages.send.mock_calls[0][1][0]
        # Check SequenceReset message is constructed correctly
        assert admin_messages_resend.seq_num == 1
        assert int(admin_messages_resend.NewSeqNo) == 3
        assert bool(admin_messages_resend.PossDupFlag) is True

        # Check first non-admin message starts with correct sequence number
        first_non_admin_message_resend = pipeline_with_messages.send.mock_calls[1][1][0]
        assert first_non_admin_message_resend.seq_num == 3
Esempio n. 8
0
    async def test_start_resumes_sequence_numbers(self, pipeline_with_messages):

        pipeline_with_messages.apps[ClientSessionApp.name]._new_session = False
        seq_num_app = SeqNumManagerApp(pipeline_with_messages)
        await seq_num_app.start()

        assert seq_num_app.send_seq_num == 3
        assert seq_num_app.receive_seq_num == 5
Esempio n. 9
0
    async def test_handle_seq_num_too_high_starts_buffer_and_sends_resend_request(
            self, pipeline_with_messages, email_message):
        with pytest.raises(StopMessageProcessing):
            seq_num_app = SeqNumManagerApp(pipeline_with_messages)
            seq_num_app.startup_time = datetime.utcnow() - timedelta(
                seconds=5)  # Don't wait

            email_message.MsgSeqNum = 99
            await seq_num_app._handle_sequence_number_too_high(email_message)

        # Wait for separate 'send' tasks to complete
        tasks = asyncio.all_tasks()
        await asyncio.wait(tasks, timeout=0.1)

        assert len(seq_num_app.receive_buffer) == 1
        assert seq_num_app.receive_buffer[0] == email_message
        assert pipeline_with_messages.send.call_count == 1
Esempio n. 10
0
    async def test_handle_seq_num_too_high_buffers_messages_received_out_of_order(
            self, pipeline_with_messages, user_notification_message):
        seq_num_app = SeqNumManagerApp(pipeline_with_messages)
        seq_num_app.startup_time = datetime.utcnow() - timedelta(
            seconds=5)  # Don't wait

        for idx in range(5):
            out_of_sequence_msg = user_notification_message.copy()
            out_of_sequence_msg.MsgSeqNum = 5 + idx
            try:
                await seq_num_app._handle_sequence_number_too_high(
                    out_of_sequence_msg)
            except StopMessageProcessing:
                # Expected
                pass

        # Wait for separate 'send' tasks to complete
        tasks = asyncio.all_tasks()
        await asyncio.wait(tasks, timeout=0.1)

        assert len(seq_num_app.receive_buffer) == 5
        assert pipeline_with_messages.send.call_count == 1