def test_subscribe_error_after_a_cycle(self): with make_client(endpoint=endpoint, appkey=appkey, reconnect_interval=1) as client: old_received_message =\ client._internal.connection.on_incoming_text_frame client._internal.connection.on_incoming_text_frame =\ lambda *args: None so = SubscriptionObserver() so2 = SubscriptionObserver() client.subscribe(channel, SubscriptionMode.ADVANCED, so) client.unsubscribe(channel) client.subscribe(channel, SubscriptionMode.ADVANCED, so2) client._queue.join() self.assertEqual(client._internal.subscriptions[channel]._mode, 'cycle') old_received_message( '{"action":"rtm/subscribe/ok","body":{"channel":"' + channel + '","position":"position"},"id":0}') so.wait_subscribed() self.assertEqual(client._internal.subscriptions[channel]._mode, 'cycle') old_received_message( '{"action":"rtm/unsubscribe/ok","body":{},"id":1}') so.wait_not_subscribed() self.assertEqual(client._internal.subscriptions[channel]._mode, 'linked') old_received_message( '{"action":"rtm/subscribe/error","body":{},"id":2}') self.assertEqual(client._internal.subscriptions[channel]._mode, 'linked') self.assertEqual( client._internal.subscriptions[channel]._sm.get_state_name(), 'Subscription.Failed') so2.wait_failed() expected_log = [ 'on_leave_unsubscribed', 'on_enter_subscribing', 'on_leave_subscribing', 'on_enter_unsubscribing', 'on_leave_unsubscribing', 'on_enter_unsubscribed', 'on_deleted' ] expected_log2 = [ 'on_created', 'on_leave_unsubscribed', 'on_enter_subscribing', 'on_leave_subscribing', ('on_enter_failed', 'Subscribe error') ] self.assertEqual(so.log, expected_log) self.assertEqual(so2.log, expected_log2)
def test_subscribe_error_in_cycle_mode(self): with make_client(endpoint=endpoint, appkey=appkey, reconnect_interval=1) as client: old_received_message =\ client._internal.connection.on_incoming_json client._internal.connection.on_incoming_json =\ lambda *args: None so = SubscriptionObserver() so2 = SubscriptionObserver() client.subscribe(channel, SubscriptionMode.ADVANCED, so) client.unsubscribe(channel) client.subscribe(channel, SubscriptionMode.ADVANCED, so2) client._queue.join() self.assertEqual(client._internal.subscriptions[channel].mode, 'cycle') old_received_message({ u"action": u"rtm/subscribe/error", u"body": {}, u"id": 0 }) client._queue.join() self.assertEqual(client._internal.subscriptions[channel].mode, 'linked') old_received_message({ u"action": u"rtm/subscribe/ok", u"body": {}, u"id": 1 }) so2.wait_subscribed() expected_log = [ 'on_leave_unsubscribed', 'on_enter_subscribing', 'on_leave_subscribing', 'on_deleted' ] expected_log2 = [ 'on_created', 'on_enter_subscribing', 'on_leave_subscribing', 'on_enter_subscribed' ] self.assertEqual(so.log, expected_log) self.assertEqual(so2.log, expected_log2)
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_quickly_change_observer_twice(self): with make_client(endpoint=endpoint, appkey=appkey) as client: channel = make_channel_name('change_observer_twice') so2 = SubscriptionObserver() so1 = sync_subscribe(client, channel) client.unsubscribe(channel) client.subscribe(channel, SubscriptionMode.ADVANCED, so2) client.unsubscribe(channel) client.subscribe(channel, SubscriptionMode.ADVANCED, None) client.unsubscribe(channel) so3 = sync_subscribe(client, channel) 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_deleted'] expected_so3_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) self.assertEqual(so3.log, expected_so3_log)
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_exception_in_subscription_callback(self): with make_client(endpoint=endpoint, appkey=appkey) as client: exit = threading.Event() class CrashyObserver(SubscriptionObserver): def on_deleted(this): SubscriptionObserver.on_deleted(this) exit.set() raise ValueError('Error in on_deleted') def on_enter_subscribing(this): SubscriptionObserver.on_enter_subscribing(this) raise ValueError('Error in on_enter_subscribing') so = CrashyObserver() client.subscribe(channel, SubscriptionMode.ADVANCED, so) so.wait_subscribed() client.unsubscribe(channel) client.subscribe(channel, SubscriptionMode.ADVANCED, CrashyObserver()) client.unsubscribe(channel) client.subscribe(channel, SubscriptionMode.ADVANCED, SubscriptionObserver(), args={'position': '123'}) so.wait_deleted() client.unsubscribe(channel) if not exit.wait(20): raise RuntimeError('Timeout')
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)
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_filter(self): with make_client(endpoint=endpoint, appkey=appkey) as client: ch = make_channel_name('filter') so = SubscriptionObserver() mode = SubscriptionMode.RELIABLE args = {'filter': 'select test from ' + ch} client.subscribe(ch, mode, so, args=args) so.wait_subscribed() sync_publish(client, ch, {'test': 42, 'unused': 1}) message = so.wait_for_channel_data()['messages'][0] self.assertEqual(message, {'test': 42}) sync_publish(client, ch, {'unused': 1}) message = so.wait_for_channel_data()['messages'][0] self.assertEqual(message, {'test': None})
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 on_enter_subscribing(this): SubscriptionObserver.on_enter_subscribing(this) raise ValueError('Error in on_enter_subscribing')
def on_deleted(this): SubscriptionObserver.on_deleted(this) exit.set() raise ValueError('Error in on_deleted')
def on_subscription_data(this, data): SubscriptionObserver.on_subscription_data(this, data) raise ValueError('Error in on_subscription_data')