# # 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()