Example #1
0
 def _publish():
     service_session = self._router._realm.session
     if session._session_id is None:
         options = types.PublishOptions(
             correlation=unsubscribe.
             correlation if unsubscribe else None)
     else:
         options = types.PublishOptions(
             # we exclude the client session from the set of receivers
             # for the WAMP session meta events (race conditions!)
             exclude=[session._session_id],
             correlation=unsubscribe.correlation
             if unsubscribe else None)
     if was_subscribed:
         service_session.publish(
             u'wamp.subscription.on_unsubscribe',
             session._session_id,
             subscription.id,
             options=options,
         )
     if was_deleted:
         service_session.publish(
             u'wamp.subscription.on_delete',
             session._session_id,
             subscription.id,
             options=options,
         )
Example #2
0
        def test_publish(self):
            handler = ApplicationSession()
            MockTransport(handler)

            publication = yield handler.publish(u'com.myapp.topic1')
            self.assertEqual(publication, None)

            publication = yield handler.publish(u'com.myapp.topic1', 1, 2, 3)
            self.assertEqual(publication, None)

            publication = yield handler.publish(u'com.myapp.topic1',
                                                1,
                                                2,
                                                3,
                                                foo=23,
                                                bar='hello')
            self.assertEqual(publication, None)

            publication = yield handler.publish(
                u'com.myapp.topic1',
                options=types.PublishOptions(exclude_me=False))
            self.assertEqual(publication, None)

            publication = yield handler.publish(u'com.myapp.topic1',
                                                1,
                                                2,
                                                3,
                                                foo=23,
                                                bar='hello',
                                                options=types.PublishOptions(
                                                    exclude_me=False,
                                                    exclude=[100, 200, 300]))
            self.assertEqual(publication, None)
Example #3
0
def test_decorator_multi_subscribe(crossbar):
    """
    subscribe with a class using decorators, multiple times
    """
    # setup
    foo_pub = Deferred()
    bar_pub = Deferred()
    from autobahn import wamp

    class TestSession(HelperSession):
        @wamp.subscribe(u"test.foo")
        def foo(self, data):
            print("FOO:", data)
            foo_pub.callback(data)

        @wamp.subscribe(u"test.bar")
        def bar(self, data):
            print("BAR:", data)
            bar_pub.callback(data)

        def onJoin(self, details):
            HelperSession.onJoin(self, details)
            self.subscribe(self)

    sub_session = yield functest_session(session_factory=TestSession)
    pub_session = yield functest_session()

    # execute
    d0 = pub_session.publish(
        u"test.foo",
        "foo_arg",
        options=types.PublishOptions(acknowledge=True),
    )
    d1 = pub_session.publish(
        u"test.bar",
        "bar_arg",
        options=types.PublishOptions(acknowledge=True),
    )
    timeout = sleep(5)

    try:
        test_results = DeferredList([d0, d1, foo_pub, bar_pub],
                                    fireOnOneErrback=True)
        res = yield DeferredList([test_results, timeout],
                                 fireOnOneCallback=True,
                                 fireOnOneErrback=True)
    except Exception as e:
        print("ERROR", e)
        raise

    assert not timeout.called, "timed out"
    assert foo_pub.called, "test.foo should have been subscribed"
    assert bar_pub.called, "test.bar should have been subscribed"
Example #4
0
    def send(session, details):
        yield listening
        # this one should be small enough to go through
        yield session.publish(u"foo",
                              u"a" * 20,
                              options=types.PublishOptions(acknowledge=True))

        # this will definitely be over 1500 and should fail (due to the other
        # side's decoder dropping it because the payload is too big). We can't
        # get an error here because the router accepts it, but the other
        # *client* will reject...
        yield session.publish(u"foo",
                              u"a" * 2000,
                              options=types.PublishOptions(acknowledge=True))
Example #5
0
def test_blacklist_publish_authid(auth_crossbar):
    '''
    One publisher, 3 subscribers and blacklisting
    '''
    # setup
    pub_session = yield functest_auth_session(authid=u'steve')
    sub_session0 = yield functest_auth_session(authid=u'alice')
    sub_session1 = yield functest_auth_session(authid=u'bob')
    sub_session2 = yield functest_auth_session(authid=u'carol')

    alice = Deferred()
    bob = Deferred()
    carol = Deferred()

    sub0 = yield sub_session0.subscribe(alice.callback, u"test_topic")
    sub1 = yield sub_session1.subscribe(bob.callback, u"test_topic")
    sub2 = yield sub_session2.subscribe(carol.callback, u"test_topic")
    try:
        # execute
        yield pub_session.publish(
            u"test_topic",
            "nothing",
            options=types.PublishOptions(exclude_authid=[u'alice']))

        # we should have received two publishes: for bob and carol but
        # *not* alice
        yield wait_for(bob, 1, "waiting for publish0")
        yield wait_for(carol, 1, "waiting for publish1")

        assert not alice.called

    finally:
        yield sub0.unsubscribe()
        yield sub1.unsubscribe()
        yield sub2.unsubscribe()
Example #6
0
 def _publish():
     service_session = self._router._realm.session
     options = types.PublishOptions(
         correlation_id=subscribe.correlation_id,
         correlation_is_anchor=False,
         correlation_is_last=False,
     )
     if is_first_subscriber:
         subscription_details = {
             u'id': subscription.id,
             u'created': subscription.created,
             u'uri': subscription.uri,
             u'match': subscription.match,
         }
         service_session.publish(
             u'wamp.subscription.on_create',
             session._session_id,
             subscription_details,
             options=options,
         )
     if not was_already_subscribed:
         options.correlation_is_last = True
         service_session.publish(
             u'wamp.subscription.on_subscribe',
             session._session_id,
             subscription.id,
             options=options,
         )
Example #7
0
            def _publish():
                service_session = self._router._realm.session

                if unsubscribe and self._router.is_traced:
                    options = types.PublishOptions(
                        correlation_id=unsubscribe.correlation_id,
                        correlation_is_anchor=False,
                        correlation_is_last=False)
                else:
                    options = None

                if was_subscribed:
                    service_session.publish(
                        u'wamp.subscription.on_unsubscribe',
                        session._session_id,
                        subscription.id,
                        options=options,
                    )

                if was_deleted:
                    if options:
                        options.correlation_is_last = True

                    service_session.publish(
                        u'wamp.subscription.on_delete',
                        session._session_id,
                        subscription.id,
                        options=options,
                    )
Example #8
0
    def _unregister(self, registration, session):

        # drop session from registration observers
        #
        was_registered, was_last_callee = self._registration_map.drop_observer(session, registration)

        if was_registered and was_last_callee:
            self._registration_map.delete_observation(registration)

        # remove registration from session->registrations map
        #
        if was_registered:
            self._session_to_registrations[session].discard(registration)

        # publish WAMP meta events
        #
        if self._router._realm:
            service_session = self._router._realm.session
            if service_session and not registration.uri.startswith(u'wamp.'):
                options = types.PublishOptions(
                    correlation=None
                )
                if was_registered:
                    service_session.publish(u'wamp.registration.on_unregister', session._session_id, registration.id, options=options)
                if was_last_callee:
                    service_session.publish(u'wamp.registration.on_delete', session._session_id, registration.id, options=options)

        return was_registered, was_last_callee
Example #9
0
 def _(session, details):
     connects.append(details)
     yield session.publish(
         u"multiverse", group=g, member=m,
         options=types.PublishOptions(acknowledge=True)
     )
     yield session.leave()
Example #10
0
def test_whitelist_publish_authid(auth_crossbar):
    '''
    One publisher, 3 subscribers and blacklisting
    '''
    # setup
    pub_session = yield functest_auth_session(authid=u'steve')
    sub_session0 = yield functest_auth_session(authid=u'alice')
    sub_session1 = yield functest_auth_session(authid=u'bob')
    sub_session2 = yield functest_auth_session(authid=u'carol')

    alice = Deferred()
    bob = Deferred()
    carol = Deferred()

    sub0 = yield sub_session0.subscribe(alice.callback, u"test_topic")
    sub1 = yield sub_session1.subscribe(bob.callback, u"test_topic")
    sub2 = yield sub_session2.subscribe(carol.callback, u"test_topic")
    try:
        # execute
        yield pub_session.publish(
            u"test_topic",
            "nothing",
            options=types.PublishOptions(
                eligible_authid=[u'alice', u'carol', u'eve']))

        # alice, carol only should get the pub
        yield wait_for(alice, 1, "waiting for publish0")
        yield wait_for(carol, 1, "waiting for publish1")
        assert not bob.called

    finally:
        yield sub0.unsubscribe()
        yield sub1.unsubscribe()
        yield sub2.unsubscribe()
Example #11
0
        def test_double_subscribe(self):
            handler = ApplicationSession()
            MockTransport(handler)

            event0 = Deferred()
            event1 = Deferred()

            subscription0 = yield handler.subscribe(
                lambda: event0.callback(42), u'com.myapp.topic1')
            subscription1 = yield handler.subscribe(
                lambda: event1.callback('foo'), u'com.myapp.topic1')
            # same topic, same ID
            self.assertTrue(subscription0.id == subscription1.id)

            # do a publish (MockTransport fakes the acknowledgement
            # message) and then do an actual publish event. The IDs
            # are the same, so we just do one Event.
            publish = yield handler.publish(
                u'com.myapp.topic1',
                options=types.PublishOptions(acknowledge=True,
                                             exclude_me=False),
            )
            handler.onMessage(message.Event(subscription0.id, publish.id))

            # ensure we actually got both callbacks
            self.assertTrue(event0.called, "Missing callback")
            self.assertTrue(event1.called, "Missing callback")
Example #12
0
        def test_publish_callback_exception(self):
            """
            Ensure we handle an exception from the user code.
            """
            handler = ApplicationSession()
            MockTransport(handler)

            error_instance = RuntimeError("we have a problem")
            got_err_d = Deferred()

            def observer(e, msg):
                if error_instance == e.value:
                    got_err_d.callback(True)
            handler.onUserError = observer

            def boom():
                raise error_instance

            sub = yield handler.subscribe(boom, u'com.myapp.topic1')

            # MockTransport gives us the ack reply and then we do our
            # own event message
            publish = yield handler.publish(
                u'com.myapp.topic1',
                options=types.PublishOptions(acknowledge=True, exclude_me=False),
            )
            msg = message.Event(sub.id, publish.id)
            handler.onMessage(msg)

            # we know it worked if our observer worked and did
            # .callback on our Deferred above.
            self.assertTrue(got_err_d.called)
Example #13
0
def test_single_session_pub_sub_success(crossbar):
    """
    Override exclude_me so we publish to ourselves as well.

    Note: not paramterized over publish_options because we need to
    know the status of "exclude_me"
    """
    # setup
    session = yield functest_session()

    pub_d = Deferred()
    sub = yield session.subscribe(pub_d.callback, u"test_topic")
    try:
        assert not pub_d.called

        # execute
        yield session.publish(u"test_topic",
                              "foo",
                              options=types.PublishOptions(acknowledge=True,
                                                           exclude_me=False))

        # test
        yield wait_for(pub_d, 5, "Waiting for our publish callback")
        assert pub_d.called, "Should publish to ourselves with exclude_me=False"
        assert pub_d.result == "foo"
    finally:
        yield sub.unsubscribe()
Example #14
0
def test_internal_uri(crossbar):
    """
    publish to crossbar.* should be denied
    """
    # setup
    pub_session = yield functest_session()

    # execute
    d0 = pub_session.publish(
        u"wamp.awesome",
        "arg",
        options=types.PublishOptions(acknowledge=True),
    )
    d1 = sleep(5)

    try:
        res = yield DeferredList([d0, d1],
                                 fireOnOneCallback=True,
                                 fireOnOneErrback=True)
        assert False, "Should have gotten error"
    except FirstError as e:
        real_e = e.subFailure.value
        assert 'restricted topic' in str(real_e)

    assert not d1.called
Example #15
0
def test_authenticated_two_session_pub_sub(auth_crossbar):
    """
    authenticated publisher and subscriber
    """
    # setup
    pub_session = yield functest_auth_session()
    sub_session = yield functest_auth_session()

    pub_d = Deferred()
    sub = yield sub_session.subscribe(pub_d.callback, u"auth_topic")
    try:
        assert not pub_d.called

        # execute
        pub = yield pub_session.publish(
            u"auth_topic",
            ("foo", "bar"),
            options=types.PublishOptions(
                acknowledge=True,
                # XXX need a "legitimate" way to get session id?
                eligible=[sub_session._session_id],
            ))
        yield wait_for(pub_d, 5, "waiting for two-session publish callback")

        # test
        assert pub_d.called, "Failed to get publish callback"
        # we should have published our two args
        # NOTE: any sequence converted to list...
        assert pub_d.result == ["foo", "bar"]
    finally:
        yield sub.unsubscribe()
Example #16
0
 def _publish():
     service_session = self._router._realm.session
     options = types.PublishOptions(
         # we exclude the client session from the set of receivers
         # for the WAMP session meta events (race conditions!)
         exclude=[session._session_id],
         correlation=subscribe.correlation)
     if is_first_subscriber:
         subscription_details = {
             u'id': subscription.id,
             u'created': subscription.created,
             u'uri': subscription.uri,
             u'match': subscription.match,
         }
         service_session.publish(
             u'wamp.subscription.on_create',
             session._session_id,
             subscription_details,
             options=options,
         )
     if not was_already_subscribed:
         service_session.publish(
             u'wamp.subscription.on_subscribe',
             session._session_id,
             subscription.id,
             options=options,
         )
Example #17
0
def test_single_session_pub_sub_to_self(crossbar):
    '''
    With exclude_me=False we should get our own publish
    '''
    # setup
    session = yield functest_session()
    pub_session = session
    sub_session = session

    pub_d = Deferred()
    sub = yield sub_session.subscribe(pub_d.callback, u"test_topic")

    try:
        # execute
        assert not pub_d.called
        yield pub_session.publish(u"test_topic",
                                  "foo",
                                  options=types.PublishOptions(
                                      acknowledge=True, exclude_me=False))

        # test
        try:
            yield wait_for(pub_d, 1, "Expected this timeout")
        except RuntimeError as e:
            assert False, "Should have gotten a publish"
        assert pub_d.called, "Should publish to ourselves with exclude_me=False"

    finally:
        yield sub.unsubscribe()
Example #18
0
def test_single_session_pub_sub(crossbar):
    '''
    Ensure we don't publish to our own session by default.
    '''
    # setup
    session = yield functest_session()
    pub_session = session
    sub_session = session

    pub_d = Deferred()
    sub = yield sub_session.subscribe(pub_d.callback, u"test_topic")

    try:
        # execute
        assert not pub_d.called
        yield pub_session.publish(
            u"test_topic",
            "foo",
            options=types.PublishOptions(acknowledge=True))

        # test
        try:
            yield wait_for(pub_d, 1, "Expected this timeout")
            assert False, "Should have gotten an exception"
        except RuntimeError as e:
            pass
        assert not pub_d.called, "Shouldn't publish to ourselves"
    finally:
        yield sub.unsubscribe()
Example #19
0
        def test_publish_undefined_exception(self):
            handler = ApplicationSession()
            MockTransport(handler)

            options = types.PublishOptions(acknowledge=True)

            yield self.assertFailure(handler.publish(u'de.myapp.topic1', options=options), ApplicationError)
            yield self.assertFailure(handler.publish(u'', options=options), ApplicationError)
Example #20
0
 def bob_join(session, details):
     print("bob joined: PID={x_cb_pid}".format(**details.authextra))
     print("publishing 'test.a_thing'")
     p = yield session.publish("test.a_thing", 3, 2, 1, options=types.PublishOptions(acknowledge=True))
     print("published {}".format(p))
     res = yield session.call("test.rpc", 1, 2, 3)
     print("test.rpc returned: {}".format(res))
     reactor.callLater(2, session.leave)
Example #21
0
        def test_publish_acknowledged(self):
            handler = ApplicationSession()
            MockTransport(handler)

            publication = yield handler.publish(u'com.myapp.topic1', options=types.PublishOptions(acknowledge=True))
            self.assertTrue(type(publication.id) in (int, long))

            publication = yield handler.publish(u'com.myapp.topic1', 1, 2, 3, options=types.PublishOptions(acknowledge=True))
            self.assertTrue(type(publication.id) in (int, long))

            publication = yield handler.publish(u'com.myapp.topic1', 1, 2, 3, foo=23, bar='hello', options=types.PublishOptions(acknowledge=True))
            self.assertTrue(type(publication.id) in (int, long))

            publication = yield handler.publish(u'com.myapp.topic1', options=types.PublishOptions(exclude_me=False, acknowledge=True))
            self.assertTrue(type(publication.id) in (int, long))

            publication = yield handler.publish(u'com.myapp.topic1', 1, 2, 3, foo=23, bar='hello', options=types.PublishOptions(exclude_me=False, exclude=[100, 200, 300], acknowledge=True))
            self.assertTrue(type(publication.id) in (int, long))
Example #22
0
        def on_authorize_success(authorization):
            if not authorization[u'allow']:
                # error reply since session is not authorized to register
                #
                reply = message.Error(message.Register.MESSAGE_TYPE, register.request, ApplicationError.NOT_AUTHORIZED, [u"session is not authorized to register procedure '{0}'".format(register.procedure)])

            else:
                registration = self._registration_map.get_observation(register.procedure, register.match)
                if register.force_reregister and registration:
                    for obs in registration.observers:
                        self._registration_map.drop_observer(obs, registration)
                        kicked = message.Unregistered(
                            0,
                            registration=registration.id,
                            reason=u"wamp.error.unregistered",
                        )
                        kicked.correlation = register.correlation
                        self._router.send(obs, kicked)
                    self._registration_map.delete_observation(registration)

                # ok, session authorized to register. now get the registration
                #
                registration_extra = RegistrationExtra(register.invoke)
                registration_callee_extra = RegistrationCalleeExtra(register.concurrency)
                registration, was_already_registered, is_first_callee = self._registration_map.add_observer(session, register.procedure, register.match, registration_extra, registration_callee_extra)

                if not was_already_registered:
                    self._session_to_registrations[session].add(registration)

                # publish WAMP meta events
                #
                if self._router._realm:
                    service_session = self._router._realm.session
                    if service_session and not registration.uri.startswith(u'wamp.'):
                        options = types.PublishOptions(
                            correlation=register.correlation
                        )
                        if is_first_callee:
                            registration_details = {
                                u'id': registration.id,
                                u'created': registration.created,
                                u'uri': registration.uri,
                                u'match': registration.match,
                                u'invoke': registration.extra.invoke,
                            }
                            service_session.publish(u'wamp.registration.on_create', session._session_id, registration_details, options=options)
                        if not was_already_registered:
                            service_session.publish(u'wamp.registration.on_register', session._session_id, registration.id, options=options)

                # acknowledge register with registration ID
                #
                reply = message.Registered(register.request, registration.id)

            # send out reply to register requestor
            #
            reply.correlation = register.correlation
            self._router.send(session, reply)
Example #23
0
        def test_publish_defined_exception(self):
            handler = ApplicationSession()
            MockTransport(handler)

            options = types.PublishOptions(acknowledge=True)

            handler.define(NotAuthorized)
            yield self.assertFailure(handler.publish(u'de.myapp.topic1', options=options), NotAuthorized)

            handler.define(InvalidUri)
            yield self.assertFailure(handler.publish(u'', options=options), InvalidUri)
Example #24
0
        def test_double_subscribe_double_unsubscribe(self):
            '''
            If we subscribe twice, and unsubscribe twice, we should then get
            an Unsubscribed message.
            '''
            handler = ApplicationSession()
            MockTransport(handler)

            # monkey-patch ApplicationSession to ensure we get our message
            unsubscribed_d = Deferred()

            def onMessage(msg):
                if isinstance(msg, message.Unsubscribed):
                    unsubscribed_d.callback(msg)
                return ApplicationSession.onMessage(handler, msg)

            handler.onMessage = onMessage

            event0 = Deferred()
            event1 = Deferred()

            subscription0 = yield handler.subscribe(
                lambda: event0.callback(42), u'com.myapp.topic1')
            subscription1 = yield handler.subscribe(
                lambda: event1.callback('foo'), u'com.myapp.topic1')

            self.assertTrue(subscription0.id == subscription1.id)
            yield subscription0.unsubscribe()
            yield subscription1.unsubscribe()

            # after the second unsubscribe, we should have gotten an
            # Unsubscribed message
            assert unsubscribed_d.called

            # do a publish (MockTransport fakes the acknowledgement
            # message) and then do an actual publish event. Sending
            # the Event should be an error, as we have no
            # subscriptions left.
            publish = yield handler.publish(
                u'com.myapp.topic1',
                options=types.PublishOptions(acknowledge=True,
                                             exclude_me=False),
            )
            try:
                handler.onMessage(message.Event(subscription0.id, publish.id))
                self.fail("Expected ProtocolError")
            except ProtocolError:
                pass

            # since we unsubscribed the second event handler, we
            # should NOT have called its callback
            self.assertTrue(not event0.called, "First callback fired.")
            self.assertTrue(not event1.called, "Second callback fired.")
Example #25
0
    def onJoin(self, details):
        def on_event(i):
            print("Got event: {}".format(i))

        yield self.subscribe(on_event, 'com.myapp.topic1')

        counter = 0
        while True:
            self.publish('com.myapp.topic1',
                         counter,
                         options=types.PublishOptions(excludeMe=False))
            counter += 1
            yield sleep(1)
Example #26
0
        def test_double_subscribe_errors(self):
            """
            Test various error-conditions when we try to add a second
            subscription-handler (its signature must match any
            existing handlers).
            """
            handler = ApplicationSession()
            MockTransport(handler)

            event0 = Deferred()
            event1 = Deferred()

            def second(*args, **kw):
                # our EventDetails should have been passed as the
                # "boom" kwarg; see "details_arg=" below
                self.assertTrue('boom' in kw)
                self.assertTrue(isinstance(kw['boom'], types.EventDetails))
                event1.callback(args)

            subscription0 = yield handler.subscribe(
                lambda arg: event0.callback(arg), u'com.myapp.topic1')
            subscription1 = yield handler.subscribe(
                second,
                u'com.myapp.topic1',
                types.SubscribeOptions(details_arg='boom'),
            )
            # same topic, same ID
            self.assertTrue(subscription0.id == subscription1.id)

            # MockTransport gives us the ack reply and then we do our
            # own event message.
            publish = yield handler.publish(
                u'com.myapp.topic1',
                options=types.PublishOptions(acknowledge=True,
                                             exclude_me=False),
            )
            # note that the protocol serializer converts all sequences
            # to lists, so we pass "args" as a list, not a tuple on
            # purpose.
            handler.onMessage(
                message.Event(subscription0.id, publish.id, args=['arg0']))

            # each callback should have gotten called, each with its
            # own args (we check the correct kwarg in second() above)
            self.assertTrue(event0.called)
            self.assertTrue(event1.called)
            self.assertEqual(event0.result, 'arg0')
            self.assertEqual(event1.result, ('arg0', ))
Example #27
0
 def _publish():
     service_session = self._router._realm.session
     options = types.PublishOptions(correlation_id=None)
     if was_subscribed:
         service_session.publish(
             u'wamp.subscription.on_unsubscribe',
             session._session_id,
             subscription.id,
             options=options,
         )
     if was_deleted:
         service_session.publish(
             u'wamp.subscription.on_delete',
             session._session_id,
             subscription.id,
             options=options,
         )
Example #28
0
def test_whitelist_publish_authrole(auth_crossbar):
    '''
    One publisher, 3 subscribers and blacklisting
    '''
    # setup
    pub_session = yield functest_auth_session(authid=u'steve')
    sub_session0 = yield functest_auth_session(authid=u'alice')
    sub_session1 = yield functest_auth_session(authid=u'bob')
    sub_session2 = yield functest_auth_session(authid=u'carol')

    publishes = []
    got_pubs = [
        Deferred(),
        Deferred(),
        Deferred(),
        Deferred(),
        Deferred(),
        Deferred()
    ]
    notify_pubs = [x for x in got_pubs]

    alice = Deferred()
    bob = Deferred()
    carol = Deferred()

    sub0 = yield sub_session0.subscribe(alice.callback, u"test_topic")
    sub1 = yield sub_session1.subscribe(bob.callback, u"test_topic")
    sub2 = yield sub_session2.subscribe(carol.callback, u"test_topic")
    try:
        # execute
        yield pub_session.publish(
            u"test_topic",
            "nothing",
            options=types.PublishOptions(eligible_authrole=u'role1'))

        # we should have received two publishes: for alice and bob but
        # *not* carol (who is in role1 instead of role0)
        yield wait_for(carol, 1, "waiting for publish0")
        yield sleep(0.1)  # give spurious alice, bob messages time to arrive
        assert not alice.called
        assert not bob.called

    finally:
        yield sub0.unsubscribe()
        yield sub1.unsubscribe()
        yield sub2.unsubscribe()
Example #29
0
        def test_publish_callback_exception(self):
            """
            Ensure we handle an exception from the user code.
            """
            handler = ApplicationSession()
            MockTransport(handler)

            error_instance = RuntimeError("we have a problem")
            got_err_d = Deferred()

            def observer(kw):
                if kw['isError'] and 'failure' in kw:
                    fail = kw['failure']
                    fail.trap(RuntimeError)
                    if error_instance == fail.value:
                        got_err_d.callback(True)

            log.addObserver(observer)

            def boom():
                raise error_instance

            try:
                sub = yield handler.subscribe(boom, u'com.myapp.topic1')

                # MockTransport gives us the ack reply and then we do our
                # own event message
                publish = yield handler.publish(
                    u'com.myapp.topic1',
                    options=types.PublishOptions(acknowledge=True,
                                                 exclude_me=False),
                )
                msg = message.Event(sub.id, publish.id)
                handler.onMessage(msg)

                # we know it worked if our observer worked and did
                # .callback on our Deferred above.
                self.assertTrue(got_err_d.called)
                # ...otherwise trial will fail the test anyway
                self.flushLoggedErrors()

            finally:
                log.removeObserver(observer)
Example #30
0
        def test_double_subscribe_single_unsubscribe(self):
            '''
            Make sure we correctly deal with unsubscribing one of our handlers
            from the same topic.
            '''
            handler = ApplicationSession()
            MockTransport(handler)

            # monkey-patch ApplicationSession to ensure we DO NOT get
            # an Unsubscribed message -- since we only unsubscribe
            # from ONE of our handlers for com.myapp.topic1
            def onMessage(msg):
                assert not isinstance(msg, message.Unsubscribed)
                return ApplicationSession.onMessage(handler, msg)

            handler.onMessage = onMessage

            event0 = Deferred()
            event1 = Deferred()

            subscription0 = yield handler.subscribe(
                lambda: event0.callback(42), u'com.myapp.topic1')
            subscription1 = yield handler.subscribe(
                lambda: event1.callback('foo'), u'com.myapp.topic1')

            self.assertTrue(subscription0.id == subscription1.id)
            yield subscription1.unsubscribe()

            # do a publish (MockTransport fakes the acknowledgement
            # message) and then do an actual publish event. Note the
            # IDs are the same, so there's only one Event.
            publish = yield handler.publish(
                u'com.myapp.topic1',
                options=types.PublishOptions(acknowledge=True,
                                             exclude_me=False),
            )
            handler.onMessage(message.Event(subscription0.id, publish.id))

            # since we unsubscribed the second event handler, we
            # should NOT have called its callback
            self.assertTrue(event0.called, "Missing callback")
            self.assertTrue(not event1.called, "Second callback fired.")