def main(): args = docopt.docopt(__doc__) endpoint = args['--endpoint'] or test_endpoint appkey = args['--appkey'] or test_appkey scenario = args['--scenario'] profile = args['--profile'] publish_ack_match = publish_ack_re.match(scenario) publish_noack_match = publish_noack_re.match(scenario) if scenario == 'subscribe': channel = args['--channel'] if not channel: return 1 return bench_subscribe(endpoint, appkey, channel) elif publish_ack_match: size = int(publish_ack_match.group(1)) channel = args['--channel'] or make_channel_name('publish_ack') return bench_publish_ack(endpoint, appkey, channel, size, profile) elif publish_noack_match: size = int(publish_noack_match.group(1)) channel = args['--channel'] or make_channel_name('publish_no_ack') return bench_publish_noack(endpoint, appkey, channel, size, profile) else: print('Unknown scenario {}'.format(scenario)) return 1
def test_write_read(self): with make_client(endpoint, appkey) as client: k = make_channel_name('kv') v = make_channel_name('message') mailbox = [] event = Event() def callback(ack): mailbox.append(ack) event.set() client.write(k, v, callback=callback) event.wait(10) event.clear() client.read(k, callback=callback) event.wait(10) assert len(mailbox) == 2 write_ack = mailbox[0] read_ack = mailbox[1] assert write_ack['action'] == 'rtm/write/ok' assert read_ack['action'] == 'rtm/read/ok' assert read_ack['body']['message'] == v
def test_write_delete_read(self): with make_client(endpoint, appkey) as client: k = make_channel_name('delete_read') v = make_channel_name('value') mailbox = [] event = Event() def callback(ack): mailbox.append(ack) event.set() client.write(k, v, callback=callback) event.wait(10) event.clear() client.delete(k, callback=callback) event.wait(10) event.clear() client.read(k, callback=callback) event.wait(10) assert len(mailbox) == 3 assert mailbox[0]['action'] == 'rtm/write/ok' assert mailbox[1]['action'] == 'rtm/delete/ok' assert mailbox[2]['action'] == 'rtm/read/ok' assert mailbox[2]['body']['message'] is None
def test_request_throttling(self): wm = sc.high_ack_count_watermark sc.high_ack_count_watermark = 3 mailbox = [] try: conn = sc.Connection(endpoint, appkey) conn.start() def callback(ack): mailbox.append(ack) channel = make_channel_name('request_throttling') for i in range(1000): conn.publish(channel, u'message', callback=callback) origin = time.time() while time.time() < origin + 5: time.sleep(0.1) if len(mailbox) == 1000: break except Exception as e: import sys print(e, file=sys.stderr) finally: conn.stop() sc.high_ack_count_watermark = wm self.assertEqual(len(mailbox), 1000) self.assertTrue( all(ack['action'] == 'rtm/publish/ok' for ack in mailbox))
def test_kv(self): cmd_prefix = [ 'python', 'satori_rtm_cli.py', '--appkey', appkey, '--endpoint', endpoint ] channel = make_channel_name('test_kv') def read(): return subprocess.check_output(cmd_prefix + ['read', channel]).rstrip() def write(value): return subprocess.check_output(cmd_prefix + ['write', channel, value]) def delete(): return subprocess.check_output(cmd_prefix + ['delete', channel]) mailbox = [] mailbox.append(delete()) mailbox.append(write('v1')) mailbox.append(read()) mailbox.append(delete()) mailbox.append(read()) mailbox.append(write('v2')) mailbox.append(write('v3')) mailbox.append(read()) self.assertEqual(mailbox, [b'', b'', b'"v1"', b'', b'null', b'', b'', b'"v3"'])
def test_missing_subscription_observer_callbacks_are_fine(self): with make_client(endpoint=endpoint, appkey=appkey) as client: client.subscribe( make_channel_name('missing_subscription_callbacks'), SubscriptionMode.ADVANCED, object()) time.sleep(3)
def _run(self, N): channel = make_channel_name('two_identical_subscribers') with make_client(endpoint=endpoint, appkey=appkey) as pub: with make_client(endpoint=endpoint, appkey=appkey, protocol='cbor') as sub1: with make_client(endpoint=endpoint, appkey=appkey) as sub2: origin = sync_publish(pub, channel, u'prime') so1 = sync_subscribe(sub1, channel, {u'position': origin}) so2 = sync_subscribe(sub2, channel, {u'position': origin}) for i in range(N): pub.publish(channel, i) msgs1 = [] msgs2 = [] origin = time.time() while time.time() < origin + 5: msgs1 = so1.extract_received_messages() msgs2 = so2.extract_received_messages() if len(msgs1) == N + 1 and len(msgs2) == N + 1: break time.sleep(0.1) self.assertEqual(msgs1, msgs2)
def test_filter(self): mailbox = [] class ConnDelegate(object): def on_subscription_data(this, stuff): mailbox.append(stuff) event.set() def on_connection_closed(this): pass conn = sc.Connection(endpoint, appkey) conn.delegate = ConnDelegate() conn.start() ch = make_channel_name('filter') event = threading.Event() def callback(ack): mailbox.append(ack) event.set() query = 'select test from ' + ch conn.subscribe(ch, args={'filter': query}, callback=callback) event.wait(5) self.assertEqual(mailbox[0]['action'], 'rtm/subscribe/ok') event.clear() conn.publish(ch, {'test': 42, 'unused': 'whatever'}) event.wait(5) self.assertEqual(mailbox[1]['messages'], [{'test': 42}]) self.assertEqual(mailbox[1]['subscription_id'], ch) conn.stop()
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_write_read(self): conn = sc.Connection(endpoint, appkey) conn.start() k, v = make_channel_name('write_read'), 'value1' mailbox = [] event = threading.Event() def callback(pdu): mailbox.append(pdu) event.set() conn.write(k, v, callback=callback) event.wait(10) event.clear() conn.read(k, callback=callback) event.wait(10) conn.stop() assert len(mailbox) == 2 write_ack = mailbox[0] read_ack = mailbox[1] assert write_ack['action'] == 'rtm/write/ok' assert read_ack['action'] == 'rtm/read/ok' assert read_ack['body']['message'] == v
def test_write_delete_write_read(self): conn = sc.Connection(endpoint, appkey) conn.start() k, v = make_channel_name('write_delete_write_read'), 'v' mailbox = [] event = threading.Event() def callback(pdu): mailbox.append(pdu) event.set() conn.write(k, v, callback=callback) event.wait(10) event.clear() conn.delete(k, callback=callback) event.wait(10) event.clear() conn.write(k, v, callback=callback) event.wait(10) assert len(mailbox) == 3 assert mailbox[0]['action'] == 'rtm/write/ok' assert mailbox[1]['action'] == 'rtm/delete/ok' assert mailbox[2]['action'] == 'rtm/write/ok' assert conn.read_sync(k) == v conn.stop()
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_sync_operations(self): conn = sc.Connection(endpoint, appkey) conn.start() channel = make_channel_name('sync_connection_operations') conn.subscribe_sync(channel) conn.publish_sync(channel, 'test') conn.unsubscribe_sync(channel) conn.stop()
def test_subscribe_sync_fail(self): conn = sc.Connection(endpoint, appkey) conn.start() channel = make_channel_name('invalid_position') self.assertRaises( RuntimeError, lambda: conn.subscribe_sync(channel, {'position': 'invalid'})) conn.stop()
def test_sync_timeouts(self): conn = sc.Connection(endpoint, appkey) conn.start() channel = make_channel_name('sync_timeout') conn.on_incoming_text_frame = lambda *args: None with self.assertRaises(RuntimeError): conn.subscribe_sync(channel, timeout=0) with self.assertRaises(RuntimeError): conn.unsubscribe_sync(channel, timeout=0) with self.assertRaises(RuntimeError): conn.publish_sync(channel, 'msg', timeout=0) with self.assertRaises(RuntimeError): conn.read_sync(channel, timeout=0) conn.stop()
def test_missing_subscription_observer_callbacks_are_fine(self): with make_client(endpoint=endpoint, appkey=appkey) as client: channel = make_channel_name('missing_subscription_callbacks') client.subscribe(channel, SubscriptionMode.ADVANCED, object()) origin = time.time() while time.time() < origin + 5: sub = client._internal.subscriptions.get(channel) if sub and\ sub._sm.get_state_name() == 'Subscription.Subscribed': break time.sleep(0.1) else: self.assertFalse('Unexpectedly subscription failed')
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_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_delete_read(self): conn = sc.Connection(endpoint, appkey) conn.start() k = make_channel_name('delete_read') mailbox = [] event = threading.Event() def callback(pdu): mailbox.append(pdu) event.set() conn.delete(k, callback=callback) event.wait(10) assert len(mailbox) == 1 assert mailbox[0]['action'] == 'rtm/delete/ok' assert conn.read_sync(k) is None conn.stop()
def test_change_observer_from_none(self): with make_client(endpoint=endpoint, appkey=appkey) as client: channel = make_channel_name('change_observer') client.subscribe(channel, SubscriptionMode.ADVANCED, subscription_observer=None) client.unsubscribe(channel) so2 = sync_subscribe(client, channel) self.maxDiff = None expected_so2_log = [ 'on_created', 'on_leave_unsubscribed', 'on_enter_subscribing', 'on_leave_subscribing', 'on_enter_subscribed' ] self.assertEqual(so2.log, expected_so2_log) client.stop()
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_request_throttling(self): wm = sc.high_ack_count_watermark sc.high_ack_count_watermark = 3 mailbox = [] try: conn = sc.Connection(endpoint, appkey) conn.start() def callback(ack): mailbox.append(ack) channel = make_channel_name('request_throttling') for i in range(1000): conn.publish(channel, 'message', callback=callback) time.sleep(2) finally: conn.stop() sc.high_ack_count_watermark = wm self.assertEqual(len(mailbox), 1000) self.assertTrue( all(ack['action'] == 'rtm/publish/ok' for ack in mailbox))
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()
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_write_write_read(self): conn = sc.Connection(endpoint, appkey) conn.start() k, v1, v2 = make_channel_name('wwr'), 'wwr_value1', 'wwr_value2' mailbox = [] event = threading.Event() def callback(pdu): mailbox.append(pdu) event.set() conn.write(k, v1, callback=callback) event.wait(10) event.clear() conn.write(k, v2, callback=callback) event.wait(10) assert len(mailbox) == 2 for write_ack in mailbox: assert write_ack['action'] == 'rtm/write/ok' assert conn.read_sync(k) == v2 conn.stop()
# -*- coding: utf-8 -*- from __future__ import print_function import unittest from satori.rtm.client import make_client, SubscriptionMode from test.utils import ClientObserver, emulate_websocket_disconnect from test.utils import get_test_endpoint_and_appkey from test.utils import make_channel_name, sync_publish, sync_subscribe endpoint, appkey = get_test_endpoint_and_appkey() channel = make_channel_name('two_clients') class TestTwoClients(unittest.TestCase): 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)
# -*- coding: utf-8 -*- from __future__ import print_function import threading import unittest from satori.rtm.client import make_client from test.utils import get_test_endpoint_and_appkey, make_channel_name from test.utils import sync_publish endpoint, appkey = get_test_endpoint_and_appkey() channel = make_channel_name('channel_search') class TestChannelSearch(unittest.TestCase): @unittest.skip("Because backend") def test_channel_search(self): with make_client(endpoint=endpoint, appkey=appkey) as client: event = threading.Event() mailbox = [] def callback(ack): mailbox.append(ack) if ack['action'] != 'rtm/search/data': event.set() sync_publish(client, channel, 'ping') client.search('', callback=callback) event.wait(10)
def test_publish_before_start(self): conn = sc.Connection(endpoint, appkey) channel = make_channel_name('publish_before_start') self.assertRaises(RuntimeError, lambda: conn.publish_sync(channel, 'test'))
def test_subscribe_before_start(self): conn = sc.Connection(endpoint, appkey) channel = make_channel_name('subscribe_before_start') self.assertRaises(RuntimeError, lambda: conn.subscribe_sync(channel))
def test_read(self): conn = sc.Connection(endpoint, appkey) conn.start() k = make_channel_name('read') assert conn.read_sync(k) is None conn.stop()