# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unit tests for mobly.controllers.android_device_lib.snippet_client_v2."""

import socket
import unittest
from unittest import mock

from mobly.controllers.android_device_lib import adb
from mobly.controllers.android_device_lib import errors as android_device_lib_errors
from mobly.controllers.android_device_lib import snippet_client_v2
from mobly.snippet import errors
from tests.lib import mock_android_device

MOCK_PACKAGE_NAME = 'some.package.name'
MOCK_SERVER_PATH = f'{MOCK_PACKAGE_NAME}/{snippet_client_v2._INSTRUMENTATION_RUNNER_PACKAGE}'
MOCK_USER_ID = 0
MOCK_DEVICE_PORT = 1234


class _MockAdbProxy(mock_android_device.MockAdbProxy):
  """Mock class of adb proxy which covers all the calls used by snippet clients.

  To enable testing snippet clients, this class extends the functionality of
  base class from the following aspects:
  * Records the arguments of all the calls to the shell method and forward
    method.
  * Handles the adb calls to stop the snippet server in the shell function
    properly.


  Attributes:
    mock_shell_func: mock.Mock, used for recording the calls to the shell
      method.
    mock_forward_func: mock.Mock, used for recording the calls to the forward
      method.
  """

  def __init__(self, *args, **kwargs):
    """Initializes the instance of _MockAdbProxy."""
    super().__init__(*args, **kwargs)
    self.mock_shell_func = mock.Mock()
    self.mock_forward_func = mock.Mock()

  def shell(self, *args, **kwargs):
    """Mock `shell` of mobly.controllers.android_device_lib.adb.AdbProxy."""
    # Record all the call args
    self.mock_shell_func(*args, **kwargs)

    # Handle the server stop command properly
    if f'am instrument --user 0 -w -e action stop {MOCK_SERVER_PATH}' in args:
      return b'OK (0 tests)'

    # For other commands, hand it over to the base class.
    return super().shell(*args, **kwargs)

  def forward(self, *args, **kwargs):
    """Mock `forward` of mobly.controllers.android_device_lib.adb.AdbProxy."""
    self.mock_forward_func(*args, **kwargs)


def _setup_mock_socket_file(mock_socket_create_conn, resp):
  """Sets up a mock socket file from the mock connection.

  Args:
    mock_socket_create_conn: The mock method for creating a socket connection.
    resp: iterable, the side effect of the `readline` function of the mock
      socket file.

  Returns:
    The mock socket file that will be injected into the code.
  """
  fake_file = mock.Mock()
  fake_file.readline.side_effect = resp
  fake_conn = mock.Mock()
  fake_conn.makefile.return_value = fake_file
  mock_socket_create_conn.return_value = fake_conn
  return fake_file


class SnippetClientV2Test(unittest.TestCase):
  """Unit tests for SnippetClientV2."""

  def _make_client(self, adb_proxy=None, mock_properties=None):
    adb_proxy = adb_proxy or _MockAdbProxy(instrumented_packages=[
        (MOCK_PACKAGE_NAME, snippet_client_v2._INSTRUMENTATION_RUNNER_PACKAGE,
         MOCK_PACKAGE_NAME)
    ],
                                           mock_properties=mock_properties)
    self.adb = adb_proxy

    device = mock.Mock()
    device.adb = adb_proxy
    device.adb.current_user_id = MOCK_USER_ID
    device.build_info = {
        'build_version_codename':
            adb_proxy.getprop('ro.build.version.codename'),
        'build_version_sdk':
            adb_proxy.getprop('ro.build.version.sdk'),
    }
    self.device = device

    self.client = snippet_client_v2.SnippetClientV2(MOCK_PACKAGE_NAME, device)

  def _make_client_with_extra_adb_properties(self, extra_properties):
    mock_properties = mock_android_device.DEFAULT_MOCK_PROPERTIES.copy()
    mock_properties.update(extra_properties)
    self._make_client(mock_properties=mock_properties)

  def _mock_server_process_starting_response(self,
                                             mock_start_subprocess,
                                             resp_lines=None):
    resp_lines = resp_lines or [
        b'SNIPPET START, PROTOCOL 1 0', b'SNIPPET SERVING, PORT 1234'
    ]
    mock_proc = mock_start_subprocess.return_value
    mock_proc.stdout.readline.side_effect = resp_lines

  def _make_client_and_mock_socket_conn(self,
                                        mock_socket_create_conn,
                                        socket_resp=None,
                                        device_port=MOCK_DEVICE_PORT,
                                        adb_proxy=None,
                                        mock_properties=None,
                                        set_counter=True):
    """Makes the snippet client and mocks the socket connection."""
    self._make_client(adb_proxy, mock_properties)

    if socket_resp is None:
      socket_resp = [b'{"status": true, "uid": 1}']
    self.mock_socket_file = _setup_mock_socket_file(mock_socket_create_conn,
                                                    socket_resp)
    self.client.device_port = device_port
    self.socket_conn = mock_socket_create_conn.return_value
    if set_counter:
      self.client._counter = self.client._id_counter()

  def _assert_client_resources_released(self, mock_start_subprocess,
                                        mock_stop_standing_subprocess,
                                        mock_get_port):
    """Asserts the resources had been released before the client stopped."""
    self.assertIs(self.client._proc, None)
    self.adb.mock_shell_func.assert_any_call(
        f'am instrument --user {MOCK_USER_ID} -w -e action stop '
        f'{MOCK_SERVER_PATH}')
    mock_stop_standing_subprocess.assert_called_once_with(
        mock_start_subprocess.return_value)
    self.assertFalse(self.client.is_alive)
    self.assertIs(self.client._conn, None)
    self.socket_conn.close.assert_called_once_with()
    self.assertIs(self.client.host_port, None)
    self.adb.mock_forward_func.assert_any_call(
        ['--remove', f'tcp:{mock_get_port.return_value}'])

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.get_available_host_port',
              return_value=12345)
  @mock.patch('socket.create_connection')
  @mock.patch('mobly.utils.stop_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_the_whole_lifecycle_with_a_sync_rpc(self, mock_start_subprocess,
                                               mock_stop_standing_subprocess,
                                               mock_socket_create_conn,
                                               mock_get_port):
    """Tests the whole lifecycle of the client with sending a sync RPC."""
    socket_resp = [
        b'{"status": true, "uid": 1}',
        b'{"id": 0, "result": 123, "error": null, "callback": null}',
    ]
    expected_socket_writes = [
        mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
        mock.call(b'{"id": 0, "method": "some_sync_rpc", '
                  b'"params": [1, 2, "hello"]}\n'),
    ]
    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
                                           socket_resp,
                                           set_counter=False)
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.initialize()
    rpc_result = self.client.some_sync_rpc(1, 2, 'hello')
    self.client.stop()

    self._assert_client_resources_released(mock_start_subprocess,
                                           mock_stop_standing_subprocess,
                                           mock_get_port)

    self.assertListEqual(self.mock_socket_file.write.call_args_list,
                         expected_socket_writes)
    self.assertEqual(rpc_result, 123)

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.get_available_host_port',
              return_value=12345)
  @mock.patch('socket.create_connection')
  @mock.patch('mobly.utils.stop_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.callback_handler.'
              'CallbackHandler')
  def test_the_whole_lifecycle_with_an_async_rpc(self, mock_callback_class,
                                                 mock_start_subprocess,
                                                 mock_stop_standing_subprocess,
                                                 mock_socket_create_conn,
                                                 mock_get_port):
    """Tests the whole lifecycle of the client with sending an async RPC."""
    mock_socket_resp = [
        b'{"status": true, "uid": 1}',
        b'{"id": 0, "result": 123, "error": null, "callback": "1-0"}',
        b'{"status": true, "uid": 1}',
    ]
    expected_socket_writes = [
        mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
        mock.call(b'{"id": 0, "method": "some_async_rpc", '
                  b'"params": [1, 2, "async"]}\n'),
        mock.call(b'{"cmd": "continue", "uid": 1}\n'),
    ]
    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
                                           mock_socket_resp,
                                           set_counter=False)
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.initialize()
    rpc_result = self.client.some_async_rpc(1, 2, 'async')
    self.client.stop()

    self._assert_client_resources_released(mock_start_subprocess,
                                           mock_stop_standing_subprocess,
                                           mock_get_port)

    self.assertListEqual(self.mock_socket_file.write.call_args_list,
                         expected_socket_writes)
    mock_callback_class.assert_called_with(
        callback_id='1-0',
        event_client=self.client._event_client,
        ret_value=123,
        method_name='some_async_rpc',
        ad=self.device)
    self.assertIs(rpc_result, mock_callback_class.return_value)

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.get_available_host_port',
              return_value=12345)
  @mock.patch('socket.create_connection')
  @mock.patch('mobly.utils.stop_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.callback_handler.'
              'CallbackHandler')
  def test_the_whole_lifecycle_with_multiple_rpcs(self, mock_callback_class,
                                                  mock_start_subprocess,
                                                  mock_stop_standing_subprocess,
                                                  mock_socket_create_conn,
                                                  mock_get_port):
    """Tests the whole lifecycle of the client with sending multiple RPCs."""
    # Prepare the test
    mock_socket_resp = [
        b'{"status": true, "uid": 1}',
        b'{"id": 0, "result": 123, "error": null, "callback": null}',
        b'{"id": 1, "result": 456, "error": null, "callback": "1-0"}',
        # Response for starting the event client
        b'{"status": true, "uid": 1}',
        b'{"id": 2, "result": 789, "error": null, "callback": null}',
        b'{"id": 3, "result": 321, "error": null, "callback": "2-0"}',
    ]
    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
                                           mock_socket_resp,
                                           set_counter=False)
    self._mock_server_process_starting_response(mock_start_subprocess)

    rpc_results_expected = [
        123,
        mock.Mock(),
        789,
        mock.Mock(),
    ]
    # Extract the two mock objects to use as return values of callback handler
    # class
    mock_callback_class.side_effect = [
        rpc_results_expected[1], rpc_results_expected[3]
    ]

    # Run tests
    rpc_results = []
    self.client.initialize()
    rpc_results.append(self.client.some_sync_rpc(1, 2, 'hello'))
    rpc_results.append(self.client.some_async_rpc(3, 4, 'async'))
    rpc_results.append(self.client.some_sync_rpc(5, 'hello'))
    rpc_results.append(self.client.some_async_rpc(6, 'async'))
    self.client.stop()

    # Assertions
    mock_callback_class_calls_expected = [
        mock.call(callback_id='1-0',
                  event_client=self.client._event_client,
                  ret_value=456,
                  method_name='some_async_rpc',
                  ad=self.device),
        mock.call(callback_id='2-0',
                  event_client=self.client._event_client,
                  ret_value=321,
                  method_name='some_async_rpc',
                  ad=self.device),
    ]
    self.assertListEqual(rpc_results, rpc_results_expected)
    mock_callback_class.assert_has_calls(mock_callback_class_calls_expected)
    self._assert_client_resources_released(mock_start_subprocess,
                                           mock_stop_standing_subprocess,
                                           mock_get_port)

  def test_check_app_installed_normally(self):
    """Tests that app checker runs normally when app installed correctly."""
    self._make_client()
    self.client._validate_snippet_app_on_device()

  def test_check_app_installed_fail_app_not_installed(self):
    """Tests that app checker fails without installing app."""
    self._make_client(_MockAdbProxy())
    expected_msg = f'.* {MOCK_PACKAGE_NAME} is not installed.'
    with self.assertRaisesRegex(errors.ServerStartPreCheckError, expected_msg):
      self.client._validate_snippet_app_on_device()

  def test_check_app_installed_fail_not_instrumented(self):
    """Tests that app checker fails without instrumenting app."""
    self._make_client(_MockAdbProxy(installed_packages=[MOCK_PACKAGE_NAME]))
    expected_msg = (
        f'.* {MOCK_PACKAGE_NAME} is installed, but it is not instrumented.')
    with self.assertRaisesRegex(errors.ServerStartPreCheckError, expected_msg):
      self.client._validate_snippet_app_on_device()

  def test_check_app_installed_fail_instrumentation_not_installed(self):
    """Tests that app checker fails without installing instrumentation."""
    self._make_client(
        _MockAdbProxy(instrumented_packages=[(
            MOCK_PACKAGE_NAME,
            snippet_client_v2._INSTRUMENTATION_RUNNER_PACKAGE,
            'not.installed')]))
    expected_msg = ('.* Instrumentation target not.installed is not installed.')
    with self.assertRaisesRegex(errors.ServerStartPreCheckError, expected_msg):
      self.client._validate_snippet_app_on_device()

  def test_disable_hidden_api_normally(self):
    """Tests the disabling hidden api process works normally."""
    self._make_client_with_extra_adb_properties({
        'ro.build.version.codename': 'S',
        'ro.build.version.sdk': '31',
    })
    self.device.is_rootable = True
    self.client._disable_hidden_api_blocklist()
    self.adb.mock_shell_func.assert_called_with(
        'settings put global hidden_api_blacklist_exemptions "*"')

  def test_disable_hidden_api_low_sdk(self):
    """Tests it doesn't disable hidden api with low SDK."""
    self._make_client_with_extra_adb_properties({
        'ro.build.version.codename': 'O',
        'ro.build.version.sdk': '26',
    })
    self.device.is_rootable = True
    self.client._disable_hidden_api_blocklist()
    self.adb.mock_shell_func.assert_not_called()

  def test_disable_hidden_api_non_rootable(self):
    """Tests it doesn't disable hidden api with non-rootable device."""
    self._make_client_with_extra_adb_properties({
        'ro.build.version.codename': 'S',
        'ro.build.version.sdk': '31',
    })
    self.device.is_rootable = False
    self.client._disable_hidden_api_blocklist()
    self.adb.mock_shell_func.assert_not_called()

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch.object(_MockAdbProxy, 'shell', return_value=b'setsid')
  def test_start_server_with_user_id(self, mock_adb, mock_start_subprocess):
    """Tests that `--user` is added to starting command with SDK >= 24."""
    self._make_client_with_extra_adb_properties({'ro.build.version.sdk': '30'})
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.start_server()
    start_cmd_list = [
        'adb', 'shell',
        (f'setsid am instrument --user {MOCK_USER_ID} -w -e action start '
         f'{MOCK_SERVER_PATH}')
    ]
    self.assertListEqual(mock_start_subprocess.call_args_list,
                         [mock.call(start_cmd_list, shell=False)])
    self.assertEqual(self.client.device_port, 1234)
    mock_adb.assert_called_with(['which', 'setsid'])

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch.object(_MockAdbProxy, 'shell', return_value=b'setsid')
  def test_start_server_without_user_id(self, mock_adb, mock_start_subprocess):
    """Tests that `--user` is not added to starting command on SDK < 24."""
    self._make_client_with_extra_adb_properties({'ro.build.version.sdk': '21'})
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.start_server()
    start_cmd_list = [
        'adb', 'shell',
        f'setsid am instrument  -w -e action start {MOCK_SERVER_PATH}'
    ]
    self.assertListEqual(mock_start_subprocess.call_args_list,
                         [mock.call(start_cmd_list, shell=False)])
    mock_adb.assert_called_with(['which', 'setsid'])
    self.assertEqual(self.client.device_port, 1234)

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch.object(_MockAdbProxy,
                     'shell',
                     side_effect=adb.AdbError('cmd', 'stdout', 'stderr',
                                              'ret_code'))
  def test_start_server_without_persisting_commands(self, mock_adb,
                                                    mock_start_subprocess):
    """Checks the starting server command without persisting commands."""
    self._make_client()
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.start_server()
    start_cmd_list = [
        'adb', 'shell',
        (f' am instrument --user {MOCK_USER_ID} -w -e action start '
         f'{MOCK_SERVER_PATH}')
    ]
    self.assertListEqual(mock_start_subprocess.call_args_list,
                         [mock.call(start_cmd_list, shell=False)])
    mock_adb.assert_has_calls(
        [mock.call(['which', 'setsid']),
         mock.call(['which', 'nohup'])])
    self.assertEqual(self.client.device_port, 1234)

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_start_server_with_nohup(self, mock_start_subprocess):
    """Checks the starting server command with nohup."""
    self._make_client()
    self._mock_server_process_starting_response(mock_start_subprocess)

    def _mocked_shell(arg):
      if 'nohup' in arg:
        return b'nohup'
      raise adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code')

    self.client._adb.shell = _mocked_shell

    self.client.start_server()
    start_cmd_list = [
        'adb', 'shell',
        (f'nohup am instrument --user {MOCK_USER_ID} -w -e action start '
         f'{MOCK_SERVER_PATH}')
    ]
    self.assertListEqual(mock_start_subprocess.call_args_list,
                         [mock.call(start_cmd_list, shell=False)])
    self.assertEqual(self.client.device_port, 1234)

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_start_server_with_setsid(self, mock_start_subprocess):
    """Checks the starting server command with setsid."""
    self._make_client()
    self._mock_server_process_starting_response(mock_start_subprocess)

    def _mocked_shell(arg):
      if 'setsid' in arg:
        return b'setsid'
      raise adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code')

    self.client._adb.shell = _mocked_shell
    self.client.start_server()
    start_cmd_list = [
        'adb', 'shell',
        (f'setsid am instrument --user {MOCK_USER_ID} -w -e action start '
         f'{MOCK_SERVER_PATH}')
    ]
    self.assertListEqual(mock_start_subprocess.call_args_list,
                         [mock.call(start_cmd_list, shell=False)])
    self.assertEqual(self.client.device_port, 1234)

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_start_server_server_crash(self, mock_start_standing_subprocess):
    """Tests that starting server process crashes."""
    self._make_client()
    self._mock_server_process_starting_response(
        mock_start_standing_subprocess,
        resp_lines=[b'INSTRUMENTATION_RESULT: shortMsg=Process crashed.\n'])
    with self.assertRaisesRegex(
        errors.ServerStartProtocolError,
        'INSTRUMENTATION_RESULT: shortMsg=Process crashed.'):
      self.client.start_server()

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_start_server_unknown_protocol_version(
      self, mock_start_standing_subprocess):
    """Tests that starting server process reports unknown protocol version."""
    self._make_client()
    self._mock_server_process_starting_response(
        mock_start_standing_subprocess,
        resp_lines=[b'SNIPPET START, PROTOCOL 99 0\n'])
    with self.assertRaisesRegex(errors.ServerStartProtocolError,
                                'SNIPPET START, PROTOCOL 99 0'):
      self.client.start_server()

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_start_server_invalid_device_port(self,
                                            mock_start_standing_subprocess):
    """Tests that starting server process reports invalid device port."""
    self._make_client()
    self._mock_server_process_starting_response(
        mock_start_standing_subprocess,
        resp_lines=[
            b'SNIPPET START, PROTOCOL 1 0\n', b'SNIPPET SERVING, PORT ABC\n'
        ])
    with self.assertRaisesRegex(errors.ServerStartProtocolError,
                                'SNIPPET SERVING, PORT ABC'):
      self.client.start_server()

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_start_server_with_junk(self, mock_start_standing_subprocess):
    """Tests that starting server process reports known protocol with junk."""
    self._make_client()
    self._mock_server_process_starting_response(
        mock_start_standing_subprocess,
        resp_lines=[
            b'This is some header junk\n',
            b'Some phones print arbitrary output\n',
            b'SNIPPET START, PROTOCOL 1 0\n',
            b'Maybe in the middle too\n',
            b'SNIPPET SERVING, PORT 123\n',
        ])
    self.client.start_server()
    self.assertEqual(123, self.client.device_port)

  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_start_server_no_valid_line(self, mock_start_standing_subprocess):
    """Tests that starting server process reports unknown protocol message."""
    self._make_client()
    self._mock_server_process_starting_response(
        mock_start_standing_subprocess,
        resp_lines=[
            b'This is some header junk\n',
            b'Some phones print arbitrary output\n',
            b'',  # readline uses '' to mark EOF
        ])
    with self.assertRaisesRegex(
        errors.ServerStartError,
        'Unexpected EOF when waiting for server to start.'):
      self.client.start_server()

  @mock.patch('mobly.utils.stop_standing_subprocess')
  def test_stop_normally(self, mock_stop_standing_subprocess):
    """Tests that stopping server process works normally."""
    self._make_client()
    mock_proc = mock.Mock()
    self.client._proc = mock_proc
    mock_conn = mock.Mock()
    self.client._conn = mock_conn
    self.client.host_port = 12345

    self.client.stop()

    self.assertIs(self.client._proc, None)
    self.adb.mock_shell_func.assert_called_once_with(
        f'am instrument --user {MOCK_USER_ID} -w -e action stop '
        f'{MOCK_SERVER_PATH}')
    mock_stop_standing_subprocess.assert_called_once_with(mock_proc)
    self.assertFalse(self.client.is_alive)
    self.assertIs(self.client._conn, None)
    mock_conn.close.assert_called_once_with()
    self.assertIs(self.client.host_port, None)
    self.device.adb.mock_forward_func.assert_called_once_with(
        ['--remove', 'tcp:12345'])

  @mock.patch('mobly.utils.stop_standing_subprocess')
  def test_stop_when_server_is_already_cleaned(self,
                                               mock_stop_standing_subprocess):
    """Tests that stop server process when subprocess is already cleaned."""
    self._make_client()
    self.client._proc = None
    mock_conn = mock.Mock()
    self.client._conn = mock_conn
    self.client.host_port = 12345

    self.client.stop()

    self.assertIs(self.client._proc, None)
    mock_stop_standing_subprocess.assert_not_called()
    self.adb.assert_called_once_with(
        f'am instrument --user {MOCK_USER_ID} -w -e action stop '
        f'{MOCK_SERVER_PATH}')
    self.assertFalse(self.client.is_alive)
    self.assertIs(self.client._conn, None)
    mock_conn.close.assert_called_once_with()
    self.assertIs(self.client.host_port, None)
    self.device.adb.mock_forward_func.assert_called_once_with(
        ['--remove', 'tcp:12345'])

  @mock.patch('mobly.utils.stop_standing_subprocess')
  def test_stop_when_conn_is_already_cleaned(self,
                                             mock_stop_standing_subprocess):
    """Tests that stop server process when the connection is already closed."""
    self._make_client()
    mock_proc = mock.Mock()
    self.client._proc = mock_proc
    self.client._conn = None
    self.client.host_port = 12345

    self.client.stop()

    self.assertIs(self.client._proc, None)
    mock_stop_standing_subprocess.assert_called_once_with(mock_proc)
    self.adb.assert_called_once_with(
        f'am instrument --user {MOCK_USER_ID} -w -e action stop '
        f'{MOCK_SERVER_PATH}')
    self.assertFalse(self.client.is_alive)
    self.assertIs(self.client._conn, None)
    self.assertIs(self.client.host_port, None)
    self.device.adb.mock_forward_func.assert_called_once_with(
        ['--remove', 'tcp:12345'])

  @mock.patch('mobly.utils.stop_standing_subprocess')
  @mock.patch.object(_MockAdbProxy, 'shell', return_value=b'Closed with error.')
  def test_stop_with_device_side_error(self, mock_adb_shell,
                                       mock_stop_standing_subprocess):
    """Tests all resources will be cleaned when server stop throws an error."""
    self._make_client()
    mock_proc = mock.Mock()
    self.client._proc = mock_proc
    mock_conn = mock.Mock()
    self.client._conn = mock_conn
    self.client.host_port = 12345
    with self.assertRaisesRegex(android_device_lib_errors.DeviceError,
                                'Closed with error'):
      self.client.stop()

    self.assertIs(self.client._proc, None)
    mock_stop_standing_subprocess.assert_called_once_with(mock_proc)
    mock_adb_shell.assert_called_once_with(
        f'am instrument --user {MOCK_USER_ID} -w -e action stop '
        f'{MOCK_SERVER_PATH}')
    self.assertFalse(self.client.is_alive)
    self.assertIs(self.client._conn, None)
    mock_conn.close.assert_called_once_with()
    self.assertIs(self.client.host_port, None)
    self.device.adb.mock_forward_func.assert_called_once_with(
        ['--remove', 'tcp:12345'])

  @mock.patch('mobly.utils.stop_standing_subprocess')
  def test_stop_with_conn_close_error(self, mock_stop_standing_subprocess):
    """Tests port resource will be cleaned when socket close throws an error."""
    del mock_stop_standing_subprocess
    self._make_client()
    mock_proc = mock.Mock()
    self.client._proc = mock_proc
    mock_conn = mock.Mock()
    # The deconstructor will call this mock function again after tests, so
    # only throw this error when it is called the first time.
    mock_conn.close.side_effect = (OSError('Closed with error'), None)
    self.client._conn = mock_conn
    self.client.host_port = 12345
    with self.assertRaisesRegex(OSError, 'Closed with error'):
      self.client.stop()

    self.device.adb.mock_forward_func.assert_called_once_with(
        ['--remove', 'tcp:12345'])

  def test_close_connection_normally(self):
    """Tests that closing connection works normally."""
    self._make_client()
    mock_conn = mock.Mock()
    self.client._conn = mock_conn
    self.client.host_port = 123

    self.client.close_connection()

    self.assertIs(self.client._conn, None)
    self.assertIs(self.client.host_port, None)
    mock_conn.close.assert_called_once_with()
    self.device.adb.mock_forward_func.assert_called_once_with(
        ['--remove', 'tcp:123'])

  def test_close_connection_when_host_port_has_been_released(self):
    """Tests that close connection when the host port has been released."""
    self._make_client()
    mock_conn = mock.Mock()
    self.client._conn = mock_conn
    self.client.host_port = None

    self.client.close_connection()

    self.assertIs(self.client._conn, None)
    self.assertIs(self.client.host_port, None)
    mock_conn.close.assert_called_once_with()
    self.device.adb.mock_forward_func.assert_not_called()

  def test_close_connection_when_conn_have_been_closed(self):
    """Tests that close connection when the connection has been closed."""
    self._make_client()
    self.client._conn = None
    self.client.host_port = 123

    self.client.close_connection()

    self.assertIs(self.client._conn, None)
    self.assertIs(self.client.host_port, None)
    self.device.adb.mock_forward_func.assert_called_once_with(
        ['--remove', 'tcp:123'])

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_send_sync_rpc_normally(self, mock_start_subprocess,
                                  mock_socket_create_conn):
    """Tests that sending a sync RPC works normally."""
    socket_resp = [
        b'{"status": true, "uid": 1}',
        b'{"id": 0, "result": 123, "error": null, "callback": null}',
    ]
    self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.make_connection()
    rpc_result = self.client.some_rpc(1, 2, 'hello')

    self.assertEqual(rpc_result, 123)
    self.mock_socket_file.write.assert_called_with(
        b'{"id": 0, "method": "some_rpc", "params": [1, 2, "hello"]}\n')

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.callback_handler.'
              'CallbackHandler')
  def test_async_rpc_start_event_client(self, mock_callback_class,
                                        mock_start_subprocess,
                                        mock_socket_create_conn):
    """Tests that sending an async RPC starts the event client."""
    socket_resp = [
        b'{"status": true, "uid": 1}',
        b'{"id": 0, "result": 123, "error": null, "callback": "1-0"}',
        b'{"status": true, "uid": 1}',
        b'{"id":1,"result":"async-rpc-event","callback":null,"error":null}',
    ]
    socket_write_expected = [
        mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
        mock.call(b'{"id": 0, "method": "some_async_rpc", '
                  b'"params": [1, 2, "hello"]}\n'),
        mock.call(b'{"cmd": "continue", "uid": 1}\n'),
        mock.call(b'{"id": 1, "method": "eventGetAll", '
                  b'"params": ["1-0", "eventName"]}\n'),
    ]
    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
                                           socket_resp,
                                           set_counter=True)
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.host_port = 12345
    self.client.make_connection()
    rpc_result = self.client.some_async_rpc(1, 2, 'hello')

    mock_callback_class.assert_called_with(
        callback_id='1-0',
        event_client=self.client._event_client,
        ret_value=123,
        method_name='some_async_rpc',
        ad=self.device)
    self.assertIs(rpc_result, mock_callback_class.return_value)

    # Ensure the event client is alive
    self.assertTrue(self.client._event_client.is_alive)

    # Ensure the event client shared the same ports and uid with main client
    self.assertEqual(self.client._event_client.host_port, 12345)
    self.assertEqual(self.client._event_client.device_port, MOCK_DEVICE_PORT)
    self.assertEqual(self.client._event_client.uid, self.client.uid)

    # Ensure the event client has reset its own RPC id counter
    self.assertEqual(next(self.client._counter), 1)
    self.assertEqual(next(self.client._event_client._counter), 0)

    # Ensure that event client can send RPCs
    event_string = self.client._event_client.eventGetAll('1-0', 'eventName')
    self.assertEqual(event_string, 'async-rpc-event')
    self.assertListEqual(
        self.mock_socket_file.write.call_args_list,
        socket_write_expected,
    )

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.get_available_host_port')
  def test_initialize_client_normally(self, mock_get_port,
                                      mock_start_subprocess,
                                      mock_socket_create_conn):
    """Tests that initializing the client works normally."""
    mock_get_port.return_value = 12345
    socket_resp = [b'{"status": true, "uid": 1}']
    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
                                           socket_resp,
                                           set_counter=True)
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.initialize()
    self.assertTrue(self.client.is_alive)
    self.assertEqual(self.client.uid, 1)
    self.assertEqual(self.client.host_port, 12345)
    self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
    self.assertEqual(next(self.client._counter), 0)

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.get_available_host_port')
  def test_restore_event_client(self, mock_get_port, mock_start_subprocess,
                                mock_socket_create_conn):
    """Tests restoring the event client."""
    mock_get_port.return_value = 12345
    socket_resp = [
        # response of handshake when initializing the client
        b'{"status": true, "uid": 1}',
        # response of an async RPC
        b'{"id": 0, "result": 123, "error": null, "callback": "1-0"}',
        # response of starting event client
        b'{"status": true, "uid": 1}',
        # response of restoring server connection
        b'{"status": true, "uid": 2}',
        # response of restoring event client
        b'{"status": true, "uid": 3}',
        # response of restoring server connection
        b'{"status": true, "uid": 4}',
        # response of restoring event client
        b'{"status": true, "uid": 5}',
    ]
    socket_write_expected = [
        # request of handshake when initializing the client
        mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
        # request of an async RPC
        mock.call(b'{"id": 0, "method": "some_async_rpc", "params": []}\n'),
        # request of starting event client
        mock.call(b'{"cmd": "continue", "uid": 1}\n'),
        # request of restoring server connection
        mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
        # request of restoring event client
        mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
        # request of restoring server connection
        mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
        # request of restoring event client
        mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
    ]
    self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.make_connection()
    callback = self.client.some_async_rpc()

    # before reconnect, clients use previously selected ports
    self.assertEqual(self.client.host_port, 12345)
    self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
    self.assertEqual(callback._event_client.host_port, 12345)
    self.assertEqual(callback._event_client.device_port, MOCK_DEVICE_PORT)
    self.assertEqual(next(self.client._event_client._counter), 0)

    # after reconnect, if host port specified, clients use specified port
    self.client.restore_server_connection(port=54321)
    self.assertEqual(self.client.host_port, 54321)
    self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
    self.assertEqual(callback._event_client.host_port, 54321)
    self.assertEqual(callback._event_client.device_port, MOCK_DEVICE_PORT)
    self.assertEqual(next(self.client._event_client._counter), 0)

    # after reconnect, if host port not specified, clients use selected
    # available port
    mock_get_port.return_value = 56789
    self.client.restore_server_connection()
    self.assertEqual(self.client.host_port, 56789)
    self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
    self.assertEqual(callback._event_client.host_port, 56789)
    self.assertEqual(callback._event_client.device_port, MOCK_DEVICE_PORT)
    self.assertEqual(next(self.client._event_client._counter), 0)

    # if unable to reconnect for any reason, a
    # errors.ServerRestoreConnectionError is raised.
    mock_socket_create_conn.side_effect = IOError('socket timed out')
    with self.assertRaisesRegex(
        errors.ServerRestoreConnectionError,
        (f'Failed to restore server connection for {MOCK_PACKAGE_NAME} at '
         f'host port 56789, device port {MOCK_DEVICE_PORT}')):
      self.client.restore_server_connection()

    self.assertListEqual(self.mock_socket_file.write.call_args_list,
                         socket_write_expected)

  @mock.patch.object(snippet_client_v2.SnippetClientV2, '_make_connection')
  @mock.patch.object(snippet_client_v2.SnippetClientV2,
                     'send_handshake_request')
  @mock.patch.object(snippet_client_v2.SnippetClientV2,
                     'create_socket_connection')
  def test_restore_server_connection_with_event_client(
      self, mock_create_socket_conn_func, mock_send_handshake_func,
      mock_make_connection):
    """Tests restoring server connection when the event client is not None."""
    self._make_client()
    event_client = snippet_client_v2.SnippetClientV2('mock-package',
                                                     mock.Mock())
    self.client._event_client = event_client
    self.client.device_port = 54321
    self.client.uid = 5

    self.client.restore_server_connection(port=12345)

    mock_make_connection.assert_called_once_with()
    self.assertEqual(event_client.host_port, 12345)
    self.assertEqual(event_client.device_port, 54321)
    self.assertEqual(next(event_client._counter), 0)
    mock_create_socket_conn_func.assert_called_once_with()
    mock_send_handshake_func.assert_called_once_with(
        -1, snippet_client_v2.ConnectionHandshakeCommand.INIT)

  @mock.patch('builtins.print')
  def test_help_rpc_when_printing_by_default(self, mock_print):
    """Tests the `help` method when it prints the output by default."""
    self._make_client()
    mock_rpc = mock.MagicMock()
    self.client._rpc = mock_rpc

    result = self.client.help()
    mock_rpc.assert_called_once_with('help')
    self.assertIsNone(result)
    mock_print.assert_called_once_with(mock_rpc.return_value)

  @mock.patch('builtins.print')
  def test_help_rpc_when_not_printing(self, mock_print):
    """Tests the `help` method when it was set not to print the output."""
    self._make_client()
    mock_rpc = mock.MagicMock()
    self.client._rpc = mock_rpc

    result = self.client.help(print_output=False)
    mock_rpc.assert_called_once_with('help')
    self.assertEqual(mock_rpc.return_value, result)
    mock_print.assert_not_called()

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.get_available_host_port',
              return_value=12345)
  def test_make_connection_normally(self, mock_get_port, mock_start_subprocess,
                                    mock_socket_create_conn):
    """Tests that making a connection works normally."""
    del mock_get_port
    socket_resp = [b'{"status": true, "uid": 1}']
    self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.make_connection()
    self.assertEqual(self.client.uid, 1)
    self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
    self.adb.mock_forward_func.assert_called_once_with(
        ['tcp:12345', f'tcp:{MOCK_DEVICE_PORT}'])
    mock_socket_create_conn.assert_called_once_with(
        ('localhost', 12345), snippet_client_v2._SOCKET_CONNECTION_TIMEOUT)
    self.socket_conn.settimeout.assert_called_once_with(
        snippet_client_v2._SOCKET_READ_TIMEOUT)

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.get_available_host_port',
              return_value=12345)
  def test_make_connection_with_preset_host_port(self, mock_get_port,
                                                 mock_start_subprocess,
                                                 mock_socket_create_conn):
    """Tests that make a connection with the preset host port."""
    del mock_get_port
    socket_resp = [b'{"status": true, "uid": 1}']
    self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.host_port = 23456
    self.client.make_connection()
    self.assertEqual(self.client.uid, 1)
    self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
    # Test that the host port for forwarding is 23456 instead of 12345
    self.adb.mock_forward_func.assert_called_once_with(
        ['tcp:23456', f'tcp:{MOCK_DEVICE_PORT}'])
    mock_socket_create_conn.assert_called_once_with(
        ('localhost', 23456), snippet_client_v2._SOCKET_CONNECTION_TIMEOUT)
    self.socket_conn.settimeout.assert_called_once_with(
        snippet_client_v2._SOCKET_READ_TIMEOUT)

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.get_available_host_port',
              return_value=12345)
  def test_make_connection_with_ip(self, mock_get_port, mock_start_subprocess,
                                   mock_socket_create_conn):
    """Tests that make a connection with 127.0.0.1 instead of localhost."""
    del mock_get_port
    socket_resp = [b'{"status": true, "uid": 1}']
    self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
    self._mock_server_process_starting_response(mock_start_subprocess)

    mock_conn = mock_socket_create_conn.return_value

    # Refuse creating socket connection with 'localhost', only accept
    # '127.0.0.1' as address
    def _mock_create_conn_side_effect(address, *args, **kwargs):
      del args, kwargs
      if address[0] == '127.0.0.1':
        return mock_conn
      raise ConnectionRefusedError(f'Refusing connection to {address[0]}.')

    mock_socket_create_conn.side_effect = _mock_create_conn_side_effect

    self.client.make_connection()
    self.assertEqual(self.client.uid, 1)
    self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
    self.adb.mock_forward_func.assert_called_once_with(
        ['tcp:12345', f'tcp:{MOCK_DEVICE_PORT}'])
    mock_socket_create_conn.assert_any_call(
        ('127.0.0.1', 12345), snippet_client_v2._SOCKET_CONNECTION_TIMEOUT)
    self.socket_conn.settimeout.assert_called_once_with(
        snippet_client_v2._SOCKET_READ_TIMEOUT)

  @mock.patch('socket.create_connection')
  def test_make_connection_io_error(self, mock_socket_create_conn):
    """Tests IOError occurred trying to create a socket connection."""
    mock_socket_create_conn.side_effect = IOError()
    with self.assertRaises(IOError):
      self._make_client()
      self.client.device_port = 123
      self.client.make_connection()

  @mock.patch('socket.create_connection')
  def test_make_connection_timeout(self, mock_socket_create_conn):
    """Tests timeout occurred trying to create a socket connection."""
    mock_socket_create_conn.side_effect = socket.timeout
    with self.assertRaises(socket.timeout):
      self._make_client()
      self.client.device_port = 123
      self.client.make_connection()

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_make_connection_receives_none_handshake_response(
      self, mock_start_subprocess, mock_socket_create_conn):
    """Tests make_connection receives None as the handshake response."""
    socket_resp = [None]
    self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
    self._mock_server_process_starting_response(mock_start_subprocess)

    with self.assertRaisesRegex(
        errors.ProtocolError, errors.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE):
      self.client.make_connection()

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_make_connection_receives_empty_handshake_response(
      self, mock_start_subprocess, mock_socket_create_conn):
    """Tests make_connection receives an empty handshake response."""
    socket_resp = [b'']
    self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
    self._mock_server_process_starting_response(mock_start_subprocess)

    with self.assertRaisesRegex(
        errors.ProtocolError, errors.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE):
      self.client.make_connection()

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_make_connection_receives_invalid_handshake_response(
      self, mock_start_subprocess, mock_socket_create_conn):
    """Tests make_connection receives an invalid handshake response."""
    socket_resp = [b'{"status": false, "uid": 1}']
    self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
    self._mock_server_process_starting_response(mock_start_subprocess)

    self.client.make_connection()
    self.assertEqual(self.client.uid, -1)

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_make_connection_send_handshake_request_error(
      self, mock_start_subprocess, mock_socket_create_conn):
    """Tests that an error occurred trying to send a handshake request."""
    self._make_client_and_mock_socket_conn(mock_socket_create_conn)
    self._mock_server_process_starting_response(mock_start_subprocess)
    self.mock_socket_file.write.side_effect = socket.error('Socket write error')

    with self.assertRaisesRegex(errors.Error, 'Socket write error'):
      self.client.make_connection()

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_make_connection_receive_handshake_response_error(
      self, mock_start_subprocess, mock_socket_create_conn):
    """Tests that an error occurred trying to receive a handshake response."""
    self._make_client_and_mock_socket_conn(mock_socket_create_conn)
    self._mock_server_process_starting_response(mock_start_subprocess)
    self.mock_socket_file.readline.side_effect = socket.error(
        'Socket read error')

    with self.assertRaisesRegex(errors.Error, 'Socket read error'):
      self.client.make_connection()

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
              'utils.start_standing_subprocess')
  def test_make_connection_decode_handshake_response_bytes_error(
      self, mock_start_subprocess, mock_socket_create_conn):
    """Tests that an error occurred trying to decode a handshake response."""
    self._make_client_and_mock_socket_conn(mock_socket_create_conn)
    self._mock_server_process_starting_response(mock_start_subprocess)
    self.client.log = mock.Mock()
    socket_response = bytes('{"status": false, "uid": 1}', encoding='cp037')
    self.mock_socket_file.readline.side_effect = [socket_response]

    with self.assertRaises(UnicodeError):
      self.client.make_connection()

    self.client.log.error.assert_has_calls([
        mock.call(
            'Failed to decode socket response bytes using encoding utf8: %s',
            socket_response)
    ])

  def test_rpc_sending_and_receiving(self):
    """Test RPC sending and receiving.

    Tests that when sending and receiving an RPC the correct data is used.
    """
    self._make_client()
    rpc_request = '{"id": 0, "method": "some_rpc", "params": []}'
    rpc_response_expected = ('{"id": 0, "result": 123, "error": null, '
                             '"callback": null}')

    socket_write_expected = [
        mock.call(b'{"id": 0, "method": "some_rpc", "params": []}\n')
    ]
    socket_response = (b'{"id": 0, "result": 123, "error": null, '
                       b'"callback": null}')

    mock_socket_file = mock.Mock()
    mock_socket_file.readline.return_value = socket_response
    self.client._client = mock_socket_file

    rpc_response = self.client.send_rpc_request(rpc_request)

    self.assertEqual(rpc_response, rpc_response_expected)
    self.assertEqual(mock_socket_file.write.call_args_list,
                     socket_write_expected)

  def test_rpc_send_socket_write_error(self):
    """Tests that an error occurred trying to write the socket file."""
    self._make_client()
    self.client._client = mock.Mock()
    self.client._client.write.side_effect = socket.error('Socket write error')

    rpc_request = '{"id": 0, "method": "some_rpc", "params": []}'
    with self.assertRaisesRegex(errors.Error, 'Socket write error'):
      self.client.send_rpc_request(rpc_request)

  def test_rpc_send_socket_read_error(self):
    """Tests that an error occurred trying to read the socket file."""
    self._make_client()
    self.client._client = mock.Mock()
    self.client._client.readline.side_effect = socket.error('Socket read error')

    rpc_request = '{"id": 0, "method": "some_rpc", "params": []}'
    with self.assertRaisesRegex(errors.Error, 'Socket read error'):
      self.client.send_rpc_request(rpc_request)

  def test_rpc_send_decode_socket_response_bytes_error(self):
    """Tests that an error occurred trying to decode the socket response."""
    self._make_client()
    self.client.log = mock.Mock()
    self.client._client = mock.Mock()
    socket_response = bytes(
        '{"id": 0, "result": 123, "error": null, "callback": null}',
        encoding='cp037')
    self.client._client.readline.return_value = socket_response

    rpc_request = '{"id": 0, "method": "some_rpc", "params": []}'
    with self.assertRaises(UnicodeError):
      self.client.send_rpc_request(rpc_request)

    self.client.log.error.assert_has_calls([
        mock.call(
            'Failed to decode socket response bytes using encoding utf8: %s',
            socket_response)
    ])

  @mock.patch.object(snippet_client_v2.SnippetClientV2,
                     'send_handshake_request')
  @mock.patch.object(snippet_client_v2.SnippetClientV2,
                     'create_socket_connection')
  def test_make_conn_with_forwarded_port_init(self,
                                              mock_create_socket_conn_func,
                                              mock_send_handshake_func):
    """Tests make_connection_with_forwarded_port initiates a new session."""
    self._make_client()
    self.client._counter = None
    self.client.make_connection_with_forwarded_port(12345, 54321)

    self.assertEqual(self.client.host_port, 12345)
    self.assertEqual(self.client.device_port, 54321)
    self.assertEqual(next(self.client._counter), 0)
    mock_create_socket_conn_func.assert_called_once_with()
    mock_send_handshake_func.assert_called_once_with(
        -1, snippet_client_v2.ConnectionHandshakeCommand.INIT)

  @mock.patch.object(snippet_client_v2.SnippetClientV2,
                     'send_handshake_request')
  @mock.patch.object(snippet_client_v2.SnippetClientV2,
                     'create_socket_connection')
  def test_make_conn_with_forwarded_port_continue(self,
                                                  mock_create_socket_conn_func,
                                                  mock_send_handshake_func):
    """Tests make_connection_with_forwarded_port continues current session."""
    self._make_client()
    self.client._counter = None
    self.client.make_connection_with_forwarded_port(
        12345, 54321, 3, snippet_client_v2.ConnectionHandshakeCommand.CONTINUE)

    self.assertEqual(self.client.host_port, 12345)
    self.assertEqual(self.client.device_port, 54321)
    self.assertEqual(next(self.client._counter), 0)
    mock_create_socket_conn_func.assert_called_once_with()
    mock_send_handshake_func.assert_called_once_with(
        3, snippet_client_v2.ConnectionHandshakeCommand.CONTINUE)


if __name__ == '__main__':
  unittest.main()
