1# Copyright 2016 Google Inc. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import io 16import logging 17import os 18import shutil 19import tempfile 20import unittest 21from unittest import mock 22 23from mobly import runtime_test_info 24from mobly.controllers import android_device 25from mobly.controllers.android_device_lib import adb 26from mobly.controllers.android_device_lib import errors 27from mobly.controllers.android_device_lib import snippet_client_v2 28from mobly.controllers.android_device_lib.services import base_service 29from mobly.controllers.android_device_lib.services import logcat 30from tests.lib import mock_android_device 31import yaml 32 33MOCK_SNIPPET_PACKAGE_NAME = 'com.my.snippet' 34 35# A mock SnippetClient used for testing snippet management logic. 36MockSnippetClient = mock.MagicMock() 37MockSnippetClient.package = MOCK_SNIPPET_PACKAGE_NAME 38 39 40class AndroidDeviceTest(unittest.TestCase): 41 """This test class has unit tests for the implementation of everything 42 under mobly.controllers.android_device. 43 """ 44 45 def setUp(self): 46 # Set log_path to logging since mobly logger setup is not called. 47 if not hasattr(logging, 'log_path'): 48 setattr(logging, 'log_path', '/tmp/logs') 49 # Creates a temp dir to be used by tests in this test class. 50 self.tmp_dir = tempfile.mkdtemp() 51 52 def tearDown(self): 53 """Removes the temp dir.""" 54 shutil.rmtree(self.tmp_dir) 55 56 # Tests for android_device module functions. 57 # These tests use mock AndroidDevice instances. 58 59 @mock.patch.object( 60 android_device, 61 'get_all_instances', 62 new=mock_android_device.get_all_instances, 63 ) 64 @mock.patch.object( 65 android_device, 66 'list_adb_devices', 67 new=mock_android_device.list_adb_devices, 68 ) 69 @mock.patch.object( 70 android_device, 71 'list_adb_devices_by_usb_id', 72 new=mock_android_device.list_adb_devices, 73 ) 74 def test_create_with_pickup_all(self): 75 pick_all_token = android_device.ANDROID_DEVICE_PICK_ALL_TOKEN 76 actual_ads = android_device.create(pick_all_token) 77 for actual, expected in zip( 78 actual_ads, mock_android_device.get_mock_ads(5) 79 ): 80 self.assertEqual(actual.serial, expected.serial) 81 82 @mock.patch.object( 83 android_device, 'get_instances', new=mock_android_device.get_instances 84 ) 85 @mock.patch.object( 86 android_device, 87 'list_adb_devices', 88 new=mock_android_device.list_adb_devices, 89 ) 90 @mock.patch.object( 91 android_device, 92 'list_adb_devices_by_usb_id', 93 new=mock_android_device.list_adb_devices, 94 ) 95 def test_create_with_string_list(self): 96 string_list = ['1', '2'] 97 actual_ads = android_device.create(string_list) 98 for actual_ad, expected_serial in zip(actual_ads, ['1', '2']): 99 self.assertEqual(actual_ad.serial, expected_serial) 100 101 @mock.patch.object( 102 android_device, 103 'get_instances_with_configs', 104 new=mock_android_device.get_instances_with_configs, 105 ) 106 @mock.patch.object( 107 android_device, 108 'list_adb_devices', 109 new=mock_android_device.list_adb_devices, 110 ) 111 @mock.patch.object( 112 android_device, 113 'list_adb_devices_by_usb_id', 114 new=mock_android_device.list_adb_devices, 115 ) 116 def test_create_with_dict_list(self): 117 string_list = [{'serial': '1'}, {'serial': '2'}] 118 actual_ads = android_device.create(string_list) 119 for actual_ad, expected_serial in zip(actual_ads, ['1', '2']): 120 self.assertEqual(actual_ad.serial, expected_serial) 121 122 @mock.patch.object( 123 android_device, 124 'get_instances_with_configs', 125 new=mock_android_device.get_instances_with_configs, 126 ) 127 @mock.patch.object( 128 android_device, 129 'list_adb_devices', 130 new=mock_android_device.list_adb_devices, 131 ) 132 @mock.patch.object( 133 android_device, 'list_adb_devices_by_usb_id', return_value=['usb:1'] 134 ) 135 def test_create_with_usb_id(self, mock_list_adb_devices_by_usb_id): 136 string_list = [{'serial': '1'}, {'serial': '2'}, {'serial': 'usb:1'}] 137 actual_ads = android_device.create(string_list) 138 for actual_ad, expected_serial in zip(actual_ads, ['1', '2', 'usb:1']): 139 self.assertEqual(actual_ad.serial, expected_serial) 140 141 def test_create_with_empty_config(self): 142 expected_msg = android_device.ANDROID_DEVICE_EMPTY_CONFIG_MSG 143 with self.assertRaisesRegex(android_device.Error, expected_msg): 144 android_device.create([]) 145 146 def test_create_with_not_list_config(self): 147 expected_msg = android_device.ANDROID_DEVICE_NOT_LIST_CONFIG_MSG 148 with self.assertRaisesRegex(android_device.Error, expected_msg): 149 android_device.create('HAHA') 150 151 def test_create_with_no_valid_config(self): 152 expected_msg = 'No valid config found in: .*' 153 with self.assertRaisesRegex(android_device.Error, expected_msg): 154 android_device.create([1]) 155 156 @mock.patch('mobly.controllers.android_device.list_fastboot_devices') 157 @mock.patch('mobly.controllers.android_device.list_adb_devices') 158 @mock.patch('mobly.controllers.android_device.list_adb_devices_by_usb_id') 159 @mock.patch('mobly.controllers.android_device.AndroidDevice') 160 def test_get_instances( 161 self, mock_ad_class, mock_list_adb_usb, mock_list_adb, mock_list_fastboot 162 ): 163 mock_list_fastboot.return_value = ['0'] 164 mock_list_adb.return_value = ['1'] 165 mock_list_adb_usb.return_value = [] 166 android_device.get_instances(['0', '1']) 167 mock_ad_class.assert_any_call('0') 168 mock_ad_class.assert_any_call('1') 169 170 @mock.patch('mobly.controllers.android_device.list_fastboot_devices') 171 @mock.patch('mobly.controllers.android_device.list_adb_devices') 172 @mock.patch('mobly.controllers.android_device.list_adb_devices_by_usb_id') 173 @mock.patch('mobly.controllers.android_device.AndroidDevice') 174 def test_get_instances_do_not_exist( 175 self, mock_ad_class, mock_list_adb_usb, mock_list_adb, mock_list_fastboot 176 ): 177 mock_list_fastboot.return_value = [] 178 mock_list_adb.return_value = [] 179 mock_list_adb_usb.return_value = [] 180 with self.assertRaisesRegex( 181 errors.Error, 182 'Android device serial "1" is specified in config but is not reachable', 183 ): 184 android_device.get_instances(['1']) 185 186 @mock.patch('mobly.controllers.android_device.list_fastboot_devices') 187 @mock.patch('mobly.controllers.android_device.list_adb_devices') 188 @mock.patch('mobly.controllers.android_device.list_adb_devices_by_usb_id') 189 @mock.patch('mobly.controllers.android_device.AndroidDevice') 190 def test_get_instances_with_configs( 191 self, mock_ad_class, mock_list_adb_usb, mock_list_adb, mock_list_fastboot 192 ): 193 mock_list_fastboot.return_value = ['1'] 194 mock_list_adb.return_value = ['2'] 195 mock_list_adb_usb.return_value = [] 196 configs = [{'serial': '1'}, {'serial': '2'}] 197 android_device.get_instances_with_configs(configs) 198 mock_ad_class.assert_any_call('1') 199 mock_ad_class.assert_any_call('2') 200 201 def test_get_instances_with_configs_invalid_config(self): 202 config = {'something': 'random'} 203 with self.assertRaisesRegex( 204 errors.Error, 205 f'Required value "serial" is missing in AndroidDevice config {config}', 206 ): 207 android_device.get_instances_with_configs([config]) 208 209 @mock.patch('mobly.controllers.android_device.list_fastboot_devices') 210 @mock.patch('mobly.controllers.android_device.list_adb_devices') 211 @mock.patch('mobly.controllers.android_device.list_adb_devices_by_usb_id') 212 @mock.patch('mobly.controllers.android_device.AndroidDevice') 213 def test_get_instances_with_configsdo_not_exist( 214 self, mock_ad_class, mock_list_adb_usb, mock_list_adb, mock_list_fastboot 215 ): 216 mock_list_fastboot.return_value = [] 217 mock_list_adb.return_value = [] 218 mock_list_adb_usb.return_value = [] 219 config = {'serial': '1'} 220 with self.assertRaisesRegex( 221 errors.Error, 222 'Android device serial "1" is specified in config but is not reachable', 223 ): 224 android_device.get_instances_with_configs([config]) 225 226 def test_get_devices_success_with_extra_field(self): 227 ads = mock_android_device.get_mock_ads(5) 228 expected_label = 'selected' 229 expected_count = 2 230 for ad in ads[:expected_count]: 231 ad.label = expected_label 232 selected_ads = android_device.get_devices(ads, label=expected_label) 233 self.assertEqual(expected_count, len(selected_ads)) 234 for ad in selected_ads: 235 self.assertEqual(ad.label, expected_label) 236 237 def test_get_devices_no_match(self): 238 ads = mock_android_device.get_mock_ads(5) 239 expected_msg = ( 240 'Could not find a target device that matches condition' 241 ": {'label': 'selected'}." 242 ) 243 with self.assertRaisesRegex(android_device.Error, expected_msg): 244 selected_ads = android_device.get_devices(ads, label='selected') 245 246 def test_get_device_success_with_serial(self): 247 ads = mock_android_device.get_mock_ads(5) 248 expected_serial = '0' 249 ad = android_device.get_device(ads, serial=expected_serial) 250 self.assertEqual(ad.serial, expected_serial) 251 252 def test_get_device_success_with_serial_and_extra_field(self): 253 ads = mock_android_device.get_mock_ads(5) 254 expected_serial = '1' 255 expected_h_port = 5555 256 ads[1].h_port = expected_h_port 257 ad = android_device.get_device( 258 ads, serial=expected_serial, h_port=expected_h_port 259 ) 260 self.assertEqual(ad.serial, expected_serial) 261 self.assertEqual(ad.h_port, expected_h_port) 262 263 def test_get_device_no_match(self): 264 ads = mock_android_device.get_mock_ads(5) 265 expected_msg = ( 266 "Could not find a target device that matches condition: {'serial': 5}." 267 ) 268 with self.assertRaisesRegex(android_device.Error, expected_msg): 269 ad = android_device.get_device(ads, serial=len(ads)) 270 271 def test_get_device_too_many_matches(self): 272 ads = mock_android_device.get_mock_ads(5) 273 target_serial = ads[1].serial = ads[0].serial 274 expected_msg = r"More than one device matched: \['0', '0'\]" 275 with self.assertRaisesRegex(android_device.Error, expected_msg): 276 android_device.get_device(ads, serial=target_serial) 277 278 def test_start_services_on_ads(self): 279 """Makes sure when an AndroidDevice fails to start some services, all 280 AndroidDevice objects get cleaned up. 281 """ 282 msg = 'Some error happened.' 283 ads = mock_android_device.get_mock_ads(3) 284 for ad in ads: 285 ad.services.logcat.start = mock.MagicMock() 286 ad.services.stop_all = mock.MagicMock() 287 ad.skip_logcat = False 288 ad.is_required = True 289 ads[1].services.logcat.start = mock.MagicMock( 290 side_effect=android_device.Error(msg) 291 ) 292 with self.assertRaisesRegex(android_device.Error, msg): 293 android_device._start_services_on_ads(ads) 294 ads[0].services.stop_all.assert_called_once_with() 295 ads[1].services.stop_all.assert_called_once_with() 296 ads[2].services.stop_all.assert_called_once_with() 297 298 def test_start_services_on_ads_skip_logcat(self): 299 ads = mock_android_device.get_mock_ads(3) 300 ads[0].services.logcat.start = mock.MagicMock() 301 ads[1].services.logcat.start = mock.MagicMock() 302 ads[2].services.logcat.start = mock.MagicMock( 303 side_effect=Exception('Should not have called this.') 304 ) 305 ads[2].skip_logcat = True 306 android_device._start_services_on_ads(ads) 307 308 def test_take_bug_reports(self): 309 ads = mock_android_device.get_mock_ads(3) 310 android_device.take_bug_reports(ads, 'test_something', 'sometime') 311 ads[0].take_bug_report.assert_called_once_with( 312 test_name='test_something', begin_time='sometime', destination=None 313 ) 314 ads[1].take_bug_report.assert_called_once_with( 315 test_name='test_something', begin_time='sometime', destination=None 316 ) 317 ads[2].take_bug_report.assert_called_once_with( 318 test_name='test_something', begin_time='sometime', destination=None 319 ) 320 321 def test_take_bug_reports_with_int_begin_time(self): 322 ads = mock_android_device.get_mock_ads(3) 323 android_device.take_bug_reports(ads, 'test_something', 123) 324 ads[0].take_bug_report.assert_called_once_with( 325 test_name='test_something', begin_time='123', destination=None 326 ) 327 ads[1].take_bug_report.assert_called_once_with( 328 test_name='test_something', begin_time='123', destination=None 329 ) 330 ads[2].take_bug_report.assert_called_once_with( 331 test_name='test_something', begin_time='123', destination=None 332 ) 333 334 @mock.patch('mobly.logger.get_log_file_timestamp') 335 def test_take_bug_reports_with_none_values(self, get_log_file_timestamp_mock): 336 mock_timestamp = '07-22-2019_17-55-30-765' 337 get_log_file_timestamp_mock.return_value = mock_timestamp 338 ads = mock_android_device.get_mock_ads(3) 339 android_device.take_bug_reports(ads) 340 ads[0].take_bug_report.assert_called_once_with( 341 test_name=None, begin_time=mock_timestamp, destination=None 342 ) 343 ads[1].take_bug_report.assert_called_once_with( 344 test_name=None, begin_time=mock_timestamp, destination=None 345 ) 346 ads[2].take_bug_report.assert_called_once_with( 347 test_name=None, begin_time=mock_timestamp, destination=None 348 ) 349 350 # Tests for android_device.AndroidDevice class. 351 # These tests mock out any interaction with the OS and real android device 352 # in AndroidDeivce. 353 354 @mock.patch( 355 'mobly.controllers.android_device_lib.adb.AdbProxy', 356 return_value=mock_android_device.MockAdbProxy('1'), 357 ) 358 @mock.patch( 359 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 360 return_value=mock_android_device.MockFastbootProxy('1'), 361 ) 362 def test_AndroidDevice_instantiation(self, MockFastboot, MockAdbProxy): 363 """Verifies the AndroidDevice object's basic attributes are correctly 364 set after instantiation. 365 """ 366 mock_serial = 1 367 ad = android_device.AndroidDevice(serial=mock_serial) 368 self.assertEqual(ad.serial, '1') 369 self.assertEqual(ad.model, 'fakemodel') 370 expected_lp = os.path.join( 371 logging.log_path, 'AndroidDevice%s' % mock_serial 372 ) 373 self.assertEqual(ad.log_path, expected_lp) 374 self.assertIsNotNone(ad.services.logcat) 375 self.assertIsNotNone(ad.services.snippets) 376 377 @mock.patch( 378 'mobly.controllers.android_device_lib.adb.AdbProxy', 379 return_value=mock_android_device.MockAdbProxy(1), 380 ) 381 @mock.patch( 382 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 383 return_value=mock_android_device.MockFastbootProxy(1), 384 ) 385 @mock.patch('mobly.utils.create_dir') 386 def test_AndroidDevice_load_config( 387 self, create_dir_mock, FastbootProxy, MockAdbProxy 388 ): 389 mock_serial = '1' 390 config = {'space': 'the final frontier', 'number': 1, 'debug_tag': 'my_tag'} 391 ad = android_device.AndroidDevice(serial=mock_serial) 392 ad.load_config(config) 393 self.assertEqual(ad.space, 'the final frontier') 394 self.assertEqual(ad.number, 1) 395 self.assertEqual(ad.debug_tag, 'my_tag') 396 397 @mock.patch( 398 'mobly.controllers.android_device_lib.adb.AdbProxy', 399 return_value=mock_android_device.MockAdbProxy(1), 400 ) 401 @mock.patch( 402 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 403 return_value=mock_android_device.MockFastbootProxy(1), 404 ) 405 @mock.patch('mobly.utils.create_dir') 406 def test_AndroidDevice_load_config_dup( 407 self, create_dir_mock, FastbootProxy, MockAdbProxy 408 ): 409 mock_serial = '1' 410 config = {'serial': 'new_serial'} 411 ad = android_device.AndroidDevice(serial=mock_serial) 412 with self.assertRaisesRegex( 413 android_device.DeviceError, 'Attribute serial already exists with' 414 ): 415 ad.load_config(config) 416 417 @mock.patch( 418 'mobly.controllers.android_device_lib.adb.AdbProxy', 419 return_value=mock_android_device.MockAdbProxy('1'), 420 ) 421 @mock.patch( 422 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 423 return_value=mock_android_device.MockFastbootProxy('1'), 424 ) 425 def test_AndroidDevice_build_info(self, MockFastboot, MockAdbProxy): 426 """Verifies the AndroidDevice object's basic attributes are correctly 427 set after instantiation. 428 """ 429 ad = android_device.AndroidDevice(serial='1') 430 build_info = ad.build_info 431 self.assertEqual(build_info['build_id'], 'AB42') 432 self.assertEqual(build_info['build_type'], 'userdebug') 433 self.assertEqual( 434 build_info['build_fingerprint'], 435 'FakeModel:Dessert/AB42/1234567:userdebug/dev-keys', 436 ) 437 self.assertEqual(build_info['build_version_codename'], 'Z') 438 self.assertEqual(build_info['build_version_incremental'], '1234567') 439 self.assertEqual(build_info['build_version_sdk'], '28') 440 self.assertEqual(build_info['build_product'], 'FakeModel') 441 self.assertEqual(build_info['build_characteristics'], 'emulator,phone') 442 self.assertEqual(build_info['product_name'], 'FakeModel') 443 self.assertEqual(build_info['debuggable'], '1') 444 self.assertEqual(build_info['hardware'], 'marlin') 445 self.assertEqual(len(build_info), len(android_device.CACHED_SYSTEM_PROPS)) 446 447 @mock.patch( 448 'mobly.controllers.android_device_lib.adb.AdbProxy', 449 return_value=mock_android_device.MockAdbProxy( 450 '1', 451 mock_properties={ 452 'ro.build.id': 'AB42', 453 'ro.build.type': 'userdebug', 454 }, 455 ), 456 ) 457 @mock.patch( 458 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 459 return_value=mock_android_device.MockFastbootProxy('1'), 460 ) 461 def test_AndroidDevice_build_info_with_minimal_properties( 462 self, MockFastboot, MockAdbProxy 463 ): 464 ad = android_device.AndroidDevice(serial='1') 465 build_info = ad.build_info 466 self.assertEqual(build_info['build_id'], 'AB42') 467 self.assertEqual(build_info['build_type'], 'userdebug') 468 self.assertEqual(build_info['build_fingerprint'], '') 469 self.assertEqual(build_info['build_version_codename'], '') 470 self.assertEqual(build_info['build_version_incremental'], '') 471 self.assertEqual(build_info['build_version_sdk'], '') 472 self.assertEqual(build_info['build_product'], '') 473 self.assertEqual(build_info['build_characteristics'], '') 474 self.assertEqual(build_info['product_name'], '') 475 self.assertEqual(build_info['debuggable'], '') 476 self.assertEqual(build_info['hardware'], '') 477 478 @mock.patch( 479 'mobly.controllers.android_device_lib.adb.AdbProxy', 480 return_value=mock_android_device.MockAdbProxy('1'), 481 ) 482 @mock.patch( 483 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 484 return_value=mock_android_device.MockFastbootProxy('1'), 485 ) 486 def test_AndroidDevice_build_info_cached(self, MockFastboot, MockAdbProxy): 487 """Verifies the AndroidDevice object's basic attributes are correctly 488 set after instantiation. 489 """ 490 ad = android_device.AndroidDevice(serial='1') 491 _ = ad.build_info 492 _ = ad.build_info 493 _ = ad.build_info 494 self.assertEqual(ad.adb.getprops_call_count, 1) 495 496 @mock.patch( 497 'mobly.controllers.android_device_lib.adb.AdbProxy', 498 return_value=mock_android_device.MockAdbProxy('1'), 499 ) 500 @mock.patch( 501 'mobly.controllers.android_device.list_fastboot_devices', 502 return_value=mock.MagicMock(), 503 ) 504 def test_AndroidDevice_model_property_is_cached( 505 self, mock_list_fastboot_devices, _ 506 ): 507 """Accessing `model` a second time shouldn't invoke all the fastboot/adb 508 calls again. 509 """ 510 mock_serial = 1 511 # mock returns '2' so the device is not considered in bootloader mode. 512 mock_list_fastboot_devices.return_value = ['2'] 513 ad = android_device.AndroidDevice(serial=mock_serial) 514 ad.model 515 mock_count_first = mock_list_fastboot_devices.call_count 516 ad.model # access `model` again. 517 mock_count_second = mock_list_fastboot_devices.call_count 518 self.assertEqual(mock_count_first, mock_count_second) 519 520 @mock.patch( 521 'mobly.controllers.android_device_lib.adb.AdbProxy', 522 return_value=mock_android_device.MockAdbProxy( 523 '1', 524 mock_properties={ 525 'ro.build.id': 'AB42', 526 'ro.build.type': 'userdebug', 527 'ro.debuggable': '1', 528 }, 529 ), 530 ) 531 @mock.patch( 532 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 533 return_value=mock_android_device.MockFastbootProxy('1'), 534 ) 535 def test_AndroidDevice_is_rootable_when_userdebug_device( 536 self, MockFastboot, MockAdbProxy 537 ): 538 ad = android_device.AndroidDevice(serial='1') 539 self.assertTrue(ad.is_rootable) 540 541 @mock.patch( 542 'mobly.controllers.android_device_lib.adb.AdbProxy', 543 return_value=mock_android_device.MockAdbProxy( 544 '1', 545 mock_properties={ 546 'ro.build.id': 'AB42', 547 'ro.build.type': 'user', 548 'ro.debuggable': '0', 549 }, 550 ), 551 ) 552 @mock.patch( 553 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 554 return_value=mock_android_device.MockFastbootProxy('1'), 555 ) 556 def test_AndroidDevice_is_rootable_when_user_device( 557 self, MockFastboot, MockAdbProxy 558 ): 559 ad = android_device.AndroidDevice(serial='1') 560 self.assertFalse(ad.is_rootable) 561 562 @mock.patch( 563 'mobly.controllers.android_device_lib.adb.AdbProxy', 564 return_value=mock_android_device.MockAdbProxy('1'), 565 ) 566 @mock.patch( 567 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 568 return_value=mock_android_device.MockFastbootProxy('1'), 569 ) 570 def test_AndroidDevice_device_info(self, MockFastboot, MockAdbProxy): 571 ad = android_device.AndroidDevice(serial=1) 572 device_info = ad.device_info 573 self.assertEqual(device_info['serial'], '1') 574 self.assertEqual(device_info['model'], 'fakemodel') 575 self.assertEqual(device_info['build_info']['build_id'], 'AB42') 576 self.assertEqual(device_info['build_info']['build_type'], 'userdebug') 577 ad.add_device_info('sim_type', 'Fi') 578 ad.add_device_info('build_id', 'CD42') 579 device_info = ad.device_info 580 self.assertEqual(device_info['user_added_info']['sim_type'], 'Fi') 581 self.assertEqual(device_info['user_added_info']['build_id'], 'CD42') 582 583 @mock.patch( 584 'mobly.controllers.android_device_lib.adb.AdbProxy', 585 return_value=mock_android_device.MockAdbProxy('1'), 586 ) 587 @mock.patch( 588 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 589 return_value=mock_android_device.MockFastbootProxy('1'), 590 ) 591 def test_AndroidDevice_serial_is_valid(self, MockFastboot, MockAdbProxy): 592 """Verifies that the serial is a primitive string type and serializable.""" 593 ad = android_device.AndroidDevice(serial=1) 594 self.assertTrue(isinstance(ad.serial, str)) 595 yaml.safe_dump(ad.serial) 596 597 @mock.patch( 598 'mobly.controllers.android_device_lib.adb.AdbProxy', 599 return_value=mock_android_device.MockAdbProxy('1'), 600 ) 601 @mock.patch( 602 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 603 return_value=mock_android_device.MockFastbootProxy('1'), 604 ) 605 def test_AndroidDevice_is_emulator_when_realish_device( 606 self, MockFastboot, MockAdbProxy 607 ): 608 ad = android_device.AndroidDevice(serial='1') 609 self.assertFalse(ad.is_emulator) 610 611 @mock.patch( 612 'mobly.controllers.android_device_lib.adb.AdbProxy', 613 return_value=mock_android_device.MockAdbProxy('localhost:123'), 614 ) 615 @mock.patch( 616 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 617 return_value=mock_android_device.MockFastbootProxy('localhost:123'), 618 ) 619 def test_AndroidDevice_is_emulator_when_local_networked_device( 620 self, MockFastboot, MockAdbProxy 621 ): 622 # Although these devices are usually emulators, there might be a reason 623 # to do this with a real device. 624 ad = android_device.AndroidDevice(serial='localhost:123') 625 self.assertFalse(ad.is_emulator) 626 627 @mock.patch( 628 'mobly.controllers.android_device_lib.adb.AdbProxy', 629 return_value=mock_android_device.MockAdbProxy('example.com:123'), 630 ) 631 @mock.patch( 632 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 633 return_value=mock_android_device.MockFastbootProxy('example:123'), 634 ) 635 def test_AndroidDevice_is_emulator_when_remote_networked_device( 636 self, MockFastboot, MockAdbProxy 637 ): 638 ad = android_device.AndroidDevice(serial='example.com:123') 639 self.assertFalse(ad.is_emulator) 640 641 @mock.patch( 642 'mobly.controllers.android_device_lib.adb.AdbProxy', 643 return_value=mock_android_device.MockAdbProxy( 644 'localhost:5554', 645 mock_properties={ 646 'ro.hardware': 'ranchu', 647 'ro.build.id': 'AB42', 648 'ro.build.type': 'userdebug', 649 }, 650 ), 651 ) 652 @mock.patch( 653 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 654 return_value=mock_android_device.MockFastbootProxy('localhost:5554'), 655 ) 656 def test_AndroidDevice_is_emulator_when_ranchu_device( 657 self, MockFastboot, MockAdbProxy 658 ): 659 ad = android_device.AndroidDevice(serial='localhost:5554') 660 self.assertTrue(ad.is_emulator) 661 662 @mock.patch( 663 'mobly.controllers.android_device_lib.adb.AdbProxy', 664 return_value=mock_android_device.MockAdbProxy( 665 '1', 666 mock_properties={ 667 'ro.build.id': 'AB42', 668 'ro.build.type': 'userdebug', 669 'ro.hardware': 'goldfish', 670 }, 671 ), 672 ) 673 @mock.patch( 674 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 675 return_value=mock_android_device.MockFastbootProxy('1'), 676 ) 677 def test_AndroidDevice_is_emulator_when_goldfish_device( 678 self, MockFastboot, MockAdbProxy 679 ): 680 ad = android_device.AndroidDevice(serial='1') 681 self.assertTrue(ad.is_emulator) 682 683 @mock.patch( 684 'mobly.controllers.android_device_lib.adb.AdbProxy', 685 return_value=mock_android_device.MockAdbProxy( 686 'example.com:123', 687 mock_properties={ 688 'ro.build.id': 'AB42', 689 'ro.build.type': 'userdebug', 690 'ro.build.characteristics': 'emulator', 691 }, 692 ), 693 ) 694 @mock.patch( 695 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 696 return_value=mock_android_device.MockFastbootProxy('example.com:123'), 697 ) 698 def test_AndroidDevice_is_emulator_when_emulator_characteristic( 699 self, MockFastboot, MockAdbProxy 700 ): 701 ad = android_device.AndroidDevice(serial='example.com:123') 702 self.assertTrue(ad.is_emulator) 703 704 @mock.patch( 705 'mobly.controllers.android_device_lib.adb.AdbProxy', 706 return_value=mock_android_device.MockAdbProxy('emulator-5554'), 707 ) 708 @mock.patch( 709 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 710 return_value=mock_android_device.MockFastbootProxy('emulator-5554'), 711 ) 712 def test_AndroidDevice_is_emulator_when_emulator_serial( 713 self, MockFastboot, MockAdbProxy 714 ): 715 ad = android_device.AndroidDevice(serial='emulator-5554') 716 self.assertTrue(ad.is_emulator) 717 718 @mock.patch( 719 'mobly.controllers.android_device_lib.adb.AdbProxy', 720 return_value=mock_android_device.MockAdbProxy('1'), 721 ) 722 @mock.patch( 723 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 724 return_value=mock_android_device.MockFastbootProxy('1'), 725 ) 726 @mock.patch( 727 'mobly.controllers.android_device.list_fastboot_devices', return_value='1' 728 ) 729 def test_AndroidDevice_is_fastboot(self, _, MockFastboot, MockAdbProxy): 730 ad = android_device.AndroidDevice(serial='1') 731 self.assertTrue(ad.is_bootloader) 732 733 @mock.patch( 734 'mobly.controllers.android_device_lib.adb.AdbProxy', 735 return_value=mock_android_device.MockAdbProxy('1'), 736 ) 737 @mock.patch( 738 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 739 return_value=mock_android_device.MockFastbootProxy('1'), 740 ) 741 @mock.patch('mobly.logger.get_log_file_timestamp') 742 def test_AndroidDevice_generate_filename_default( 743 self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy 744 ): 745 mock_serial = 1 746 ad = android_device.AndroidDevice(serial=mock_serial) 747 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 748 filename = ad.generate_filename('MagicLog') 749 self.assertEqual(filename, 'MagicLog,1,fakemodel,07-22-2019_17-53-34-450') 750 751 @mock.patch( 752 'mobly.controllers.android_device_lib.adb.AdbProxy', 753 return_value=mock_android_device.MockAdbProxy('1'), 754 ) 755 @mock.patch( 756 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 757 return_value=mock_android_device.MockFastbootProxy('1'), 758 ) 759 @mock.patch('mobly.logger.get_log_file_timestamp') 760 @mock.patch('mobly.logger.sanitize_filename') 761 def test_AndroidDevice_generate_filename_assert_sanitation( 762 self, 763 sanitize_filename_mock, 764 get_log_file_timestamp_mock, 765 MockFastboot, 766 MockAdbProxy, 767 ): 768 mock_serial = 1 769 sanitize_filename_mock.return_value = '1' 770 ad = android_device.AndroidDevice(serial=mock_serial) 771 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 772 filename = ad.generate_filename('MagicLog') 773 sanitize_filename_mock.assert_called_with( 774 'MagicLog,1,fakemodel,07-22-2019_17-53-34-450' 775 ) 776 777 @mock.patch( 778 'mobly.controllers.android_device_lib.adb.AdbProxy', 779 return_value=mock_android_device.MockAdbProxy('1'), 780 ) 781 @mock.patch( 782 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 783 return_value=mock_android_device.MockFastbootProxy('1'), 784 ) 785 @mock.patch('mobly.logger.get_log_file_timestamp') 786 def test_AndroidDevice_generate_filename_with_ext( 787 self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy 788 ): 789 mock_serial = 1 790 ad = android_device.AndroidDevice(serial=mock_serial) 791 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 792 filename = ad.generate_filename('MagicLog', extension_name='log') 793 self.assertEqual( 794 filename, 'MagicLog,1,fakemodel,07-22-2019_17-53-34-450.log' 795 ) 796 797 @mock.patch( 798 'mobly.controllers.android_device_lib.adb.AdbProxy', 799 return_value=mock_android_device.MockAdbProxy('1'), 800 ) 801 @mock.patch( 802 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 803 return_value=mock_android_device.MockFastbootProxy('1'), 804 ) 805 @mock.patch('mobly.logger.get_log_file_timestamp') 806 def test_AndroidDevice_generate_filename_with_debug_tag( 807 self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy 808 ): 809 mock_serial = 1 810 ad = android_device.AndroidDevice(serial=mock_serial) 811 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 812 ad.debug_tag = 'RoleX' 813 filename = ad.generate_filename('MagicLog') 814 self.assertEqual( 815 filename, 'MagicLog,RoleX,1,fakemodel,07-22-2019_17-53-34-450' 816 ) 817 818 @mock.patch( 819 'mobly.controllers.android_device_lib.adb.AdbProxy', 820 return_value=mock_android_device.MockAdbProxy('1'), 821 ) 822 @mock.patch( 823 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 824 return_value=mock_android_device.MockFastbootProxy('1'), 825 ) 826 @mock.patch('mobly.logger.get_log_file_timestamp') 827 def test_AndroidDevice_generate_filename_with_runtime_info( 828 self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy 829 ): 830 mock_serial = 1 831 ad = android_device.AndroidDevice(serial=mock_serial) 832 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 833 mock_record = mock.MagicMock( 834 test_name='test_xyz', begin_time='1234567', signature='test_xyz-1234567' 835 ) 836 mock_test_info = runtime_test_info.RuntimeTestInfo( 837 mock_record.test_name, '/tmp/blah/', mock_record 838 ) 839 filename = ad.generate_filename('MagicLog', time_identifier=mock_test_info) 840 self.assertEqual(filename, 'MagicLog,1,fakemodel,test_xyz-1234567') 841 842 @mock.patch( 843 'mobly.controllers.android_device_lib.adb.AdbProxy', 844 return_value=mock_android_device.MockAdbProxy('1'), 845 ) 846 @mock.patch( 847 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 848 return_value=mock_android_device.MockFastbootProxy('1'), 849 ) 850 @mock.patch('mobly.logger.get_log_file_timestamp') 851 def test_AndroidDevice_generate_filename_with_custom_timestamp( 852 self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy 853 ): 854 mock_serial = 1 855 ad = android_device.AndroidDevice(serial=mock_serial) 856 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 857 filename = ad.generate_filename( 858 'MagicLog', time_identifier='my_special_time' 859 ) 860 self.assertEqual(filename, 'MagicLog,1,fakemodel,my_special_time') 861 862 @mock.patch( 863 'mobly.controllers.android_device_lib.adb.AdbProxy', 864 return_value=mock_android_device.MockAdbProxy(1), 865 ) 866 @mock.patch( 867 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 868 return_value=mock_android_device.MockFastbootProxy(1), 869 ) 870 @mock.patch('mobly.utils.create_dir') 871 def test_AndroidDevice_take_bug_report( 872 self, create_dir_mock, FastbootProxy, MockAdbProxy 873 ): 874 """Verifies AndroidDevice.take_bug_report calls the correct adb command 875 and writes the bugreport file to the correct path. 876 """ 877 mock_serial = '1' 878 ad = android_device.AndroidDevice(serial=mock_serial) 879 output_path = ad.take_bug_report( 880 test_name='test_something', begin_time='sometime' 881 ) 882 expected_path = os.path.join( 883 logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports' 884 ) 885 create_dir_mock.assert_called_with(expected_path) 886 self.assertEqual( 887 output_path, 888 os.path.join( 889 expected_path, 'bugreport,test_something,1,fakemodel,sometime.zip' 890 ), 891 ) 892 893 @mock.patch( 894 'mobly.controllers.android_device_lib.adb.AdbProxy', 895 return_value=mock_android_device.MockAdbProxy('1', fail_br=True), 896 ) 897 @mock.patch( 898 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 899 return_value=mock_android_device.MockFastbootProxy('1'), 900 ) 901 @mock.patch('mobly.utils.create_dir') 902 def test_AndroidDevice_take_bug_report_fail( 903 self, create_dir_mock, FastbootProxy, MockAdbProxy 904 ): 905 """Verifies AndroidDevice.take_bug_report writes out the correct message 906 when taking bugreport fails. 907 """ 908 mock_serial = '1' 909 ad = android_device.AndroidDevice(serial=mock_serial) 910 expected_msg = '.* Failed to take bugreport.' 911 with self.assertRaisesRegex(android_device.Error, expected_msg): 912 ad.take_bug_report(test_name='test_something', begin_time='sometime') 913 914 @mock.patch( 915 'mobly.controllers.android_device_lib.adb.AdbProxy', 916 return_value=mock_android_device.MockAdbProxy('1'), 917 ) 918 @mock.patch( 919 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 920 return_value=mock_android_device.MockFastbootProxy('1'), 921 ) 922 @mock.patch('mobly.utils.create_dir') 923 @mock.patch('mobly.logger.get_log_file_timestamp') 924 def test_AndroidDevice_take_bug_report_without_args( 925 self, 926 get_log_file_timestamp_mock, 927 create_dir_mock, 928 FastbootProxy, 929 MockAdbProxy, 930 ): 931 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 932 mock_serial = '1' 933 ad = android_device.AndroidDevice(serial=mock_serial) 934 output_path = ad.take_bug_report() 935 expected_path = os.path.join( 936 logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports' 937 ) 938 self.assertEqual( 939 output_path, 940 os.path.join( 941 expected_path, 'bugreport,1,fakemodel,07-22-2019_17-53-34-450.zip' 942 ), 943 ) 944 945 @mock.patch( 946 'mobly.controllers.android_device_lib.adb.AdbProxy', 947 return_value=mock_android_device.MockAdbProxy('1'), 948 ) 949 @mock.patch( 950 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 951 return_value=mock_android_device.MockFastbootProxy('1'), 952 ) 953 @mock.patch('mobly.utils.create_dir') 954 @mock.patch('mobly.logger.get_log_file_timestamp') 955 def test_AndroidDevice_take_bug_report_with_only_test_name( 956 self, 957 get_log_file_timestamp_mock, 958 create_dir_mock, 959 FastbootProxy, 960 MockAdbProxy, 961 ): 962 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 963 mock_serial = '1' 964 ad = android_device.AndroidDevice(serial=mock_serial) 965 output_path = ad.take_bug_report(test_name='test_something') 966 expected_path = os.path.join( 967 logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports' 968 ) 969 create_dir_mock.assert_called_with(expected_path) 970 self.assertEqual( 971 output_path, 972 os.path.join( 973 expected_path, 974 'bugreport,test_something,1,fakemodel,07-22-2019_17-53-34-450.zip', 975 ), 976 ) 977 978 @mock.patch( 979 'mobly.controllers.android_device_lib.adb.AdbProxy', 980 return_value=mock_android_device.MockAdbProxy(1), 981 ) 982 @mock.patch( 983 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 984 return_value=mock_android_device.MockFastbootProxy(1), 985 ) 986 @mock.patch('mobly.utils.create_dir') 987 def test_AndroidDevice_take_bug_report_with_only_begin_time( 988 self, create_dir_mock, FastbootProxy, MockAdbProxy 989 ): 990 mock_serial = '1' 991 ad = android_device.AndroidDevice(serial=mock_serial) 992 output_path = ad.take_bug_report(begin_time='sometime') 993 expected_path = os.path.join( 994 logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports' 995 ) 996 create_dir_mock.assert_called_with(expected_path) 997 self.assertEqual( 998 output_path, 999 os.path.join(expected_path, 'bugreport,1,fakemodel,sometime.zip'), 1000 ) 1001 1002 @mock.patch( 1003 'mobly.controllers.android_device_lib.adb.AdbProxy', 1004 return_value=mock_android_device.MockAdbProxy(1), 1005 ) 1006 @mock.patch( 1007 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1008 return_value=mock_android_device.MockFastbootProxy(1), 1009 ) 1010 @mock.patch('mobly.utils.create_dir') 1011 def test_AndroidDevice_take_bug_report_with_int_begin_time( 1012 self, create_dir_mock, FastbootProxy, MockAdbProxy 1013 ): 1014 mock_serial = '1' 1015 ad = android_device.AndroidDevice(serial=mock_serial) 1016 output_path = ad.take_bug_report(begin_time=123) 1017 expected_path = os.path.join( 1018 logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports' 1019 ) 1020 create_dir_mock.assert_called_with(expected_path) 1021 self.assertEqual( 1022 output_path, 1023 os.path.join(expected_path, 'bugreport,1,fakemodel,123.zip'), 1024 ) 1025 1026 @mock.patch( 1027 'mobly.controllers.android_device_lib.adb.AdbProxy', 1028 return_value=mock_android_device.MockAdbProxy(1), 1029 ) 1030 @mock.patch( 1031 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1032 return_value=mock_android_device.MockFastbootProxy(1), 1033 ) 1034 @mock.patch('mobly.utils.create_dir') 1035 def test_AndroidDevice_take_bug_report_with_positional_args( 1036 self, create_dir_mock, FastbootProxy, MockAdbProxy 1037 ): 1038 mock_serial = '1' 1039 ad = android_device.AndroidDevice(serial=mock_serial) 1040 output_path = ad.take_bug_report('test_something', 'sometime') 1041 expected_path = os.path.join( 1042 logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports' 1043 ) 1044 create_dir_mock.assert_called_with(expected_path) 1045 self.assertEqual( 1046 output_path, 1047 os.path.join( 1048 expected_path, 'bugreport,test_something,1,fakemodel,sometime.zip' 1049 ), 1050 ) 1051 1052 @mock.patch( 1053 'mobly.controllers.android_device_lib.adb.AdbProxy', 1054 return_value=mock_android_device.MockAdbProxy('1'), 1055 ) 1056 @mock.patch( 1057 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1058 return_value=mock_android_device.MockFastbootProxy('1'), 1059 ) 1060 @mock.patch('mobly.utils.create_dir') 1061 def test_AndroidDevice_take_bug_report_with_destination( 1062 self, create_dir_mock, FastbootProxy, MockAdbProxy 1063 ): 1064 mock_serial = '1' 1065 ad = android_device.AndroidDevice(serial=mock_serial) 1066 dest = tempfile.gettempdir() 1067 output_path = ad.take_bug_report( 1068 test_name='test_something', begin_time='sometime', destination=dest 1069 ) 1070 expected_path = os.path.join(dest) 1071 create_dir_mock.assert_called_with(expected_path) 1072 self.assertEqual( 1073 output_path, 1074 os.path.join( 1075 expected_path, 'bugreport,test_something,1,fakemodel,sometime.zip' 1076 ), 1077 ) 1078 1079 @mock.patch( 1080 'mobly.controllers.android_device_lib.adb.AdbProxy', 1081 return_value=mock_android_device.MockAdbProxy('1', fail_br_before_N=True), 1082 ) 1083 @mock.patch( 1084 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1085 return_value=mock_android_device.MockFastbootProxy('1'), 1086 ) 1087 @mock.patch('mobly.utils.create_dir') 1088 def test_AndroidDevice_take_bug_report_fallback( 1089 self, create_dir_mock, FastbootProxy, MockAdbProxy 1090 ): 1091 """Verifies AndroidDevice.take_bug_report falls back to traditional 1092 bugreport on builds that do not have bugreportz. 1093 """ 1094 mock_serial = '1' 1095 ad = android_device.AndroidDevice(serial=mock_serial) 1096 output_path = ad.take_bug_report( 1097 test_name='test_something', begin_time='sometime' 1098 ) 1099 expected_path = os.path.join( 1100 logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports' 1101 ) 1102 create_dir_mock.assert_called_with(expected_path) 1103 self.assertEqual( 1104 output_path, 1105 os.path.join( 1106 expected_path, 'bugreport,test_something,1,fakemodel,sometime.txt' 1107 ), 1108 ) 1109 1110 @mock.patch( 1111 'mobly.controllers.android_device_lib.adb.AdbProxy', 1112 return_value=mock_android_device.MockAdbProxy('1'), 1113 ) 1114 @mock.patch( 1115 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1116 return_value=mock_android_device.MockFastbootProxy('1'), 1117 ) 1118 @mock.patch('mobly.utils.create_dir') 1119 @mock.patch('mobly.logger.get_log_file_timestamp') 1120 def test_AndroidDevice_take_screenshot( 1121 self, 1122 get_log_file_timestamp_mock, 1123 create_dir_mock, 1124 FastbootProxy, 1125 MockAdbProxy, 1126 ): 1127 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 1128 mock_serial = '1' 1129 ad = android_device.AndroidDevice(serial=mock_serial) 1130 full_pic_path = ad.take_screenshot(self.tmp_dir) 1131 self.assertEqual( 1132 full_pic_path, 1133 os.path.join( 1134 self.tmp_dir, 'screenshot,1,fakemodel,07-22-2019_17-53-34-450.png' 1135 ), 1136 ) 1137 1138 @mock.patch( 1139 'mobly.controllers.android_device_lib.adb.AdbProxy', 1140 return_value=mock_android_device.MockAdbProxy('1'), 1141 ) 1142 @mock.patch( 1143 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1144 return_value=mock_android_device.MockFastbootProxy('1'), 1145 ) 1146 @mock.patch('mobly.utils.create_dir') 1147 @mock.patch('mobly.logger.get_log_file_timestamp') 1148 def test_AndroidDevice_take_screenshot_with_prefix( 1149 self, 1150 get_log_file_timestamp_mock, 1151 create_dir_mock, 1152 FastbootProxy, 1153 MockAdbProxy, 1154 ): 1155 get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450' 1156 mock_serial = '1' 1157 ad = android_device.AndroidDevice(serial=mock_serial) 1158 1159 full_pic_path = ad.take_screenshot(self.tmp_dir, 'page_a') 1160 1161 self.assertEqual( 1162 full_pic_path, 1163 os.path.join( 1164 self.tmp_dir, 'page_a,1,fakemodel,07-22-2019_17-53-34-450.png' 1165 ), 1166 ) 1167 1168 @mock.patch( 1169 'mobly.controllers.android_device_lib.adb.AdbProxy', 1170 return_value=mock_android_device.MockAdbProxy('1'), 1171 ) 1172 @mock.patch( 1173 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1174 return_value=mock_android_device.MockFastbootProxy('1'), 1175 ) 1176 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1177 @mock.patch('mobly.utils.stop_standing_subprocess') 1178 def test_AndroidDevice_change_log_path( 1179 self, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy 1180 ): 1181 ad = android_device.AndroidDevice(serial='1') 1182 old_path = ad.log_path 1183 new_log_path = tempfile.mkdtemp() 1184 ad.log_path = new_log_path 1185 self.assertTrue(os.path.exists(new_log_path)) 1186 self.assertFalse(os.path.exists(old_path)) 1187 1188 @mock.patch( 1189 'mobly.controllers.android_device_lib.adb.AdbProxy', 1190 return_value=mock_android_device.MockAdbProxy('1'), 1191 ) 1192 @mock.patch( 1193 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1194 return_value=mock_android_device.MockFastbootProxy('1'), 1195 ) 1196 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1197 @mock.patch('mobly.utils.stop_standing_subprocess') 1198 def test_AndroidDevice_change_log_path_no_log_exists( 1199 self, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy 1200 ): 1201 ad = android_device.AndroidDevice(serial='1') 1202 old_path = ad.log_path 1203 new_log_path = tempfile.mkdtemp() 1204 ad.log_path = new_log_path 1205 self.assertTrue(os.path.exists(new_log_path)) 1206 self.assertFalse(os.path.exists(old_path)) 1207 1208 @mock.patch( 1209 'mobly.controllers.android_device_lib.adb.AdbProxy', 1210 return_value=mock_android_device.MockAdbProxy('127.0.0.1:5557'), 1211 ) 1212 @mock.patch( 1213 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1214 return_value=mock_android_device.MockFastbootProxy('127.0.0.1:5557'), 1215 ) 1216 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1217 @mock.patch('mobly.utils.stop_standing_subprocess') 1218 def test_AndroidDevice_with_reserved_character_in_serial_log_path( 1219 self, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy 1220 ): 1221 ad = android_device.AndroidDevice(serial='127.0.0.1:5557') 1222 base_log_path = os.path.basename(ad.log_path) 1223 self.assertEqual(base_log_path, 'AndroidDevice127.0.0.1-5557') 1224 1225 @mock.patch( 1226 'mobly.controllers.android_device_lib.adb.AdbProxy', 1227 return_value=mock_android_device.MockAdbProxy('1'), 1228 ) 1229 @mock.patch( 1230 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1231 return_value=mock_android_device.MockFastbootProxy('1'), 1232 ) 1233 @mock.patch('mobly.utils.create_dir') 1234 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1235 @mock.patch('mobly.utils.stop_standing_subprocess') 1236 @mock.patch.object(logcat.Logcat, '_open_logcat_file') 1237 def test_AndroidDevice_change_log_path_with_service( 1238 self, 1239 open_logcat_mock, 1240 stop_proc_mock, 1241 start_proc_mock, 1242 creat_dir_mock, 1243 FastbootProxy, 1244 MockAdbProxy, 1245 ): 1246 ad = android_device.AndroidDevice(serial='1') 1247 ad.services.logcat.start() 1248 new_log_path = tempfile.mkdtemp() 1249 expected_msg = '.* Cannot change `log_path` when there is service running.' 1250 with self.assertRaisesRegex(android_device.Error, expected_msg): 1251 ad.log_path = new_log_path 1252 1253 @mock.patch( 1254 'mobly.controllers.android_device_lib.adb.AdbProxy', 1255 return_value=mock_android_device.MockAdbProxy('1'), 1256 ) 1257 @mock.patch( 1258 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1259 return_value=mock_android_device.MockFastbootProxy('1'), 1260 ) 1261 @mock.patch('mobly.utils.create_dir') 1262 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1263 @mock.patch('mobly.utils.stop_standing_subprocess') 1264 def test_AndroidDevice_change_log_path_with_existing_file( 1265 self, 1266 stop_proc_mock, 1267 start_proc_mock, 1268 creat_dir_mock, 1269 FastbootProxy, 1270 MockAdbProxy, 1271 ): 1272 ad = android_device.AndroidDevice(serial='1') 1273 new_log_path = tempfile.mkdtemp() 1274 new_file_path = os.path.join(new_log_path, 'file.txt') 1275 with io.open(new_file_path, 'w', encoding='utf-8') as f: 1276 f.write('hahah.') 1277 expected_msg = '.* Logs already exist .*' 1278 with self.assertRaisesRegex(android_device.Error, expected_msg): 1279 ad.log_path = new_log_path 1280 1281 @mock.patch( 1282 'mobly.controllers.android_device_lib.adb.AdbProxy', 1283 return_value=mock_android_device.MockAdbProxy('1'), 1284 ) 1285 @mock.patch( 1286 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1287 return_value=mock_android_device.MockFastbootProxy('1'), 1288 ) 1289 @mock.patch('mobly.utils.create_dir') 1290 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1291 @mock.patch('mobly.utils.stop_standing_subprocess') 1292 def test_AndroidDevice_update_serial( 1293 self, 1294 stop_proc_mock, 1295 start_proc_mock, 1296 creat_dir_mock, 1297 FastbootProxy, 1298 MockAdbProxy, 1299 ): 1300 ad = android_device.AndroidDevice(serial='1') 1301 ad.update_serial('2') 1302 self.assertEqual(ad.serial, '2') 1303 self.assertEqual(ad.debug_tag, ad.serial) 1304 self.assertEqual(ad.adb.serial, ad.serial) 1305 self.assertEqual(ad.fastboot.serial, ad.serial) 1306 1307 @mock.patch( 1308 'mobly.controllers.android_device_lib.adb.AdbProxy', 1309 return_value=mock_android_device.MockAdbProxy('1'), 1310 ) 1311 @mock.patch( 1312 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1313 return_value=mock_android_device.MockFastbootProxy('1'), 1314 ) 1315 @mock.patch('mobly.utils.create_dir') 1316 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1317 @mock.patch('mobly.utils.stop_standing_subprocess') 1318 @mock.patch.object(logcat.Logcat, '_open_logcat_file') 1319 def test_AndroidDevice_update_serial_with_service_running( 1320 self, 1321 open_logcat_mock, 1322 stop_proc_mock, 1323 start_proc_mock, 1324 creat_dir_mock, 1325 FastbootProxy, 1326 MockAdbProxy, 1327 ): 1328 ad = android_device.AndroidDevice(serial='1') 1329 ad.services.logcat.start() 1330 expected_msg = ( 1331 '.* Cannot change device serial number when there is service running.' 1332 ) 1333 with self.assertRaisesRegex(android_device.Error, expected_msg): 1334 ad.update_serial('2') 1335 1336 @mock.patch( 1337 'mobly.controllers.android_device_lib.adb.AdbProxy', 1338 return_value=mock_android_device.MockAdbProxy('1'), 1339 ) 1340 @mock.patch( 1341 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1342 return_value=mock_android_device.MockFastbootProxy('1'), 1343 ) 1344 @mock.patch( 1345 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2' 1346 ) 1347 @mock.patch('mobly.utils.get_available_host_port') 1348 def test_AndroidDevice_load_snippet( 1349 self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy 1350 ): 1351 ad = android_device.AndroidDevice(serial='1') 1352 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME) 1353 self.assertTrue(hasattr(ad, 'snippet')) 1354 1355 @mock.patch( 1356 'mobly.controllers.android_device_lib.adb.AdbProxy', 1357 return_value=mock_android_device.MockAdbProxy('1'), 1358 ) 1359 @mock.patch( 1360 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1361 return_value=mock_android_device.MockFastbootProxy('1'), 1362 ) 1363 @mock.patch( 1364 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2' 1365 ) 1366 @mock.patch('mobly.utils.get_available_host_port') 1367 def test_AndroidDevice_getattr( 1368 self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy 1369 ): 1370 ad = android_device.AndroidDevice(serial='1') 1371 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME) 1372 value = {'value': 42} 1373 actual_value = getattr(ad, 'some_attr', value) 1374 self.assertEqual(actual_value, value) 1375 1376 @mock.patch( 1377 'mobly.controllers.android_device_lib.adb.AdbProxy', 1378 return_value=mock_android_device.MockAdbProxy('1'), 1379 ) 1380 @mock.patch( 1381 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1382 return_value=mock_android_device.MockFastbootProxy('1'), 1383 ) 1384 @mock.patch( 1385 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2', 1386 return_value=MockSnippetClient, 1387 ) 1388 @mock.patch('mobly.utils.get_available_host_port') 1389 def test_AndroidDevice_load_snippet_dup_package( 1390 self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy 1391 ): 1392 ad = android_device.AndroidDevice(serial='1') 1393 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME) 1394 expected_msg = ( 1395 'Snippet package "%s" has already been loaded under name "snippet".' 1396 ) % MOCK_SNIPPET_PACKAGE_NAME 1397 with self.assertRaisesRegex(android_device.Error, expected_msg): 1398 ad.load_snippet('snippet2', MOCK_SNIPPET_PACKAGE_NAME) 1399 1400 @mock.patch( 1401 'mobly.controllers.android_device_lib.adb.AdbProxy', 1402 return_value=mock_android_device.MockAdbProxy('1'), 1403 ) 1404 @mock.patch( 1405 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1406 return_value=mock_android_device.MockFastbootProxy('1'), 1407 ) 1408 @mock.patch( 1409 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2', 1410 return_value=MockSnippetClient, 1411 ) 1412 @mock.patch('mobly.utils.get_available_host_port') 1413 def test_AndroidDevice_load_snippet_dup_snippet_name( 1414 self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy 1415 ): 1416 ad = android_device.AndroidDevice(serial='1') 1417 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME) 1418 expected_msg = ( 1419 '.* Attribute "snippet" already exists, please use a different name.' 1420 ) 1421 with self.assertRaisesRegex(android_device.Error, expected_msg): 1422 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME + 'haha') 1423 1424 @mock.patch( 1425 'mobly.controllers.android_device_lib.adb.AdbProxy', 1426 return_value=mock_android_device.MockAdbProxy('1'), 1427 ) 1428 @mock.patch( 1429 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1430 return_value=mock_android_device.MockFastbootProxy('1'), 1431 ) 1432 @mock.patch( 1433 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2' 1434 ) 1435 @mock.patch('mobly.utils.get_available_host_port') 1436 def test_AndroidDevice_load_snippet_dup_attribute_name( 1437 self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy 1438 ): 1439 ad = android_device.AndroidDevice(serial='1') 1440 expected_msg = ( 1441 'Attribute "%s" already exists, please use a different name' 1442 ) % 'adb' 1443 with self.assertRaisesRegex(android_device.Error, expected_msg): 1444 ad.load_snippet('adb', MOCK_SNIPPET_PACKAGE_NAME) 1445 1446 @mock.patch( 1447 'mobly.controllers.android_device_lib.adb.AdbProxy', 1448 return_value=mock_android_device.MockAdbProxy('1'), 1449 ) 1450 @mock.patch( 1451 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1452 return_value=mock_android_device.MockFastbootProxy('1'), 1453 ) 1454 @mock.patch( 1455 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2' 1456 ) 1457 @mock.patch('mobly.utils.get_available_host_port') 1458 def test_AndroidDevice_load_snippet_start_app_fails( 1459 self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy 1460 ): 1461 """Verifies that the correct exception is raised if start app failed. 1462 1463 It's possible that the `stop` call as part of the start app failure 1464 teardown also fails. So we want the exception from the start app 1465 failure. 1466 """ 1467 expected_e = Exception('start failed.') 1468 MockSnippetClient.initialize = mock.Mock(side_effect=expected_e) 1469 MockSnippetClient.stop = mock.Mock(side_effect=Exception('stop failed.')) 1470 ad = android_device.AndroidDevice(serial='1') 1471 try: 1472 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME) 1473 except Exception as e: 1474 assertIs(e, expected_e) 1475 1476 @mock.patch( 1477 'mobly.controllers.android_device_lib.adb.AdbProxy', 1478 return_value=mock_android_device.MockAdbProxy('1'), 1479 ) 1480 @mock.patch( 1481 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1482 return_value=mock_android_device.MockFastbootProxy('1'), 1483 ) 1484 @mock.patch( 1485 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2' 1486 ) 1487 @mock.patch('mobly.utils.get_available_host_port') 1488 def test_AndroidDevice_load_snippet_with_snippet_config( 1489 self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy 1490 ): 1491 ad = android_device.AndroidDevice(serial='1') 1492 snippet_config = snippet_client_v2.Config() 1493 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME, snippet_config) 1494 self.assertTrue(hasattr(ad, 'snippet')) 1495 MockSnippetClient.assert_called_once_with( 1496 package=mock.ANY, ad=mock.ANY, config=snippet_config 1497 ) 1498 1499 @mock.patch( 1500 'mobly.controllers.android_device_lib.adb.AdbProxy', 1501 return_value=mock_android_device.MockAdbProxy('1'), 1502 ) 1503 @mock.patch( 1504 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1505 return_value=mock_android_device.MockFastbootProxy('1'), 1506 ) 1507 @mock.patch( 1508 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2' 1509 ) 1510 @mock.patch('mobly.utils.get_available_host_port') 1511 def test_AndroidDevice_unload_snippet( 1512 self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy 1513 ): 1514 ad = android_device.AndroidDevice(serial='1') 1515 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME) 1516 ad.unload_snippet('snippet') 1517 self.assertFalse(hasattr(ad, 'snippet')) 1518 with self.assertRaisesRegex( 1519 android_device.SnippetError, 1520 '<AndroidDevice|1> No snippet registered with name "snippet"', 1521 ): 1522 ad.unload_snippet('snippet') 1523 # Loading the same snippet again should succeed 1524 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME) 1525 self.assertTrue(hasattr(ad, 'snippet')) 1526 1527 @mock.patch( 1528 'mobly.controllers.android_device_lib.adb.AdbProxy', 1529 return_value=mock_android_device.MockAdbProxy('1'), 1530 ) 1531 @mock.patch( 1532 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1533 return_value=mock_android_device.MockFastbootProxy('1'), 1534 ) 1535 @mock.patch( 1536 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2' 1537 ) 1538 @mock.patch('mobly.utils.get_available_host_port') 1539 @mock.patch.object(logcat.Logcat, '_open_logcat_file') 1540 def test_AndroidDevice_snippet_cleanup( 1541 self, 1542 open_logcat_mock, 1543 MockGetPort, 1544 MockSnippetClient, 1545 MockFastboot, 1546 MockAdbProxy, 1547 ): 1548 ad = android_device.AndroidDevice(serial='1') 1549 ad.services.start_all() 1550 ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME) 1551 ad.unload_snippet('snippet') 1552 self.assertFalse(hasattr(ad, 'snippet')) 1553 1554 @mock.patch( 1555 'mobly.controllers.android_device_lib.adb.AdbProxy', 1556 return_value=mock_android_device.MockAdbProxy('1'), 1557 ) 1558 @mock.patch( 1559 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1560 return_value=mock_android_device.MockFastbootProxy('1'), 1561 ) 1562 def test_AndroidDevice_debug_tag(self, MockFastboot, MockAdbProxy): 1563 mock_serial = '1' 1564 ad = android_device.AndroidDevice(serial=mock_serial) 1565 self.assertEqual(ad.debug_tag, '1') 1566 with self.assertRaisesRegex( 1567 android_device.DeviceError, r'<AndroidDevice\|1> Something' 1568 ): 1569 raise android_device.DeviceError(ad, 'Something') 1570 1571 # Verify that debug tag's setter updates the debug prefix correctly. 1572 ad.debug_tag = 'Mememe' 1573 with self.assertRaisesRegex( 1574 android_device.DeviceError, r'<AndroidDevice\|Mememe> Something' 1575 ): 1576 raise android_device.DeviceError(ad, 'Something') 1577 1578 # Verify that repr is changed correctly. 1579 with self.assertRaisesRegex( 1580 Exception, r'(<AndroidDevice\|Mememe>, \'Something\')' 1581 ): 1582 raise Exception(ad, 'Something') 1583 1584 @mock.patch( 1585 'mobly.controllers.android_device_lib.adb.AdbProxy', 1586 return_value=mock_android_device.MockAdbProxy('1'), 1587 ) 1588 @mock.patch( 1589 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1590 return_value=mock_android_device.MockFastbootProxy('1'), 1591 ) 1592 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1593 @mock.patch('mobly.utils.stop_standing_subprocess') 1594 @mock.patch.object(logcat.Logcat, '_open_logcat_file') 1595 def test_AndroidDevice_handle_usb_disconnect( 1596 self, 1597 open_logcat_mock, 1598 stop_proc_mock, 1599 start_proc_mock, 1600 FastbootProxy, 1601 MockAdbProxy, 1602 ): 1603 class MockService(base_service.BaseService): 1604 1605 def __init__(self, device, configs=None): 1606 self._alive = False 1607 self.pause_called = False 1608 self.resume_called = False 1609 1610 @property 1611 def is_alive(self): 1612 return self._alive 1613 1614 def start(self, configs=None): 1615 self._alive = True 1616 1617 def stop(self): 1618 self._alive = False 1619 1620 def pause(self): 1621 self._alive = False 1622 self.pause_called = True 1623 1624 def resume(self): 1625 self._alive = True 1626 self.resume_called = True 1627 1628 ad = android_device.AndroidDevice(serial='1') 1629 ad.services.start_all() 1630 ad.services.register('mock_service', MockService) 1631 with ad.handle_usb_disconnect(): 1632 self.assertFalse(ad.services.is_any_alive) 1633 self.assertTrue(ad.services.mock_service.pause_called) 1634 self.assertFalse(ad.services.mock_service.resume_called) 1635 self.assertTrue(ad.services.is_any_alive) 1636 self.assertTrue(ad.services.mock_service.resume_called) 1637 1638 @mock.patch( 1639 'mobly.controllers.android_device_lib.adb.AdbProxy', 1640 return_value=mock_android_device.MockAdbProxy('1'), 1641 ) 1642 @mock.patch( 1643 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1644 return_value=mock_android_device.MockFastbootProxy('1'), 1645 ) 1646 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1647 @mock.patch('mobly.utils.stop_standing_subprocess') 1648 @mock.patch.object(logcat.Logcat, '_open_logcat_file') 1649 def test_AndroidDevice_handle_reboot( 1650 self, 1651 open_logcat_mock, 1652 stop_proc_mock, 1653 start_proc_mock, 1654 FastbootProxy, 1655 MockAdbProxy, 1656 ): 1657 class MockService(base_service.BaseService): 1658 1659 def __init__(self, device, configs=None): 1660 self._alive = False 1661 self.pause_called = False 1662 self.resume_called = False 1663 1664 @property 1665 def is_alive(self): 1666 return self._alive 1667 1668 def start(self, configs=None): 1669 self._alive = True 1670 1671 def stop(self): 1672 self._alive = False 1673 1674 def pause(self): 1675 self._alive = False 1676 self.pause_called = True 1677 1678 def resume(self): 1679 self._alive = True 1680 self.resume_called = True 1681 1682 ad = android_device.AndroidDevice(serial='1') 1683 ad.services.start_all() 1684 ad.services.register('mock_service', MockService) 1685 with ad.handle_reboot(): 1686 self.assertFalse(ad.services.is_any_alive) 1687 self.assertFalse(ad.services.mock_service.pause_called) 1688 self.assertFalse(ad.services.mock_service.resume_called) 1689 self.assertTrue(ad.services.is_any_alive) 1690 self.assertFalse(ad.services.mock_service.resume_called) 1691 1692 @mock.patch( 1693 'mobly.controllers.android_device_lib.adb.AdbProxy', 1694 return_value=mock_android_device.MockAdbProxy('1'), 1695 ) 1696 @mock.patch( 1697 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1698 return_value=mock_android_device.MockFastbootProxy('1'), 1699 ) 1700 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1701 @mock.patch('mobly.utils.stop_standing_subprocess') 1702 @mock.patch.object(logcat.Logcat, '_open_logcat_file') 1703 def test_AndroidDevice_handle_reboot_changes_build_info( 1704 self, 1705 open_logcat_mock, 1706 stop_proc_mock, 1707 start_proc_mock, 1708 FastbootProxy, 1709 MockAdbProxy, 1710 ): 1711 ad = android_device.AndroidDevice(serial='1') 1712 with ad.handle_reboot(): 1713 ad.adb.mock_properties['ro.build.type'] = 'user' 1714 ad.adb.mock_properties['ro.debuggable'] = '0' 1715 self.assertEqual(ad.build_info['build_type'], 'user') 1716 self.assertEqual(ad.build_info['debuggable'], '0') 1717 self.assertFalse(ad.is_rootable) 1718 self.assertEqual(ad.adb.getprops_call_count, 2) 1719 1720 @mock.patch( 1721 'mobly.controllers.android_device_lib.adb.AdbProxy', 1722 return_value=mock_android_device.MockAdbProxy('1'), 1723 ) 1724 @mock.patch( 1725 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1726 return_value=mock_android_device.MockFastbootProxy('1'), 1727 ) 1728 @mock.patch('mobly.utils.start_standing_subprocess', return_value='process') 1729 @mock.patch('mobly.utils.stop_standing_subprocess') 1730 @mock.patch.object(logcat.Logcat, '_open_logcat_file') 1731 def test_AndroidDevice_handle_reboot_changes_build_info_with_caching( 1732 self, 1733 open_logcat_mock, 1734 stop_proc_mock, 1735 start_proc_mock, 1736 FastbootProxy, 1737 MockAdbProxy, 1738 ): 1739 ad = android_device.AndroidDevice(serial='1') # Call getprops 1. 1740 rootable_states = [ad.is_rootable] 1741 with ad.handle_reboot(): 1742 rootable_states.append(ad.is_rootable) # Call getprops 2. 1743 ad.adb.mock_properties['ro.debuggable'] = '0' 1744 rootable_states.append(ad.is_rootable) # Call getprops 3. 1745 # Call getprops 4, on context manager end. 1746 rootable_states.append(ad.is_rootable) # Cached call. 1747 rootable_states.append(ad.is_rootable) # Cached call. 1748 self.assertEqual(ad.adb.getprops_call_count, 4) 1749 self.assertEqual(rootable_states, [True, True, False, False, False]) 1750 1751 @mock.patch( 1752 'mobly.controllers.android_device_lib.adb.AdbProxy', 1753 return_value=mock_android_device.MockAdbProxy('1'), 1754 ) 1755 @mock.patch( 1756 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1757 return_value=mock_android_device.MockFastbootProxy('1'), 1758 ) 1759 @mock.patch( 1760 'mobly.controllers.android_device.AndroidDevice.is_boot_completed', 1761 side_effect=[ 1762 False, 1763 False, 1764 adb.AdbTimeoutError( 1765 ['adb', 'shell', 'getprop sys.boot_completed'], 1766 timeout=5, 1767 serial=1, 1768 ), 1769 True, 1770 ], 1771 ) 1772 @mock.patch('time.sleep', return_value=None) 1773 @mock.patch('time.time', side_effect=[0, 5, 10, 15, 20, 25, 30]) 1774 def test_AndroidDevice_wait_for_completion_completed( 1775 self, 1776 MockTime, 1777 MockSleep, 1778 MockIsBootCompleted, 1779 FastbootProxy, 1780 MockAdbProxy, 1781 ): 1782 ad = android_device.AndroidDevice(serial='1') 1783 raised = False 1784 try: 1785 ad.wait_for_boot_completion() 1786 except (adb.AdbError, adb.AdbTimeoutError): 1787 raised = True 1788 self.assertFalse( 1789 raised, 1790 'adb.AdbError or adb.AdbTimeoutError exception raised but not handled.', 1791 ) 1792 1793 @mock.patch( 1794 'mobly.controllers.android_device_lib.adb.AdbProxy', 1795 return_value=mock_android_device.MockAdbProxy('1'), 1796 ) 1797 @mock.patch( 1798 'mobly.controllers.android_device_lib.fastboot.FastbootProxy', 1799 return_value=mock_android_device.MockFastbootProxy('1'), 1800 ) 1801 @mock.patch( 1802 'mobly.controllers.android_device.AndroidDevice.is_boot_completed', 1803 side_effect=[ 1804 False, 1805 False, 1806 adb.AdbTimeoutError( 1807 ['adb', 'shell', 'getprop sys.boot_completed'], 1808 timeout=5, 1809 serial=1, 1810 ), 1811 False, 1812 False, 1813 False, 1814 False, 1815 ], 1816 ) 1817 @mock.patch('time.sleep', return_value=None) 1818 @mock.patch('time.perf_counter', side_effect=[0, 5, 10, 15, 20, 25, 30]) 1819 def test_AndroidDevice_wait_for_completion_never_boot( 1820 self, 1821 MockTime, 1822 MockSleep, 1823 MockIsBootCompleted, 1824 FastbootProxy, 1825 MockAdbProxy, 1826 ): 1827 ad = android_device.AndroidDevice(serial='1') 1828 raised = False 1829 try: 1830 with self.assertRaises(android_device.DeviceError): 1831 ad.wait_for_boot_completion(timeout=20) 1832 except (adb.AdbError, adb.AdbTimeoutError): 1833 raised = True 1834 self.assertFalse( 1835 raised, 1836 'adb.AdbError or adb.AdbTimeoutError exception raised but not handled.', 1837 ) 1838 1839 def test_AndroidDevice_parse_device_list_when_decode_error(self): 1840 gbk_str = b'\xc4\xe3\xba\xc3' 1841 raised = False 1842 try: 1843 android_device.parse_device_list(gbk_str, 'some_key') 1844 except UnicodeDecodeError: 1845 raised = True 1846 self.assertTrue(raised, 'did not raise an exception when parsing gbk bytes') 1847 1848 1849if __name__ == '__main__': 1850 unittest.main() 1851