| # |
| # Copyright (C) 2024 The Android Open Source Project |
| # |
| # 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 unittest |
| import os |
| import subprocess |
| from unittest import mock |
| from command import ProfilerCommand |
| from device import AdbDevice |
| |
| TEST_DEVICE_SERIAL = "test-device-serial" |
| TEST_DEVICE_SERIAL2 = "test-device-serial2" |
| TEST_FILE_PATH = "test-file-path" |
| TEST_STRING_FILE = "test-string-file" |
| TEST_FAILURE_MSG = "test-failure" |
| TEST_EXCEPTION = Exception(TEST_FAILURE_MSG) |
| TEST_USER_ID_1 = 0 |
| TEST_USER_ID_2 = 1 |
| TEST_USER_ID_3 = 2 |
| TEST_PACKAGE_1 = "test-package-1" |
| TEST_PACKAGE_2 = "test-package-2" |
| TEST_PROP = "test-prop" |
| TEST_PROP_VALUE = "test-prop-value" |
| TEST_PID_OUTPUT = b"8241\n" |
| BOOT_COMPLETE_OUTPUT = b"1\n" |
| ANDROID_SDK_VERSION_T = 33 |
| |
| class DeviceUnitTest(unittest.TestCase): |
| |
| @staticmethod |
| def generate_adb_devices_result(devices, adb_started=True): |
| devices = [device.encode('utf-8') for device in devices] |
| stdout_string = b'List of devices attached\n' |
| if not adb_started: |
| stdout_string = (b'* daemon not running; starting now at tcp:1234\n' |
| b'* daemon started successfully\n') + stdout_string |
| if len(devices) > 0: |
| stdout_string += b'\tdevice\n'.join(devices) + b'\tdevice\n' |
| stdout_string += b'\n' |
| return subprocess.CompletedProcess(args=['adb', 'devices'], returncode=0, |
| stdout=stdout_string) |
| |
| @staticmethod |
| def generate_mock_completed_process(stdout_string=b'\n', stderr_string=b'\n'): |
| return mock.create_autospec(subprocess.CompletedProcess, instance=True, |
| stdout=stdout_string, stderr=stderr_string) |
| |
| @staticmethod |
| def subprocess_output(first_return_value, polling_return_value): |
| # Mocking the return value of a call to adb root and the return values of |
| # many followup calls to adb devices |
| yield first_return_value |
| while True: |
| yield polling_return_value |
| |
| @staticmethod |
| def mock_users(): |
| return mock.create_autospec(subprocess.CompletedProcess, instance=True, |
| stdout=(b'Users:\n\tUserInfo{%d:Driver:813}' |
| b' running\n\tUserInfo{%d:Driver:412}\n' |
| % (TEST_USER_ID_1, TEST_USER_ID_2))) |
| |
| @staticmethod |
| def mock_packages(): |
| return mock.create_autospec(subprocess.CompletedProcess, instance=True, |
| stdout=(b'package:%b\npackage:%b\n' |
| % (TEST_PACKAGE_1.encode("utf-8"), |
| TEST_PACKAGE_2.encode("utf-8")))) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_adb_devices_returns_devices(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([TEST_DEVICE_SERIAL, |
| TEST_DEVICE_SERIAL2])) |
| adbDevice = AdbDevice(None) |
| |
| devices = adbDevice.get_adb_devices() |
| |
| self.assertEqual(len(devices), 2) |
| self.assertEqual(devices[0], TEST_DEVICE_SERIAL) |
| self.assertEqual(devices[1], TEST_DEVICE_SERIAL2) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_adb_devices_returns_devices_and_adb_not_started(self, |
| mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([TEST_DEVICE_SERIAL, |
| TEST_DEVICE_SERIAL2], False)) |
| adbDevice = AdbDevice(None) |
| |
| devices = adbDevice.get_adb_devices() |
| |
| self.assertEqual(len(devices), 2) |
| self.assertEqual(devices[0], TEST_DEVICE_SERIAL) |
| self.assertEqual(devices[1], TEST_DEVICE_SERIAL2) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_adb_devices_returns_no_device(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_adb_devices_result([]) |
| adbDevice = AdbDevice(None) |
| |
| devices = adbDevice.get_adb_devices() |
| |
| self.assertEqual(devices, []) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_adb_devices_returns_no_device_and_adb_not_started(self, |
| mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([], False)) |
| adbDevice = AdbDevice(None) |
| |
| devices = adbDevice.get_adb_devices() |
| |
| self.assertEqual(devices, []) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_adb_devices_command_failure_error(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(None) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.get_adb_devices() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_check_device_connection_serial_arg_in_devices(self, |
| mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| error = adbDevice.check_device_connection() |
| |
| self.assertEqual(error, None) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_check_device_connection_serial_arg_not_in_devices_error(self, |
| mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) |
| invalid_device_serial = "invalid-device-serial" |
| adbDevice = AdbDevice(invalid_device_serial) |
| |
| error = adbDevice.check_device_connection() |
| |
| self.assertNotEqual(error, None) |
| self.assertEqual(error.message, ("Device with serial %s is not connected." |
| % invalid_device_serial)) |
| self.assertEqual(error.suggestion, None) |
| |
| @mock.patch.dict(os.environ, {"ANDROID_SERIAL": TEST_DEVICE_SERIAL}, |
| clear=True) |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_check_device_connection_env_variable_in_devices(self, |
| mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) |
| adbDevice = AdbDevice(None) |
| |
| error = adbDevice.check_device_connection() |
| |
| self.assertEqual(error, None) |
| self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL) |
| |
| @mock.patch.dict(os.environ, {"ANDROID_SERIAL": "invalid-device-serial"}, |
| clear=True) |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_check_device_connection_env_variable_not_in_devices_error(self, |
| mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) |
| adbDevice = AdbDevice(None) |
| |
| error = adbDevice.check_device_connection() |
| |
| self.assertNotEqual(error, None) |
| self.assertEqual(error.message, ("Device with serial invalid-device-serial" |
| " is set as environment variable," |
| " ANDROID_SERIAL, but is not connected.")) |
| self.assertEqual(error.suggestion, None) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_check_device_connection_adb_devices_command_fails_error(self, |
| mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(None) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.check_device_connection() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_check_device_connection_no_devices_connected_error(self, |
| mock_subprocess_run): |
| mock_subprocess_run.return_value = (self.generate_adb_devices_result([])) |
| adbDevice = AdbDevice(None) |
| |
| error = adbDevice.check_device_connection() |
| |
| self.assertNotEqual(error, None) |
| self.assertEqual(error.message, "There are currently no devices connected.") |
| self.assertEqual(error.suggestion, None) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_check_device_connection_no_devices_connected_adb_not_started_error( |
| self, mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([], False)) |
| adbDevice = AdbDevice(None) |
| |
| error = adbDevice.check_device_connection() |
| |
| self.assertNotEqual(error, None) |
| self.assertEqual(error.message, "There are currently no devices connected.") |
| self.assertEqual(error.suggestion, None) |
| |
| @mock.patch.dict(os.environ, {}, clear=True) |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_check_device_connection_only_one_device(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) |
| adbDevice = AdbDevice(None) |
| |
| error = adbDevice.check_device_connection() |
| |
| self.assertEqual(error, None) |
| self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL) |
| |
| @mock.patch.dict(os.environ, {}, clear=True) |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_check_device_connection_multiple_devices_error(self, |
| mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_adb_devices_result([TEST_DEVICE_SERIAL, |
| TEST_DEVICE_SERIAL2])) |
| adbDevice = AdbDevice(None) |
| |
| error = adbDevice.check_device_connection() |
| |
| self.assertNotEqual(error, None) |
| self.assertEqual(error.message, ("There is more than one device currently" |
| " connected.")) |
| self.assertEqual(error.suggestion, ("Run one of the following commands to" |
| " choose one of the connected devices:" |
| "\n\t torq --serial %s" |
| "\n\t torq --serial %s" |
| % (TEST_DEVICE_SERIAL, |
| TEST_DEVICE_SERIAL2))) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_root_device_success(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = [ |
| self.generate_mock_completed_process(), |
| self.generate_adb_devices_result([TEST_DEVICE_SERIAL])] |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.root_device() |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_root_device_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.root_device() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_root_device_times_out_error(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = lambda args, capture_output=True: ( |
| next(self.subprocess_output(self.generate_adb_devices_result([]), |
| self.generate_mock_completed_process()))) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.root_device() |
| |
| self.assertEqual(str(e.exception), ("Device with serial %s took too long to" |
| " reconnect after being rooted." |
| % TEST_DEVICE_SERIAL)) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_root_device_and_adb_devices_fails_error(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = [self.generate_mock_completed_process(), |
| TEST_EXCEPTION] |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.root_device() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_remove_file_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.remove_file(TEST_FILE_PATH) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_remove_file_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.remove_file(TEST_FILE_PATH) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "Popen", autospec=True) |
| def test_start_perfetto_trace_success(self, mock_subprocess_popen): |
| # Mocking the return value of subprocess.Popen to ensure it's |
| # not modified and returned by AdbDevice.start_perfetto_trace |
| mock_subprocess_popen.return_value = mock.Mock() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| mock_process = adbDevice.start_perfetto_trace(None) |
| |
| # No exception is expected to be thrown |
| self.assertEqual(mock_process, mock_subprocess_popen.return_value) |
| |
| @mock.patch.object(subprocess, "Popen", autospec=True) |
| def test_start_perfetto_trace_failure(self, mock_subprocess_popen): |
| mock_subprocess_popen.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.start_perfetto_trace(None) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "Popen", autospec=True) |
| def test_start_simpleperf_trace_success(self, mock_subprocess_popen): |
| # Mocking the return value of subprocess.Popen to ensure it's |
| # not modified and returned by AdbDevice.start_simpleperf_trace |
| mock_subprocess_popen.return_value = mock.Mock() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| command = ProfilerCommand("profiler", "custom", None, None, |
| 10000, None, None, ["cpu-cycles"], None, None, |
| None, None, None, None, None) |
| mock_process = adbDevice.start_simpleperf_trace(command) |
| |
| # No exception is expected to be thrown |
| self.assertEqual(mock_process, mock_subprocess_popen.return_value) |
| |
| @mock.patch.object(subprocess, "Popen", autospec=True) |
| def test_start_simpleperf_trace_failure(self, mock_subprocess_popen): |
| mock_subprocess_popen.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| command = ProfilerCommand("profiler", "custom", None, None, |
| 10000, None, None, ["cpu-cycles"], None, None, |
| None, None, None, None, None) |
| with self.assertRaises(Exception) as e: |
| adbDevice.start_simpleperf_trace(command) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_pull_file_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.pull_file(TEST_FILE_PATH, TEST_FILE_PATH) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_pull_file_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.pull_file(TEST_FILE_PATH, TEST_FILE_PATH) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_all_users_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.mock_users() |
| |
| users = AdbDevice(TEST_DEVICE_SERIAL).get_all_users() |
| |
| self.assertEqual(users, [TEST_USER_ID_1, TEST_USER_ID_2]) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_all_users_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.get_all_users() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_user_exists_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.mock_users() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| error = adbDevice.user_exists(TEST_USER_ID_1) |
| |
| self.assertEqual(error, None) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_user_exists_and_user_does_not_exist_failure(self, |
| mock_subprocess_run): |
| mock_subprocess_run.return_value = self.mock_users() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| error = adbDevice.user_exists(TEST_USER_ID_3) |
| |
| self.assertNotEqual(error, None) |
| self.assertEqual(error.message, ("User ID %s does not exist on device with" |
| " serial %s." % (TEST_USER_ID_3, |
| TEST_DEVICE_SERIAL))) |
| self.assertEqual(error.suggestion, |
| ("Select from one of the following user IDs on device with" |
| " serial %s: %s, %s" |
| % (TEST_DEVICE_SERIAL, TEST_USER_ID_1, TEST_USER_ID_2))) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_user_exists_and_get_all_users_fails_error(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.user_exists(TEST_USER_ID_1) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_current_user_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| mock.create_autospec(subprocess.CompletedProcess, instance=True, |
| stdout=b'%d\n' % TEST_USER_ID_1)) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| user = adbDevice.get_current_user() |
| |
| self.assertEqual(user, TEST_USER_ID_1) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_current_user_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.get_current_user() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_perform_user_switch_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.perform_user_switch(TEST_USER_ID_1) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_perform_user_switch_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.perform_user_switch(TEST_USER_ID_1) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_write_to_file_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.write_to_file(TEST_FILE_PATH, TEST_STRING_FILE) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_write_to_file_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.write_to_file(TEST_FILE_PATH, TEST_STRING_FILE) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_set_prop_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.set_prop(TEST_PROP, TEST_PROP_VALUE) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_set_prop_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.set_prop(TEST_PROP, TEST_PROP_VALUE) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_reboot_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.reboot() |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_reboot_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.reboot() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_wait_for_device_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.wait_for_device() |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_wait_for_device_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.wait_for_device() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_is_boot_completed_and_is_completed(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_mock_completed_process(BOOT_COMPLETE_OUTPUT)) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| is_completed = adbDevice.is_boot_completed() |
| |
| self.assertEqual(is_completed, True) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_is_boot_completed_and_is_not_completed(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| is_completed = adbDevice.is_boot_completed() |
| |
| self.assertEqual(is_completed, False) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_is_boot_completed_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.is_boot_completed() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_wait_for_boot_to_complete_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_mock_completed_process(BOOT_COMPLETE_OUTPUT)) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.wait_for_boot_to_complete() |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_wait_for_boot_to_complete_and_is_boot_completed_fails_error(self, |
| mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.wait_for_boot_to_complete() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_wait_for_boot_to_complete_times_out_error(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.wait_for_boot_to_complete() |
| |
| self.assertEqual(str(e.exception), ("Device with serial %s took too long to" |
| " finish rebooting." |
| % adbDevice.serial)) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_packages_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.mock_packages() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| packages = adbDevice.get_packages() |
| |
| self.assertEqual(packages, [TEST_PACKAGE_1, TEST_PACKAGE_2]) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_packages_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.get_packages() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_pid_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process( |
| TEST_PID_OUTPUT) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| process_id = adbDevice.get_pid(TEST_PACKAGE_1) |
| |
| self.assertEqual(process_id, "8241") |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_pid_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.get_pid(TEST_PACKAGE_1) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_package_running(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process( |
| TEST_PID_OUTPUT) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| is_running = adbDevice.is_package_running(TEST_PACKAGE_1) |
| |
| self.assertEqual(is_running, True) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_package_not_running(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| is_running = adbDevice.is_package_running(TEST_PACKAGE_1) |
| |
| self.assertEqual(is_running, False) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_package_running_and_get_pid_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.is_package_running(TEST_PACKAGE_1) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_start_package_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process() |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| error = adbDevice.start_package(TEST_PACKAGE_1) |
| |
| self.assertEqual(error, None) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_start_package_fails_with_service_app(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process( |
| stderr_string=b'%s\n' % TEST_FAILURE_MSG.encode("utf-8")) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| error = adbDevice.start_package(TEST_PACKAGE_1) |
| |
| self.assertNotEqual(error, None) |
| self.assertEqual(error.message, ("Cannot start package %s on device with" |
| " serial %s because %s is a service" |
| " package, which doesn't implement a MAIN" |
| " activity." % (TEST_PACKAGE_1, |
| TEST_DEVICE_SERIAL, |
| TEST_PACKAGE_1))) |
| self.assertEqual(error.suggestion, None) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_start_package_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.start_package(TEST_PACKAGE_1) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_kill_pid_success(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = [ |
| self.generate_mock_completed_process(TEST_PID_OUTPUT), None] |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.kill_pid(TEST_PACKAGE_1) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_kill_pid_and_get_pid_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.kill_pid(TEST_PACKAGE_1) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_kill_pid_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = [ |
| self.generate_mock_completed_process(TEST_PID_OUTPUT), TEST_EXCEPTION] |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.kill_pid(TEST_PACKAGE_1) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_force_stop_package_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = None |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| # No exception is expected to be thrown |
| adbDevice.force_stop_package(TEST_PACKAGE_1) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_force_stop_package_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.force_stop_package(TEST_PACKAGE_1) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_prop_success(self, mock_subprocess_run): |
| test_prop_value = ANDROID_SDK_VERSION_T |
| mock_subprocess_run.return_value = self.generate_mock_completed_process( |
| stdout_string=b'%d\n' % test_prop_value) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| prop_value = int(adbDevice.get_prop(TEST_PROP)) |
| |
| self.assertEqual(prop_value, test_prop_value) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_prop_package_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.get_prop(TEST_PROP) |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_android_sdk_version_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = self.generate_mock_completed_process( |
| stdout_string=b'%d\n' % ANDROID_SDK_VERSION_T) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| prop_value = adbDevice.get_android_sdk_version() |
| |
| self.assertEqual(prop_value, ANDROID_SDK_VERSION_T) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_get_android_sdk_version_failure(self, mock_subprocess_run): |
| mock_subprocess_run.side_effect = TEST_EXCEPTION |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| with self.assertRaises(Exception) as e: |
| adbDevice.get_android_sdk_version() |
| |
| self.assertEqual(str(e.exception), TEST_FAILURE_MSG) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_simpleperf_event_exists_success(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_mock_completed_process(b'List of software events:\n ' |
| b'alignment-faults\n ' |
| b'context-switches\n ' |
| b'cpu-clock\n ' |
| b'cpu-migrations\n ' |
| b'emulation-faults\n ' |
| b'major-faults\n ' |
| b'minor-faults\n page-faults\n ' |
| b'task-clock')) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| events = ["cpu-clock", "minor-faults"] |
| # No exception is expected to be thrown |
| error = adbDevice.simpleperf_event_exists(events) |
| |
| self.assertEqual(error, None) |
| # Check that the list passed to the function is unchanged |
| self.assertEqual(events, ["cpu-clock", "minor-faults"]) |
| |
| @mock.patch.object(subprocess, "run", autospec=True) |
| def test_simpleperf_event_exists_failure(self, mock_subprocess_run): |
| mock_subprocess_run.return_value = ( |
| self.generate_mock_completed_process(b'List of software events:\n ' |
| b'alignment-faults\n ' |
| b'context-switches\n ' |
| b'cpu-clock\n ' |
| b'cpu-migrations\n ' |
| b'emulation-faults\n ' |
| b'major-faults\n ' |
| b'minor-faults\n page-faults\n ' |
| b'task-clock')) |
| adbDevice = AdbDevice(TEST_DEVICE_SERIAL) |
| |
| error = adbDevice.simpleperf_event_exists(["cpu-clock", "minor-faults", |
| "List"]) |
| |
| self.assertEqual(error.message, "The following simpleperf event(s) are " |
| "invalid: ['List'].") |
| self.assertEqual(error.suggestion, "Run adb shell simpleperf list to" |
| " see valid simpleperf events.") |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |