def test_publish_traced_events(self): """ with two subscribers and message tracing the last event should have a magic flag """ # we want to trigger a deeply-nested condition in # processPublish in class Broker -- lets try w/o refactoring # anything first... class TestSession(ApplicationSession): pass session0 = TestSession() session1 = TestSession() session2 = TestSession() router = mock.MagicMock() router.send = mock.Mock() router.new_correlation_id = lambda: 'fake correlation id' router.is_traced = True broker = Broker(router, reactor) # let's just "cheat" our way a little to the right state by # injecting our subscription "directly" (e.g. instead of # faking out an entire Subscribe etc. flow # ...so we need _subscriptions_map to have at least one # subscription (our test one) for the topic we'll publish to broker._subscription_map.add_observer(session0, 'test.topic') broker._subscription_map.add_observer(session1, 'test.topic') session0._session_id = 1000 session0._transport = mock.MagicMock() session0._transport.get_channel_id = mock.MagicMock(return_value=b'deadbeef') session1._session_id = 1001 session1._transport = mock.MagicMock() session1._transport.get_channel_id = mock.MagicMock(return_value=b'deadbeef') session2._session_id = 1002 session2._transport = mock.MagicMock() session2._transport.get_channel_id = mock.MagicMock(return_value=b'deadbeef') # here's the main "cheat"; we're faking out the # router.authorize because we need it to callback immediately router.authorize = mock.MagicMock(return_value=txaio.create_future_success(dict(allow=True, cache=False, disclose=True))) # now we scan call "processPublish" such that we get to the # condition we're interested in (this "comes from" session1 # beacuse by default publishes don't go to the same session) pubmsg = message.Publish(123, 'test.topic') broker.processPublish(session2, pubmsg) # extract all the event calls events = [ call[1][1] for call in router.send.mock_calls if call[1][0] in [session0, session1, session2] ] self.assertEqual(2, len(events)) self.assertFalse(events[0].correlation_is_last) self.assertTrue(events[1].correlation_is_last)
def test_publish_traced_events(self): """ with two subscribers and message tracing the last event should have a magic flag """ # we want to trigger a deeply-nested condition in # processPublish in class Broker -- lets try w/o refactoring # anything first... class TestSession(ApplicationSession): pass session0 = TestSession() session1 = TestSession() session2 = TestSession() router = mock.MagicMock() router.send = mock.Mock() router.new_correlation_id = lambda: u'fake correlation id' router.is_traced = True broker = Broker(router, reactor) # let's just "cheat" our way a little to the right state by # injecting our subscription "directly" (e.g. instead of # faking out an entire Subscribe etc. flow # ...so we need _subscriptions_map to have at least one # subscription (our test one) for the topic we'll publish to broker._subscription_map.add_observer(session0, u'test.topic') broker._subscription_map.add_observer(session1, u'test.topic') session0._session_id = 1000 session0._transport = mock.MagicMock() session0._transport.get_channel_id = mock.MagicMock(return_value=b'deadbeef') session1._session_id = 1001 session1._transport = mock.MagicMock() session1._transport.get_channel_id = mock.MagicMock(return_value=b'deadbeef') session2._session_id = 1002 session2._transport = mock.MagicMock() session2._transport.get_channel_id = mock.MagicMock(return_value=b'deadbeef') # here's the main "cheat"; we're faking out the # router.authorize because we need it to callback immediately router.authorize = mock.MagicMock(return_value=txaio.create_future_success(dict(allow=True, cache=False, disclose=True))) # now we scan call "processPublish" such that we get to the # condition we're interested in (this "comes from" session1 # beacuse by default publishes don't go to the same session) pubmsg = message.Publish(123, u'test.topic') broker.processPublish(session2, pubmsg) # extract all the event calls events = [ call[1][1] for call in router.send.mock_calls if call[1][0] in [session0, session1, session2] ] self.assertEqual(2, len(events)) self.assertFalse(events[0].correlation_is_last) self.assertTrue(events[1].correlation_is_last)
def test_publish_closed_session(self): """ ensure a session doesn't get Events if it's closed (see also issue #431) """ # we want to trigger a deeply-nested condition in # processPublish in class Broker -- lets try w/o refactoring # anything first... class TestSession(ApplicationSession): pass session0 = TestSession() session1 = TestSession() router = mock.MagicMock() router.new_correlation_id = lambda: 'fake correlation id' broker = Broker(router, reactor) # let's just "cheat" our way a little to the right state by # injecting our subscription "directly" (e.g. instead of # faking out an entire Subscribe etc. flow # ...so we need _subscriptions_map to have at least one # subscription (our test one) for the topic we'll publish to broker._subscription_map.add_observer(session0, 'test.topic') # simulate the session state we want, which is that a # transport is connected (._transport != None) but there # _session_id *is* None (not joined yet, or left already) self.assertIs(None, session0._session_id) session0._transport = mock.MagicMock() session0._transport.transport_details = TransportDetails( channel_id={'tls-unique': b'deadbeef'}) session1._session_id = 1234 # "from" session should look connected + joined session1._transport = mock.MagicMock() session1._transport.transport_details = TransportDetails( channel_id={'tls-unique': b'aaaabeef'}) # here's the main "cheat"; we're faking out the # router.authorize because we need it to callback immediately router.authorize = mock.MagicMock( return_value=txaio.create_future_success( dict(allow=True, cache=False, disclose=True))) # now we scan call "processPublish" such that we get to the # condition we're interested in (this "comes from" session1 # beacuse by default publishes don't go to the same session) pubmsg = message.Publish(123, 'test.topic') broker.processPublish(session1, pubmsg) # neither session should have sent anything on its transport self.assertEqual(session0._transport.method_calls, []) self.assertEqual(session1._transport.method_calls, [])
def test_publish_closed_session(self): """ ensure a session doesn't get Events if it's closed (see also issue #431) """ # we want to trigger a deeply-nested condition in # processPublish in class Broker -- lets try w/o refactoring # anything first... class TestSession(ApplicationSession): pass session0 = TestSession() session1 = TestSession() router = mock.MagicMock() router.new_correlation_id = lambda: u'fake correlation id' broker = Broker(router, reactor) # let's just "cheat" our way a little to the right state by # injecting our subscription "directly" (e.g. instead of # faking out an entire Subscribe etc. flow # ...so we need _subscriptions_map to have at least one # subscription (our test one) for the topic we'll publish to broker._subscription_map.add_observer(session0, u'test.topic') # simulate the session state we want, which is that a # transport is connected (._transport != None) but there # _session_id *is* None (not joined yet, or left already) self.assertIs(None, session0._session_id) session0._transport = mock.MagicMock() session0._transport.get_channel_id = mock.MagicMock(return_value=b'deadbeef') session1._session_id = 1234 # "from" session should look connected + joined session1._transport = mock.MagicMock() session1._transport.channel_id = b'aaaabeef' # here's the main "cheat"; we're faking out the # router.authorize because we need it to callback immediately router.authorize = mock.MagicMock(return_value=txaio.create_future_success(dict(allow=True, cache=False, disclose=True))) # now we scan call "processPublish" such that we get to the # condition we're interested in (this "comes from" session1 # beacuse by default publishes don't go to the same session) pubmsg = message.Publish(123, u'test.topic') broker.processPublish(session1, pubmsg) # neither session should have sent anything on its transport self.assertEquals(session0._transport.method_calls, []) self.assertEquals(session1._transport.method_calls, [])
def test_publish_traced_events_batched(self): """ with two subscribers and message tracing the last event should have a magic flag """ # we want to trigger a deeply-nested condition in # processPublish in class Broker -- lets try w/o refactoring # anything first... class TestSession(ApplicationSession): pass session0 = TestSession() session1 = TestSession() session2 = TestSession() session3 = TestSession() session4 = TestSession() # NOTE! We ensure that "session0" (the publishing session) is # *last* in the observation-list to trigger a (now fixed) # edge-case) sessions = [session1, session2, session3, session4, session0] router = mock.MagicMock() router.send = mock.Mock() router.new_correlation_id = lambda: 'fake correlation id' router.is_traced = True clock = Clock() with replace_loop(clock): broker = Broker(router, clock) broker._options.event_dispatching_chunk_size = 2 # to ensure we get "session0" last, we turn on ordering in # the observations broker._subscription_map._ordered = 1 # let's just "cheat" our way a little to the right state by # injecting our subscription "directly" (e.g. instead of # faking out an entire Subscribe etc. flow # ...so we need _subscriptions_map to have at least one # subscription (our test one) for the topic we'll publish to for session in sessions: broker._subscription_map.add_observer(session, 'test.topic') for i, sess in enumerate(sessions): sess._session_id = 1000 + i sess._transport = mock.MagicMock() sess._transport.get_channel_id = mock.MagicMock( return_value=b'deadbeef') # here's the main "cheat"; we're faking out the # router.authorize because we need it to callback immediately router.authorize = mock.MagicMock( return_value=txaio.create_future_success( dict(allow=True, cache=False, disclose=True))) # now we scan call "processPublish" such that we get to the # condition we're interested in; should go to all sessions # except session0 pubmsg = message.Publish(123, 'test.topic') broker.processPublish(session0, pubmsg) clock.advance(1) clock.advance(1) # extract all the event calls events = [ call[1][1] for call in router.send.mock_calls if call[1][0] in [session0, session1, session2, session3, session4] ] # all except session0 should have gotten an event, and # session4's should have the "last" flag set self.assertEqual(4, len(events)) self.assertFalse(events[0].correlation_is_last) self.assertFalse(events[1].correlation_is_last) self.assertFalse(events[2].correlation_is_last) self.assertTrue(events[3].correlation_is_last)
def test_publish_traced_events_batched(self): """ with two subscribers and message tracing the last event should have a magic flag """ # we want to trigger a deeply-nested condition in # processPublish in class Broker -- lets try w/o refactoring # anything first... class TestSession(ApplicationSession): pass session0 = TestSession() session1 = TestSession() session2 = TestSession() session3 = TestSession() session4 = TestSession() # NOTE! We ensure that "session0" (the publishing session) is # *last* in the observation-list to trigger a (now fixed) # edge-case) sessions = [session1, session2, session3, session4, session0] router = mock.MagicMock() router.send = mock.Mock() router.new_correlation_id = lambda: u'fake correlation id' router.is_traced = True clock = Clock() with replace_loop(clock): broker = Broker(router, clock) broker._options.event_dispatching_chunk_size = 2 # to ensure we get "session0" last, we turn on ordering in # the observations broker._subscription_map._ordered = 1 # let's just "cheat" our way a little to the right state by # injecting our subscription "directly" (e.g. instead of # faking out an entire Subscribe etc. flow # ...so we need _subscriptions_map to have at least one # subscription (our test one) for the topic we'll publish to for session in sessions: broker._subscription_map.add_observer(session, u'test.topic') for i, sess in enumerate(sessions): sess._session_id = 1000 + i sess._transport = mock.MagicMock() sess._transport.get_channel_id = mock.MagicMock(return_value=b'deadbeef') # here's the main "cheat"; we're faking out the # router.authorize because we need it to callback immediately router.authorize = mock.MagicMock(return_value=txaio.create_future_success(dict(allow=True, cache=False, disclose=True))) # now we scan call "processPublish" such that we get to the # condition we're interested in; should go to all sessions # except session0 pubmsg = message.Publish(123, u'test.topic') broker.processPublish(session0, pubmsg) clock.advance(1) clock.advance(1) # extract all the event calls events = [ call[1][1] for call in router.send.mock_calls if call[1][0] in [session0, session1, session2, session3, session4] ] # all except session0 should have gotten an event, and # session4's should have the "last" flag set self.assertEqual(4, len(events)) self.assertFalse(events[0].correlation_is_last) self.assertFalse(events[1].correlation_is_last) self.assertFalse(events[2].correlation_is_last) self.assertTrue(events[3].correlation_is_last)