class TestAioStomp(AsyncTestCase): async def setUpAsync(self): self.stomp = AioStomp("127.0.0.1", 61613) @patch("aiostomp.aiostomp.StompProtocol") @unittest_run_loop async def test_aiostomp_supports_ssl(self, stom_protocol_mock): ssl_context = ssl.create_default_context() stomp = AioStomp("127.0.0.1", 61613, ssl_context=ssl_context) args, kwargs = stom_protocol_mock.call_args self.assertTrue("127.0.0.1" in args) self.assertTrue(61613 in args) self.assertTrue(stomp in args) self.assertTrue(kwargs["ssl_context"] == ssl_context) @unittest_run_loop async def test_can_connect_to_server(self): self.stomp._protocol.connect = CoroutineMock() await self.stomp.connect() self.stomp._protocol.connect.assert_called_once() self.assertTrue(self.stomp._connected) @unittest_run_loop async def test_can_reconnect_to_server(self): self.stomp._protocol.connect = CoroutineMock() self.stomp._protocol.connect.side_effect = [OSError(), True] await self.stomp.connect() self.assertEqual(self.stomp._protocol.connect.call_count, 2) @unittest_run_loop async def test_can_reconnect_to_server_with_max_attemps(self): self.stomp._reconnect_max_attempts = 2 self.stomp._protocol.connect = CoroutineMock() self.stomp._protocol.connect.side_effect = [OSError(), True] await self.stomp.connect() self.assertEqual(self.stomp._protocol.connect.call_count, 2) @unittest_run_loop async def test_reconnection(self): self.stomp._protocol.connect = CoroutineMock() await self.stomp._reconnect() self.stomp._protocol.connect.assert_called_once() @patch("aiostomp.aiostomp.logger") @unittest_run_loop async def test_reconnection_error(self, logger_mock): self.stomp._reconnect_max_attempts = 1 self.stomp._reconnect_attempts = 1 self.stomp._protocol.connect = CoroutineMock() self.stomp._protocol.connect.side_effect = OSError() self.stomp._on_error = CoroutineMock() await self.stomp._reconnect() logger_mock.error.assert_called_with( "All connections attempts failed.") self.assertIsInstance(self.stomp._on_error.call_args[0][0], ExceededRetryCount) self.assertEqual(self.stomp._on_error.call_args[0][0].ref, self.stomp) @unittest_run_loop async def test_can_reconnect_on_connection_lost(self): self.stomp._reconnect = CoroutineMock() self.stomp.connection_lost(Exception()) self.stomp._reconnect.assert_called_once() @unittest_run_loop async def test_no_reconnect_on_close(self): self.stomp._reconnect = CoroutineMock() self.stomp._closed = True self.stomp.connection_lost(Exception()) self.stomp._reconnect.assert_not_called() self.stomp._closed = False @patch("aiostomp.aiostomp.StompProtocol.close") def test_can_close_connection(self, close_mock): self.stomp.close() close_mock.assert_called_once() def test_can_subscribe(self): self.stomp._protocol.subscribe = Mock() self.stomp.subscribe("/queue/test") self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp._protocol.subscribe.assert_not_called() def test_can_get_subscription(self): self.stomp._protocol.subscribe = Mock() subscription = self.stomp.subscribe("/queue/test") self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp._protocol.subscribe.assert_not_called() value = self.stomp.get("1") self.assertEqual(value, subscription) def test_can_subscribe_when_connected(self): self.stomp._protocol.subscribe = Mock() self.stomp._connected = True subscription = self.stomp.subscribe("/queue/test") self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp._protocol.subscribe.assert_called_with(subscription) @unittest_run_loop async def test_subscribe_after_connection(self): self.stomp._protocol.connect = CoroutineMock() self.stomp._protocol.subscribe = Mock() self.stomp.subscribe("/queue/test") self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp._protocol.subscribe.assert_not_called() await self.stomp.connect() self.assertTrue(self.stomp._connected) self.stomp._protocol.subscribe.assert_called_once() def test_can_unsubscribe(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.unsubscribe = Mock() self.stomp._connected = True subscription = self.stomp.subscribe("/queue/test") self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp.unsubscribe(subscription) self.stomp._protocol.unsubscribe.assert_called_with(subscription) self.assertEqual(len(self.stomp._subscriptions), 0) def test_cannot_unsubscribe_when_not_subcribed(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.unsubscribe = Mock() self.stomp._connected = True subscription = self.stomp.subscribe("/queue/test") subscription.id = 2 self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp.unsubscribe(subscription) self.stomp._protocol.unsubscribe.assert_not_called() self.assertEqual(len(self.stomp._subscriptions), 1) def test_can_send_message_with_body_utf8(self): send_mock = Mock() self.stomp._protocol.send = send_mock self.stomp.send("/topic/test", headers={"my-header": "my-value"}, body="my body utf-8 ç") send_mock.assert_called_with( { "destination": "/topic/test", "my-header": "my-value", "content-length": 16, }, b"my body utf-8 \xc3\xa7", ) def test_can_send_message_with_body_binary(self): send_mock = Mock() self.stomp._protocol.send = send_mock self.stomp.send("/topic/test", headers={"my-header": "my-value"}, body=b"\xc3\xa7") send_mock.assert_called_with( { "destination": "/topic/test", "my-header": "my-value", "content-length": 2, }, b"\xc3\xa7", ) def test_can_send_message_with_body_without_content_length(self): send_mock = Mock() self.stomp._protocol.send = send_mock self.stomp.send( "/topic/test", headers={"my-header": "my-value"}, body="my body utf-8 ç", send_content_length=False, ) send_mock.assert_called_with( { "destination": "/topic/test", "my-header": "my-value" }, b"my body utf-8 \xc3\xa7", ) def test_can_send_message_without_body(self): send_mock = Mock() self.stomp._protocol.send = send_mock self.stomp.send("/topic/test", headers={"my-header": "my-value"}) send_mock.assert_called_with( { "destination": "/topic/test", "my-header": "my-value", "content-length": 0, }, b"", ) def test_can_ack_a_frame(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.ack = Mock() self.stomp.subscribe("/queue/test", auto_ack=False) self.assertEqual(len(self.stomp._subscriptions), 1) frame = Frame("MESSAGE", {"subscription": "1"}, "data") self.stomp.ack(frame) self.stomp._protocol.ack.assert_called_with(frame) def test_can_nack_a_frame(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.nack = Mock() self.stomp.subscribe("/queue/test", auto_ack=False) self.assertEqual(len(self.stomp._subscriptions), 1) frame = Frame("MESSAGE", {"subscription": "1"}, "data") self.stomp.nack(frame) self.stomp._protocol.nack.assert_called_with(frame) def test_cannot_ack_an_unsubscribed_frame(self): self.stomp._protocol.ack = Mock() self.assertEqual(len(self.stomp._subscriptions), 0) frame = Frame("MESSAGE", {"subscription": "1"}, "data") with self.assertLogs() as cm: self.stomp.ack(frame) self.assertIn("WARNING:aiostomp:Subscription 1 not found", cm.output) self.stomp._protocol.ack.assert_not_called() def test_cannot_nack_an_unsubscribed_frame(self): self.stomp._protocol.nack = Mock() self.assertEqual(len(self.stomp._subscriptions), 0) frame = Frame("MESSAGE", {"subscription": "1"}, "data") with self.assertLogs() as cm: self.stomp.nack(frame) self.assertIn("WARNING:aiostomp:Subscription 1 not found", cm.output) self.stomp._protocol.nack.assert_not_called() def test_cannot_ack_an_auto_ack_frame(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.ack = Mock() self.stomp.subscribe("/queue/test", auto_ack=True) self.assertEqual(len(self.stomp._subscriptions), 1) frame = Frame("MESSAGE", {"subscription": "1"}, "data") with self.assertLogs() as cm: self.stomp.ack(frame) self.assertIn( "WARNING:aiostomp:Auto ack/nack is enabled. Ignoring call.", cm.output) self.stomp._protocol.ack.assert_not_called()
class TestAioStomp(AsyncTestCase): async def setUpAsync(self): self.stomp = AioStomp('127.0.0.1', 61613) @patch('aiostomp.aiostomp.StompProtocol') @unittest_run_loop async def test_aiostomp_supports_ssl(self, stom_protocol_mock): ssl_context = ssl.create_default_context() stomp = AioStomp('127.0.0.1', 61613, ssl_context=ssl_context) args, kwargs = stom_protocol_mock.call_args self.assertTrue('127.0.0.1' in args) self.assertTrue(61613 in args) self.assertTrue(stomp in args) self.assertTrue(kwargs['ssl_context'] == ssl_context) @unittest_run_loop async def test_can_connect_to_server(self): self.stomp._protocol.connect = CoroutineMock() await self.stomp.connect() self.stomp._protocol.connect.assert_called_once() self.assertTrue(self.stomp._connected) @unittest_run_loop async def test_can_reconnect_to_server(self): self.stomp._protocol.connect = CoroutineMock() self.stomp._protocol.connect.side_effect = [OSError(), True] await self.stomp.connect() self.assertEqual(self.stomp._protocol.connect.call_count, 2) @unittest_run_loop async def test_can_reconnect_to_server_with_max_attemps(self): self.stomp._reconnect_max_attempts = 2 self.stomp._protocol.connect = CoroutineMock() self.stomp._protocol.connect.side_effect = [OSError(), True] await self.stomp.connect() self.assertEqual(self.stomp._protocol.connect.call_count, 2) @unittest_run_loop async def test_reconnection(self): self.stomp._protocol.connect = CoroutineMock() await self.stomp._reconnect() self.stomp._protocol.connect.assert_called_once() @patch('aiostomp.aiostomp.logger') @unittest_run_loop async def test_reconnection_error(self, logger_mock): self.stomp._reconnect_max_attempts = 1 self.stomp._reconnect_attempts = 1 self.stomp._protocol.connect = CoroutineMock() self.stomp._protocol.connect.side_effect = OSError() self.stomp._on_error = CoroutineMock() await self.stomp._reconnect() logger_mock.error.assert_called_with( 'All connections attempts failed.') self.assertIsInstance(self.stomp._on_error.call_args[0][0], ExceededRetryCount) self.assertEqual(self.stomp._on_error.call_args[0][0].ref, self.stomp) @unittest_run_loop async def test_can_reconnect_on_connection_lost(self): self.stomp._reconnect = CoroutineMock() self.stomp.connection_lost(Exception()) self.stomp._reconnect.assert_called_once() @unittest_run_loop async def test_no_reconnect_on_close(self): self.stomp._reconnect = CoroutineMock() self.stomp._closed = True self.stomp.connection_lost(Exception()) self.stomp._reconnect.assert_not_called() self.stomp._closed = False @patch('aiostomp.aiostomp.StompProtocol.close') def test_can_close_connection(self, close_mock): self.stomp.close() close_mock.assert_called_once() def test_can_subscribe(self): self.stomp._protocol.subscribe = Mock() self.stomp.subscribe('/queue/test') self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp._protocol.subscribe.assert_not_called() def test_can_get_subscription(self): self.stomp._protocol.subscribe = Mock() subscription = self.stomp.subscribe('/queue/test') self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp._protocol.subscribe.assert_not_called() value = self.stomp.get('1') self.assertEqual(value, subscription) def test_can_subscribe_when_connected(self): self.stomp._protocol.subscribe = Mock() self.stomp._connected = True subscription = self.stomp.subscribe('/queue/test') self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp._protocol.subscribe.assert_called_with(subscription) @unittest_run_loop async def test_subscribe_after_connection(self): self.stomp._protocol.connect = CoroutineMock() self.stomp._protocol.subscribe = Mock() self.stomp.subscribe('/queue/test') self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp._protocol.subscribe.assert_not_called() await self.stomp.connect() self.assertTrue(self.stomp._connected) self.stomp._protocol.subscribe.assert_called_once() def test_can_unsubscribe(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.unsubscribe = Mock() self.stomp._connected = True subscription = self.stomp.subscribe('/queue/test') self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp.unsubscribe(subscription) self.stomp._protocol.unsubscribe.assert_called_with(subscription) self.assertEqual(len(self.stomp._subscriptions), 0) def test_cannot_unsubscribe_when_not_subcribed(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.unsubscribe = Mock() self.stomp._connected = True subscription = self.stomp.subscribe('/queue/test') subscription.id = 2 self.assertEqual(len(self.stomp._subscriptions), 1) self.stomp.unsubscribe(subscription) self.stomp._protocol.unsubscribe.assert_not_called() self.assertEqual(len(self.stomp._subscriptions), 1) def test_can_send_message_with_body_utf8(self): send_mock = Mock() self.stomp._protocol.send = send_mock self.stomp.send('/topic/test', headers={'my-header': 'my-value'}, body='my body utf-8 ç') send_mock.assert_called_with( { 'destination': '/topic/test', 'my-header': 'my-value', 'content-length': 16, }, b'my body utf-8 \xc3\xa7', ) def test_can_send_message_with_body_binary(self): send_mock = Mock() self.stomp._protocol.send = send_mock self.stomp.send('/topic/test', headers={'my-header': 'my-value'}, body=b'\xc3\xa7') send_mock.assert_called_with( { 'destination': '/topic/test', 'my-header': 'my-value', 'content-length': 2, }, b'\xc3\xa7', ) def test_can_send_message_with_body_without_content_length(self): send_mock = Mock() self.stomp._protocol.send = send_mock self.stomp.send( '/topic/test', headers={'my-header': 'my-value'}, body='my body utf-8 ç', send_content_length=False, ) send_mock.assert_called_with( { 'destination': '/topic/test', 'my-header': 'my-value' }, b'my body utf-8 \xc3\xa7', ) def test_can_send_message_without_body(self): send_mock = Mock() self.stomp._protocol.send = send_mock self.stomp.send('/topic/test', headers={'my-header': 'my-value'}) send_mock.assert_called_with( { 'destination': '/topic/test', 'my-header': 'my-value', 'content-length': 0 }, b'') def test_can_ack_a_frame(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.ack = Mock() self.stomp.subscribe('/queue/test', auto_ack=False) self.assertEqual(len(self.stomp._subscriptions), 1) frame = Frame('MESSAGE', {'subscription': '1'}, 'data') self.stomp.ack(frame) self.stomp._protocol.ack.assert_called_with(frame) def test_can_nack_a_frame(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.nack = Mock() self.stomp.subscribe('/queue/test', auto_ack=False) self.assertEqual(len(self.stomp._subscriptions), 1) frame = Frame('MESSAGE', {'subscription': '1'}, 'data') self.stomp.nack(frame) self.stomp._protocol.nack.assert_called_with(frame) def test_cannot_ack_an_unsubscribed_frame(self): self.stomp._protocol.ack = Mock() self.assertEqual(len(self.stomp._subscriptions), 0) frame = Frame('MESSAGE', {'subscription': '1'}, 'data') with self.assertLogs() as cm: self.stomp.ack(frame) self.assertIn('WARNING:aiostomp:Subscription 1 not found', cm.output) self.stomp._protocol.ack.assert_not_called() def test_cannot_nack_an_unsubscribed_frame(self): self.stomp._protocol.nack = Mock() self.assertEqual(len(self.stomp._subscriptions), 0) frame = Frame('MESSAGE', {'subscription': '1'}, 'data') with self.assertLogs() as cm: self.stomp.nack(frame) self.assertIn('WARNING:aiostomp:Subscription 1 not found', cm.output) self.stomp._protocol.nack.assert_not_called() def test_cannot_ack_an_auto_ack_frame(self): self.stomp._protocol.subscribe = Mock() self.stomp._protocol.ack = Mock() self.stomp.subscribe('/queue/test', auto_ack=True) self.assertEqual(len(self.stomp._subscriptions), 1) frame = Frame('MESSAGE', {'subscription': '1'}, 'data') with self.assertLogs() as cm: self.stomp.ack(frame) self.assertIn( 'WARNING:aiostomp:Auto ack/nack is enabled. Ignoring call.', cm.output) self.stomp._protocol.ack.assert_not_called()