class AltmarketsWebsocketTests(TestCase): def setUp(self) -> None: super().setUp() self.mocking_assistant = NetworkMockingAssistant() def async_run_with_timeout(self, coroutine: Awaitable, timeout: int = 1): ret = asyncio.get_event_loop().run_until_complete(asyncio.wait_for(coroutine, timeout)) return ret @patch("websockets.connect", new_callable=AsyncMock) @patch("hummingbot.connector.exchange.altmarkets.altmarkets_websocket.AltmarketsWebsocket.generate_request_id") def test_send_subscription_message(self, request_id_mock, ws_connect_mock): request_id_mock.return_value = 1234567899 ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() throttler = AsyncThrottler(Constants.RATE_LIMITS) websocket = AltmarketsWebsocket(throttler=throttler) message = [Constants.WS_SUB["TRADES"].format(trading_pair="btcusdt")] self.async_run_with_timeout(websocket.connect()) self.async_run_with_timeout(websocket.subscribe(message)) self.async_run_with_timeout(websocket.unsubscribe(message)) sent_requests = self.mocking_assistant.text_messages_sent_through_websocket(ws_connect_mock.return_value) expected_subscribe_message = {"event": "subscribe", "id": 1234567899, "streams": ['btcusdt.trades']} self.assertTrue(any( (expected_subscribe_message == json.loads(sent_request) for sent_request in sent_requests))) expected_unsubscribe_message = {"event": "unsubscribe", "id": 1234567899, "streams": ['btcusdt.trades']} self.assertTrue(any( (expected_unsubscribe_message == json.loads(sent_request) for sent_request in sent_requests)))
class CoinzoomWebsocketTests(TestCase): def setUp(self) -> None: super().setUp() self.mocking_assistant = NetworkMockingAssistant() def async_run_with_timeout(self, coroutine: Awaitable, timeout: int = 1): ret = asyncio.get_event_loop().run_until_complete( asyncio.wait_for(coroutine, timeout)) return ret @patch("websockets.connect", new_callable=AsyncMock) def test_send_subscription_message(self, ws_connect_mock): ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock( ) throttler = AsyncThrottler(Constants.RATE_LIMITS) websocket = CoinzoomWebsocket(throttler=throttler) message = {Constants.WS_SUB["TRADES"]: {'symbol': "BTC/USDT"}} self.async_run_with_timeout(websocket.connect()) self.async_run_with_timeout(websocket.subscribe(message)) self.async_run_with_timeout(websocket.unsubscribe(message)) sent_requests = self.mocking_assistant.text_messages_sent_through_websocket( ws_connect_mock.return_value) sent_subscribe_message = json.loads(sent_requests[0]) expected_subscribe_message = { "TradeSummaryRequest": { "action": "subscribe", "symbol": "BTC/USDT" } } self.assertEquals(expected_subscribe_message, sent_subscribe_message) sent_unsubscribe_message = json.loads(sent_requests[0]) expected_unsubscribe_message = { "TradeSummaryRequest": { "action": "subscribe", "symbol": "BTC/USDT" } } self.assertEquals(expected_unsubscribe_message, sent_unsubscribe_message)
class BitmartAPIUserStreamDataSourceTests(unittest.TestCase): # the level is required to receive logs from the data source logger level = 0 @classmethod def setUpClass(cls) -> None: super().setUpClass() cls.api_key = 'testAPIKey' cls.secret = 'testSecret' cls.memo = '001' cls.account_id = 528 cls.username = '******' cls.oms_id = 1 cls.ev_loop = asyncio.get_event_loop() def setUp(self) -> None: super().setUp() self.listening_task = None self.log_records = [] throttler = AsyncThrottler(CONSTANTS.RATE_LIMITS) auth_assistant = BitmartAuth(api_key=self.api_key, secret_key=self.secret, memo=self.memo) self.data_source = BitmartAPIUserStreamDataSource(auth_assistant, throttler) self.data_source.logger().setLevel(1) self.data_source.logger().addHandler(self) self.data_source._trading_pairs = ["HBOT-USDT"] self.mocking_assistant = NetworkMockingAssistant() def tearDown(self) -> None: self.listening_task and self.listening_task.cancel() super().tearDown() def handle(self, record): self.log_records.append(record) def _is_logged(self, log_level: str, message: str) -> bool: return any(record.levelname == log_level and record.getMessage() == message for record in self.log_records) def _raise_exception(self, exception_class): raise exception_class @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_authenticates_and_subscribes_to_events(self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() initial_last_recv_time = self.data_source.last_recv_time self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, messages)) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, json.dumps({"event": "login"})) # Add a dummy message for the websocket to read and include in the "messages" queue self.mocking_assistant.add_websocket_text_message(ws_connect_mock.return_value, json.dumps('dummyMessage')) first_received_message = self.ev_loop.run_until_complete(messages.get()) self.assertEqual('dummyMessage', first_received_message) self.assertTrue(self._is_logged('INFO', "Authenticating to User Stream...")) self.assertTrue(self._is_logged('INFO', "Successfully authenticated to User Stream.")) self.assertTrue(self._is_logged('INFO', "Successfully subscribed to all Private channels.")) sent_messages = self.mocking_assistant.text_messages_sent_through_websocket(ws_connect_mock.return_value) self.assertEqual(2, len(sent_messages)) auth_req = json.loads(sent_messages[0]) sub_req = json.loads(sent_messages[1]) self.assertTrue("op" in auth_req and "args" in auth_req and "testAPIKey" in auth_req["args"]) self.assertEqual({"op": "subscribe", "args": ["spot/user/order:HBOT_USDT"]}, sub_req) self.assertGreater(self.data_source.last_recv_time, initial_last_recv_time) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_fails_when_authentication_fails(self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() # Make the close function raise an exception to finish the execution ws_connect_mock.return_value.close.side_effect = lambda: self._raise_exception(Exception) self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, messages)) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, json.dumps({"errorCode": "test code", "errorMessage": "test err message"}) ) try: self.ev_loop.run_until_complete(self.listening_task) except Exception: pass self.assertTrue(self._is_logged("ERROR", "WebSocket login errored with message: test err message")) self.assertTrue(self._is_logged("ERROR", "Error occurred when authenticating to user stream.")) self.assertTrue(self._is_logged("ERROR", "Unexpected error with BitMart WebSocket connection. " "Retrying after 30 seconds...")) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_canceled_when_cancel_exception_during_initialization(self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.side_effect = asyncio.CancelledError with self.assertRaises(asyncio.CancelledError): self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, messages)) self.ev_loop.run_until_complete(self.listening_task) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_canceled_when_cancel_exception_during_authentication(self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() ws_connect_mock.return_value.send.side_effect = lambda sent_message: ( self._raise_exception(asyncio.CancelledError) if "testAPIKey" in sent_message else self.mocking_assistant._sent_websocket_text_messages[ws_connect_mock.return_value].append( sent_message)) with self.assertRaises(asyncio.CancelledError): self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, messages)) self.ev_loop.run_until_complete(self.listening_task) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_canceled_when_cancel_exception_during_events_subscription(self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() ws_connect_mock.return_value.send.side_effect = lambda sent_message: ( self._raise_exception(asyncio.CancelledError) if "order:HBOT_USDT" in sent_message else self.mocking_assistant._sent_websocket_text_messages[ws_connect_mock.return_value].append(sent_message) ) with self.assertRaises(asyncio.CancelledError): self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, messages)) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, json.dumps({"event": "login"}) ) self.ev_loop.run_until_complete(self.listening_task) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_logs_exception_details_during_initialization(self, ws_connect_mock): ws_connect_mock.side_effect = Exception with self.assertRaises(Exception): self.listening_task = self.ev_loop.create_task(self.data_source._init_websocket_connection()) self.ev_loop.run_until_complete(self.listening_task) self.assertTrue(self._is_logged("NETWORK", "Unexpected error occured with BitMart WebSocket Connection")) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_logs_exception_details_during_authentication(self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() ws_connect_mock.return_value.send.side_effect = lambda sent_message: ( self._raise_exception(Exception) if "testAPIKey" in sent_message else self.mocking_assistant._sent_websocket_text_messages[ws_connect_mock.return_value].append(sent_message)) # Make the close function raise an exception to finish the execution ws_connect_mock.return_value.close.side_effect = lambda: self._raise_exception(Exception) try: self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, messages)) self.ev_loop.run_until_complete(self.listening_task) except Exception: pass self.assertTrue(self._is_logged("ERROR", "Error occurred when authenticating to user stream.")) self.assertTrue(self._is_logged("ERROR", "Unexpected error with BitMart WebSocket connection. " "Retrying after 30 seconds...")) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_logs_exception_during_events_subscription(self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() ws_connect_mock.return_value.send.side_effect = lambda sent_message: ( self._raise_exception(Exception) if "order:HBOT_USDT" in sent_message else self.mocking_assistant._sent_websocket_text_messages[ws_connect_mock.return_value].append(sent_message) ) # Make the close function raise an exception to finish the execution ws_connect_mock.return_value.close.side_effect = lambda: self._raise_exception(Exception) try: self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, messages)) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, json.dumps({"event": "login"})) self.ev_loop.run_until_complete(self.listening_task) except Exception: pass self.assertTrue(self._is_logged("ERROR", "Error occured during subscribing to Bitmart private channels.")) self.assertTrue(self._is_logged("ERROR", "Unexpected error with BitMart WebSocket connection. " "Retrying after 30 seconds...")) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_invalid_json_message_logged(self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() # Make the close function raise an exception to finish the execution ws_connect_mock.return_value.close.side_effect = lambda: self._raise_exception(Exception) try: self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, messages)) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, json.dumps({"event": "login"})) # Add invalid json message self.mocking_assistant.add_websocket_text_message(ws_connect_mock.return_value, 'invalid message') self.ev_loop.run_until_complete(self.listening_task) except Exception: pass self.assertTrue(self._is_logged("ERROR", "Unexpected error when parsing BitMart user_stream message. ")) self.assertTrue(self._is_logged("ERROR", "Unexpected error with BitMart WebSocket connection. " "Retrying after 30 seconds...")) @patch('websockets.connect', new_callable=AsyncMock) def test_listen_for_user_stream_inner_messages_recv_timeout(self, ws_connect_mock): self.data_source.MESSAGE_TIMEOUT = 0.1 ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() ws_connect_mock.return_value.ping.side_effect = lambda: done_callback_event.set() # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, json.dumps({"event": "login"})) done_callback_event = asyncio.Event() message_queue = asyncio.Queue() self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, message_queue) ) self.ev_loop.run_until_complete(done_callback_event.wait()) @patch('websockets.connect', new_callable=AsyncMock) def test_listen_for_user_stream_inner_messages_recv_timeout_ping_timeout(self, ws_connect_mock): self.data_source.PING_TIMEOUT = 0.1 self.data_source.MESSAGE_TIMEOUT = 0.1 ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock() ws_connect_mock.return_value.close.side_effect = lambda: done_callback_event.set() ws_connect_mock.return_value.ping.side_effect = NetworkMockingAssistant.async_partial( self.mocking_assistant._get_next_websocket_text_message, ws_connect_mock.return_value ) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, json.dumps({"event": "login"})) done_callback_event = asyncio.Event() message_queue = asyncio.Queue() self.listening_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, message_queue) ) self.ev_loop.run_until_complete(done_callback_event.wait()) self.assertTrue(self._is_logged("WARNING", "WebSocket ping timed out. Going to reconnect..."))
class ProbitAPIUserStreamDataSourceTest(unittest.TestCase): # logging.Level required to receive logs from the data source logger level = 0 @classmethod def setUpClass(cls) -> None: cls.base_asset = "BTC" cls.quote_asset = "USDT" cls.trading_pair = f"{cls.base_asset}-{cls.quote_asset}" def setUp(self) -> None: super().setUp() self.ev_loop = asyncio.get_event_loop() self.api_key = "someKey" self.api_secret = "someSecret" self.auth = ProbitAuth(self.api_key, self.api_secret) self.data_source = ProbitAPIUserStreamDataSource( self.auth, trading_pairs=[self.trading_pair]) self.data_source.logger().setLevel(1) self.data_source.logger().addHandler(self) self.log_records = [] self.mocking_assistant = NetworkMockingAssistant() self.async_task: Optional[asyncio.Task] = None def tearDown(self) -> None: self.async_task and self.async_task.cancel() super().tearDown() def handle(self, record): self.log_records.append(record) def check_is_logged(self, log_level: str, message: str) -> bool: return any( record.levelname == log_level and record.getMessage() == message for record in self.log_records) def async_run_with_timeout(self, coroutine: Awaitable, timeout: float = 1): ret = self.ev_loop.run_until_complete( asyncio.wait_for(coroutine, timeout)) return ret @patch("aiohttp.client.ClientSession.ws_connect", new_callable=AsyncMock) @patch( "hummingbot.connector.exchange.probit.probit_auth.ProbitAuth.get_ws_auth_payload", new_callable=AsyncMock, ) def test_listen_for_user_stream(self, get_ws_auth_payload_mock, ws_connect_mock): auth_msg = {"type": "authorization", "token": "someToken"} get_ws_auth_payload_mock.return_value = auth_msg ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock( ) self.mocking_assistant.add_websocket_json_message( ws_connect_mock.return_value, message={"result": "ok"} # authentication ) self.mocking_assistant.add_websocket_aiohttp_message( ws_connect_mock.return_value, message=json.dumps({"my_msg": "test"}) # first message ) output_queue = asyncio.Queue() self.async_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, output_queue)) self.mocking_assistant.run_until_all_json_messages_delivered( ws_connect_mock.return_value) self.mocking_assistant.run_until_all_aiohttp_messages_delivered( ws_connect_mock.return_value) self.assertFalse(output_queue.empty()) sent_text_msgs = self.mocking_assistant.text_messages_sent_through_websocket( ws_connect_mock.return_value) self.assertEqual(auth_msg, json.loads(sent_text_msgs[0])) sent_json_msgs = self.mocking_assistant.json_messages_sent_through_websocket( ws_connect_mock.return_value) for sent_json_msg in sent_json_msgs: self.assertEqual("subscribe", sent_json_msg["type"]) self.assertIn(sent_json_msg["channel"], CONSTANTS.WS_PRIVATE_CHANNELS) CONSTANTS.WS_PRIVATE_CHANNELS.remove(sent_json_msg["channel"]) self.assertEqual(0, len(CONSTANTS.WS_PRIVATE_CHANNELS)) self.assertNotEqual(0, self.data_source.last_recv_time) @patch("aiohttp.client.ClientSession.ws_connect") @patch( "hummingbot.connector.exchange.probit.probit_api_user_stream_data_source.ProbitAPIUserStreamDataSource._sleep", new_callable=AsyncMock, ) def test_listen_for_user_stream_attempts_again_on_exception( self, sleep_mock, ws_connect_mock): called_event = asyncio.Event() async def _sleep(delay): called_event.set() await asyncio.sleep(delay) sleep_mock.side_effect = _sleep ws_connect_mock.side_effect = Exception self.async_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, asyncio.Queue())) self.async_run_with_timeout(called_event.wait()) self.check_is_logged( log_level="ERROR", message= "Unexpected error with Probit WebSocket connection. Retrying after 30 seconds...", ) @patch("aiohttp.client.ClientSession.ws_connect") def test_listen_for_user_stream_stops_on_asyncio_cancelled_error( self, ws_connect_mock): ws_connect_mock.side_effect = asyncio.CancelledError with self.assertRaises(asyncio.CancelledError): self.async_run_with_timeout( self.data_source.listen_for_user_stream( self.ev_loop, asyncio.Queue())) @patch("aiohttp.client.ClientSession.ws_connect", new_callable=AsyncMock) @patch( "hummingbot.connector.exchange.probit.probit_auth.ProbitAuth.get_ws_auth_payload", new_callable=AsyncMock, ) def test_listen_for_user_stream_registers_ping_msg( self, get_ws_auth_payload_mock, ws_connect_mock): auth_msg = {"type": "authorization", "token": "someToken"} get_ws_auth_payload_mock.return_value = auth_msg ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock( ) self.mocking_assistant.add_websocket_json_message( ws_connect_mock.return_value, message={"result": "ok"} # authentication ) self.mocking_assistant.add_websocket_aiohttp_message( ws_connect_mock.return_value, message="", message_type=WSMsgType.PING) output_queue = asyncio.Queue() self.async_task = self.ev_loop.create_task( self.data_source.listen_for_user_stream(self.ev_loop, output_queue)) self.mocking_assistant.run_until_all_aiohttp_messages_delivered( ws_connect_mock.return_value) self.assertTrue(output_queue.empty()) ws_connect_mock.return_value.pong.assert_called()
class NdaxAPIUserStreamDataSourceTests(TestCase): # the level is required to receive logs from the data source loger level = 0 def setUp(self) -> None: super().setUp() self.uid = '001' self.api_key = 'testAPIKey' self.secret = 'testSecret' self.account_id = 528 self.username = '******' self.oms_id = 1 self.log_records = [] self.listening_task = None throttler = AsyncThrottler(CONSTANTS.RATE_LIMITS) auth_assistant = NdaxAuth(uid=self.uid, api_key=self.api_key, secret_key=self.secret, account_name=self.username) self.data_source = NdaxAPIUserStreamDataSource(throttler, auth_assistant) self.data_source.logger().setLevel(1) self.data_source.logger().addHandler(self) self.mocking_assistant = NetworkMockingAssistant() def tearDown(self) -> None: self.listening_task and self.listening_task.cancel() super().tearDown() def handle(self, record): self.log_records.append(record) def _is_logged(self, log_level: str, message: str) -> bool: return any( record.levelname == log_level and record.getMessage() == message for record in self.log_records) def _authentication_response(self, authenticated: bool) -> str: user = { "UserId": 492, "UserName": "******", "Email": "*****@*****.**", "EmailVerified": True, "AccountId": self.account_id, "OMSId": self.oms_id, "Use2FA": True } payload = { "Authenticated": authenticated, "SessionToken": "74e7c5b0-26b1-4ca5-b852-79b796b0e599", "User": user, "Locked": False, "Requires2FA": False, "EnforceEnable2FA": False, "TwoFAType": None, "TwoFAToken": None, "errormsg": None } message = { "m": 1, "i": 1, "n": CONSTANTS.AUTHENTICATE_USER_ENDPOINT_NAME, "o": json.dumps(payload) } return json.dumps(message) def _raise_exception(self, exception_class): raise exception_class @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_authenticates_and_subscribes_to_events( self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock( ) initial_last_recv_time = self.data_source.last_recv_time self.listening_task = asyncio.get_event_loop().create_task( self.data_source.listen_for_user_stream(asyncio.get_event_loop(), messages)) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, self._authentication_response(True)) # Add a dummy message for the websocket to read and include in the "messages" queue self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, json.dumps('dummyMessage')) first_received_message = asyncio.get_event_loop().run_until_complete( messages.get()) self.assertEqual('dummyMessage', first_received_message) self.assertTrue( self._is_logged('INFO', "Authenticating to User Stream...")) self.assertTrue( self._is_logged('INFO', "Successfully authenticated to User Stream.")) self.assertTrue( self._is_logged('INFO', "Successfully subscribed to user events.")) sent_messages = self.mocking_assistant.text_messages_sent_through_websocket( ws_connect_mock.return_value) self.assertEqual(2, len(sent_messages)) authentication_request = sent_messages[0] subscription_request = sent_messages[1] self.assertEqual( CONSTANTS.AUTHENTICATE_USER_ENDPOINT_NAME, NdaxWebSocketAdaptor.endpoint_from_raw_message( authentication_request)) self.assertEqual( CONSTANTS.SUBSCRIBE_ACCOUNT_EVENTS_ENDPOINT_NAME, NdaxWebSocketAdaptor.endpoint_from_raw_message( subscription_request)) subscription_payload = NdaxWebSocketAdaptor.payload_from_raw_message( subscription_request) expected_payload = {"AccountId": self.account_id, "OMSId": self.oms_id} self.assertEqual(expected_payload, subscription_payload) self.assertGreater(self.data_source.last_recv_time, initial_last_recv_time) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_fails_when_authentication_fails( self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock( ) # Make the close function raise an exception to finish the execution ws_connect_mock.return_value.close.side_effect = lambda: self._raise_exception( Exception) self.listening_task = asyncio.get_event_loop().create_task( self.data_source.listen_for_user_stream(asyncio.get_event_loop(), messages)) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, self._authentication_response(False)) try: asyncio.get_event_loop().run_until_complete(self.listening_task) except Exception: pass self.assertTrue( self._is_logged( "ERROR", "Error occurred when authenticating to user stream " "(Could not authenticate websocket connection with NDAX)")) self.assertTrue( self._is_logged( "ERROR", "Unexpected error with NDAX WebSocket connection. Retrying in 30 seconds. " "(Could not authenticate websocket connection with NDAX)")) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_canceled_when_cancel_exception_during_initialization( self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.side_effect = asyncio.CancelledError with self.assertRaises(asyncio.CancelledError): self.listening_task = asyncio.get_event_loop().create_task( self.data_source.listen_for_user_stream( asyncio.get_event_loop(), messages)) asyncio.get_event_loop().run_until_complete(self.listening_task) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_canceled_when_cancel_exception_during_authentication( self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock( ) ws_connect_mock.return_value.send.side_effect = lambda sent_message: ( self._raise_exception(asyncio.CancelledError) if CONSTANTS.AUTHENTICATE_USER_ENDPOINT_NAME in sent_message else self.mocking_assistant._sent_websocket_text_messages[ ws_connect_mock.return_value].append(sent_message)) with self.assertRaises(asyncio.CancelledError): self.listening_task = asyncio.get_event_loop().create_task( self.data_source.listen_for_user_stream( asyncio.get_event_loop(), messages)) asyncio.get_event_loop().run_until_complete(self.listening_task) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_canceled_when_cancel_exception_during_events_subscription( self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock( ) ws_connect_mock.return_value.send.side_effect = lambda sent_message: ( self._raise_exception(asyncio.CancelledError) if CONSTANTS.SUBSCRIBE_ACCOUNT_EVENTS_ENDPOINT_NAME in sent_message else self.mocking_assistant._sent_websocket_text_messages[ ws_connect_mock.return_value].append(sent_message)) with self.assertRaises(asyncio.CancelledError): self.listening_task = asyncio.get_event_loop().create_task( self.data_source.listen_for_user_stream( asyncio.get_event_loop(), messages)) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, self._authentication_response(True)) asyncio.get_event_loop().run_until_complete(self.listening_task) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_logs_exception_details_during_initialization( self, ws_connect_mock): ws_connect_mock.side_effect = Exception with self.assertRaises(Exception): self.listening_task = asyncio.get_event_loop().create_task( self.data_source._init_websocket_connection()) asyncio.get_event_loop().run_until_complete(self.listening_task) self.assertTrue( self._is_logged( "NETWORK", "Unexpected error occurred during ndax WebSocket Connection ()" )) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_logs_exception_details_during_authentication( self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock( ) ws_connect_mock.return_value.send.side_effect = lambda sent_message: ( self._raise_exception(Exception) if CONSTANTS.AUTHENTICATE_USER_ENDPOINT_NAME in sent_message else self.mocking_assistant._sent_websocket_text_messages[ ws_connect_mock.return_value].append(sent_message)) # Make the close function raise an exception to finish the execution ws_connect_mock.return_value.close.side_effect = lambda: self._raise_exception( Exception) try: self.listening_task = asyncio.get_event_loop().create_task( self.data_source.listen_for_user_stream( asyncio.get_event_loop(), messages)) asyncio.get_event_loop().run_until_complete(self.listening_task) except Exception: pass self.assertTrue( self._is_logged( "ERROR", "Error occurred when authenticating to user stream ()")) self.assertTrue( self._is_logged( "ERROR", "Unexpected error with NDAX WebSocket connection. Retrying in 30 seconds. ()" )) @patch('websockets.connect', new_callable=AsyncMock) def test_listening_process_logs_exception_during_events_subscription( self, ws_connect_mock): messages = asyncio.Queue() ws_connect_mock.return_value = self.mocking_assistant.create_websocket_mock( ) ws_connect_mock.return_value.send.side_effect = lambda sent_message: ( CONSTANTS.SUBSCRIBE_ACCOUNT_EVENTS_ENDPOINT_NAME in sent_message and self._raise_exception(Exception)) # Make the close function raise an exception to finish the execution ws_connect_mock.return_value.close.side_effect = lambda: self._raise_exception( Exception) try: self.listening_task = asyncio.get_event_loop().create_task( self.data_source.listen_for_user_stream( asyncio.get_event_loop(), messages)) # Add the authentication response for the websocket self.mocking_assistant.add_websocket_text_message( ws_connect_mock.return_value, self._authentication_response(True)) asyncio.get_event_loop().run_until_complete(self.listening_task) except Exception: pass self.assertTrue( self._is_logged( "ERROR", "Error occurred subscribing to ndax private channels ()")) self.assertTrue( self._is_logged( "ERROR", "Unexpected error with NDAX WebSocket connection. Retrying in 30 seconds. ()" ))