Beispiel #1
0
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)))
Beispiel #2
0
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..."))
Beispiel #4
0
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()
Beispiel #5
0
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. ()"
            ))