Beispiel #1
0
    def generic_test_two_clients_with_message_list(self, message_list):

        with make_client(endpoint=endpoint,
                         appkey=appkey,
                         reconnect_interval=0) as subscriber:
            with make_client(endpoint=endpoint, appkey=appkey) as publisher:

                co1 = ClientObserver()
                subscriber.observer = co1
                co2 = ClientObserver()
                publisher.observer = co2

                so = sync_subscribe(subscriber, channel)

                for msg in message_list:
                    publisher.publish(channel, msg)

                sync_publish(publisher, channel, 'finalizer')

                while 'finalizer' !=\
                        so.last_received_channel_data['messages'][-1]:
                    print(so.last_received_channel_data)
                    last_data = so.wait_for_channel_data()
                    if last_data['messages'][-1] == 'finalizer':
                        break

                got_messages = so.extract_received_messages()

                self.assertEqual(got_messages, message_list + ['finalizer'])
 def on_enter_stopped(this):
     ClientObserver.on_enter_stopped(this)
     global step
     if step == 1:
         step = 2
         client.start()
     elif step == 3:
         exit.set()
Beispiel #3
0
    def test_exception_in_solicited_pdu_callback(self):

        observer = ClientObserver()

        with make_client(endpoint=endpoint, appkey=appkey,
                         observer=observer) as client:

            def crashy(ack):
                print(ack["no-such-field"])

            observer.stopped.clear()
            client.publish(channel, 'message', callback=crashy)
            observer.wait_stopped()
Beispiel #4
0
    def test_wrong_subscribe_ack(self):
        with make_client(endpoint=endpoint,
                         appkey=appkey,
                         reconnect_interval=10) as client:

            client.observer = ClientObserver()
            old_received_message =\
                client._internal.connection.on_incoming_json
            client._internal.connection.on_incoming_json =\
                lambda *args: None

            so = SubscriptionObserver()
            client.subscribe('test_wrong_subscribe_ack',
                             SubscriptionMode.ADVANCED, so)

            client._queue.join()

            old_received_message({
                u"action": u"rtm/publish/ok",
                u"body": {},
                u"id": 0
            })

            client._queue.join()

            expected_log = ['on_leave_connected', 'on_enter_awaiting']

            self.assertEqual(client.observer.log[:2], expected_log)
    def test_wrong_unsubscribe_ack(self):
        with make_client(endpoint=endpoint, appkey=appkey) as client:

            client.observer = ClientObserver()
            sync_subscribe(client, channel)

            old_received_message =\
                client._internal.connection.on_incoming_text_frame
            client._internal.connection.on_incoming_text_frame =\
                lambda *args: None

            client.unsubscribe(channel)

            client._queue.join()

            old_received_message(
                b'{"action":"rtm/publish/ok","body":{},"id":1}')

            client._queue.join()

            client.observer.wait_connected()

            expected_log = [
                'on_leave_connected',
                'on_enter_awaiting',
                'on_leave_awaiting',
                'on_enter_connecting',
                'on_leave_connecting',
                'on_enter_connected',
                ]

            self.assertEqual(client.observer.log, expected_log)
    def test_reconnect(self):
        client = Client(
            endpoint=endpoint, appkey=appkey,
            reconnect_interval=0, fail_count_threshold=1)
        client.observer = ClientObserver()

        client.start()
        client.observer.wait_connected('First connect timeout')
        emulate_websocket_disconnect(client)
        client.observer.wait_disconnected()
        client.observer.wait_connected('Second connect timeout')
        client.stop()
        client.observer.wait_stopped()
        client.dispose()

        expected_log = [
            'on_leave_stopped',
            'on_enter_connecting',
            'on_leave_connecting',
            'on_enter_connected',
            'on_leave_connected',
            'on_enter_awaiting',
            'on_leave_awaiting',
            'on_enter_connecting',
            'on_leave_connecting',
            'on_enter_connected',
            'on_leave_connected',
            'on_enter_stopping',
            'on_leave_stopping',
            'on_enter_stopped',
            'on_leave_stopped',
            'on_enter_disposed']

        self.assertEqual(client.observer.log, expected_log)
    def test_reconnect_zero_threshold(self):
        client = Client(
            endpoint=endpoint, appkey=appkey,
            reconnect_interval=0, fail_count_threshold=0)
        client.observer = ClientObserver()

        client.start()
        client.observer.wait_connected()

        client._internal._endpoint = 'ws://bogus'
        emulate_websocket_disconnect(client)

        client.observer.wait_disconnected()
        client.observer.wait_stopped()
        client.dispose()

        expected_log = [
            'on_leave_stopped',
            'on_enter_connecting',
            'on_leave_connecting',
            'on_enter_connected',
            'on_leave_connected',
            'on_enter_awaiting',
            'on_leave_awaiting',
            'on_enter_connecting',
            'on_leave_connecting',
            'on_enter_stopped',
            'on_leave_stopped',
            'on_enter_disposed']

        self.assertEqual(client.observer.log, expected_log)
    def test_start_stop(self):
        client = Client(endpoint=endpoint, appkey=appkey)
        client.observer = ClientObserver()

        client.start()
        client.observer.wait_connected()
        client.stop()
        client.observer.wait_stopped()

        expected_log_1 = [
            'on_leave_stopped',
            'on_enter_connecting',
            'on_leave_connecting',
            'on_enter_connected',
            'on_leave_connected',
            'on_enter_stopping',
            'on_leave_stopping',
            'on_enter_stopped']

        expected_log_2 = [
            'on_leave_stopped',
            'on_enter_connecting',
            'on_leave_connecting',
            'on_enter_stopped']

        try:
            self.assertEqual(client.observer.log, expected_log_1)
        except:
            self.assertEqual(client.observer.log, expected_log_2)
Beispiel #9
0
    def test_two_clients_with_best_effort_delivery(self):

        with make_client(endpoint=endpoint,
                         appkey=appkey,
                         reconnect_interval=0) as subscriber:
            with make_client(endpoint=endpoint, appkey=appkey) as publisher:

                co1 = ClientObserver()
                subscriber.observer = co1
                co2 = ClientObserver()
                publisher.observer = co2

                try:
                    so = sync_subscribe(subscriber,
                                        channel,
                                        mode=SubscriptionMode.RELIABLE)

                    sync_publish(publisher, channel, 'first-message')
                    so.wait_for_channel_data('First receive timeout')
                    emulate_websocket_disconnect(subscriber)
                    so.wait_not_subscribed()

                    # send a message while subscriber is disconnected
                    sync_publish(publisher, channel, 'second-message')

                    so.wait_subscribed('Second subscribe timeout')
                    so.wait_for_channel_data('Second receive timeout')

                    # send a message after subscribed reconnected
                    publisher.publish(channel, 'third-message')

                    so.wait_for_channel_data('Third receive timeout')
                    expected_messages =\
                        ['first-message', 'second-message', 'third-message']

                    got_messages = []
                    for log_entry in so.log:
                        if log_entry[0] == 'data':
                            got_messages += log_entry[1]['messages']

                    self.assertEqual(got_messages, expected_messages)
                except Exception:
                    print('Subscriber log: {0}'.format(co1.log))
                    print('Publisher log: {0}'.format(co2.log))
                    print('Subscription log: {0}'.format(so.log))
                    raise
Beispiel #10
0
    def test_exception_in_subscription_data_callback(self):

        observer = ClientObserver()

        with make_client(endpoint=endpoint, appkey=appkey,
                         observer=observer) as client:

            class CrashyObserver(SubscriptionObserver):
                def on_subscription_data(this, data):
                    SubscriptionObserver.on_subscription_data(this, data)
                    raise ValueError('Error in on_subscription_data')

            observer.stopped.clear()
            so = CrashyObserver()
            client.subscribe(channel, SubscriptionMode.SIMPLE, so)
            so.wait_subscribed()
            client.publish(channel, 'message')
            observer.wait_stopped()
Beispiel #11
0
    def test_stop_already_stopped(self):
        client = Client(endpoint=endpoint, appkey=appkey)
        client.observer = ClientObserver()
        client.stop()
        client.dispose()

        expected_log = ['on_leave_stopped', 'on_enter_disposed']

        self.assertEqual(client.observer.log, expected_log)
    def test_subscribe_error_and_resubscribe_with_no_position(self):
        with make_client(endpoint=endpoint,
                         appkey=appkey,
                         reconnect_interval=1) as client:

            client.observer = ClientObserver()
            ev = threading.Event()

            threads = []

            class RecoveringSubscriptionObserver(SubscriptionObserver):
                def on_enter_failed(this, error):
                    this.log.append(('on_enter_failed', error))
                    if error == 'Subscribe error':
                        import threading

                        def resubscribe_sans_position():
                            client.unsubscribe(channel)
                            client.subscribe(channel,
                                             SubscriptionMode.ADVANCED, this)
                            ev.set()

                        t = threading.Thread(
                            target=resubscribe_sans_position,
                            name='test_resubscribe_sans_position')
                        t.start()
                        threads.append(t)

            so = RecoveringSubscriptionObserver()
            client.subscribe(channel,
                             SubscriptionMode.ADVANCED,
                             so,
                             args={'position': 'this_is_invalid_position'})
            ev.wait(10)

            so.wait_subscribed()

            expected_log = [
                'on_leave_unsubscribed',
                'on_enter_subscribing', 'on_leave_subscribing',
                ('on_enter_failed', 'Subscribe error'), 'on_leave_failed',
                'on_enter_unsubscribed', 'on_deleted', 'on_created',
                'on_leave_unsubscribed', 'on_enter_subscribing',
                'on_leave_subscribing', 'on_enter_subscribed'
            ]

            self.assertEqual(so.log, expected_log)

            sync_publish(client, channel, 'message')
            data = so.wait_for_channel_data()

            self.assertEqual(data['subscription_id'], channel)
            self.assertEqual(data['messages'], ['message'])

            threads[0].join()
    def test_fast_forward(self):
        with make_client(endpoint=endpoint, appkey=appkey) as client:

            sync_subscribe(client, channel)
            co = ClientObserver()
            client.observer = co

            emulate_fast_forward(client, channel)
            client._queue.join()

            self.assertEqual([('on_fast_forward', channel)], co.log)
Beispiel #14
0
    def test_two_clients(self):

        with make_client(endpoint=endpoint,
                         appkey=appkey,
                         reconnect_interval=0) as subscriber:
            with make_client(endpoint=endpoint, appkey=appkey) as publisher:

                co1 = ClientObserver()
                subscriber.observer = co1
                co2 = ClientObserver()
                publisher.observer = co2

                try:
                    so = sync_subscribe(subscriber, channel)

                    sync_publish(publisher, channel, 'first-message')
                    so.wait_for_channel_data('First receive timeout')
                    emulate_websocket_disconnect(subscriber)
                    so.wait_not_subscribed()

                    # send a message while subscriber is disconnected
                    sync_publish(publisher, channel, 'second-message')

                    so.wait_subscribed('Second subscribe timeout')
                    so.wait_for_channel_data('Second receive timeout')

                    # send a message after subscribed reconnected
                    publisher.publish(channel, 'third-message')

                    so.wait_for_channel_data('Third receive timeout')
                    expected_messages =\
                        ['first-message', 'second-message', 'third-message']

                    got_messages = so.extract_received_messages()

                    self.assertEqual(got_messages, expected_messages)
                except Exception:
                    print('Subscriber log: {0}'.format(co1.log))
                    print('Publisher log: {0}'.format(co2.log))
                    print('Subscription log: {0}'.format(so.log))
                    raise
    def test_ack_with_no_id(self):
        with make_client(
                endpoint=endpoint, appkey=appkey, reconnect_interval=10)\
                as client:
            client.observer = ClientObserver()

            client._internal.connection.on_incoming_text_frame(
                b'{"action":"rtm/publish/ok", "body":{}}')

            client._queue.join()

            expected_log = ['on_leave_connected', 'on_enter_awaiting']

            self.assertEqual(client.observer.log, expected_log)
    def test_unsolicited_error(self):
        with make_client(
                endpoint=endpoint, appkey=appkey, reconnect_interval=10)\
                as client:
            client.observer = ClientObserver()

            client._internal.connection.on_incoming_text_frame(
                b'{"action":"/error", "body":{"error":"bad"}}')

            client._queue.join()

            expected_log = ['on_leave_connected', 'on_enter_awaiting']

            self.assertEqual(client.observer.log, expected_log)
    def test_change_observer(self):
        with make_client(endpoint=endpoint, appkey=appkey) as client:

            co = ClientObserver()
            client.observer = co

            channel = make_channel_name('change_observer')
            so1 = sync_subscribe(client, channel)

            client.unsubscribe(channel)
            so2 = SubscriptionObserver()
            client.subscribe(channel,
                             SubscriptionMode.ADVANCED,
                             subscription_observer=so2)

            so2.wait_subscribed()

            client.stop()

            co.wait_disconnected()

            self.maxDiff = None
            expected_so1_log = [
                'on_leave_unsubscribed', 'on_enter_subscribing',
                'on_leave_subscribing', 'on_enter_subscribed',
                'on_leave_subscribed', 'on_enter_unsubscribing',
                'on_leave_unsubscribing', 'on_enter_unsubscribed', 'on_deleted'
            ]

            expected_so2_log = [
                'on_created', 'on_leave_unsubscribed', 'on_enter_subscribing',
                'on_leave_subscribing', 'on_enter_subscribed'
            ]

            self.assertEqual(so1.log, expected_so1_log)
            self.assertEqual(so2.log, expected_so2_log)
    def test_reauth(self):
        client = Client(endpoint=endpoint, appkey=appkey, reconnect_interval=0)
        auth_delegate = auth.RoleSecretAuthDelegate(role, secret)
        auth_event = threading.Event()
        mailbox = []

        co = ClientObserver()
        client.observer = co
        client.start()

        co.wait_connected()

        def auth_callback(auth_result):
            if type(auth_result) == auth.Done:
                mailbox.append('Auth success')
                auth_event.set()
            else:
                mailbox.append('Auth failure: {0}'.format(
                    auth_result.message))
                auth_event.set()
        client.authenticate(auth_delegate, auth_callback)

        if not auth_event.wait(30):
            raise RuntimeError("Auth timeout")

        self.assertEqual(mailbox, ['Auth success'])

        so = sync_subscribe(client, restricted_channel)

        message1 = make_channel_name('before disconnect')
        sync_publish(client, restricted_channel, message1)
        first_data = so.wait_for_channel_data()
        self.assertTrue(message1 in first_data['messages'])

        emulate_websocket_disconnect(client)

        co.wait_disconnected()
        co.wait_connected()

        message2 = make_channel_name('after reconnect')
        sync_publish(client, restricted_channel, message2)
        second_data = so.wait_for_channel_data()
        self.assertTrue(message2 in second_data['messages'])

        client.stop()
        client.dispose()
    def test_pdu_with_no_action(self):
        with make_client(
                endpoint=endpoint, appkey=appkey, reconnect_interval=10)\
                as client:
            client.observer = ClientObserver()

            client._internal.connection.on_incoming_json({
                u"body": {},
                u"id": 42
            })

            client._queue.join()

            expected_log = ['on_leave_connected', 'on_enter_awaiting']

            self.assertEqual(client.observer.log, expected_log)
    def test_automatic_resubscribe(self):
        client = Client(
            endpoint=endpoint, appkey=appkey,
            reconnect_interval=0)
        client.observer = ClientObserver()

        channel = make_channel_name('resubscribe')

        client.start()
        client.observer.wait_connected('First connect timeout')
        so = sync_subscribe(client, channel)
        sync_publish(client, channel, 'first-message')
        first_channel_data = so.wait_for_channel_data()
        emulate_websocket_disconnect(client)
        so.wait_not_subscribed()
        client.observer.wait_disconnected()
        client.observer.wait_connected('Second connect timeout')
        so.wait_subscribed('Second subscribe timeout')
        sync_publish(client, channel, 'second-message')
        second_channel_data = so.wait_for_channel_data()
        client.unsubscribe(channel)
        so.wait_not_subscribed()
        client.stop()
        client.dispose()

        expected_log = [
            'on_leave_unsubscribed',
            'on_enter_subscribing',
            'on_leave_subscribing',
            'on_enter_subscribed',
            ('data', first_channel_data),
            # point of disconnect
            'on_leave_subscribed',
            'on_enter_unsubscribed',
            # point of reconnect
            'on_leave_unsubscribed',
            'on_enter_subscribing',
            'on_leave_subscribing',
            'on_enter_subscribed',
            ('data', second_channel_data),
            'on_leave_subscribed',
            'on_enter_unsubscribing',
            'on_leave_unsubscribing',
            'on_enter_unsubscribed',
            'on_deleted']

        self.assertEqual(so.log, expected_log)
    def test_subscribe_error(self):
        with make_client(endpoint=endpoint,
                         appkey=appkey,
                         reconnect_interval=1) as client:

            client.observer = ClientObserver()
            so = SubscriptionObserver()
            client.subscribe(channel, SubscriptionMode.ADVANCED, so,
                             {'position': 'this_is_invalid_position'})
            so.wait_failed()

            expected_log = [
                'on_leave_unsubscribed', 'on_enter_subscribing',
                'on_leave_subscribing', ('on_enter_failed', 'Subscribe error')
            ]

            self.assertEqual(so.log, expected_log)
Beispiel #22
0
    def test_start_wait_stop(self):
        client = Client(endpoint=endpoint, appkey=appkey)
        client.observer = ClientObserver()

        client.start()
        client.observer.wait_connected()
        client.stop()
        client.observer.wait_stopped()
        client.dispose()

        expected_log = [
            'on_leave_stopped', 'on_enter_connecting', 'on_leave_connecting',
            'on_enter_connected', 'on_leave_connected', 'on_enter_stopping',
            'on_leave_stopping', 'on_enter_stopped', 'on_leave_stopped',
            'on_enter_disposed'
        ]

        self.assertEqual(client.observer.log, expected_log)
    def test_missing_pong(self):
        satori.rtm.connection.ping_interval_in_seconds = 0.4
        client = Client(endpoint=endpoint, appkey=appkey, reconnect_interval=0)
        co = ClientObserver()
        client.observer = co

        client.start()
        client.observer.wait_connected('First connect timeout')

        # emulate the absence of server pongs and silence in the socket
        client._internal.connection.on_ws_ponged = lambda: None
        client._internal.connection.last_ponged_time = 0
        client._internal.connection.on_ws_pong = lambda x, y: None

        client.observer.wait_disconnected('First disconnect timeout')
        client.observer.wait_connected('Second connect timeout')

        client.stop()
        client.dispose()
        satori.rtm.connection.ping_interval_in_seconds = 60
Beispiel #24
0
    def test_double_subscribe(self):
        with make_client(endpoint=endpoint,
                         appkey=appkey,
                         reconnect_interval=1) as client:

            client.observer = ClientObserver()
            so = sync_subscribe(client, channel)
            client.subscribe(channel,
                             SubscriptionMode.ADVANCED,
                             subscription_observer=so)

            sync_publish(client, channel, 'message')
            data = so.wait_for_channel_data()

            expected_log = [
                'on_leave_unsubscribed', 'on_enter_subscribing',
                'on_leave_subscribing', 'on_enter_subscribed', ('data', data)
            ]

            self.assertEqual(so.log, expected_log)
 def test_before_start(self):
     client = Client(endpoint=endpoint, appkey=appkey)
     co = ClientObserver()
     client.observer = co
     so = SubscriptionObserver()
     client.subscribe(channel,
                      SubscriptionMode.ADVANCED,
                      subscription_observer=so)
     client.start()
     co.wait_connected()
     sync_publish(client, channel, 'message')
     channel_data = so.wait_for_channel_data()
     self.assertEqual(channel_data['messages'], ['message'])
     client.stop()
     co.wait_stopped()
    def test_resubscribe_after_manual_reconnect(self):
        with make_client(endpoint, appkey) as client:
            channel = make_channel_name('manual_reconnect')

            so = sync_subscribe(client, channel)

            sync_publish(client, channel, 'first-message')
            m = so.wait_for_channel_data()
            self.assertEqual(m['messages'], ['first-message'])

            client.observer = ClientObserver()
            client.stop()
            client.observer.wait_disconnected()

            client.start()
            client._queue.join()
            client.observer.wait_connected()

            sync_publish(client, channel, 'second-message')
            m = so.wait_for_channel_data()
            self.assertEqual(m['messages'], ['second-message'])
    def test_internal_error(self):
        with make_client(
                endpoint=endpoint, appkey=appkey, reconnect_interval=10)\
                as client:

            client.observer = ClientObserver()
            old_received_message =\
                client._internal.connection.on_incoming_text_frame
            client._internal.connection.on_incoming_text_frame =\
                lambda *args: None

            so = SubscriptionObserver()
            client.subscribe('test_internal_error', SubscriptionMode.ADVANCED,
                             so)

            old_received_message("not-a-json-object")

            client._queue.join()

            expected_log = ['on_leave_connected', 'on_enter_awaiting']

            self.assertEqual(client.observer.log, expected_log)
    def test_repeat_second_message(self):
        client = Client(endpoint=endpoint, appkey=appkey, reconnect_interval=1)
        client.observer = ClientObserver()

        channel = make_channel_name('resubscribe')

        client.start()
        client.observer.wait_connected()
        so = sync_subscribe(client, channel)
        sync_publish(client, channel, 'first-message')
        first_channel_data = so.wait_for_channel_data()
        sync_publish(client, channel, 'second-message')
        second_channel_data = so.wait_for_channel_data()
        client.unsubscribe(channel)
        client.subscribe(channel,
                         SubscriptionMode.ADVANCED,
                         so,
                         args={'position': first_channel_data['position']})
        self.assertEqual(second_channel_data['messages'],
                         so.wait_for_channel_data()['messages'])
        client.unsubscribe(channel)
        so.wait_not_subscribed()
        client.stop()
        client.dispose()
Beispiel #29
0
 def on_enter_stopped(this):
     ClientObserver.on_enter_stopped(this)
     client.dispose()
     raise ValueError('Division by zero')
 def on_enter_connected(this):
     ClientObserver.on_enter_connected(this)
     global step
     if step == 2:
         step = 3
         client.stop()