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 build_application_service_scheduler(self): return ApplicationServiceScheduler(self)
def get_application_service_scheduler(self) -> ApplicationServiceScheduler: return ApplicationServiceScheduler(self)
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)