1# 2# Copyright (C) 2024 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17import builtins 18import unittest 19import os 20import subprocess 21from unittest import mock 22from src.command import ProfilerCommand 23from src.device import AdbDevice 24 25TEST_DEVICE_SERIAL = "test-device-serial" 26TEST_DEVICE_SERIAL2 = "test-device-serial2" 27TEST_FILE_PATH = "test-file-path" 28TEST_STRING_FILE = "test-string-file" 29TEST_FAILURE_MSG = "test-failure" 30TEST_EXCEPTION = Exception(TEST_FAILURE_MSG) 31TEST_USER_ID_1 = 0 32TEST_USER_ID_2 = 1 33TEST_USER_ID_3 = 2 34TEST_PACKAGE_1 = "test-package-1" 35TEST_PACKAGE_2 = "test-package-2" 36TEST_PROP = "test-prop" 37TEST_PROP_VALUE = "test-prop-value" 38TEST_PID_OUTPUT = b"8241\n" 39BOOT_COMPLETE_OUTPUT = b"1\n" 40ANDROID_SDK_VERSION_T = 33 41 42class DeviceUnitTest(unittest.TestCase): 43 44 @staticmethod 45 def generate_adb_devices_result(devices, adb_started=True): 46 devices = [device.encode('utf-8') for device in devices] 47 stdout_string = b'List of devices attached\n' 48 if not adb_started: 49 stdout_string = (b'* daemon not running; starting now at tcp:1234\n' 50 b'* daemon started successfully\n') + stdout_string 51 if len(devices) > 0: 52 stdout_string += b'\tdevice\n'.join(devices) + b'\tdevice\n' 53 stdout_string += b'\n' 54 return subprocess.CompletedProcess(args=['adb', 'devices'], returncode=0, 55 stdout=stdout_string) 56 57 @staticmethod 58 def generate_mock_completed_process(stdout_string=b'\n', stderr_string=b'\n'): 59 return mock.create_autospec(subprocess.CompletedProcess, instance=True, 60 stdout=stdout_string, stderr=stderr_string) 61 62 @staticmethod 63 def subprocess_output(first_return_value, polling_return_value): 64 # Mocking the return value of a call to adb root and the return values of 65 # many followup calls to adb devices 66 yield first_return_value 67 while True: 68 yield polling_return_value 69 70 @staticmethod 71 def mock_users(): 72 return mock.create_autospec(subprocess.CompletedProcess, instance=True, 73 stdout=(b'Users:\n\tUserInfo{%d:Driver:813}' 74 b' running\n\tUserInfo{%d:Driver:412}\n' 75 % (TEST_USER_ID_1, TEST_USER_ID_2))) 76 77 @staticmethod 78 def mock_packages(): 79 return mock.create_autospec(subprocess.CompletedProcess, instance=True, 80 stdout=(b'package:%b\npackage:%b\n' 81 % (TEST_PACKAGE_1.encode("utf-8"), 82 TEST_PACKAGE_2.encode("utf-8")))) 83 84 @mock.patch.object(subprocess, "run", autospec=True) 85 def test_get_adb_devices_returns_devices(self, mock_subprocess_run): 86 mock_subprocess_run.return_value = ( 87 self.generate_adb_devices_result([TEST_DEVICE_SERIAL, 88 TEST_DEVICE_SERIAL2])) 89 adbDevice = AdbDevice(None) 90 91 devices = adbDevice.get_adb_devices() 92 93 self.assertEqual(len(devices), 2) 94 self.assertEqual(devices[0], TEST_DEVICE_SERIAL) 95 self.assertEqual(devices[1], TEST_DEVICE_SERIAL2) 96 97 @mock.patch.object(subprocess, "run", autospec=True) 98 def test_get_adb_devices_returns_devices_and_adb_not_started(self, 99 mock_subprocess_run): 100 mock_subprocess_run.return_value = ( 101 self.generate_adb_devices_result([TEST_DEVICE_SERIAL, 102 TEST_DEVICE_SERIAL2], False)) 103 adbDevice = AdbDevice(None) 104 105 devices = adbDevice.get_adb_devices() 106 107 self.assertEqual(len(devices), 2) 108 self.assertEqual(devices[0], TEST_DEVICE_SERIAL) 109 self.assertEqual(devices[1], TEST_DEVICE_SERIAL2) 110 111 @mock.patch.object(subprocess, "run", autospec=True) 112 def test_get_adb_devices_returns_no_device(self, mock_subprocess_run): 113 mock_subprocess_run.return_value = self.generate_adb_devices_result([]) 114 adbDevice = AdbDevice(None) 115 116 devices = adbDevice.get_adb_devices() 117 118 self.assertEqual(devices, []) 119 120 @mock.patch.object(subprocess, "run", autospec=True) 121 def test_get_adb_devices_returns_no_device_and_adb_not_started(self, 122 mock_subprocess_run): 123 mock_subprocess_run.return_value = ( 124 self.generate_adb_devices_result([], False)) 125 adbDevice = AdbDevice(None) 126 127 devices = adbDevice.get_adb_devices() 128 129 self.assertEqual(devices, []) 130 131 @mock.patch.object(subprocess, "run", autospec=True) 132 def test_get_adb_devices_command_failure_error(self, mock_subprocess_run): 133 mock_subprocess_run.side_effect = TEST_EXCEPTION 134 adbDevice = AdbDevice(None) 135 136 with self.assertRaises(Exception) as e: 137 adbDevice.get_adb_devices() 138 139 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 140 141 @mock.patch.object(subprocess, "run", autospec=True) 142 def test_check_device_connection_serial_arg_in_devices(self, 143 mock_subprocess_run): 144 mock_subprocess_run.return_value = ( 145 self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) 146 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 147 148 error = adbDevice.check_device_connection() 149 150 self.assertEqual(error, None) 151 152 @mock.patch.object(subprocess, "run", autospec=True) 153 def test_check_device_connection_serial_arg_not_in_devices_error(self, 154 mock_subprocess_run): 155 mock_subprocess_run.return_value = ( 156 self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) 157 invalid_device_serial = "invalid-device-serial" 158 adbDevice = AdbDevice(invalid_device_serial) 159 160 error = adbDevice.check_device_connection() 161 162 self.assertNotEqual(error, None) 163 self.assertEqual(error.message, ("Device with serial %s is not connected." 164 % invalid_device_serial)) 165 self.assertEqual(error.suggestion, None) 166 167 @mock.patch.dict(os.environ, {"ANDROID_SERIAL": TEST_DEVICE_SERIAL}, 168 clear=True) 169 @mock.patch.object(subprocess, "run", autospec=True) 170 def test_check_device_connection_env_variable_in_devices(self, 171 mock_subprocess_run): 172 mock_subprocess_run.return_value = ( 173 self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) 174 adbDevice = AdbDevice(None) 175 176 error = adbDevice.check_device_connection() 177 178 self.assertEqual(error, None) 179 self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL) 180 181 @mock.patch.dict(os.environ, {"ANDROID_SERIAL": "invalid-device-serial"}, 182 clear=True) 183 @mock.patch.object(subprocess, "run", autospec=True) 184 def test_check_device_connection_env_variable_not_in_devices_error(self, 185 mock_subprocess_run): 186 mock_subprocess_run.return_value = ( 187 self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) 188 adbDevice = AdbDevice(None) 189 190 error = adbDevice.check_device_connection() 191 192 self.assertNotEqual(error, None) 193 self.assertEqual(error.message, ("Device with serial invalid-device-serial" 194 " is set as environment variable," 195 " ANDROID_SERIAL, but is not connected.")) 196 self.assertEqual(error.suggestion, None) 197 198 @mock.patch.object(subprocess, "run", autospec=True) 199 def test_check_device_connection_adb_devices_command_fails_error(self, 200 mock_subprocess_run): 201 mock_subprocess_run.side_effect = TEST_EXCEPTION 202 adbDevice = AdbDevice(None) 203 204 with self.assertRaises(Exception) as e: 205 adbDevice.check_device_connection() 206 207 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 208 209 @mock.patch.object(subprocess, "run", autospec=True) 210 def test_check_device_connection_no_devices_connected_error(self, 211 mock_subprocess_run): 212 mock_subprocess_run.return_value = (self.generate_adb_devices_result([])) 213 adbDevice = AdbDevice(None) 214 215 error = adbDevice.check_device_connection() 216 217 self.assertNotEqual(error, None) 218 self.assertEqual(error.message, "There are currently no devices connected.") 219 self.assertEqual(error.suggestion, None) 220 221 @mock.patch.object(subprocess, "run", autospec=True) 222 def test_check_device_connection_no_devices_connected_adb_not_started_error( 223 self, mock_subprocess_run): 224 mock_subprocess_run.return_value = ( 225 self.generate_adb_devices_result([], False)) 226 adbDevice = AdbDevice(None) 227 228 error = adbDevice.check_device_connection() 229 230 self.assertNotEqual(error, None) 231 self.assertEqual(error.message, "There are currently no devices connected.") 232 self.assertEqual(error.suggestion, None) 233 234 @mock.patch.dict(os.environ, {}, clear=True) 235 @mock.patch.object(subprocess, "run", autospec=True) 236 def test_check_device_connection_only_one_device(self, mock_subprocess_run): 237 mock_subprocess_run.return_value = ( 238 self.generate_adb_devices_result([TEST_DEVICE_SERIAL])) 239 adbDevice = AdbDevice(None) 240 241 error = adbDevice.check_device_connection() 242 243 self.assertEqual(error, None) 244 self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL) 245 246 @mock.patch.dict(os.environ, {}, clear=True) 247 @mock.patch.object(subprocess, "run", autospec=True) 248 @mock.patch.object(builtins, "input") 249 def test_check_device_connection_multiple_devices_select_first(self, mock_input, 250 mock_subprocess_run): 251 mock_input.return_value = "0" 252 mock_subprocess_run.return_value = ( 253 self.generate_adb_devices_result([TEST_DEVICE_SERIAL, 254 TEST_DEVICE_SERIAL2])) 255 adbDevice = AdbDevice(None) 256 257 error = adbDevice.check_device_connection() 258 259 self.assertEqual(error, None) 260 self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL) 261 262 @mock.patch.dict(os.environ, {}, clear=True) 263 @mock.patch.object(subprocess, "run", autospec=True) 264 @mock.patch.object(builtins, "input") 265 def test_check_device_connection_multiple_devices_select_second(self, mock_input, 266 mock_subprocess_run): 267 mock_input.return_value = "1" 268 mock_subprocess_run.return_value = ( 269 self.generate_adb_devices_result([TEST_DEVICE_SERIAL, 270 TEST_DEVICE_SERIAL2])) 271 adbDevice = AdbDevice(None) 272 273 error = adbDevice.check_device_connection() 274 275 self.assertEqual(error, None) 276 self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL2) 277 278 @mock.patch.object(subprocess, "run", autospec=True) 279 def test_root_device_success(self, mock_subprocess_run): 280 mock_subprocess_run.side_effect = [ 281 self.generate_mock_completed_process(), 282 self.generate_adb_devices_result([TEST_DEVICE_SERIAL])] 283 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 284 285 # No exception is expected to be thrown 286 adbDevice.root_device() 287 288 @mock.patch.object(subprocess, "run", autospec=True) 289 def test_root_device_failure(self, mock_subprocess_run): 290 mock_subprocess_run.side_effect = TEST_EXCEPTION 291 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 292 293 with self.assertRaises(Exception) as e: 294 adbDevice.root_device() 295 296 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 297 298 @mock.patch.object(subprocess, "run", autospec=True) 299 def test_root_device_times_out_error(self, mock_subprocess_run): 300 mock_subprocess_run.side_effect = lambda args, capture_output=True: ( 301 next(self.subprocess_output(self.generate_adb_devices_result([]), 302 self.generate_mock_completed_process()))) 303 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 304 305 with self.assertRaises(Exception) as e: 306 adbDevice.root_device() 307 308 self.assertEqual(str(e.exception), ("Device with serial %s took too long to" 309 " reconnect after being rooted." 310 % TEST_DEVICE_SERIAL)) 311 312 @mock.patch.object(subprocess, "run", autospec=True) 313 def test_root_device_and_adb_devices_fails_error(self, mock_subprocess_run): 314 mock_subprocess_run.side_effect = [self.generate_mock_completed_process(), 315 TEST_EXCEPTION] 316 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 317 318 with self.assertRaises(Exception) as e: 319 adbDevice.root_device() 320 321 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 322 323 @mock.patch.object(subprocess, "run", autospec=True) 324 def test_remove_file_success(self, mock_subprocess_run): 325 mock_subprocess_run.return_value = self.generate_mock_completed_process() 326 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 327 328 # No exception is expected to be thrown 329 adbDevice.remove_file(TEST_FILE_PATH) 330 331 @mock.patch.object(subprocess, "run", autospec=True) 332 def test_remove_file_failure(self, mock_subprocess_run): 333 mock_subprocess_run.side_effect = TEST_EXCEPTION 334 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 335 336 with self.assertRaises(Exception) as e: 337 adbDevice.remove_file(TEST_FILE_PATH) 338 339 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 340 341 @mock.patch.object(subprocess, "Popen", autospec=True) 342 def test_start_perfetto_trace_success(self, mock_subprocess_popen): 343 # Mocking the return value of subprocess.Popen to ensure it's 344 # not modified and returned by AdbDevice.start_perfetto_trace 345 mock_subprocess_popen.return_value = mock.Mock() 346 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 347 348 mock_process = adbDevice.start_perfetto_trace(None) 349 350 # No exception is expected to be thrown 351 self.assertEqual(mock_process, mock_subprocess_popen.return_value) 352 353 @mock.patch.object(subprocess, "Popen", autospec=True) 354 def test_start_perfetto_trace_failure(self, mock_subprocess_popen): 355 mock_subprocess_popen.side_effect = TEST_EXCEPTION 356 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 357 358 with self.assertRaises(Exception) as e: 359 adbDevice.start_perfetto_trace(None) 360 361 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 362 363 @mock.patch.object(subprocess, "Popen", autospec=True) 364 def test_start_simpleperf_trace_success(self, mock_subprocess_popen): 365 # Mocking the return value of subprocess.Popen to ensure it's 366 # not modified and returned by AdbDevice.start_simpleperf_trace 367 mock_subprocess_popen.return_value = mock.Mock() 368 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 369 command = ProfilerCommand("profiler", "custom", None, None, 370 10000, None, None, ["cpu-cycles"], None, None, 371 None, None, None, None, None, None, None) 372 mock_process = adbDevice.start_simpleperf_trace(command) 373 374 # No exception is expected to be thrown 375 self.assertEqual(mock_process, mock_subprocess_popen.return_value) 376 377 @mock.patch.object(subprocess, "Popen", autospec=True) 378 def test_start_simpleperf_trace_failure(self, mock_subprocess_popen): 379 mock_subprocess_popen.side_effect = TEST_EXCEPTION 380 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 381 382 command = ProfilerCommand("profiler", "custom", None, None, 383 10000, None, None, ["cpu-cycles"], None, None, 384 None, None, None, None, None, None, None) 385 with self.assertRaises(Exception) as e: 386 adbDevice.start_simpleperf_trace(command) 387 388 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 389 390 391 @mock.patch.object(subprocess, "run", autospec=True) 392 def test_pull_file_success(self, mock_subprocess_run): 393 mock_subprocess_run.return_value = self.generate_mock_completed_process() 394 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 395 396 # No exception is expected to be thrown 397 adbDevice.pull_file(TEST_FILE_PATH, TEST_FILE_PATH) 398 399 @mock.patch.object(subprocess, "run", autospec=True) 400 def test_pull_file_failure(self, mock_subprocess_run): 401 mock_subprocess_run.side_effect = TEST_EXCEPTION 402 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 403 404 with self.assertRaises(Exception) as e: 405 adbDevice.pull_file(TEST_FILE_PATH, TEST_FILE_PATH) 406 407 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 408 409 @mock.patch.object(subprocess, "run", autospec=True) 410 def test_get_all_users_success(self, mock_subprocess_run): 411 mock_subprocess_run.return_value = self.mock_users() 412 413 users = AdbDevice(TEST_DEVICE_SERIAL).get_all_users() 414 415 self.assertEqual(users, [TEST_USER_ID_1, TEST_USER_ID_2]) 416 417 @mock.patch.object(subprocess, "run", autospec=True) 418 def test_get_all_users_failure(self, mock_subprocess_run): 419 mock_subprocess_run.side_effect = TEST_EXCEPTION 420 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 421 422 with self.assertRaises(Exception) as e: 423 adbDevice.get_all_users() 424 425 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 426 427 @mock.patch.object(subprocess, "run", autospec=True) 428 def test_user_exists_success(self, mock_subprocess_run): 429 mock_subprocess_run.return_value = self.mock_users() 430 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 431 432 error = adbDevice.user_exists(TEST_USER_ID_1) 433 434 self.assertEqual(error, None) 435 436 @mock.patch.object(subprocess, "run", autospec=True) 437 def test_user_exists_and_user_does_not_exist_failure(self, 438 mock_subprocess_run): 439 mock_subprocess_run.return_value = self.mock_users() 440 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 441 442 error = adbDevice.user_exists(TEST_USER_ID_3) 443 444 self.assertNotEqual(error, None) 445 self.assertEqual(error.message, ("User ID %s does not exist on device with" 446 " serial %s." % (TEST_USER_ID_3, 447 TEST_DEVICE_SERIAL))) 448 self.assertEqual(error.suggestion, 449 ("Select from one of the following user IDs on device with" 450 " serial %s: %s, %s" 451 % (TEST_DEVICE_SERIAL, TEST_USER_ID_1, TEST_USER_ID_2))) 452 453 @mock.patch.object(subprocess, "run", autospec=True) 454 def test_user_exists_and_get_all_users_fails_error(self, mock_subprocess_run): 455 mock_subprocess_run.side_effect = TEST_EXCEPTION 456 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 457 458 with self.assertRaises(Exception) as e: 459 adbDevice.user_exists(TEST_USER_ID_1) 460 461 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 462 463 @mock.patch.object(subprocess, "run", autospec=True) 464 def test_get_current_user_success(self, mock_subprocess_run): 465 mock_subprocess_run.return_value = ( 466 mock.create_autospec(subprocess.CompletedProcess, instance=True, 467 stdout=b'%d\n' % TEST_USER_ID_1)) 468 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 469 470 user = adbDevice.get_current_user() 471 472 self.assertEqual(user, TEST_USER_ID_1) 473 474 @mock.patch.object(subprocess, "run", autospec=True) 475 def test_get_current_user_failure(self, mock_subprocess_run): 476 mock_subprocess_run.side_effect = TEST_EXCEPTION 477 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 478 479 with self.assertRaises(Exception) as e: 480 adbDevice.get_current_user() 481 482 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 483 484 @mock.patch.object(subprocess, "run", autospec=True) 485 def test_perform_user_switch_success(self, mock_subprocess_run): 486 mock_subprocess_run.return_value = self.generate_mock_completed_process() 487 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 488 489 # No exception is expected to be thrown 490 adbDevice.perform_user_switch(TEST_USER_ID_1) 491 492 @mock.patch.object(subprocess, "run", autospec=True) 493 def test_perform_user_switch_failure(self, mock_subprocess_run): 494 mock_subprocess_run.side_effect = TEST_EXCEPTION 495 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 496 497 with self.assertRaises(Exception) as e: 498 adbDevice.perform_user_switch(TEST_USER_ID_1) 499 500 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 501 502 @mock.patch.object(subprocess, "run", autospec=True) 503 def test_write_to_file_success(self, mock_subprocess_run): 504 mock_subprocess_run.return_value = self.generate_mock_completed_process() 505 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 506 507 # No exception is expected to be thrown 508 adbDevice.write_to_file(TEST_FILE_PATH, TEST_STRING_FILE) 509 510 @mock.patch.object(subprocess, "run", autospec=True) 511 def test_write_to_file_failure(self, mock_subprocess_run): 512 mock_subprocess_run.side_effect = TEST_EXCEPTION 513 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 514 515 with self.assertRaises(Exception) as e: 516 adbDevice.write_to_file(TEST_FILE_PATH, TEST_STRING_FILE) 517 518 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 519 520 @mock.patch.object(subprocess, "run", autospec=True) 521 def test_set_prop_success(self, mock_subprocess_run): 522 mock_subprocess_run.return_value = self.generate_mock_completed_process() 523 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 524 525 # No exception is expected to be thrown 526 adbDevice.set_prop(TEST_PROP, TEST_PROP_VALUE) 527 528 @mock.patch.object(subprocess, "run", autospec=True) 529 def test_set_prop_failure(self, mock_subprocess_run): 530 mock_subprocess_run.side_effect = TEST_EXCEPTION 531 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 532 533 with self.assertRaises(Exception) as e: 534 adbDevice.set_prop(TEST_PROP, TEST_PROP_VALUE) 535 536 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 537 538 @mock.patch.object(subprocess, "run", autospec=True) 539 def test_reboot_success(self, mock_subprocess_run): 540 mock_subprocess_run.return_value = self.generate_mock_completed_process() 541 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 542 543 # No exception is expected to be thrown 544 adbDevice.reboot() 545 546 @mock.patch.object(subprocess, "run", autospec=True) 547 def test_reboot_failure(self, mock_subprocess_run): 548 mock_subprocess_run.side_effect = TEST_EXCEPTION 549 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 550 551 with self.assertRaises(Exception) as e: 552 adbDevice.reboot() 553 554 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 555 556 @mock.patch.object(subprocess, "run", autospec=True) 557 def test_wait_for_device_success(self, mock_subprocess_run): 558 mock_subprocess_run.return_value = self.generate_mock_completed_process() 559 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 560 561 # No exception is expected to be thrown 562 adbDevice.wait_for_device() 563 564 @mock.patch.object(subprocess, "run", autospec=True) 565 def test_wait_for_device_failure(self, mock_subprocess_run): 566 mock_subprocess_run.side_effect = TEST_EXCEPTION 567 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 568 569 with self.assertRaises(Exception) as e: 570 adbDevice.wait_for_device() 571 572 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 573 574 @mock.patch.object(subprocess, "run", autospec=True) 575 def test_is_boot_completed_and_is_completed(self, mock_subprocess_run): 576 mock_subprocess_run.return_value = ( 577 self.generate_mock_completed_process(BOOT_COMPLETE_OUTPUT)) 578 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 579 580 is_completed = adbDevice.is_boot_completed() 581 582 self.assertEqual(is_completed, True) 583 584 @mock.patch.object(subprocess, "run", autospec=True) 585 def test_is_boot_completed_and_is_not_completed(self, mock_subprocess_run): 586 mock_subprocess_run.return_value = self.generate_mock_completed_process() 587 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 588 589 is_completed = adbDevice.is_boot_completed() 590 591 self.assertEqual(is_completed, False) 592 593 @mock.patch.object(subprocess, "run", autospec=True) 594 def test_is_boot_completed_failure(self, mock_subprocess_run): 595 mock_subprocess_run.side_effect = TEST_EXCEPTION 596 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 597 598 with self.assertRaises(Exception) as e: 599 adbDevice.is_boot_completed() 600 601 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 602 603 @mock.patch.object(subprocess, "run", autospec=True) 604 def test_wait_for_boot_to_complete_success(self, mock_subprocess_run): 605 mock_subprocess_run.return_value = ( 606 self.generate_mock_completed_process(BOOT_COMPLETE_OUTPUT)) 607 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 608 609 # No exception is expected to be thrown 610 adbDevice.wait_for_boot_to_complete() 611 612 @mock.patch.object(subprocess, "run", autospec=True) 613 def test_wait_for_boot_to_complete_and_is_boot_completed_fails_error(self, 614 mock_subprocess_run): 615 mock_subprocess_run.side_effect = TEST_EXCEPTION 616 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 617 618 with self.assertRaises(Exception) as e: 619 adbDevice.wait_for_boot_to_complete() 620 621 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 622 623 @mock.patch.object(subprocess, "run", autospec=True) 624 def test_wait_for_boot_to_complete_times_out_error(self, mock_subprocess_run): 625 mock_subprocess_run.return_value = self.generate_mock_completed_process() 626 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 627 628 with self.assertRaises(Exception) as e: 629 adbDevice.wait_for_boot_to_complete() 630 631 self.assertEqual(str(e.exception), ("Device with serial %s took too long to" 632 " finish rebooting." 633 % adbDevice.serial)) 634 635 @mock.patch.object(subprocess, "run", autospec=True) 636 def test_get_packages_success(self, mock_subprocess_run): 637 mock_subprocess_run.return_value = self.mock_packages() 638 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 639 640 packages = adbDevice.get_packages() 641 642 self.assertEqual(packages, [TEST_PACKAGE_1, TEST_PACKAGE_2]) 643 644 @mock.patch.object(subprocess, "run", autospec=True) 645 def test_get_packages_failure(self, mock_subprocess_run): 646 mock_subprocess_run.side_effect = TEST_EXCEPTION 647 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 648 649 with self.assertRaises(Exception) as e: 650 adbDevice.get_packages() 651 652 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 653 654 @mock.patch.object(subprocess, "run", autospec=True) 655 def test_get_pid_success(self, mock_subprocess_run): 656 mock_subprocess_run.return_value = self.generate_mock_completed_process( 657 TEST_PID_OUTPUT) 658 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 659 660 process_id = adbDevice.get_pid(TEST_PACKAGE_1) 661 662 self.assertEqual(process_id, "8241") 663 664 @mock.patch.object(subprocess, "run", autospec=True) 665 def test_get_pid_failure(self, mock_subprocess_run): 666 mock_subprocess_run.side_effect = TEST_EXCEPTION 667 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 668 669 with self.assertRaises(Exception) as e: 670 adbDevice.get_pid(TEST_PACKAGE_1) 671 672 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 673 674 @mock.patch.object(subprocess, "run", autospec=True) 675 def test_package_running(self, mock_subprocess_run): 676 mock_subprocess_run.return_value = self.generate_mock_completed_process( 677 TEST_PID_OUTPUT) 678 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 679 680 is_running = adbDevice.is_package_running(TEST_PACKAGE_1) 681 682 self.assertEqual(is_running, True) 683 684 @mock.patch.object(subprocess, "run", autospec=True) 685 def test_package_not_running(self, mock_subprocess_run): 686 mock_subprocess_run.return_value = self.generate_mock_completed_process() 687 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 688 689 is_running = adbDevice.is_package_running(TEST_PACKAGE_1) 690 691 self.assertEqual(is_running, False) 692 693 @mock.patch.object(subprocess, "run", autospec=True) 694 def test_package_running_and_get_pid_failure(self, mock_subprocess_run): 695 mock_subprocess_run.side_effect = TEST_EXCEPTION 696 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 697 698 with self.assertRaises(Exception) as e: 699 adbDevice.is_package_running(TEST_PACKAGE_1) 700 701 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 702 703 @mock.patch.object(subprocess, "run", autospec=True) 704 def test_start_package_success(self, mock_subprocess_run): 705 mock_subprocess_run.return_value = self.generate_mock_completed_process() 706 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 707 708 error = adbDevice.start_package(TEST_PACKAGE_1) 709 710 self.assertEqual(error, None) 711 712 @mock.patch.object(subprocess, "run", autospec=True) 713 def test_start_package_fails_with_service_app(self, mock_subprocess_run): 714 mock_subprocess_run.return_value = self.generate_mock_completed_process( 715 stderr_string=b'%s\n' % TEST_FAILURE_MSG.encode("utf-8")) 716 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 717 718 error = adbDevice.start_package(TEST_PACKAGE_1) 719 720 self.assertNotEqual(error, None) 721 self.assertEqual(error.message, ("Cannot start package %s on device with" 722 " serial %s because %s is a service" 723 " package, which doesn't implement a MAIN" 724 " activity." % (TEST_PACKAGE_1, 725 TEST_DEVICE_SERIAL, 726 TEST_PACKAGE_1))) 727 self.assertEqual(error.suggestion, None) 728 729 @mock.patch.object(subprocess, "run", autospec=True) 730 def test_start_package_failure(self, mock_subprocess_run): 731 mock_subprocess_run.side_effect = TEST_EXCEPTION 732 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 733 734 with self.assertRaises(Exception) as e: 735 adbDevice.start_package(TEST_PACKAGE_1) 736 737 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 738 739 @mock.patch.object(subprocess, "run", autospec=True) 740 def test_kill_pid_success(self, mock_subprocess_run): 741 mock_subprocess_run.side_effect = [ 742 self.generate_mock_completed_process(TEST_PID_OUTPUT), None] 743 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 744 745 # No exception is expected to be thrown 746 adbDevice.kill_pid(TEST_PACKAGE_1) 747 748 @mock.patch.object(subprocess, "run", autospec=True) 749 def test_kill_pid_and_get_pid_failure(self, mock_subprocess_run): 750 mock_subprocess_run.side_effect = TEST_EXCEPTION 751 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 752 753 with self.assertRaises(Exception) as e: 754 adbDevice.kill_pid(TEST_PACKAGE_1) 755 756 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 757 758 @mock.patch.object(subprocess, "run", autospec=True) 759 def test_kill_pid_failure(self, mock_subprocess_run): 760 mock_subprocess_run.side_effect = [ 761 self.generate_mock_completed_process(TEST_PID_OUTPUT), TEST_EXCEPTION] 762 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 763 764 with self.assertRaises(Exception) as e: 765 adbDevice.kill_pid(TEST_PACKAGE_1) 766 767 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 768 769 @mock.patch.object(subprocess, "run", autospec=True) 770 def test_force_stop_package_success(self, mock_subprocess_run): 771 mock_subprocess_run.return_value = None 772 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 773 774 # No exception is expected to be thrown 775 adbDevice.force_stop_package(TEST_PACKAGE_1) 776 777 @mock.patch.object(subprocess, "run", autospec=True) 778 def test_force_stop_package_failure(self, mock_subprocess_run): 779 mock_subprocess_run.side_effect = TEST_EXCEPTION 780 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 781 782 with self.assertRaises(Exception) as e: 783 adbDevice.force_stop_package(TEST_PACKAGE_1) 784 785 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 786 787 @mock.patch.object(subprocess, "run", autospec=True) 788 def test_get_prop_success(self, mock_subprocess_run): 789 test_prop_value = ANDROID_SDK_VERSION_T 790 mock_subprocess_run.return_value = self.generate_mock_completed_process( 791 stdout_string=b'%d\n' % test_prop_value) 792 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 793 794 prop_value = int(adbDevice.get_prop(TEST_PROP)) 795 796 self.assertEqual(prop_value, test_prop_value) 797 798 @mock.patch.object(subprocess, "run", autospec=True) 799 def test_get_prop_package_failure(self, mock_subprocess_run): 800 mock_subprocess_run.side_effect = TEST_EXCEPTION 801 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 802 803 with self.assertRaises(Exception) as e: 804 adbDevice.get_prop(TEST_PROP) 805 806 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 807 808 @mock.patch.object(subprocess, "run", autospec=True) 809 def test_get_android_sdk_version_success(self, mock_subprocess_run): 810 mock_subprocess_run.return_value = self.generate_mock_completed_process( 811 stdout_string=b'%d\n' % ANDROID_SDK_VERSION_T) 812 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 813 814 prop_value = adbDevice.get_android_sdk_version() 815 816 self.assertEqual(prop_value, ANDROID_SDK_VERSION_T) 817 818 @mock.patch.object(subprocess, "run", autospec=True) 819 def test_get_android_sdk_version_failure(self, mock_subprocess_run): 820 mock_subprocess_run.side_effect = TEST_EXCEPTION 821 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 822 823 with self.assertRaises(Exception) as e: 824 adbDevice.get_android_sdk_version() 825 826 self.assertEqual(str(e.exception), TEST_FAILURE_MSG) 827 828 @mock.patch.object(subprocess, "run", autospec=True) 829 def test_simpleperf_event_exists_success(self, mock_subprocess_run): 830 mock_subprocess_run.return_value = ( 831 self.generate_mock_completed_process(b'List of software events:\n ' 832 b'alignment-faults\n ' 833 b'context-switches\n ' 834 b'cpu-clock\n ' 835 b'cpu-migrations\n ' 836 b'emulation-faults\n ' 837 b'major-faults\n ' 838 b'minor-faults\n page-faults\n ' 839 b'task-clock')) 840 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 841 842 events = ["cpu-clock", "minor-faults"] 843 # No exception is expected to be thrown 844 error = adbDevice.simpleperf_event_exists(events) 845 846 self.assertEqual(error, None) 847 # Check that the list passed to the function is unchanged 848 self.assertEqual(events, ["cpu-clock", "minor-faults"]) 849 850 @mock.patch.object(subprocess, "run", autospec=True) 851 def test_simpleperf_event_exists_failure(self, mock_subprocess_run): 852 mock_subprocess_run.return_value = ( 853 self.generate_mock_completed_process(b'List of software events:\n ' 854 b'alignment-faults\n ' 855 b'context-switches\n ' 856 b'cpu-clock\n ' 857 b'cpu-migrations\n ' 858 b'emulation-faults\n ' 859 b'major-faults\n ' 860 b'minor-faults\n page-faults\n ' 861 b'task-clock')) 862 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 863 864 error = adbDevice.simpleperf_event_exists(["cpu-clock", "minor-faults", 865 "List"]) 866 867 self.assertEqual(error.message, "The following simpleperf event(s) are " 868 "invalid: ['List'].") 869 self.assertEqual(error.suggestion, "Run adb shell simpleperf list to" 870 " see valid simpleperf events.") 871 872 @mock.patch.object(subprocess, "run", autospec=True) 873 def test_simpleperf_not_installed(self, mock_subprocess_run): 874 mock_subprocess_run.return_value = ( 875 self.generate_mock_completed_process( 876 b'', 877 b'/system/bin/sh: simpleperf: inaccessible or not found\n') 878 ) 879 adbDevice = AdbDevice(TEST_DEVICE_SERIAL) 880 881 error = adbDevice.simpleperf_event_exists(["cpu-clock", "minor-faults", 882 "List"]) 883 884 self.assertEqual(error.message, "Simpleperf was not found in the device") 885 self.assertEqual(error.suggestion, "Push the simpleperf binary to the device") 886 887if __name__ == '__main__': 888 unittest.main() 889