Exemple #1
0
    def prepare(self, reactor: "MemoryReactor", clock: Clock, hs: HomeServer):
        self.scheduler = ApplicationServiceScheduler(hs)
        self.txn_ctrl = Mock()
        self.txn_ctrl.send = simple_async_mock()

        # Replace instantiated _TransactionController instances with our Mock
        self.scheduler.txn_ctrl = self.txn_ctrl
        self.scheduler.queuer.txn_ctrl = self.txn_ctrl
Exemple #2
0
 def build_application_service_scheduler(self):
     return ApplicationServiceScheduler(self)
Exemple #3
0
 def get_application_service_scheduler(self) -> ApplicationServiceScheduler:
     return ApplicationServiceScheduler(self)
Exemple #4
0
class ApplicationServiceSchedulerQueuerTestCase(unittest.HomeserverTestCase):
    def prepare(self, reactor: "MemoryReactor", clock: Clock, hs: HomeServer):
        self.scheduler = ApplicationServiceScheduler(hs)
        self.txn_ctrl = Mock()
        self.txn_ctrl.send = simple_async_mock()

        # Replace instantiated _TransactionController instances with our Mock
        self.scheduler.txn_ctrl = self.txn_ctrl
        self.scheduler.queuer.txn_ctrl = self.txn_ctrl

    def test_send_single_event_no_queue(self):
        # Expect the event to be sent immediately.
        service = Mock(id=4)
        event = Mock()
        self.scheduler.enqueue_for_appservice(service, events=[event])
        self.txn_ctrl.send.assert_called_once_with(service, [event], [], [],
                                                   None, None,
                                                   DeviceListUpdates())

    def test_send_single_event_with_queue(self):
        d = defer.Deferred()
        self.txn_ctrl.send = Mock(return_value=make_deferred_yieldable(d))
        service = Mock(id=4)
        event = Mock(event_id="first")
        event2 = Mock(event_id="second")
        event3 = Mock(event_id="third")
        # Send an event and don't resolve it just yet.
        self.scheduler.enqueue_for_appservice(service, events=[event])
        # Send more events: expect send() to NOT be called multiple times.
        # (call enqueue_for_appservice multiple times deliberately)
        self.scheduler.enqueue_for_appservice(service, events=[event2])
        self.scheduler.enqueue_for_appservice(service, events=[event3])
        self.txn_ctrl.send.assert_called_with(service, [event], [], [], None,
                                              None, DeviceListUpdates())
        self.assertEqual(1, self.txn_ctrl.send.call_count)
        # Resolve the send event: expect the queued events to be sent
        d.callback(service)
        self.txn_ctrl.send.assert_called_with(service, [event2, event3], [],
                                              [], None, None,
                                              DeviceListUpdates())
        self.assertEqual(2, self.txn_ctrl.send.call_count)

    def test_multiple_service_queues(self):
        # Tests that each service has its own queue, and that they don't block
        # on each other.
        srv1 = Mock(id=4)
        srv_1_defer = defer.Deferred()
        srv_1_event = Mock(event_id="srv1a")
        srv_1_event2 = Mock(event_id="srv1b")

        srv2 = Mock(id=6)
        srv_2_defer = defer.Deferred()
        srv_2_event = Mock(event_id="srv2a")
        srv_2_event2 = Mock(event_id="srv2b")

        send_return_list = [srv_1_defer, srv_2_defer]

        def do_send(*args, **kwargs):
            return make_deferred_yieldable(send_return_list.pop(0))

        self.txn_ctrl.send = Mock(side_effect=do_send)

        # send events for different ASes and make sure they are sent
        self.scheduler.enqueue_for_appservice(srv1, events=[srv_1_event])
        self.scheduler.enqueue_for_appservice(srv1, events=[srv_1_event2])
        self.txn_ctrl.send.assert_called_with(srv1, [srv_1_event], [], [],
                                              None, None, DeviceListUpdates())
        self.scheduler.enqueue_for_appservice(srv2, events=[srv_2_event])
        self.scheduler.enqueue_for_appservice(srv2, events=[srv_2_event2])
        self.txn_ctrl.send.assert_called_with(srv2, [srv_2_event], [], [],
                                              None, None, DeviceListUpdates())

        # make sure callbacks for a service only send queued events for THAT
        # service
        srv_2_defer.callback(srv2)
        self.txn_ctrl.send.assert_called_with(srv2, [srv_2_event2], [], [],
                                              None, None, DeviceListUpdates())
        self.assertEqual(3, self.txn_ctrl.send.call_count)

    def test_send_large_txns(self):
        srv_1_defer = defer.Deferred()
        srv_2_defer = defer.Deferred()
        send_return_list = [srv_1_defer, srv_2_defer]

        def do_send(*args, **kwargs):
            return make_deferred_yieldable(send_return_list.pop(0))

        self.txn_ctrl.send = Mock(side_effect=do_send)

        service = Mock(id=4, name="service")
        event_list = [Mock(name="event%i" % (i + 1)) for i in range(200)]
        for event in event_list:
            self.scheduler.enqueue_for_appservice(service, [event], [])

        # Expect the first event to be sent immediately.
        self.txn_ctrl.send.assert_called_with(service, [event_list[0]], [], [],
                                              None, None, DeviceListUpdates())
        srv_1_defer.callback(service)
        # Then send the next 100 events
        self.txn_ctrl.send.assert_called_with(service, event_list[1:101], [],
                                              [], None, None,
                                              DeviceListUpdates())
        srv_2_defer.callback(service)
        # Then the final 99 events
        self.txn_ctrl.send.assert_called_with(service, event_list[101:], [],
                                              [], None, None,
                                              DeviceListUpdates())
        self.assertEqual(3, self.txn_ctrl.send.call_count)

    def test_send_single_ephemeral_no_queue(self):
        # Expect the event to be sent immediately.
        service = Mock(id=4, name="service")
        event_list = [Mock(name="event")]
        self.scheduler.enqueue_for_appservice(service, ephemeral=event_list)
        self.txn_ctrl.send.assert_called_once_with(service, [], event_list, [],
                                                   None, None,
                                                   DeviceListUpdates())

    def test_send_multiple_ephemeral_no_queue(self):
        # Expect the event to be sent immediately.
        service = Mock(id=4, name="service")
        event_list = [
            Mock(name="event1"),
            Mock(name="event2"),
            Mock(name="event3")
        ]
        self.scheduler.enqueue_for_appservice(service, ephemeral=event_list)
        self.txn_ctrl.send.assert_called_once_with(service, [], event_list, [],
                                                   None, None,
                                                   DeviceListUpdates())

    def test_send_single_ephemeral_with_queue(self):
        d = defer.Deferred()
        self.txn_ctrl.send = Mock(return_value=make_deferred_yieldable(d))
        service = Mock(id=4)
        event_list_1 = [Mock(event_id="event1"), Mock(event_id="event2")]
        event_list_2 = [Mock(event_id="event3"), Mock(event_id="event4")]
        event_list_3 = [Mock(event_id="event5"), Mock(event_id="event6")]

        # Send an event and don't resolve it just yet.
        self.scheduler.enqueue_for_appservice(service, ephemeral=event_list_1)
        # Send more events: expect send() to NOT be called multiple times.
        self.scheduler.enqueue_for_appservice(service, ephemeral=event_list_2)
        self.scheduler.enqueue_for_appservice(service, ephemeral=event_list_3)
        self.txn_ctrl.send.assert_called_with(service, [], event_list_1, [],
                                              None, None, DeviceListUpdates())
        self.assertEqual(1, self.txn_ctrl.send.call_count)
        # Resolve txn_ctrl.send
        d.callback(service)
        # Expect the queued events to be sent
        self.txn_ctrl.send.assert_called_with(
            service,
            [],
            event_list_2 + event_list_3,
            [],
            None,
            None,
            DeviceListUpdates(),
        )
        self.assertEqual(2, self.txn_ctrl.send.call_count)

    def test_send_large_txns_ephemeral(self):
        d = defer.Deferred()
        self.txn_ctrl.send = Mock(return_value=make_deferred_yieldable(d))
        # Expect the event to be sent immediately.
        service = Mock(id=4, name="service")
        first_chunk = [Mock(name="event%i" % (i + 1)) for i in range(100)]
        second_chunk = [Mock(name="event%i" % (i + 101)) for i in range(50)]
        event_list = first_chunk + second_chunk
        self.scheduler.enqueue_for_appservice(service, ephemeral=event_list)
        self.txn_ctrl.send.assert_called_once_with(service, [], first_chunk,
                                                   [], None, None,
                                                   DeviceListUpdates())
        d.callback(service)
        self.txn_ctrl.send.assert_called_with(service, [], second_chunk, [],
                                              None, None, DeviceListUpdates())
        self.assertEqual(2, self.txn_ctrl.send.call_count)