# 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.

import io
import mock
import subprocess

from collections import OrderedDict
from future.tests.base import unittest
from mobly.controllers.android_device_lib import adb

# Mock parameters for instrumentation.
MOCK_INSTRUMENTATION_PACKAGE = 'com.my.instrumentation.tests'
MOCK_INSTRUMENTATION_RUNNER = 'com.my.instrumentation.runner'
MOCK_INSTRUMENTATION_OPTIONS = OrderedDict([
    ('option1', 'value1'),
    ('option2', 'value2'),
])
# Mock android instrumentation commands.
MOCK_BASIC_INSTRUMENTATION_COMMAND = ('am instrument -r -w  com.my'
                                      '.instrumentation.tests/com.android'
                                      '.common.support.test.runner'
                                      '.AndroidJUnitRunner')
MOCK_RUNNER_INSTRUMENTATION_COMMAND = ('am instrument -r -w  com.my'
                                       '.instrumentation.tests/com.my'
                                       '.instrumentation.runner')
MOCK_OPTIONS_INSTRUMENTATION_COMMAND = ('am instrument -r -w -e option1 value1'
                                        ' -e option2 value2 com.my'
                                        '.instrumentation.tests/com.android'
                                        '.common.support.test.runner'
                                        '.AndroidJUnitRunner')

# Mock root command outputs.
MOCK_ROOT_SUCCESS_OUTPUT = 'adbd is already running as root'
MOCK_ROOT_ERROR_OUTPUT = (
    'adb: unable to connect for root: closed'.encode('utf-8'))

# Mock Shell Command
MOCK_SHELL_COMMAND = 'ls'
MOCK_COMMAND_OUTPUT = '/system/bin/ls'.encode('utf-8')
MOCK_DEFAULT_STDOUT = 'out'
MOCK_DEFAULT_STDERR = 'err'
MOCK_DEFAULT_COMMAND_OUTPUT = MOCK_DEFAULT_STDOUT.encode('utf-8')
MOCK_ADB_SHELL_COMMAND_CHECK = 'adb shell command -v ls'


class AdbTest(unittest.TestCase):
    """Unit tests for mobly.controllers.android_device_lib.adb.
    """

    def _mock_process(self, mock_psutil_process, mock_popen):
        # the created proc object in adb._exec_cmd()
        mock_proc = mock.Mock()
        mock_popen.return_value = mock_proc

        # the created process object in adb._exec_cmd()
        mock_psutil_process.return_value = mock.Mock()

        mock_proc.communicate = mock.Mock(
            return_value=(MOCK_DEFAULT_STDOUT.encode('utf-8'),
                          MOCK_DEFAULT_STDERR.encode('utf-8')))
        mock_proc.returncode = 0
        return (mock_psutil_process, mock_popen)

    def _mock_execute_and_process_stdout_process(self, mock_popen):
        # the created proc object in adb._execute_and_process_stdout()
        mock_proc = mock.Mock()
        mock_popen.return_value = mock_proc

        mock_popen.return_value.stdout.readline.side_effect = ['']

        mock_proc.communicate = mock.Mock(
            return_value=('', MOCK_DEFAULT_STDERR.encode('utf-8')))
        mock_proc.returncode = 0
        return mock_popen

    @mock.patch('mobly.utils.run_command')
    def test_exec_cmd_no_timeout_success(self, mock_run_command):
        mock_run_command.return_value = (0,
                                         MOCK_DEFAULT_STDOUT.encode('utf-8'),
                                         MOCK_DEFAULT_STDERR.encode('utf-8'))
        out = adb.AdbProxy()._exec_cmd(['fake_cmd'],
                                       shell=False,
                                       timeout=None,
                                       stderr=None)
        self.assertEqual(MOCK_DEFAULT_STDOUT, out.decode('utf-8'))
        mock_run_command.assert_called_with(['fake_cmd'],
                                            shell=False,
                                            timeout=None)

    @mock.patch('mobly.utils.run_command')
    def test_exec_cmd_error_with_serial(self, mock_run_command):
        # Return 1 for retcode for error.
        mock_run_command.return_value = (1,
                                         MOCK_DEFAULT_STDOUT.encode('utf-8'),
                                         MOCK_DEFAULT_STDERR.encode('utf-8'))
        mock_serial = 'ABCD1234'
        with self.assertRaisesRegex(adb.AdbError,
                                    'Error executing adb cmd .*') as context:
            adb.AdbProxy(mock_serial).fake_cmd()
        self.assertEqual(context.exception.serial, mock_serial)
        self.assertIn(mock_serial, context.exception.cmd)

    @mock.patch('mobly.utils.run_command')
    def test_exec_cmd_error_without_serial(self, mock_run_command):
        # Return 1 for retcode for error.
        mock_run_command.return_value = (1,
                                         MOCK_DEFAULT_STDOUT.encode('utf-8'),
                                         MOCK_DEFAULT_STDERR.encode('utf-8'))
        with self.assertRaisesRegex(adb.AdbError,
                                    'Error executing adb cmd .*') as context:
            adb.AdbProxy()._exec_cmd(['fake_cmd'],
                                     shell=False,
                                     timeout=None,
                                     stderr=None)
        self.assertFalse(context.exception.serial)
        mock_run_command.assert_called_with(['fake_cmd'],
                                            shell=False,
                                            timeout=None)

    @mock.patch('mobly.utils.run_command')
    def test_exec_cmd_with_timeout_success(self, mock_run_command):
        mock_run_command.return_value = (0,
                                         MOCK_DEFAULT_STDOUT.encode('utf-8'),
                                         MOCK_DEFAULT_STDERR.encode('utf-8'))

        out = adb.AdbProxy()._exec_cmd(['fake_cmd'],
                                       shell=False,
                                       timeout=1,
                                       stderr=None)
        self.assertEqual(MOCK_DEFAULT_STDOUT, out.decode('utf-8'))
        mock_run_command.assert_called_with(['fake_cmd'],
                                            shell=False,
                                            timeout=1)

    @mock.patch('mobly.utils.run_command')
    def test_exec_cmd_timed_out(self, mock_run_command):
        mock_run_command.side_effect = adb.psutil.TimeoutExpired('Timed out')
        mock_serial = '1234Abcd'
        with self.assertRaisesRegex(
                adb.AdbTimeoutError, 'Timed out executing command "adb -s '
                '1234Abcd fake-cmd" after 0.01s.') as context:
            adb.AdbProxy(mock_serial).fake_cmd(timeout=0.01)
        self.assertEqual(context.exception.serial, mock_serial)
        self.assertIn(mock_serial, context.exception.cmd)

    @mock.patch('mobly.utils.run_command')
    def test_exec_cmd_timed_out_without_serial(self, mock_run_command):
        mock_run_command.side_effect = adb.psutil.TimeoutExpired('Timed out')
        with self.assertRaisesRegex(
                adb.AdbTimeoutError, 'Timed out executing command "adb '
                'fake-cmd" after 0.01s.') as context:
            adb.AdbProxy().fake_cmd(timeout=0.01)

    def test_exec_cmd_with_negative_timeout_value(self):
        with self.assertRaisesRegex(ValueError,
                                    'Timeout is not a positive value: -1'):
            adb.AdbProxy()._exec_cmd(['fake_cmd'],
                                     shell=False,
                                     timeout=-1,
                                     stderr=None)

    @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
    def test_execute_and_process_stdout_reads_stdout(self, mock_popen):
        self._mock_execute_and_process_stdout_process(mock_popen)
        mock_popen.return_value.stdout.readline.side_effect = ['1', '2', '']
        mock_handler = mock.MagicMock()

        err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
                                                         shell=False,
                                                         handler=mock_handler)
        self.assertEqual(mock_handler.call_count, 2)
        mock_handler.assert_any_call('1')
        mock_handler.assert_any_call('2')

    @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
    def test_execute_and_process_stdout_reads_unexpected_stdout(
            self, mock_popen):
        unexpected_stdout = MOCK_DEFAULT_STDOUT.encode('utf-8')

        self._mock_execute_and_process_stdout_process(mock_popen)
        mock_handler = mock.MagicMock()
        mock_popen.return_value.communicate = mock.Mock(
            return_value=(unexpected_stdout,
                          MOCK_DEFAULT_STDERR.encode('utf-8')))

        err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
                                                         shell=False,
                                                         handler=mock_handler)
        self.assertEqual(mock_handler.call_count, 1)
        mock_handler.assert_called_with(unexpected_stdout)

    @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
    @mock.patch('logging.debug')
    def test_execute_and_process_stdout_logs_cmd(self, mock_debug_logger,
                                                 mock_popen):
        raw_expected_stdout = ''
        expected_stdout = '[elided, processed via handler]'
        expected_stderr = MOCK_DEFAULT_STDERR.encode('utf-8')
        self._mock_execute_and_process_stdout_process(mock_popen)
        mock_popen.return_value.communicate = mock.Mock(
            return_value=(raw_expected_stdout, expected_stderr))

        err = adb.AdbProxy()._execute_and_process_stdout(
            ['fake_cmd'], shell=False, handler=mock.MagicMock())
        mock_debug_logger.assert_called_with(
            'cmd: %s, stdout: %s, stderr: %s, ret: %s', 'fake_cmd',
            expected_stdout, expected_stderr, 0)

    @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
    @mock.patch('logging.debug')
    def test_execute_and_process_stdout_logs_cmd_with_unexpected_stdout(
            self, mock_debug_logger, mock_popen):
        raw_expected_stdout = MOCK_DEFAULT_STDOUT.encode('utf-8')
        expected_stdout = '[unexpected stdout] %s' % raw_expected_stdout
        expected_stderr = MOCK_DEFAULT_STDERR.encode('utf-8')

        self._mock_execute_and_process_stdout_process(mock_popen)
        mock_popen.return_value.communicate = mock.Mock(
            return_value=(raw_expected_stdout, expected_stderr))

        err = adb.AdbProxy()._execute_and_process_stdout(
            ['fake_cmd'], shell=False, handler=mock.MagicMock())
        mock_debug_logger.assert_called_with(
            'cmd: %s, stdout: %s, stderr: %s, ret: %s', 'fake_cmd',
            expected_stdout, expected_stderr, 0)

    @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
    def test_execute_and_process_stdout_despite_cmd_exits(self, mock_popen):
        self._mock_execute_and_process_stdout_process(mock_popen)
        mock_popen.return_value.poll.side_effect = [None, 0]
        mock_popen.return_value.stdout.readline.side_effect = [
            '1', '2', '3', ''
        ]
        mock_handler = mock.MagicMock()

        err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
                                                         shell=False,
                                                         handler=mock_handler)

        self.assertEqual(mock_handler.call_count, 3)
        mock_handler.assert_any_call('1')
        mock_handler.assert_any_call('2')
        mock_handler.assert_any_call('3')

    @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
    def test_execute_and_process_stdout_when_cmd_eof(self, mock_popen):
        self._mock_execute_and_process_stdout_process(mock_popen)
        mock_popen.return_value.stdout.readline.side_effect = [
            '1', '2', '3', ''
        ]
        mock_handler = mock.MagicMock()

        err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
                                                         shell=False,
                                                         handler=mock_handler)

        self.assertEqual(mock_handler.call_count, 3)
        mock_handler.assert_any_call('1')
        mock_handler.assert_any_call('2')
        mock_handler.assert_any_call('3')

    @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
    def test_execute_and_process_stdout_returns_stderr(self, mock_popen):
        self._mock_execute_and_process_stdout_process(mock_popen)

        err = adb.AdbProxy()._execute_and_process_stdout(
            ['fake_cmd'], shell=False, handler=mock.MagicMock())
        self.assertEqual(MOCK_DEFAULT_STDERR, err.decode('utf-8'))

    @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
    def test_execute_and_process_stdout_raises_adb_error(self, mock_popen):
        self._mock_execute_and_process_stdout_process(mock_popen)
        mock_popen.return_value.returncode = 1

        with self.assertRaisesRegex(adb.AdbError,
                                    'Error executing adb cmd .*'):
            err = adb.AdbProxy()._execute_and_process_stdout(
                ['fake_cmd'], shell=False, handler=mock.MagicMock())

    @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
    def test_execute_and_process_stdout_when_handler_crash(self, mock_popen):
        self._mock_execute_and_process_stdout_process(mock_popen)
        mock_popen.return_value.stdout.readline.side_effect = [
            '1', '2', '3', ''
        ]
        mock_handler = mock.MagicMock()
        mock_handler.side_effect = ['', TypeError('fake crash'), '', '']

        with self.assertRaisesRegex(TypeError, 'fake crash'):
            err = adb.AdbProxy()._execute_and_process_stdout(
                ['fake_cmd'], shell=False, handler=mock_handler)

        mock_popen.return_value.communicate.assert_called_once_with()

    def test_construct_adb_cmd(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
                                                    'arg1',
                                                    shell=False)
        self.assertEqual(adb_cmd, ['adb', 'shell', 'arg1'])

    def test_construct_adb_cmd_with_one_command(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd(
            'shell ls /asdafsfd/asdf-asfd/asa', [], shell=False)
        self.assertEqual(adb_cmd, ['adb', 'shell ls /asdafsfd/asdf-asfd/asa'])

    def test_construct_adb_cmd_with_one_arg_command(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd(
            'shell', 'ls /asdafsfd/asdf-asfd/asa', shell=False)
        self.assertEqual(adb_cmd,
                         ['adb', 'shell', 'ls /asdafsfd/asdf-asfd/asa'])

    def test_construct_adb_cmd_with_one_arg_command_list(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd(
            'shell', ['ls /asdafsfd/asdf-asfd/asa'], shell=False)
        self.assertEqual(adb_cmd,
                         ['adb', 'shell', 'ls /asdafsfd/asdf-asfd/asa'])

    def test_construct_adb_cmd_with_special_characters(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
                                                    ['a b', '"blah"', r'\/\/'],
                                                    shell=False)
        self.assertEqual(adb_cmd, ['adb', 'shell', 'a b', '"blah"', r"\/\/"])

    def test_construct_adb_cmd_with_serial(self):
        adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd('shell',
                                                           'arg1',
                                                           shell=False)
        self.assertEqual(adb_cmd, ['adb', '-s', '12345', 'shell', 'arg1'])

    def test_construct_adb_cmd_with_list(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell', ['arg1', 'arg2'],
                                                    shell=False)
        self.assertEqual(adb_cmd, ['adb', 'shell', 'arg1', 'arg2'])

    def test_construct_adb_cmd_with_serial_with_list(self):
        adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd('shell',
                                                           ['arg1', 'arg2'],
                                                           shell=False)
        self.assertEqual(adb_cmd,
                         ['adb', '-s', '12345', 'shell', 'arg1', 'arg2'])

    def test_construct_adb_cmd_with_shell_true(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
                                                    'arg1 arg2',
                                                    shell=True)
        self.assertEqual(adb_cmd, '"adb" shell arg1 arg2')

    def test_construct_adb_cmd_with_shell_true_with_one_command(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd(
            'shell ls /asdafsfd/asdf-asfd/asa', [], shell=True)
        self.assertEqual(adb_cmd, '"adb" shell ls /asdafsfd/asdf-asfd/asa ')

    def test_construct_adb_cmd_with_shell_true_with_one_arg_command(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd(
            'shell', 'ls /asdafsfd/asdf-asfd/asa', shell=True)
        self.assertEqual(adb_cmd, '"adb" shell ls /asdafsfd/asdf-asfd/asa')

    def test_construct_adb_cmd_with_shell_true_with_one_arg_command_list(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd(
            'shell', ['ls /asdafsfd/asdf-asfd/asa'], shell=True)
        self.assertEqual(adb_cmd, '"adb" shell \'ls /asdafsfd/asdf-asfd/asa\'')

    def test_construct_adb_cmd_with_shell_true_with_auto_quotes(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
                                                    ['a b', '"blah"', r'\/\/'],
                                                    shell=True)
        self.assertEqual(adb_cmd, '"adb" shell \'a b\' \'"blah"\' \'\\/\\/\'')

    def test_construct_adb_cmd_with_shell_true_with_serial(self):
        adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd('shell',
                                                           'arg1 arg2',
                                                           shell=True)
        self.assertEqual(adb_cmd, '"adb" -s "12345" shell arg1 arg2')

    def test_construct_adb_cmd_with_shell_true_with_list(self):
        adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell', ['arg1', 'arg2'],
                                                    shell=True)
        self.assertEqual(adb_cmd, '"adb" shell arg1 arg2')

    def test_construct_adb_cmd_with_shell_true_with_serial_with_list(self):
        adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd('shell',
                                                           ['arg1', 'arg2'],
                                                           shell=True)
        self.assertEqual(adb_cmd, '"adb" -s "12345" shell arg1 arg2')

    def test_exec_adb_cmd(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
            adb.AdbProxy().shell(['arg1', 'arg2'])
            mock_exec_cmd.assert_called_once_with(
                ['adb', 'shell', 'arg1', 'arg2'],
                shell=False,
                timeout=None,
                stderr=None)

    def test_exec_adb_cmd_with_shell_true(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
            adb.AdbProxy().shell('arg1 arg2', shell=True)
            mock_exec_cmd.assert_called_once_with('"adb" shell arg1 arg2',
                                                  shell=True,
                                                  timeout=None,
                                                  stderr=None)

    def test_exec_adb_cmd_formats_command(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            with mock.patch.object(
                    adb.AdbProxy,
                    '_construct_adb_cmd') as mock_construct_adb_cmd:
                mock_adb_cmd = mock.MagicMock()
                mock_adb_args = mock.MagicMock()
                mock_construct_adb_cmd.return_value = mock_adb_cmd
                mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT

                adb.AdbProxy().shell(mock_adb_args)
                mock_construct_adb_cmd.assert_called_once_with('shell',
                                                               mock_adb_args,
                                                               shell=False)
                mock_exec_cmd.assert_called_once_with(mock_adb_cmd,
                                                      shell=False,
                                                      timeout=None,
                                                      stderr=None)

    def test_exec_adb_cmd_formats_command_with_shell_true(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            with mock.patch.object(
                    adb.AdbProxy,
                    '_construct_adb_cmd') as mock_construct_adb_cmd:
                mock_adb_cmd = mock.MagicMock()
                mock_adb_args = mock.MagicMock()
                mock_construct_adb_cmd.return_value = mock_adb_cmd

                adb.AdbProxy().shell(mock_adb_args, shell=True)
                mock_construct_adb_cmd.assert_called_once_with('shell',
                                                               mock_adb_args,
                                                               shell=True)
                mock_exec_cmd.assert_called_once_with(mock_adb_cmd,
                                                      shell=True,
                                                      timeout=None,
                                                      stderr=None)

    def test_execute_adb_and_process_stdout_formats_command(self):
        with mock.patch.object(adb.AdbProxy, '_execute_and_process_stdout'
                               ) as mock_execute_and_process_stdout:
            with mock.patch.object(
                    adb.AdbProxy,
                    '_construct_adb_cmd') as mock_construct_adb_cmd:
                mock_adb_cmd = mock.MagicMock()
                mock_adb_args = mock.MagicMock()
                mock_handler = mock.MagicMock()
                mock_construct_adb_cmd.return_value = mock_adb_cmd

                adb.AdbProxy()._execute_adb_and_process_stdout(
                    'shell', mock_adb_args, shell=False, handler=mock_handler)
                mock_construct_adb_cmd.assert_called_once_with('shell',
                                                               mock_adb_args,
                                                               shell=False)
                mock_execute_and_process_stdout.assert_called_once_with(
                    mock_adb_cmd, shell=False, handler=mock_handler)

    @mock.patch('mobly.utils.run_command')
    def test_exec_adb_cmd_with_stderr_pipe(self, mock_run_command):
        mock_run_command.return_value = (0,
                                         MOCK_DEFAULT_STDOUT.encode('utf-8'),
                                         MOCK_DEFAULT_STDERR.encode('utf-8'))
        stderr_redirect = io.BytesIO()
        out = adb.AdbProxy().shell('arg1 arg2',
                                   shell=True,
                                   stderr=stderr_redirect)
        self.assertEqual(MOCK_DEFAULT_STDOUT, out.decode('utf-8'))
        self.assertEqual(MOCK_DEFAULT_STDERR,
                         stderr_redirect.getvalue().decode('utf-8'))

    def test_getprop(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.return_value = b'blah'
            self.assertEqual(adb.AdbProxy().getprop('haha'), 'blah')
            mock_exec_cmd.assert_called_once_with(
                ['adb', 'shell', 'getprop', 'haha'],
                shell=False,
                stderr=None,
                timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC)

    def test__parse_getprop_output_special_values(self):
        mock_adb_output = (
            b'[selinux.restorecon_recursive]: [/data/misc_ce/10]\n'
            b'[selinux.abc]: [key: value]\n'  # "key: value" as value
            b'[persist.sys.boot.reason.history]: [reboot,adb,1558549857\n'
            b'reboot,factory_reset,1558483886\n'  # multi-line value
            b'reboot,1558483823]\n'
            b'[persist.something]: [haha\n'
            b']\n'
            b'[[wrapped.key]]: [[wrapped value]]\n'
            b'[persist.byte]: [J\xaa\x8bb\xab\x9dP\x0f]\n'  # non-decodable
        )
        parsed_props = adb.AdbProxy()._parse_getprop_output(mock_adb_output)
        expected_output = {
            'persist.sys.boot.reason.history':
            ('reboot,adb,1558549857\nreboot,factory_reset,1558483886\n'
             'reboot,1558483823'),
            'selinux.abc':
            'key: value',
            'persist.something':
            'haha\n',
            'selinux.restorecon_recursive':
            '/data/misc_ce/10',
            '[wrapped.key]':
            '[wrapped value]',
            'persist.byte':
            'JbP\x0f',
        }
        self.assertEqual(parsed_props, expected_output)

    def test__parse_getprop_output_malformat_output(self):
        mock_adb_output = (
            b'[selinux.restorecon_recursive][/data/misc_ce/10]\n'  # Malformat
            b'[persist.sys.boot.reason]: [reboot,adb,1558549857]\n'
            b'[persist.something]: [haha]\n')
        parsed_props = adb.AdbProxy()._parse_getprop_output(mock_adb_output)
        expected_output = {
            'persist.sys.boot.reason': 'reboot,adb,1558549857',
            'persist.something': 'haha'
        }
        self.assertEqual(parsed_props, expected_output)

    def test__parse_getprop_output_special_line_separator(self):
        mock_adb_output = (
            b'[selinux.restorecon_recursive][/data/misc_ce/10]\r\n'  # Malformat
            b'[persist.sys.boot.reason]: [reboot,adb,1558549857]\r\n'
            b'[persist.something]: [haha]\r\n')
        parsed_props = adb.AdbProxy()._parse_getprop_output(mock_adb_output)
        expected_output = {
            'persist.sys.boot.reason': 'reboot,adb,1558549857',
            'persist.something': 'haha'
        }
        self.assertEqual(parsed_props, expected_output)

    @mock.patch('time.sleep', return_value=mock.MagicMock())
    def test_getprops(self, mock_sleep):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.return_value = (
                b'\n[sendbug.preferred.domain]: [google.com]\n'
                b'[sys.uidcpupower]: []\n'
                b'[sys.wifitracing.started]: [1]\n'
                b'[telephony.lteOnCdmaDevice]: [1]\n\n')
            actual_output = adb.AdbProxy().getprops([
                'sys.wifitracing.started',  # "numeric" value
                'sys.uidcpupower',  # empty value
                'sendbug.preferred.domain',  # string value
                'nonExistentProp'
            ])
            self.assertEqual(
                actual_output, {
                    'sys.wifitracing.started': '1',
                    'sys.uidcpupower': '',
                    'sendbug.preferred.domain': 'google.com'
                })
            mock_exec_cmd.assert_called_once_with(
                ['adb', 'shell', 'getprop'],
                shell=False,
                stderr=None,
                timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC)
            mock_sleep.assert_not_called()

    @mock.patch('time.sleep', return_value=mock.MagicMock())
    def test_getprops_when_empty_string_randomly_returned(self, mock_sleep):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.side_effect = [
                b'',
                (b'\n[ro.build.id]: [AB42]\n'
                 b'[ro.build.type]: [userdebug]\n\n')
            ]
            actual_output = adb.AdbProxy().getprops(['ro.build.id'])
            self.assertEqual(actual_output, {
                'ro.build.id': 'AB42',
            })
            self.assertEqual(mock_exec_cmd.call_count, 2)
            mock_exec_cmd.assert_called_with(
                ['adb', 'shell', 'getprop'],
                shell=False,
                stderr=None,
                timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC)
            self.assertEqual(mock_sleep.call_count, 1)
            mock_sleep.assert_called_with(1)

    @mock.patch('time.sleep', return_value=mock.MagicMock())
    def test_getprops_when_empty_string_always_returned(self, mock_sleep):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.return_value = b''
            actual_output = adb.AdbProxy().getprops(['ro.build.id'])
            self.assertEqual(actual_output, {})
            self.assertEqual(mock_exec_cmd.call_count, 3)
            mock_exec_cmd.assert_called_with(
                ['adb', 'shell', 'getprop'],
                shell=False,
                stderr=None,
                timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC)
            self.assertEqual(mock_sleep.call_count, 2)
            mock_sleep.assert_called_with(1)

    def test_forward(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            adb.AdbProxy().forward(MOCK_SHELL_COMMAND)

    def test_instrument_without_parameters(self):
        """Verifies the AndroidDevice object's instrument command is correct in
        the basic case.
        """
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            output = adb.AdbProxy().instrument(MOCK_INSTRUMENTATION_PACKAGE)
            mock_exec_cmd.assert_called_once_with(
                ['adb', 'shell', MOCK_BASIC_INSTRUMENTATION_COMMAND],
                shell=False,
                timeout=None,
                stderr=None)
            self.assertEqual(output, mock_exec_cmd.return_value)

    def test_instrument_with_runner(self):
        """Verifies the AndroidDevice object's instrument command is correct
        with a runner specified.
        """
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            stdout = adb.AdbProxy().instrument(
                MOCK_INSTRUMENTATION_PACKAGE,
                runner=MOCK_INSTRUMENTATION_RUNNER)
            mock_exec_cmd.assert_called_once_with(
                ['adb', 'shell', MOCK_RUNNER_INSTRUMENTATION_COMMAND],
                shell=False,
                timeout=None,
                stderr=None)
            self.assertEqual(stdout, mock_exec_cmd.return_value)

    def test_instrument_with_options(self):
        """Verifies the AndroidDevice object's instrument command is correct
        with options.
        """
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            stdout = adb.AdbProxy().instrument(
                MOCK_INSTRUMENTATION_PACKAGE,
                options=MOCK_INSTRUMENTATION_OPTIONS)
            mock_exec_cmd.assert_called_once_with(
                ['adb', 'shell', MOCK_OPTIONS_INSTRUMENTATION_COMMAND],
                shell=False,
                timeout=None,
                stderr=None)
            self.assertEqual(stdout, mock_exec_cmd.return_value)

    def test_instrument_with_handler(self):
        """Verifies the AndroidDevice object's instrument command is correct
        with a handler passed in.
        """

        def mock_handler(raw_line):
            pass

        with mock.patch.object(adb.AdbProxy, '_execute_and_process_stdout'
                               ) as mock_execute_and_process_stdout:
            stderr = adb.AdbProxy().instrument(MOCK_INSTRUMENTATION_PACKAGE,
                                               handler=mock_handler)
            mock_execute_and_process_stdout.assert_called_once_with(
                ['adb', 'shell', MOCK_BASIC_INSTRUMENTATION_COMMAND],
                shell=False,
                handler=mock_handler)
            self.assertEqual(stderr,
                             mock_execute_and_process_stdout.return_value)

    def test_instrument_with_handler_with_runner(self):
        """Verifies the AndroidDevice object's instrument command is correct
        with a handler passed in and a runner specified.
        """

        def mock_handler(raw_line):
            pass

        with mock.patch.object(adb.AdbProxy, '_execute_and_process_stdout'
                               ) as mock_execute_and_process_stdout:
            stderr = adb.AdbProxy().instrument(
                MOCK_INSTRUMENTATION_PACKAGE,
                runner=MOCK_INSTRUMENTATION_RUNNER,
                handler=mock_handler)
            mock_execute_and_process_stdout.assert_called_once_with(
                ['adb', 'shell', MOCK_RUNNER_INSTRUMENTATION_COMMAND],
                shell=False,
                handler=mock_handler)
            self.assertEqual(stderr,
                             mock_execute_and_process_stdout.return_value)

    def test_instrument_with_handler_with_options(self):
        """Verifies the AndroidDevice object's instrument command is correct
        with a handler passed in and options.
        """

        def mock_handler(raw_line):
            pass

        with mock.patch.object(adb.AdbProxy, '_execute_and_process_stdout'
                               ) as mock_execute_and_process_stdout:
            stderr = adb.AdbProxy().instrument(
                MOCK_INSTRUMENTATION_PACKAGE,
                options=MOCK_INSTRUMENTATION_OPTIONS,
                handler=mock_handler)
            mock_execute_and_process_stdout.assert_called_once_with(
                ['adb', 'shell', MOCK_OPTIONS_INSTRUMENTATION_COMMAND],
                shell=False,
                handler=mock_handler)
            self.assertEqual(stderr,
                             mock_execute_and_process_stdout.return_value)

    @mock.patch.object(adb.AdbProxy, '_exec_cmd')
    def test_root_success(self, mock_exec_cmd):
        mock_exec_cmd.return_value = MOCK_ROOT_SUCCESS_OUTPUT
        output = adb.AdbProxy().root()
        mock_exec_cmd.assert_called_once_with(
            ['adb', 'root'],
            shell=False,
            timeout=None,
            stderr=None)
        self.assertEqual(output, MOCK_ROOT_SUCCESS_OUTPUT)

    @mock.patch('time.sleep', return_value=mock.MagicMock())
    @mock.patch.object(adb.AdbProxy, '_exec_cmd')
    def test_root_success_with_retry(self, mock_exec_cmd, mock_sleep):
        mock_exec_cmd.side_effect = [
            adb.AdbError('adb root', '', MOCK_ROOT_ERROR_OUTPUT, 1),
            MOCK_ROOT_SUCCESS_OUTPUT]
        output = adb.AdbProxy().root()
        mock_exec_cmd.assert_called_with(
            ['adb', 'root'],
            shell=False,
            timeout=None,
            stderr=None)
        self.assertEqual(output, MOCK_ROOT_SUCCESS_OUTPUT)
        self.assertEqual(mock_sleep.call_count, 1)
        mock_sleep.assert_called_with(10)

    @mock.patch('time.sleep', return_value=mock.MagicMock())
    @mock.patch.object(adb.AdbProxy, '_exec_cmd')
    def test_root_raises_adb_error_when_all_retries_failed(self, mock_exec_cmd,
                                                           mock_sleep):
        mock_exec_cmd.side_effect = adb.AdbError('adb root',
                                                 '',
                                                 MOCK_ROOT_ERROR_OUTPUT,
                                                 1)
        expected_msg = ('Error executing adb cmd "adb root". '
                        'ret: 1, stdout: , stderr: %s' %
                        MOCK_ROOT_ERROR_OUTPUT)
        with self.assertRaisesRegex(adb.AdbError, expected_msg):
            adb.AdbProxy().root()
            mock_exec_cmd.assert_called_with(
                ['adb', 'root'],
                shell=False,
                timeout=None,
                stderr=None)
        self.assertEqual(mock_sleep.call_count, 2)
        mock_sleep.assert_called_with(10)

    def test_has_shell_command_called_correctly(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
            adb.AdbProxy().has_shell_command(MOCK_SHELL_COMMAND)
            mock_exec_cmd.assert_called_once_with(
                ['adb', 'shell', 'command', '-v', MOCK_SHELL_COMMAND],
                shell=False,
                timeout=None,
                stderr=None)

    def test_has_shell_command_with_existing_command(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.return_value = MOCK_COMMAND_OUTPUT
            self.assertTrue(
                adb.AdbProxy().has_shell_command(MOCK_SHELL_COMMAND))

    def test_has_shell_command_with_missing_command_on_older_devices(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
            mock_exec_cmd.side_effect = adb.AdbError(
                MOCK_ADB_SHELL_COMMAND_CHECK, '', '', 0)
            self.assertFalse(
                adb.AdbProxy().has_shell_command(MOCK_SHELL_COMMAND))

    def test_has_shell_command_with_missing_command_on_newer_devices(self):
        with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
            mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
            mock_exec_cmd.side_effect = adb.AdbError(
                MOCK_ADB_SHELL_COMMAND_CHECK, '', '', 1)
            self.assertFalse(
                adb.AdbProxy().has_shell_command(MOCK_SHELL_COMMAND))

    @mock.patch.object(adb.AdbProxy, 'getprop')
    @mock.patch.object(adb.AdbProxy, '_exec_cmd')
    def test_current_user_id_25_and_above(self, mock_exec_cmd, mock_getprop):
        mock_getprop.return_value = b'25'
        mock_exec_cmd.return_value = b'123'
        user_id = adb.AdbProxy().current_user_id
        mock_exec_cmd.assert_called_once_with(
            ['adb', 'shell', 'am', 'get-current-user'],
            shell=False,
            stderr=None,
            timeout=None)
        self.assertEqual(user_id, 123)

    @mock.patch.object(adb.AdbProxy, 'getprop')
    @mock.patch.object(adb.AdbProxy, '_exec_cmd')
    def test_current_user_id_between_21_and_24(self, mock_exec_cmd,
                                               mock_getprop):
        mock_getprop.return_value = b'23'
        mock_exec_cmd.return_value = (b'Users:\n'
                                      b'UserInfo{123:Owner:13} serialNo=0\n'
                                      b'Created: <unknown>\n'
                                      b'Last logged in: +1h22m12s497ms ago\n'
                                      b'UserInfo{456:Owner:14} serialNo=0\n'
                                      b'Created: <unknown>\n'
                                      b'Last logged in: +1h01m12s497ms ago\n')
        user_id = adb.AdbProxy().current_user_id
        mock_exec_cmd.assert_called_once_with(
            ['adb', 'shell', 'dumpsys', 'user'],
            shell=False,
            stderr=None,
            timeout=None)
        self.assertEqual(user_id, 123)


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