1#!/usr/bin/env python 2# Copyright 2014 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6""" 7Unit tests for the contents of device_utils.py (mostly DeviceUtils). 8""" 9 10# pylint: disable=protected-access 11# pylint: disable=unused-argument 12 13import json 14import logging 15import os 16import stat 17import unittest 18 19from devil import devil_env 20from devil.android import device_errors 21from devil.android import device_signal 22from devil.android import device_utils 23from devil.android.sdk import adb_wrapper 24from devil.android.sdk import intent 25from devil.android.sdk import version_codes 26from devil.utils import cmd_helper 27from devil.utils import mock_calls 28 29with devil_env.SysPath(devil_env.PYMOCK_PATH): 30 import mock # pylint: disable=import-error 31 32 33class AnyStringWith(object): 34 def __init__(self, value): 35 self._value = value 36 37 def __eq__(self, other): 38 return self._value in other 39 40 def __repr__(self): 41 return '<AnyStringWith: %s>' % self._value 42 43 44class _MockApkHelper(object): 45 46 def __init__(self, path, package_name, perms=None): 47 self.path = path 48 self.package_name = package_name 49 self.perms = perms 50 51 def GetPackageName(self): 52 return self.package_name 53 54 def GetPermissions(self): 55 return self.perms 56 57 58class _MockMultipleDevicesError(Exception): 59 pass 60 61 62class DeviceUtilsInitTest(unittest.TestCase): 63 64 def testInitWithStr(self): 65 serial_as_str = str('0123456789abcdef') 66 d = device_utils.DeviceUtils('0123456789abcdef') 67 self.assertEqual(serial_as_str, d.adb.GetDeviceSerial()) 68 69 def testInitWithUnicode(self): 70 serial_as_unicode = unicode('fedcba9876543210') 71 d = device_utils.DeviceUtils(serial_as_unicode) 72 self.assertEqual(serial_as_unicode, d.adb.GetDeviceSerial()) 73 74 def testInitWithAdbWrapper(self): 75 serial = '123456789abcdef0' 76 a = adb_wrapper.AdbWrapper(serial) 77 d = device_utils.DeviceUtils(a) 78 self.assertEqual(serial, d.adb.GetDeviceSerial()) 79 80 def testInitWithMissing_fails(self): 81 with self.assertRaises(ValueError): 82 device_utils.DeviceUtils(None) 83 with self.assertRaises(ValueError): 84 device_utils.DeviceUtils('') 85 86 87class DeviceUtilsGetAVDsTest(mock_calls.TestCase): 88 89 def testGetAVDs(self): 90 mocked_attrs = { 91 'android_sdk': '/my/sdk/path' 92 } 93 with mock.patch('devil.devil_env._Environment.LocalPath', 94 mock.Mock(side_effect=lambda a: mocked_attrs[a])): 95 with self.assertCall( 96 mock.call.devil.utils.cmd_helper.GetCmdOutput( 97 [mock.ANY, 'list', 'avd']), 98 'Available Android Virtual Devices:\n' 99 ' Name: my_android5.0\n' 100 ' Path: /some/path/to/.android/avd/my_android5.0.avd\n' 101 ' Target: Android 5.0 (API level 21)\n' 102 ' Tag/ABI: default/x86\n' 103 ' Skin: WVGA800\n'): 104 self.assertEquals(['my_android5.0'], device_utils.GetAVDs()) 105 106 107class DeviceUtilsRestartServerTest(mock_calls.TestCase): 108 109 @mock.patch('time.sleep', mock.Mock()) 110 def testRestartServer_succeeds(self): 111 with self.assertCalls( 112 mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.KillServer(), 113 (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutput( 114 ['pgrep', 'adb']), 115 (1, '')), 116 mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.StartServer(), 117 (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutput( 118 ['pgrep', 'adb']), 119 (1, '')), 120 (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutput( 121 ['pgrep', 'adb']), 122 (0, '123\n'))): 123 device_utils.RestartServer() 124 125 126class MockTempFile(object): 127 128 def __init__(self, name='/tmp/some/file'): 129 self.file = mock.MagicMock(spec=file) 130 self.file.name = name 131 self.file.name_quoted = cmd_helper.SingleQuote(name) 132 133 def __enter__(self): 134 return self.file 135 136 def __exit__(self, exc_type, exc_val, exc_tb): 137 pass 138 139 @property 140 def name(self): 141 return self.file.name 142 143 144class _PatchedFunction(object): 145 146 def __init__(self, patched=None, mocked=None): 147 self.patched = patched 148 self.mocked = mocked 149 150 151def _AdbWrapperMock(test_serial, is_ready=True): 152 adb = mock.Mock(spec=adb_wrapper.AdbWrapper) 153 adb.__str__ = mock.Mock(return_value=test_serial) 154 adb.GetDeviceSerial.return_value = test_serial 155 adb.is_ready = is_ready 156 return adb 157 158 159class DeviceUtilsTest(mock_calls.TestCase): 160 161 def setUp(self): 162 self.adb = _AdbWrapperMock('0123456789abcdef') 163 self.device = device_utils.DeviceUtils( 164 self.adb, default_timeout=10, default_retries=0) 165 self.watchMethodCalls(self.call.adb, ignore=['GetDeviceSerial']) 166 167 def AdbCommandError(self, args=None, output=None, status=None, msg=None): 168 if args is None: 169 args = ['[unspecified]'] 170 return mock.Mock(side_effect=device_errors.AdbCommandFailedError( 171 args, output, status, msg, str(self.device))) 172 173 def CommandError(self, msg=None): 174 if msg is None: 175 msg = 'Command failed' 176 return mock.Mock(side_effect=device_errors.CommandFailedError( 177 msg, str(self.device))) 178 179 def ShellError(self, output=None, status=1): 180 def action(cmd, *args, **kwargs): 181 raise device_errors.AdbShellCommandFailedError( 182 cmd, output, status, str(self.device)) 183 if output is None: 184 output = 'Permission denied\n' 185 return action 186 187 def TimeoutError(self, msg=None): 188 if msg is None: 189 msg = 'Operation timed out' 190 return mock.Mock(side_effect=device_errors.CommandTimeoutError( 191 msg, str(self.device))) 192 193 def EnsureCacheInitialized(self, props=None, sdcard='/sdcard'): 194 props = props or [] 195 ret = [sdcard, 'TOKEN'] + props 196 return (self.call.device.RunShellCommand( 197 AnyStringWith('getprop'), check_return=True, large_output=True), ret) 198 199 200class DeviceUtilsEqTest(DeviceUtilsTest): 201 202 def testEq_equal_deviceUtils(self): 203 other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef')) 204 self.assertTrue(self.device == other) 205 self.assertTrue(other == self.device) 206 207 def testEq_equal_adbWrapper(self): 208 other = adb_wrapper.AdbWrapper('0123456789abcdef') 209 self.assertTrue(self.device == other) 210 self.assertTrue(other == self.device) 211 212 def testEq_equal_string(self): 213 other = '0123456789abcdef' 214 self.assertTrue(self.device == other) 215 self.assertTrue(other == self.device) 216 217 def testEq_devicesNotEqual(self): 218 other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdee')) 219 self.assertFalse(self.device == other) 220 self.assertFalse(other == self.device) 221 222 def testEq_identity(self): 223 self.assertTrue(self.device == self.device) 224 225 def testEq_serialInList(self): 226 devices = [self.device] 227 self.assertTrue('0123456789abcdef' in devices) 228 229 230class DeviceUtilsLtTest(DeviceUtilsTest): 231 232 def testLt_lessThan(self): 233 other = device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff')) 234 self.assertTrue(self.device < other) 235 self.assertTrue(other > self.device) 236 237 def testLt_greaterThan_lhs(self): 238 other = device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000')) 239 self.assertFalse(self.device < other) 240 self.assertFalse(other > self.device) 241 242 def testLt_equal(self): 243 other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef')) 244 self.assertFalse(self.device < other) 245 self.assertFalse(other > self.device) 246 247 def testLt_sorted(self): 248 devices = [ 249 device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff')), 250 device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000')), 251 ] 252 sorted_devices = sorted(devices) 253 self.assertEquals('0000000000000000', 254 sorted_devices[0].adb.GetDeviceSerial()) 255 self.assertEquals('ffffffffffffffff', 256 sorted_devices[1].adb.GetDeviceSerial()) 257 258 259class DeviceUtilsStrTest(DeviceUtilsTest): 260 261 def testStr_returnsSerial(self): 262 with self.assertCalls( 263 (self.call.adb.GetDeviceSerial(), '0123456789abcdef')): 264 self.assertEqual('0123456789abcdef', str(self.device)) 265 266 267class DeviceUtilsIsOnlineTest(DeviceUtilsTest): 268 269 def testIsOnline_true(self): 270 with self.assertCall(self.call.adb.GetState(), 'device'): 271 self.assertTrue(self.device.IsOnline()) 272 273 def testIsOnline_false(self): 274 with self.assertCall(self.call.adb.GetState(), 'offline'): 275 self.assertFalse(self.device.IsOnline()) 276 277 def testIsOnline_error(self): 278 with self.assertCall(self.call.adb.GetState(), self.CommandError()): 279 self.assertFalse(self.device.IsOnline()) 280 281 282class DeviceUtilsHasRootTest(DeviceUtilsTest): 283 284 def testHasRoot_true(self): 285 with self.assertCall(self.call.adb.Shell('ls /root'), 'foo\n'): 286 self.assertTrue(self.device.HasRoot()) 287 288 def testHasRoot_false(self): 289 with self.assertCall(self.call.adb.Shell('ls /root'), self.ShellError()): 290 self.assertFalse(self.device.HasRoot()) 291 292 293class DeviceUtilsEnableRootTest(DeviceUtilsTest): 294 295 def testEnableRoot_succeeds(self): 296 with self.assertCalls( 297 (self.call.device.IsUserBuild(), False), 298 self.call.adb.Root(), 299 self.call.device.WaitUntilFullyBooted()): 300 self.device.EnableRoot() 301 302 def testEnableRoot_userBuild(self): 303 with self.assertCalls( 304 (self.call.device.IsUserBuild(), True)): 305 with self.assertRaises(device_errors.CommandFailedError): 306 self.device.EnableRoot() 307 308 def testEnableRoot_rootFails(self): 309 with self.assertCalls( 310 (self.call.device.IsUserBuild(), False), 311 (self.call.adb.Root(), self.CommandError())): 312 with self.assertRaises(device_errors.CommandFailedError): 313 self.device.EnableRoot() 314 315 316class DeviceUtilsIsUserBuildTest(DeviceUtilsTest): 317 318 def testIsUserBuild_yes(self): 319 with self.assertCall( 320 self.call.device.GetProp('ro.build.type', cache=True), 'user'): 321 self.assertTrue(self.device.IsUserBuild()) 322 323 def testIsUserBuild_no(self): 324 with self.assertCall( 325 self.call.device.GetProp('ro.build.type', cache=True), 'userdebug'): 326 self.assertFalse(self.device.IsUserBuild()) 327 328 329class DeviceUtilsGetExternalStoragePathTest(DeviceUtilsTest): 330 331 def testGetExternalStoragePath_succeeds(self): 332 with self.assertCalls( 333 self.EnsureCacheInitialized(sdcard='/fake/storage/path')): 334 self.assertEquals('/fake/storage/path', 335 self.device.GetExternalStoragePath()) 336 337 def testGetExternalStoragePath_fails(self): 338 with self.assertCalls( 339 self.EnsureCacheInitialized(sdcard='')): 340 with self.assertRaises(device_errors.CommandFailedError): 341 self.device.GetExternalStoragePath() 342 343 344class DeviceUtilsGetApplicationPathsInternalTest(DeviceUtilsTest): 345 346 def testGetApplicationPathsInternal_exists(self): 347 with self.assertCalls( 348 (self.call.device.GetProp('ro.build.version.sdk', cache=True), '19'), 349 (self.call.device.RunShellCommand( 350 ['pm', 'path', 'android'], check_return=True), 351 ['package:/path/to/android.apk'])): 352 self.assertEquals(['/path/to/android.apk'], 353 self.device._GetApplicationPathsInternal('android')) 354 355 def testGetApplicationPathsInternal_notExists(self): 356 with self.assertCalls( 357 (self.call.device.GetProp('ro.build.version.sdk', cache=True), '19'), 358 (self.call.device.RunShellCommand( 359 ['pm', 'path', 'not.installed.app'], check_return=True), 360 '')): 361 self.assertEquals([], 362 self.device._GetApplicationPathsInternal('not.installed.app')) 363 364 def testGetApplicationPathsInternal_fails(self): 365 with self.assertCalls( 366 (self.call.device.GetProp('ro.build.version.sdk', cache=True), '19'), 367 (self.call.device.RunShellCommand( 368 ['pm', 'path', 'android'], check_return=True), 369 self.CommandError('ERROR. Is package manager running?\n'))): 370 with self.assertRaises(device_errors.CommandFailedError): 371 self.device._GetApplicationPathsInternal('android') 372 373 374class DeviceUtils_GetApplicationVersionTest(DeviceUtilsTest): 375 376 def test_GetApplicationVersion_exists(self): 377 with self.assertCalls( 378 (self.call.adb.Shell('dumpsys package com.android.chrome'), 379 'Packages:\n' 380 ' Package [com.android.chrome] (3901ecfb):\n' 381 ' userId=1234 gids=[123, 456, 789]\n' 382 ' pkg=Package{1fecf634 com.android.chrome}\n' 383 ' versionName=45.0.1234.7\n')): 384 self.assertEquals('45.0.1234.7', 385 self.device.GetApplicationVersion('com.android.chrome')) 386 387 def test_GetApplicationVersion_notExists(self): 388 with self.assertCalls( 389 (self.call.adb.Shell('dumpsys package com.android.chrome'), '')): 390 self.assertEquals(None, 391 self.device.GetApplicationVersion('com.android.chrome')) 392 393 def test_GetApplicationVersion_fails(self): 394 with self.assertCalls( 395 (self.call.adb.Shell('dumpsys package com.android.chrome'), 396 'Packages:\n' 397 ' Package [com.android.chrome] (3901ecfb):\n' 398 ' userId=1234 gids=[123, 456, 789]\n' 399 ' pkg=Package{1fecf634 com.android.chrome}\n')): 400 with self.assertRaises(device_errors.CommandFailedError): 401 self.device.GetApplicationVersion('com.android.chrome') 402 403 404class DeviceUtilsGetApplicationDataDirectoryTest(DeviceUtilsTest): 405 406 def testGetApplicationDataDirectory_exists(self): 407 with self.assertCall( 408 self.call.device._RunPipedShellCommand( 409 'pm dump foo.bar.baz | grep dataDir='), 410 ['dataDir=/data/data/foo.bar.baz']): 411 self.assertEquals( 412 '/data/data/foo.bar.baz', 413 self.device.GetApplicationDataDirectory('foo.bar.baz')) 414 415 def testGetApplicationDataDirectory_notExists(self): 416 with self.assertCall( 417 self.call.device._RunPipedShellCommand( 418 'pm dump foo.bar.baz | grep dataDir='), 419 self.ShellError()): 420 self.assertIsNone(self.device.GetApplicationDataDirectory('foo.bar.baz')) 421 422 423@mock.patch('time.sleep', mock.Mock()) 424class DeviceUtilsWaitUntilFullyBootedTest(DeviceUtilsTest): 425 426 def testWaitUntilFullyBooted_succeedsNoWifi(self): 427 with self.assertCalls( 428 self.call.adb.WaitForDevice(), 429 # sd_card_ready 430 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 431 (self.call.adb.Shell('test -d /fake/storage/path'), ''), 432 # pm_ready 433 (self.call.device._GetApplicationPathsInternal('android', 434 skip_cache=True), 435 ['package:/some/fake/path']), 436 # boot_completed 437 (self.call.device.GetProp('sys.boot_completed', cache=False), '1')): 438 self.device.WaitUntilFullyBooted(wifi=False) 439 440 def testWaitUntilFullyBooted_succeedsWithWifi(self): 441 with self.assertCalls( 442 self.call.adb.WaitForDevice(), 443 # sd_card_ready 444 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 445 (self.call.adb.Shell('test -d /fake/storage/path'), ''), 446 # pm_ready 447 (self.call.device._GetApplicationPathsInternal('android', 448 skip_cache=True), 449 ['package:/some/fake/path']), 450 # boot_completed 451 (self.call.device.GetProp('sys.boot_completed', cache=False), '1'), 452 # wifi_enabled 453 (self.call.adb.Shell('dumpsys wifi'), 454 'stuff\nWi-Fi is enabled\nmore stuff\n')): 455 self.device.WaitUntilFullyBooted(wifi=True) 456 457 def testWaitUntilFullyBooted_deviceNotInitiallyAvailable(self): 458 with self.assertCalls( 459 self.call.adb.WaitForDevice(), 460 # sd_card_ready 461 (self.call.device.GetExternalStoragePath(), self.AdbCommandError()), 462 # sd_card_ready 463 (self.call.device.GetExternalStoragePath(), self.AdbCommandError()), 464 # sd_card_ready 465 (self.call.device.GetExternalStoragePath(), self.AdbCommandError()), 466 # sd_card_ready 467 (self.call.device.GetExternalStoragePath(), self.AdbCommandError()), 468 # sd_card_ready 469 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 470 (self.call.adb.Shell('test -d /fake/storage/path'), ''), 471 # pm_ready 472 (self.call.device._GetApplicationPathsInternal('android', 473 skip_cache=True), 474 ['package:/some/fake/path']), 475 # boot_completed 476 (self.call.device.GetProp('sys.boot_completed', cache=False), '1')): 477 self.device.WaitUntilFullyBooted(wifi=False) 478 479 def testWaitUntilFullyBooted_deviceBrieflyOffline(self): 480 with self.assertCalls( 481 self.call.adb.WaitForDevice(), 482 # sd_card_ready 483 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 484 (self.call.adb.Shell('test -d /fake/storage/path'), ''), 485 # pm_ready 486 (self.call.device._GetApplicationPathsInternal('android', 487 skip_cache=True), 488 ['package:/some/fake/path']), 489 # boot_completed 490 (self.call.device.GetProp('sys.boot_completed', cache=False), 491 self.AdbCommandError()), 492 # boot_completed 493 (self.call.device.GetProp('sys.boot_completed', cache=False), '1')): 494 self.device.WaitUntilFullyBooted(wifi=False) 495 496 def testWaitUntilFullyBooted_sdCardReadyFails_noPath(self): 497 with self.assertCalls( 498 self.call.adb.WaitForDevice(), 499 # sd_card_ready 500 (self.call.device.GetExternalStoragePath(), self.CommandError())): 501 with self.assertRaises(device_errors.CommandFailedError): 502 self.device.WaitUntilFullyBooted(wifi=False) 503 504 def testWaitUntilFullyBooted_sdCardReadyFails_notExists(self): 505 with self.assertCalls( 506 self.call.adb.WaitForDevice(), 507 # sd_card_ready 508 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 509 (self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()), 510 # sd_card_ready 511 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 512 (self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()), 513 # sd_card_ready 514 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 515 (self.call.adb.Shell('test -d /fake/storage/path'), 516 self.TimeoutError())): 517 with self.assertRaises(device_errors.CommandTimeoutError): 518 self.device.WaitUntilFullyBooted(wifi=False) 519 520 def testWaitUntilFullyBooted_devicePmFails(self): 521 with self.assertCalls( 522 self.call.adb.WaitForDevice(), 523 # sd_card_ready 524 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 525 (self.call.adb.Shell('test -d /fake/storage/path'), ''), 526 # pm_ready 527 (self.call.device._GetApplicationPathsInternal('android', 528 skip_cache=True), 529 self.CommandError()), 530 # pm_ready 531 (self.call.device._GetApplicationPathsInternal('android', 532 skip_cache=True), 533 self.CommandError()), 534 # pm_ready 535 (self.call.device._GetApplicationPathsInternal('android', 536 skip_cache=True), 537 self.TimeoutError())): 538 with self.assertRaises(device_errors.CommandTimeoutError): 539 self.device.WaitUntilFullyBooted(wifi=False) 540 541 def testWaitUntilFullyBooted_bootFails(self): 542 with self.assertCalls( 543 self.call.adb.WaitForDevice(), 544 # sd_card_ready 545 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 546 (self.call.adb.Shell('test -d /fake/storage/path'), ''), 547 # pm_ready 548 (self.call.device._GetApplicationPathsInternal('android', 549 skip_cache=True), 550 ['package:/some/fake/path']), 551 # boot_completed 552 (self.call.device.GetProp('sys.boot_completed', cache=False), '0'), 553 # boot_completed 554 (self.call.device.GetProp('sys.boot_completed', cache=False), '0'), 555 # boot_completed 556 (self.call.device.GetProp('sys.boot_completed', cache=False), 557 self.TimeoutError())): 558 with self.assertRaises(device_errors.CommandTimeoutError): 559 self.device.WaitUntilFullyBooted(wifi=False) 560 561 def testWaitUntilFullyBooted_wifiFails(self): 562 with self.assertCalls( 563 self.call.adb.WaitForDevice(), 564 # sd_card_ready 565 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), 566 (self.call.adb.Shell('test -d /fake/storage/path'), ''), 567 # pm_ready 568 (self.call.device._GetApplicationPathsInternal('android', 569 skip_cache=True), 570 ['package:/some/fake/path']), 571 # boot_completed 572 (self.call.device.GetProp('sys.boot_completed', cache=False), '1'), 573 # wifi_enabled 574 (self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'), 575 # wifi_enabled 576 (self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'), 577 # wifi_enabled 578 (self.call.adb.Shell('dumpsys wifi'), self.TimeoutError())): 579 with self.assertRaises(device_errors.CommandTimeoutError): 580 self.device.WaitUntilFullyBooted(wifi=True) 581 582 583@mock.patch('time.sleep', mock.Mock()) 584class DeviceUtilsRebootTest(DeviceUtilsTest): 585 586 def testReboot_nonBlocking(self): 587 with self.assertCalls( 588 self.call.adb.Reboot(), 589 (self.call.device.IsOnline(), True), 590 (self.call.device.IsOnline(), False)): 591 self.device.Reboot(block=False) 592 593 def testReboot_blocking(self): 594 with self.assertCalls( 595 self.call.adb.Reboot(), 596 (self.call.device.IsOnline(), True), 597 (self.call.device.IsOnline(), False), 598 self.call.device.WaitUntilFullyBooted(wifi=False)): 599 self.device.Reboot(block=True) 600 601 def testReboot_blockUntilWifi(self): 602 with self.assertCalls( 603 self.call.adb.Reboot(), 604 (self.call.device.IsOnline(), True), 605 (self.call.device.IsOnline(), False), 606 self.call.device.WaitUntilFullyBooted(wifi=True)): 607 self.device.Reboot(block=True, wifi=True) 608 609 610class DeviceUtilsInstallTest(DeviceUtilsTest): 611 612 mock_apk = _MockApkHelper('/fake/test/app.apk', 'test.package', ['p1']) 613 614 def testInstall_noPriorInstall(self): 615 with self.patch_call(self.call.device.build_version_sdk, return_value=23): 616 with self.assertCalls( 617 (self.call.device._GetApplicationPathsInternal('test.package'), []), 618 self.call.adb.Install('/fake/test/app.apk', reinstall=False, 619 allow_downgrade=False), 620 (self.call.device.GrantPermissions('test.package', ['p1']), [])): 621 self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0) 622 623 def testInstall_permissionsPreM(self): 624 with self.patch_call(self.call.device.build_version_sdk, return_value=20): 625 with self.assertCalls( 626 (self.call.device._GetApplicationPathsInternal('test.package'), []), 627 (self.call.adb.Install('/fake/test/app.apk', reinstall=False, 628 allow_downgrade=False))): 629 self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0) 630 631 def testInstall_findPermissions(self): 632 with self.patch_call(self.call.device.build_version_sdk, return_value=23): 633 with self.assertCalls( 634 (self.call.device._GetApplicationPathsInternal('test.package'), []), 635 (self.call.adb.Install('/fake/test/app.apk', reinstall=False, 636 allow_downgrade=False)), 637 (self.call.device.GrantPermissions('test.package', ['p1']), [])): 638 self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0) 639 640 def testInstall_passPermissions(self): 641 with self.assertCalls( 642 (self.call.device._GetApplicationPathsInternal('test.package'), []), 643 (self.call.adb.Install('/fake/test/app.apk', reinstall=False, 644 allow_downgrade=False)), 645 (self.call.device.GrantPermissions('test.package', ['p1', 'p2']), [])): 646 self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0, 647 permissions=['p1', 'p2']) 648 649 def testInstall_differentPriorInstall(self): 650 with self.assertCalls( 651 (self.call.device._GetApplicationPathsInternal('test.package'), 652 ['/fake/data/app/test.package.apk']), 653 (self.call.device._ComputeStaleApks('test.package', 654 ['/fake/test/app.apk']), 655 (['/fake/test/app.apk'], None)), 656 self.call.device.Uninstall('test.package'), 657 self.call.adb.Install('/fake/test/app.apk', reinstall=False, 658 allow_downgrade=False)): 659 self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0, 660 permissions=[]) 661 662 def testInstall_differentPriorInstall_reinstall(self): 663 with self.assertCalls( 664 (self.call.device._GetApplicationPathsInternal('test.package'), 665 ['/fake/data/app/test.package.apk']), 666 (self.call.device._ComputeStaleApks('test.package', 667 ['/fake/test/app.apk']), 668 (['/fake/test/app.apk'], None)), 669 self.call.adb.Install('/fake/test/app.apk', reinstall=True, 670 allow_downgrade=False)): 671 self.device.Install(DeviceUtilsInstallTest.mock_apk, 672 reinstall=True, retries=0, permissions=[]) 673 674 def testInstall_identicalPriorInstall_reinstall(self): 675 with self.assertCalls( 676 (self.call.device._GetApplicationPathsInternal('test.package'), 677 ['/fake/data/app/test.package.apk']), 678 (self.call.device._ComputeStaleApks('test.package', 679 ['/fake/test/app.apk']), 680 ([], None)), 681 (self.call.device.ForceStop('test.package'))): 682 self.device.Install(DeviceUtilsInstallTest.mock_apk, 683 reinstall=True, retries=0, permissions=[]) 684 685 def testInstall_fails(self): 686 with self.assertCalls( 687 (self.call.device._GetApplicationPathsInternal('test.package'), []), 688 (self.call.adb.Install('/fake/test/app.apk', reinstall=False, 689 allow_downgrade=False), 690 self.CommandError('Failure\r\n'))): 691 with self.assertRaises(device_errors.CommandFailedError): 692 self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0) 693 694 def testInstall_downgrade(self): 695 with self.assertCalls( 696 (self.call.device._GetApplicationPathsInternal('test.package'), 697 ['/fake/data/app/test.package.apk']), 698 (self.call.device._ComputeStaleApks('test.package', 699 ['/fake/test/app.apk']), 700 (['/fake/test/app.apk'], None)), 701 self.call.adb.Install('/fake/test/app.apk', reinstall=True, 702 allow_downgrade=True)): 703 self.device.Install(DeviceUtilsInstallTest.mock_apk, 704 reinstall=True, retries=0, permissions=[], allow_downgrade=True) 705 706 707class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest): 708 709 mock_apk = _MockApkHelper('base.apk', 'test.package', ['p1']) 710 711 def testInstallSplitApk_noPriorInstall(self): 712 with self.assertCalls( 713 (self.call.device._CheckSdkLevel(21)), 714 (mock.call.devil.android.sdk.split_select.SelectSplits( 715 self.device, 'base.apk', 716 ['split1.apk', 'split2.apk', 'split3.apk'], 717 allow_cached_props=False), 718 ['split2.apk']), 719 (self.call.device._GetApplicationPathsInternal('test.package'), []), 720 (self.call.adb.InstallMultiple( 721 ['base.apk', 'split2.apk'], partial=None, reinstall=False, 722 allow_downgrade=False))): 723 self.device.InstallSplitApk(DeviceUtilsInstallSplitApkTest.mock_apk, 724 ['split1.apk', 'split2.apk', 'split3.apk'], permissions=[], retries=0) 725 726 def testInstallSplitApk_partialInstall(self): 727 with self.assertCalls( 728 (self.call.device._CheckSdkLevel(21)), 729 (mock.call.devil.android.sdk.split_select.SelectSplits( 730 self.device, 'base.apk', 731 ['split1.apk', 'split2.apk', 'split3.apk'], 732 allow_cached_props=False), 733 ['split2.apk']), 734 (self.call.device._GetApplicationPathsInternal('test.package'), 735 ['base-on-device.apk', 'split2-on-device.apk']), 736 (self.call.device._ComputeStaleApks('test.package', 737 ['base.apk', 'split2.apk']), 738 (['split2.apk'], None)), 739 (self.call.adb.InstallMultiple( 740 ['split2.apk'], partial='test.package', reinstall=True, 741 allow_downgrade=False))): 742 self.device.InstallSplitApk(DeviceUtilsInstallSplitApkTest.mock_apk, 743 ['split1.apk', 'split2.apk', 'split3.apk'], 744 reinstall=True, permissions=[], retries=0) 745 746 def testInstallSplitApk_downgrade(self): 747 with self.assertCalls( 748 (self.call.device._CheckSdkLevel(21)), 749 (mock.call.devil.android.sdk.split_select.SelectSplits( 750 self.device, 'base.apk', 751 ['split1.apk', 'split2.apk', 'split3.apk'], 752 allow_cached_props=False), 753 ['split2.apk']), 754 (self.call.device._GetApplicationPathsInternal('test.package'), 755 ['base-on-device.apk', 'split2-on-device.apk']), 756 (self.call.device._ComputeStaleApks('test.package', 757 ['base.apk', 'split2.apk']), 758 (['split2.apk'], None)), 759 (self.call.adb.InstallMultiple( 760 ['split2.apk'], partial='test.package', reinstall=True, 761 allow_downgrade=True))): 762 self.device.InstallSplitApk(DeviceUtilsInstallSplitApkTest.mock_apk, 763 ['split1.apk', 'split2.apk', 'split3.apk'], 764 reinstall=True, permissions=[], retries=0, 765 allow_downgrade=True) 766 767 768class DeviceUtilsUninstallTest(DeviceUtilsTest): 769 770 def testUninstall_callsThrough(self): 771 with self.assertCalls( 772 (self.call.device._GetApplicationPathsInternal('test.package'), 773 ['/path.apk']), 774 self.call.adb.Uninstall('test.package', True)): 775 self.device.Uninstall('test.package', True) 776 777 def testUninstall_noop(self): 778 with self.assertCalls( 779 (self.call.device._GetApplicationPathsInternal('test.package'), [])): 780 self.device.Uninstall('test.package', True) 781 782 783class DeviceUtilsSuTest(DeviceUtilsTest): 784 785 def testSu_preM(self): 786 with self.patch_call( 787 self.call.device.build_version_sdk, 788 return_value=version_codes.LOLLIPOP_MR1): 789 self.assertEquals('su -c foo', self.device._Su('foo')) 790 791 def testSu_mAndAbove(self): 792 with self.patch_call( 793 self.call.device.build_version_sdk, 794 return_value=version_codes.MARSHMALLOW): 795 self.assertEquals('su 0 foo', self.device._Su('foo')) 796 797 798class DeviceUtilsRunShellCommandTest(DeviceUtilsTest): 799 800 def setUp(self): 801 super(DeviceUtilsRunShellCommandTest, self).setUp() 802 self.device.NeedsSU = mock.Mock(return_value=False) 803 804 def testRunShellCommand_commandAsList(self): 805 with self.assertCall(self.call.adb.Shell('pm list packages'), ''): 806 self.device.RunShellCommand(['pm', 'list', 'packages']) 807 808 def testRunShellCommand_commandAsListQuoted(self): 809 with self.assertCall(self.call.adb.Shell("echo 'hello world' '$10'"), ''): 810 self.device.RunShellCommand(['echo', 'hello world', '$10']) 811 812 def testRunShellCommand_commandAsString(self): 813 with self.assertCall(self.call.adb.Shell('echo "$VAR"'), ''): 814 self.device.RunShellCommand('echo "$VAR"') 815 816 def testNewRunShellImpl_withEnv(self): 817 with self.assertCall( 818 self.call.adb.Shell('VAR=some_string echo "$VAR"'), ''): 819 self.device.RunShellCommand('echo "$VAR"', env={'VAR': 'some_string'}) 820 821 def testNewRunShellImpl_withEnvQuoted(self): 822 with self.assertCall( 823 self.call.adb.Shell('PATH="$PATH:/other/path" run_this'), ''): 824 self.device.RunShellCommand('run_this', env={'PATH': '$PATH:/other/path'}) 825 826 def testNewRunShellImpl_withEnv_failure(self): 827 with self.assertRaises(KeyError): 828 self.device.RunShellCommand('some_cmd', env={'INVALID NAME': 'value'}) 829 830 def testNewRunShellImpl_withCwd(self): 831 with self.assertCall(self.call.adb.Shell('cd /some/test/path && ls'), ''): 832 self.device.RunShellCommand('ls', cwd='/some/test/path') 833 834 def testNewRunShellImpl_withCwdQuoted(self): 835 with self.assertCall( 836 self.call.adb.Shell("cd '/some test/path with/spaces' && ls"), ''): 837 self.device.RunShellCommand('ls', cwd='/some test/path with/spaces') 838 839 def testRunShellCommand_withHugeCmd(self): 840 payload = 'hi! ' * 1024 841 expected_cmd = "echo '%s'" % payload 842 with self.assertCalls( 843 (mock.call.devil.android.device_temp_file.DeviceTempFile( 844 self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')), 845 self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd), 846 (self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')): 847 self.assertEquals([payload], 848 self.device.RunShellCommand(['echo', payload])) 849 850 def testRunShellCommand_withHugeCmdAndSU(self): 851 payload = 'hi! ' * 1024 852 expected_cmd_without_su = """sh -c 'echo '"'"'%s'"'"''""" % payload 853 expected_cmd = 'su -c %s' % expected_cmd_without_su 854 with self.assertCalls( 855 (self.call.device.NeedsSU(), True), 856 (self.call.device._Su(expected_cmd_without_su), expected_cmd), 857 (mock.call.devil.android.device_temp_file.DeviceTempFile( 858 self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')), 859 self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd), 860 (self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')): 861 self.assertEquals( 862 [payload], 863 self.device.RunShellCommand(['echo', payload], as_root=True)) 864 865 def testRunShellCommand_withSu(self): 866 expected_cmd_without_su = "sh -c 'setprop service.adb.root 0'" 867 expected_cmd = 'su -c %s' % expected_cmd_without_su 868 with self.assertCalls( 869 (self.call.device.NeedsSU(), True), 870 (self.call.device._Su(expected_cmd_without_su), expected_cmd), 871 (self.call.adb.Shell(expected_cmd), '')): 872 self.device.RunShellCommand('setprop service.adb.root 0', as_root=True) 873 874 def testRunShellCommand_manyLines(self): 875 cmd = 'ls /some/path' 876 with self.assertCall(self.call.adb.Shell(cmd), 'file1\nfile2\nfile3\n'): 877 self.assertEquals(['file1', 'file2', 'file3'], 878 self.device.RunShellCommand(cmd)) 879 880 def testRunShellCommand_manyLinesRawOutput(self): 881 cmd = 'ls /some/path' 882 with self.assertCall(self.call.adb.Shell(cmd), '\rfile1\nfile2\r\nfile3\n'): 883 self.assertEquals('\rfile1\nfile2\r\nfile3\n', 884 self.device.RunShellCommand(cmd, raw_output=True)) 885 886 def testRunShellCommand_singleLine_success(self): 887 cmd = 'echo $VALUE' 888 with self.assertCall(self.call.adb.Shell(cmd), 'some value\n'): 889 self.assertEquals('some value', 890 self.device.RunShellCommand(cmd, single_line=True)) 891 892 def testRunShellCommand_singleLine_successEmptyLine(self): 893 cmd = 'echo $VALUE' 894 with self.assertCall(self.call.adb.Shell(cmd), '\n'): 895 self.assertEquals('', 896 self.device.RunShellCommand(cmd, single_line=True)) 897 898 def testRunShellCommand_singleLine_successWithoutEndLine(self): 899 cmd = 'echo -n $VALUE' 900 with self.assertCall(self.call.adb.Shell(cmd), 'some value'): 901 self.assertEquals('some value', 902 self.device.RunShellCommand(cmd, single_line=True)) 903 904 def testRunShellCommand_singleLine_successNoOutput(self): 905 cmd = 'echo -n $VALUE' 906 with self.assertCall(self.call.adb.Shell(cmd), ''): 907 self.assertEquals('', 908 self.device.RunShellCommand(cmd, single_line=True)) 909 910 def testRunShellCommand_singleLine_failTooManyLines(self): 911 cmd = 'echo $VALUE' 912 with self.assertCall(self.call.adb.Shell(cmd), 913 'some value\nanother value\n'): 914 with self.assertRaises(device_errors.CommandFailedError): 915 self.device.RunShellCommand(cmd, single_line=True) 916 917 def testRunShellCommand_checkReturn_success(self): 918 cmd = 'echo $ANDROID_DATA' 919 output = '/data\n' 920 with self.assertCall(self.call.adb.Shell(cmd), output): 921 self.assertEquals([output.rstrip()], 922 self.device.RunShellCommand(cmd, check_return=True)) 923 924 def testRunShellCommand_checkReturn_failure(self): 925 cmd = 'ls /root' 926 output = 'opendir failed, Permission denied\n' 927 with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)): 928 with self.assertRaises(device_errors.AdbCommandFailedError): 929 self.device.RunShellCommand(cmd, check_return=True) 930 931 def testRunShellCommand_checkReturn_disabled(self): 932 cmd = 'ls /root' 933 output = 'opendir failed, Permission denied\n' 934 with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)): 935 self.assertEquals([output.rstrip()], 936 self.device.RunShellCommand(cmd, check_return=False)) 937 938 def testRunShellCommand_largeOutput_enabled(self): 939 cmd = 'echo $VALUE' 940 temp_file = MockTempFile('/sdcard/temp-123') 941 cmd_redirect = '( %s )>%s' % (cmd, temp_file.name) 942 with self.assertCalls( 943 (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb), 944 temp_file), 945 (self.call.adb.Shell(cmd_redirect)), 946 (self.call.device.ReadFile(temp_file.name, force_pull=True), 947 'something')): 948 self.assertEquals( 949 ['something'], 950 self.device.RunShellCommand( 951 cmd, large_output=True, check_return=True)) 952 953 def testRunShellCommand_largeOutput_disabledNoTrigger(self): 954 cmd = 'something' 955 with self.assertCall(self.call.adb.Shell(cmd), self.ShellError('')): 956 with self.assertRaises(device_errors.AdbCommandFailedError): 957 self.device.RunShellCommand(cmd, check_return=True) 958 959 def testRunShellCommand_largeOutput_disabledTrigger(self): 960 cmd = 'echo $VALUE' 961 temp_file = MockTempFile('/sdcard/temp-123') 962 cmd_redirect = '( %s )>%s' % (cmd, temp_file.name) 963 with self.assertCalls( 964 (self.call.adb.Shell(cmd), self.ShellError('', None)), 965 (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb), 966 temp_file), 967 (self.call.adb.Shell(cmd_redirect)), 968 (self.call.device.ReadFile(mock.ANY, force_pull=True), 969 'something')): 970 self.assertEquals(['something'], 971 self.device.RunShellCommand(cmd, check_return=True)) 972 973 974class DeviceUtilsRunPipedShellCommandTest(DeviceUtilsTest): 975 976 def testRunPipedShellCommand_success(self): 977 with self.assertCall( 978 self.call.device.RunShellCommand( 979 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"', 980 check_return=True), 981 ['This line contains foo', 'PIPESTATUS: 0 0']): 982 self.assertEquals(['This line contains foo'], 983 self.device._RunPipedShellCommand('ps | grep foo')) 984 985 def testRunPipedShellCommand_firstCommandFails(self): 986 with self.assertCall( 987 self.call.device.RunShellCommand( 988 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"', 989 check_return=True), 990 ['PIPESTATUS: 1 0']): 991 with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec: 992 self.device._RunPipedShellCommand('ps | grep foo') 993 self.assertEquals([1, 0], ec.exception.status) 994 995 def testRunPipedShellCommand_secondCommandFails(self): 996 with self.assertCall( 997 self.call.device.RunShellCommand( 998 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"', 999 check_return=True), 1000 ['PIPESTATUS: 0 1']): 1001 with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec: 1002 self.device._RunPipedShellCommand('ps | grep foo') 1003 self.assertEquals([0, 1], ec.exception.status) 1004 1005 def testRunPipedShellCommand_outputCutOff(self): 1006 with self.assertCall( 1007 self.call.device.RunShellCommand( 1008 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"', 1009 check_return=True), 1010 ['foo.bar'] * 256 + ['foo.ba']): 1011 with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec: 1012 self.device._RunPipedShellCommand('ps | grep foo') 1013 self.assertIs(None, ec.exception.status) 1014 1015 1016@mock.patch('time.sleep', mock.Mock()) 1017class DeviceUtilsKillAllTest(DeviceUtilsTest): 1018 1019 def testKillAll_noMatchingProcessesFailure(self): 1020 with self.assertCall(self.call.device.GetPids('test_process'), {}): 1021 with self.assertRaises(device_errors.CommandFailedError): 1022 self.device.KillAll('test_process') 1023 1024 def testKillAll_noMatchingProcessesQuiet(self): 1025 with self.assertCall(self.call.device.GetPids('test_process'), {}): 1026 self.assertEqual(0, self.device.KillAll('test_process', quiet=True)) 1027 1028 def testKillAll_nonblocking(self): 1029 with self.assertCalls( 1030 (self.call.device.GetPids('some.process'), 1031 {'some.process': ['1234'], 'some.processing.thing': ['5678']}), 1032 (self.call.adb.Shell('kill -9 1234 5678'), '')): 1033 self.assertEquals( 1034 2, self.device.KillAll('some.process', blocking=False)) 1035 1036 def testKillAll_blocking(self): 1037 with self.assertCalls( 1038 (self.call.device.GetPids('some.process'), 1039 {'some.process': ['1234'], 'some.processing.thing': ['5678']}), 1040 (self.call.adb.Shell('kill -9 1234 5678'), ''), 1041 (self.call.device.GetPids('some.process'), 1042 {'some.processing.thing': ['5678']}), 1043 (self.call.device.GetPids('some.process'), 1044 {'some.process': ['1111']})): # Other instance with different pid. 1045 self.assertEquals( 1046 2, self.device.KillAll('some.process', blocking=True)) 1047 1048 def testKillAll_exactNonblocking(self): 1049 with self.assertCalls( 1050 (self.call.device.GetPids('some.process'), 1051 {'some.process': ['1234'], 'some.processing.thing': ['5678']}), 1052 (self.call.adb.Shell('kill -9 1234'), '')): 1053 self.assertEquals( 1054 1, self.device.KillAll('some.process', exact=True, blocking=False)) 1055 1056 def testKillAll_exactBlocking(self): 1057 with self.assertCalls( 1058 (self.call.device.GetPids('some.process'), 1059 {'some.process': ['1234'], 'some.processing.thing': ['5678']}), 1060 (self.call.adb.Shell('kill -9 1234'), ''), 1061 (self.call.device.GetPids('some.process'), 1062 {'some.process': ['1234'], 'some.processing.thing': ['5678']}), 1063 (self.call.device.GetPids('some.process'), 1064 {'some.processing.thing': ['5678']})): 1065 self.assertEquals( 1066 1, self.device.KillAll('some.process', exact=True, blocking=True)) 1067 1068 def testKillAll_root(self): 1069 with self.assertCalls( 1070 (self.call.device.GetPids('some.process'), {'some.process': ['1234']}), 1071 (self.call.device.NeedsSU(), True), 1072 (self.call.device._Su("sh -c 'kill -9 1234'"), 1073 "su -c sh -c 'kill -9 1234'"), 1074 (self.call.adb.Shell("su -c sh -c 'kill -9 1234'"), '')): 1075 self.assertEquals( 1076 1, self.device.KillAll('some.process', as_root=True)) 1077 1078 def testKillAll_sigterm(self): 1079 with self.assertCalls( 1080 (self.call.device.GetPids('some.process'), 1081 {'some.process': ['1234']}), 1082 (self.call.adb.Shell('kill -15 1234'), '')): 1083 self.assertEquals( 1084 1, self.device.KillAll('some.process', signum=device_signal.SIGTERM)) 1085 1086 def testKillAll_multipleInstances(self): 1087 with self.assertCalls( 1088 (self.call.device.GetPids('some.process'), 1089 {'some.process': ['1234', '4567']}), 1090 (self.call.adb.Shell('kill -15 1234 4567'), '')): 1091 self.assertEquals( 1092 2, self.device.KillAll('some.process', signum=device_signal.SIGTERM)) 1093 1094 1095class DeviceUtilsStartActivityTest(DeviceUtilsTest): 1096 1097 def testStartActivity_actionOnly(self): 1098 test_intent = intent.Intent(action='android.intent.action.VIEW') 1099 with self.assertCall( 1100 self.call.adb.Shell('am start ' 1101 '-a android.intent.action.VIEW'), 1102 'Starting: Intent { act=android.intent.action.VIEW }'): 1103 self.device.StartActivity(test_intent) 1104 1105 def testStartActivity_success(self): 1106 test_intent = intent.Intent(action='android.intent.action.VIEW', 1107 package='test.package', 1108 activity='.Main') 1109 with self.assertCall( 1110 self.call.adb.Shell('am start ' 1111 '-a android.intent.action.VIEW ' 1112 '-n test.package/.Main'), 1113 'Starting: Intent { act=android.intent.action.VIEW }'): 1114 self.device.StartActivity(test_intent) 1115 1116 def testStartActivity_failure(self): 1117 test_intent = intent.Intent(action='android.intent.action.VIEW', 1118 package='test.package', 1119 activity='.Main') 1120 with self.assertCall( 1121 self.call.adb.Shell('am start ' 1122 '-a android.intent.action.VIEW ' 1123 '-n test.package/.Main'), 1124 'Error: Failed to start test activity'): 1125 with self.assertRaises(device_errors.CommandFailedError): 1126 self.device.StartActivity(test_intent) 1127 1128 def testStartActivity_blocking(self): 1129 test_intent = intent.Intent(action='android.intent.action.VIEW', 1130 package='test.package', 1131 activity='.Main') 1132 with self.assertCall( 1133 self.call.adb.Shell('am start ' 1134 '-W ' 1135 '-a android.intent.action.VIEW ' 1136 '-n test.package/.Main'), 1137 'Starting: Intent { act=android.intent.action.VIEW }'): 1138 self.device.StartActivity(test_intent, blocking=True) 1139 1140 def testStartActivity_withCategory(self): 1141 test_intent = intent.Intent(action='android.intent.action.VIEW', 1142 package='test.package', 1143 activity='.Main', 1144 category='android.intent.category.HOME') 1145 with self.assertCall( 1146 self.call.adb.Shell('am start ' 1147 '-a android.intent.action.VIEW ' 1148 '-c android.intent.category.HOME ' 1149 '-n test.package/.Main'), 1150 'Starting: Intent { act=android.intent.action.VIEW }'): 1151 self.device.StartActivity(test_intent) 1152 1153 def testStartActivity_withMultipleCategories(self): 1154 test_intent = intent.Intent(action='android.intent.action.VIEW', 1155 package='test.package', 1156 activity='.Main', 1157 category=['android.intent.category.HOME', 1158 'android.intent.category.BROWSABLE']) 1159 with self.assertCall( 1160 self.call.adb.Shell('am start ' 1161 '-a android.intent.action.VIEW ' 1162 '-c android.intent.category.HOME ' 1163 '-c android.intent.category.BROWSABLE ' 1164 '-n test.package/.Main'), 1165 'Starting: Intent { act=android.intent.action.VIEW }'): 1166 self.device.StartActivity(test_intent) 1167 1168 def testStartActivity_withData(self): 1169 test_intent = intent.Intent(action='android.intent.action.VIEW', 1170 package='test.package', 1171 activity='.Main', 1172 data='http://www.google.com/') 1173 with self.assertCall( 1174 self.call.adb.Shell('am start ' 1175 '-a android.intent.action.VIEW ' 1176 '-d http://www.google.com/ ' 1177 '-n test.package/.Main'), 1178 'Starting: Intent { act=android.intent.action.VIEW }'): 1179 self.device.StartActivity(test_intent) 1180 1181 def testStartActivity_withStringExtra(self): 1182 test_intent = intent.Intent(action='android.intent.action.VIEW', 1183 package='test.package', 1184 activity='.Main', 1185 extras={'foo': 'test'}) 1186 with self.assertCall( 1187 self.call.adb.Shell('am start ' 1188 '-a android.intent.action.VIEW ' 1189 '-n test.package/.Main ' 1190 '--es foo test'), 1191 'Starting: Intent { act=android.intent.action.VIEW }'): 1192 self.device.StartActivity(test_intent) 1193 1194 def testStartActivity_withBoolExtra(self): 1195 test_intent = intent.Intent(action='android.intent.action.VIEW', 1196 package='test.package', 1197 activity='.Main', 1198 extras={'foo': True}) 1199 with self.assertCall( 1200 self.call.adb.Shell('am start ' 1201 '-a android.intent.action.VIEW ' 1202 '-n test.package/.Main ' 1203 '--ez foo True'), 1204 'Starting: Intent { act=android.intent.action.VIEW }'): 1205 self.device.StartActivity(test_intent) 1206 1207 def testStartActivity_withIntExtra(self): 1208 test_intent = intent.Intent(action='android.intent.action.VIEW', 1209 package='test.package', 1210 activity='.Main', 1211 extras={'foo': 123}) 1212 with self.assertCall( 1213 self.call.adb.Shell('am start ' 1214 '-a android.intent.action.VIEW ' 1215 '-n test.package/.Main ' 1216 '--ei foo 123'), 1217 'Starting: Intent { act=android.intent.action.VIEW }'): 1218 self.device.StartActivity(test_intent) 1219 1220 def testStartActivity_withTraceFile(self): 1221 test_intent = intent.Intent(action='android.intent.action.VIEW', 1222 package='test.package', 1223 activity='.Main') 1224 with self.assertCall( 1225 self.call.adb.Shell('am start ' 1226 '--start-profiler test_trace_file.out ' 1227 '-a android.intent.action.VIEW ' 1228 '-n test.package/.Main'), 1229 'Starting: Intent { act=android.intent.action.VIEW }'): 1230 self.device.StartActivity(test_intent, 1231 trace_file_name='test_trace_file.out') 1232 1233 def testStartActivity_withForceStop(self): 1234 test_intent = intent.Intent(action='android.intent.action.VIEW', 1235 package='test.package', 1236 activity='.Main') 1237 with self.assertCall( 1238 self.call.adb.Shell('am start ' 1239 '-S ' 1240 '-a android.intent.action.VIEW ' 1241 '-n test.package/.Main'), 1242 'Starting: Intent { act=android.intent.action.VIEW }'): 1243 self.device.StartActivity(test_intent, force_stop=True) 1244 1245 def testStartActivity_withFlags(self): 1246 test_intent = intent.Intent(action='android.intent.action.VIEW', 1247 package='test.package', 1248 activity='.Main', 1249 flags=[ 1250 intent.FLAG_ACTIVITY_NEW_TASK, 1251 intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 1252 ]) 1253 with self.assertCall( 1254 self.call.adb.Shell('am start ' 1255 '-a android.intent.action.VIEW ' 1256 '-n test.package/.Main ' 1257 '-f 0x10200000'), 1258 'Starting: Intent { act=android.intent.action.VIEW }'): 1259 self.device.StartActivity(test_intent) 1260 1261 1262class DeviceUtilsStartInstrumentationTest(DeviceUtilsTest): 1263 1264 def testStartInstrumentation_nothing(self): 1265 with self.assertCalls( 1266 self.call.device.RunShellCommand( 1267 'p=test.package;am instrument "$p"/.TestInstrumentation', 1268 check_return=True, large_output=True)): 1269 self.device.StartInstrumentation( 1270 'test.package/.TestInstrumentation', 1271 finish=False, raw=False, extras=None) 1272 1273 def testStartInstrumentation_finish(self): 1274 with self.assertCalls( 1275 (self.call.device.RunShellCommand( 1276 'p=test.package;am instrument -w "$p"/.TestInstrumentation', 1277 check_return=True, large_output=True), 1278 ['OK (1 test)'])): 1279 output = self.device.StartInstrumentation( 1280 'test.package/.TestInstrumentation', 1281 finish=True, raw=False, extras=None) 1282 self.assertEquals(['OK (1 test)'], output) 1283 1284 def testStartInstrumentation_raw(self): 1285 with self.assertCalls( 1286 self.call.device.RunShellCommand( 1287 'p=test.package;am instrument -r "$p"/.TestInstrumentation', 1288 check_return=True, large_output=True)): 1289 self.device.StartInstrumentation( 1290 'test.package/.TestInstrumentation', 1291 finish=False, raw=True, extras=None) 1292 1293 def testStartInstrumentation_extras(self): 1294 with self.assertCalls( 1295 self.call.device.RunShellCommand( 1296 'p=test.package;am instrument -e "$p".foo Foo -e bar \'Val \'"$p" ' 1297 '"$p"/.TestInstrumentation', 1298 check_return=True, large_output=True)): 1299 self.device.StartInstrumentation( 1300 'test.package/.TestInstrumentation', 1301 finish=False, raw=False, extras={'test.package.foo': 'Foo', 1302 'bar': 'Val test.package'}) 1303 1304 1305class DeviceUtilsBroadcastIntentTest(DeviceUtilsTest): 1306 1307 def testBroadcastIntent_noExtras(self): 1308 test_intent = intent.Intent(action='test.package.with.an.INTENT') 1309 with self.assertCall( 1310 self.call.adb.Shell('am broadcast -a test.package.with.an.INTENT'), 1311 'Broadcasting: Intent { act=test.package.with.an.INTENT } '): 1312 self.device.BroadcastIntent(test_intent) 1313 1314 def testBroadcastIntent_withExtra(self): 1315 test_intent = intent.Intent(action='test.package.with.an.INTENT', 1316 extras={'foo': 'bar value'}) 1317 with self.assertCall( 1318 self.call.adb.Shell( 1319 "am broadcast -a test.package.with.an.INTENT --es foo 'bar value'"), 1320 'Broadcasting: Intent { act=test.package.with.an.INTENT } '): 1321 self.device.BroadcastIntent(test_intent) 1322 1323 def testBroadcastIntent_withExtra_noValue(self): 1324 test_intent = intent.Intent(action='test.package.with.an.INTENT', 1325 extras={'foo': None}) 1326 with self.assertCall( 1327 self.call.adb.Shell( 1328 'am broadcast -a test.package.with.an.INTENT --esn foo'), 1329 'Broadcasting: Intent { act=test.package.with.an.INTENT } '): 1330 self.device.BroadcastIntent(test_intent) 1331 1332 1333class DeviceUtilsGoHomeTest(DeviceUtilsTest): 1334 1335 def testGoHome_popupsExist(self): 1336 with self.assertCalls( 1337 (self.call.device.RunShellCommand( 1338 ['dumpsys', 'window', 'windows'], check_return=True, 1339 large_output=True), []), 1340 (self.call.device.RunShellCommand( 1341 ['am', 'start', '-W', '-a', 'android.intent.action.MAIN', 1342 '-c', 'android.intent.category.HOME'], check_return=True), 1343 'Starting: Intent { act=android.intent.action.MAIN }\r\n'''), 1344 (self.call.device.RunShellCommand( 1345 ['dumpsys', 'window', 'windows'], check_return=True, 1346 large_output=True), []), 1347 (self.call.device.RunShellCommand( 1348 ['input', 'keyevent', '66'], check_return=True)), 1349 (self.call.device.RunShellCommand( 1350 ['input', 'keyevent', '4'], check_return=True)), 1351 (self.call.device.RunShellCommand( 1352 ['dumpsys', 'window', 'windows'], check_return=True, 1353 large_output=True), 1354 ['mCurrentFocus Launcher'])): 1355 self.device.GoHome() 1356 1357 def testGoHome_willRetry(self): 1358 with self.assertCalls( 1359 (self.call.device.RunShellCommand( 1360 ['dumpsys', 'window', 'windows'], check_return=True, 1361 large_output=True), []), 1362 (self.call.device.RunShellCommand( 1363 ['am', 'start', '-W', '-a', 'android.intent.action.MAIN', 1364 '-c', 'android.intent.category.HOME'], check_return=True), 1365 'Starting: Intent { act=android.intent.action.MAIN }\r\n'''), 1366 (self.call.device.RunShellCommand( 1367 ['dumpsys', 'window', 'windows'], check_return=True, 1368 large_output=True), []), 1369 (self.call.device.RunShellCommand( 1370 ['input', 'keyevent', '66'], check_return=True,)), 1371 (self.call.device.RunShellCommand( 1372 ['input', 'keyevent', '4'], check_return=True)), 1373 (self.call.device.RunShellCommand( 1374 ['dumpsys', 'window', 'windows'], check_return=True, 1375 large_output=True), []), 1376 (self.call.device.RunShellCommand( 1377 ['input', 'keyevent', '66'], check_return=True)), 1378 (self.call.device.RunShellCommand( 1379 ['input', 'keyevent', '4'], check_return=True)), 1380 (self.call.device.RunShellCommand( 1381 ['dumpsys', 'window', 'windows'], check_return=True, 1382 large_output=True), 1383 self.TimeoutError())): 1384 with self.assertRaises(device_errors.CommandTimeoutError): 1385 self.device.GoHome() 1386 1387 def testGoHome_alreadyFocused(self): 1388 with self.assertCall( 1389 self.call.device.RunShellCommand( 1390 ['dumpsys', 'window', 'windows'], check_return=True, 1391 large_output=True), 1392 ['mCurrentFocus Launcher']): 1393 self.device.GoHome() 1394 1395 def testGoHome_alreadyFocusedAlternateCase(self): 1396 with self.assertCall( 1397 self.call.device.RunShellCommand( 1398 ['dumpsys', 'window', 'windows'], check_return=True, 1399 large_output=True), 1400 [' mCurrentFocus .launcher/.']): 1401 self.device.GoHome() 1402 1403 def testGoHome_obtainsFocusAfterGoingHome(self): 1404 with self.assertCalls( 1405 (self.call.device.RunShellCommand( 1406 ['dumpsys', 'window', 'windows'], check_return=True, 1407 large_output=True), []), 1408 (self.call.device.RunShellCommand( 1409 ['am', 'start', '-W', '-a', 'android.intent.action.MAIN', 1410 '-c', 'android.intent.category.HOME'], check_return=True), 1411 'Starting: Intent { act=android.intent.action.MAIN }\r\n'''), 1412 (self.call.device.RunShellCommand( 1413 ['dumpsys', 'window', 'windows'], check_return=True, 1414 large_output=True), 1415 ['mCurrentFocus Launcher'])): 1416 self.device.GoHome() 1417 1418 1419class DeviceUtilsForceStopTest(DeviceUtilsTest): 1420 1421 def testForceStop(self): 1422 with self.assertCall( 1423 self.call.adb.Shell('p=test.package;if [[ "$(ps)" = *$p* ]]; then ' 1424 'am force-stop $p; fi'), 1425 ''): 1426 self.device.ForceStop('test.package') 1427 1428 1429class DeviceUtilsClearApplicationStateTest(DeviceUtilsTest): 1430 1431 def testClearApplicationState_setPermissions(self): 1432 with self.assertCalls( 1433 (self.call.device.GetProp('ro.build.version.sdk', cache=True), '17'), 1434 (self.call.device._GetApplicationPathsInternal('this.package.exists'), 1435 ['/data/app/this.package.exists.apk']), 1436 (self.call.device.RunShellCommand( 1437 ['pm', 'clear', 'this.package.exists'], 1438 check_return=True), 1439 ['Success']), 1440 (self.call.device.GrantPermissions( 1441 'this.package.exists', ['p1']), [])): 1442 self.device.ClearApplicationState( 1443 'this.package.exists', permissions=['p1']) 1444 1445 def testClearApplicationState_packageDoesntExist(self): 1446 with self.assertCalls( 1447 (self.call.device.GetProp('ro.build.version.sdk', cache=True), '11'), 1448 (self.call.device._GetApplicationPathsInternal('does.not.exist'), 1449 [])): 1450 self.device.ClearApplicationState('does.not.exist') 1451 1452 def testClearApplicationState_packageDoesntExistOnAndroidJBMR2OrAbove(self): 1453 with self.assertCalls( 1454 (self.call.device.GetProp('ro.build.version.sdk', cache=True), '18'), 1455 (self.call.device.RunShellCommand( 1456 ['pm', 'clear', 'this.package.does.not.exist'], 1457 check_return=True), 1458 ['Failed'])): 1459 self.device.ClearApplicationState('this.package.does.not.exist') 1460 1461 def testClearApplicationState_packageExists(self): 1462 with self.assertCalls( 1463 (self.call.device.GetProp('ro.build.version.sdk', cache=True), '17'), 1464 (self.call.device._GetApplicationPathsInternal('this.package.exists'), 1465 ['/data/app/this.package.exists.apk']), 1466 (self.call.device.RunShellCommand( 1467 ['pm', 'clear', 'this.package.exists'], 1468 check_return=True), 1469 ['Success'])): 1470 self.device.ClearApplicationState('this.package.exists') 1471 1472 def testClearApplicationState_packageExistsOnAndroidJBMR2OrAbove(self): 1473 with self.assertCalls( 1474 (self.call.device.GetProp('ro.build.version.sdk', cache=True), '18'), 1475 (self.call.device.RunShellCommand( 1476 ['pm', 'clear', 'this.package.exists'], 1477 check_return=True), 1478 ['Success'])): 1479 self.device.ClearApplicationState('this.package.exists') 1480 1481 1482class DeviceUtilsSendKeyEventTest(DeviceUtilsTest): 1483 1484 def testSendKeyEvent(self): 1485 with self.assertCall(self.call.adb.Shell('input keyevent 66'), ''): 1486 self.device.SendKeyEvent(66) 1487 1488 1489class DeviceUtilsPushChangedFilesIndividuallyTest(DeviceUtilsTest): 1490 1491 def testPushChangedFilesIndividually_empty(self): 1492 test_files = [] 1493 with self.assertCalls(): 1494 self.device._PushChangedFilesIndividually(test_files) 1495 1496 def testPushChangedFilesIndividually_single(self): 1497 test_files = [('/test/host/path', '/test/device/path')] 1498 with self.assertCalls(self.call.adb.Push(*test_files[0])): 1499 self.device._PushChangedFilesIndividually(test_files) 1500 1501 def testPushChangedFilesIndividually_multiple(self): 1502 test_files = [ 1503 ('/test/host/path/file1', '/test/device/path/file1'), 1504 ('/test/host/path/file2', '/test/device/path/file2')] 1505 with self.assertCalls( 1506 self.call.adb.Push(*test_files[0]), 1507 self.call.adb.Push(*test_files[1])): 1508 self.device._PushChangedFilesIndividually(test_files) 1509 1510 1511class DeviceUtilsPushChangedFilesZippedTest(DeviceUtilsTest): 1512 1513 def testPushChangedFilesZipped_noUnzipCommand(self): 1514 test_files = [('/test/host/path/file1', '/test/device/path/file1')] 1515 mock_zip_temp = mock.mock_open() 1516 mock_zip_temp.return_value.name = '/test/temp/file/tmp.zip' 1517 with self.assertCalls( 1518 (mock.call.tempfile.NamedTemporaryFile(suffix='.zip'), mock_zip_temp), 1519 (mock.call.multiprocessing.Process( 1520 target=device_utils.DeviceUtils._CreateDeviceZip, 1521 args=('/test/temp/file/tmp.zip', test_files)), mock.Mock()), 1522 (self.call.device._MaybeInstallCommands(), False)): 1523 self.assertFalse(self.device._PushChangedFilesZipped(test_files, 1524 ['/test/dir'])) 1525 1526 def _testPushChangedFilesZipped_spec(self, test_files): 1527 mock_zip_temp = mock.mock_open() 1528 mock_zip_temp.return_value.name = '/test/temp/file/tmp.zip' 1529 with self.assertCalls( 1530 (mock.call.tempfile.NamedTemporaryFile(suffix='.zip'), mock_zip_temp), 1531 (mock.call.multiprocessing.Process( 1532 target=device_utils.DeviceUtils._CreateDeviceZip, 1533 args=('/test/temp/file/tmp.zip', test_files)), mock.Mock()), 1534 (self.call.device._MaybeInstallCommands(), True), 1535 (self.call.device.NeedsSU(), True), 1536 (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb, 1537 suffix='.zip'), 1538 MockTempFile('/test/sdcard/foo123.zip')), 1539 self.call.adb.Push( 1540 '/test/temp/file/tmp.zip', '/test/sdcard/foo123.zip'), 1541 self.call.device.RunShellCommand( 1542 'unzip /test/sdcard/foo123.zip&&chmod -R 777 /test/dir', 1543 as_root=True, 1544 env={'PATH': '/data/local/tmp/bin:$PATH'}, 1545 check_return=True)): 1546 self.assertTrue(self.device._PushChangedFilesZipped(test_files, 1547 ['/test/dir'])) 1548 1549 def testPushChangedFilesZipped_single(self): 1550 self._testPushChangedFilesZipped_spec( 1551 [('/test/host/path/file1', '/test/device/path/file1')]) 1552 1553 def testPushChangedFilesZipped_multiple(self): 1554 self._testPushChangedFilesZipped_spec( 1555 [('/test/host/path/file1', '/test/device/path/file1'), 1556 ('/test/host/path/file2', '/test/device/path/file2')]) 1557 1558 1559class DeviceUtilsPathExistsTest(DeviceUtilsTest): 1560 1561 def testPathExists_pathExists(self): 1562 with self.assertCall( 1563 self.call.device.RunShellCommand( 1564 "test -e '/path/file exists'", 1565 as_root=False, check_return=True, timeout=10, retries=0), 1566 []): 1567 self.assertTrue(self.device.PathExists('/path/file exists')) 1568 1569 def testPathExists_multiplePathExists(self): 1570 with self.assertCall( 1571 self.call.device.RunShellCommand( 1572 "test -e '/path 1' -a -e /path2", 1573 as_root=False, check_return=True, timeout=10, retries=0), 1574 []): 1575 self.assertTrue(self.device.PathExists(('/path 1', '/path2'))) 1576 1577 def testPathExists_pathDoesntExist(self): 1578 with self.assertCall( 1579 self.call.device.RunShellCommand( 1580 "test -e /path/file.not.exists", 1581 as_root=False, check_return=True, timeout=10, retries=0), 1582 self.ShellError()): 1583 self.assertFalse(self.device.PathExists('/path/file.not.exists')) 1584 1585 def testPathExists_asRoot(self): 1586 with self.assertCall( 1587 self.call.device.RunShellCommand( 1588 "test -e /root/path/exists", 1589 as_root=True, check_return=True, timeout=10, retries=0), 1590 self.ShellError()): 1591 self.assertFalse( 1592 self.device.PathExists('/root/path/exists', as_root=True)) 1593 1594 def testFileExists_pathDoesntExist(self): 1595 with self.assertCall( 1596 self.call.device.RunShellCommand( 1597 "test -e /path/file.not.exists", 1598 as_root=False, check_return=True, timeout=10, retries=0), 1599 self.ShellError()): 1600 self.assertFalse(self.device.FileExists('/path/file.not.exists')) 1601 1602 1603class DeviceUtilsPullFileTest(DeviceUtilsTest): 1604 1605 def testPullFile_existsOnDevice(self): 1606 with mock.patch('os.path.exists', return_value=True): 1607 with self.assertCall( 1608 self.call.adb.Pull('/data/app/test.file.exists', 1609 '/test/file/host/path')): 1610 self.device.PullFile('/data/app/test.file.exists', 1611 '/test/file/host/path') 1612 1613 def testPullFile_doesntExistOnDevice(self): 1614 with mock.patch('os.path.exists', return_value=True): 1615 with self.assertCall( 1616 self.call.adb.Pull('/data/app/test.file.does.not.exist', 1617 '/test/file/host/path'), 1618 self.CommandError('remote object does not exist')): 1619 with self.assertRaises(device_errors.CommandFailedError): 1620 self.device.PullFile('/data/app/test.file.does.not.exist', 1621 '/test/file/host/path') 1622 1623 1624class DeviceUtilsReadFileTest(DeviceUtilsTest): 1625 1626 def testReadFileWithPull_success(self): 1627 tmp_host_dir = '/tmp/dir/on.host/' 1628 tmp_host = MockTempFile('/tmp/dir/on.host/tmp_ReadFileWithPull') 1629 tmp_host.file.read.return_value = 'some interesting contents' 1630 with self.assertCalls( 1631 (mock.call.tempfile.mkdtemp(), tmp_host_dir), 1632 (self.call.adb.Pull('/path/to/device/file', mock.ANY)), 1633 (mock.call.__builtin__.open(mock.ANY, 'r'), tmp_host), 1634 (mock.call.os.path.exists(tmp_host_dir), True), 1635 (mock.call.shutil.rmtree(tmp_host_dir), None)): 1636 self.assertEquals('some interesting contents', 1637 self.device._ReadFileWithPull('/path/to/device/file')) 1638 tmp_host.file.read.assert_called_once_with() 1639 1640 def testReadFileWithPull_rejected(self): 1641 tmp_host_dir = '/tmp/dir/on.host/' 1642 with self.assertCalls( 1643 (mock.call.tempfile.mkdtemp(), tmp_host_dir), 1644 (self.call.adb.Pull('/path/to/device/file', mock.ANY), 1645 self.CommandError()), 1646 (mock.call.os.path.exists(tmp_host_dir), True), 1647 (mock.call.shutil.rmtree(tmp_host_dir), None)): 1648 with self.assertRaises(device_errors.CommandFailedError): 1649 self.device._ReadFileWithPull('/path/to/device/file') 1650 1651 def testReadFile_exists(self): 1652 with self.assertCalls( 1653 (self.call.device.FileSize('/read/this/test/file', as_root=False), 256), 1654 (self.call.device.RunShellCommand( 1655 ['cat', '/read/this/test/file'], 1656 as_root=False, check_return=True), 1657 ['this is a test file'])): 1658 self.assertEqual('this is a test file\n', 1659 self.device.ReadFile('/read/this/test/file')) 1660 1661 def testReadFile_exists2(self): 1662 # Same as testReadFile_exists, but uses Android N ls output. 1663 with self.assertCalls( 1664 (self.call.device.FileSize('/read/this/test/file', as_root=False), 256), 1665 (self.call.device.RunShellCommand( 1666 ['cat', '/read/this/test/file'], 1667 as_root=False, check_return=True), 1668 ['this is a test file'])): 1669 self.assertEqual('this is a test file\n', 1670 self.device.ReadFile('/read/this/test/file')) 1671 1672 def testReadFile_doesNotExist(self): 1673 with self.assertCall( 1674 self.call.device.FileSize('/this/file/does.not.exist', as_root=False), 1675 self.CommandError('File does not exist')): 1676 with self.assertRaises(device_errors.CommandFailedError): 1677 self.device.ReadFile('/this/file/does.not.exist') 1678 1679 def testReadFile_zeroSize(self): 1680 with self.assertCalls( 1681 (self.call.device.FileSize('/this/file/has/zero/size', as_root=False), 1682 0), 1683 (self.call.device._ReadFileWithPull('/this/file/has/zero/size'), 1684 'but it has contents\n')): 1685 self.assertEqual('but it has contents\n', 1686 self.device.ReadFile('/this/file/has/zero/size')) 1687 1688 def testReadFile_withSU(self): 1689 with self.assertCalls( 1690 (self.call.device.FileSize( 1691 '/this/file/can.be.read.with.su', as_root=True), 256), 1692 (self.call.device.RunShellCommand( 1693 ['cat', '/this/file/can.be.read.with.su'], 1694 as_root=True, check_return=True), 1695 ['this is a test file', 'read with su'])): 1696 self.assertEqual( 1697 'this is a test file\nread with su\n', 1698 self.device.ReadFile('/this/file/can.be.read.with.su', 1699 as_root=True)) 1700 1701 def testReadFile_withPull(self): 1702 contents = 'a' * 123456 1703 with self.assertCalls( 1704 (self.call.device.FileSize('/read/this/big/test/file', as_root=False), 1705 123456), 1706 (self.call.device._ReadFileWithPull('/read/this/big/test/file'), 1707 contents)): 1708 self.assertEqual( 1709 contents, self.device.ReadFile('/read/this/big/test/file')) 1710 1711 def testReadFile_withPullAndSU(self): 1712 contents = 'b' * 123456 1713 with self.assertCalls( 1714 (self.call.device.FileSize( 1715 '/this/big/file/can.be.read.with.su', as_root=True), 123456), 1716 (self.call.device.NeedsSU(), True), 1717 (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb), 1718 MockTempFile('/sdcard/tmp/on.device')), 1719 self.call.device.RunShellCommand( 1720 'SRC=/this/big/file/can.be.read.with.su DEST=/sdcard/tmp/on.device;' 1721 'cp "$SRC" "$DEST" && chmod 666 "$DEST"', 1722 as_root=True, check_return=True), 1723 (self.call.device._ReadFileWithPull('/sdcard/tmp/on.device'), 1724 contents)): 1725 self.assertEqual( 1726 contents, 1727 self.device.ReadFile('/this/big/file/can.be.read.with.su', 1728 as_root=True)) 1729 1730 def testReadFile_forcePull(self): 1731 contents = 'a' * 123456 1732 with self.assertCall( 1733 self.call.device._ReadFileWithPull('/read/this/big/test/file'), 1734 contents): 1735 self.assertEqual( 1736 contents, 1737 self.device.ReadFile('/read/this/big/test/file', force_pull=True)) 1738 1739 1740class DeviceUtilsWriteFileTest(DeviceUtilsTest): 1741 1742 def testWriteFileWithPush_success(self): 1743 tmp_host = MockTempFile('/tmp/file/on.host') 1744 contents = 'some interesting contents' 1745 with self.assertCalls( 1746 (mock.call.tempfile.NamedTemporaryFile(), tmp_host), 1747 self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file')): 1748 self.device._WriteFileWithPush('/path/to/device/file', contents) 1749 tmp_host.file.write.assert_called_once_with(contents) 1750 1751 def testWriteFileWithPush_rejected(self): 1752 tmp_host = MockTempFile('/tmp/file/on.host') 1753 contents = 'some interesting contents' 1754 with self.assertCalls( 1755 (mock.call.tempfile.NamedTemporaryFile(), tmp_host), 1756 (self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file'), 1757 self.CommandError())): 1758 with self.assertRaises(device_errors.CommandFailedError): 1759 self.device._WriteFileWithPush('/path/to/device/file', contents) 1760 1761 def testWriteFile_withPush(self): 1762 contents = 'some large contents ' * 26 # 20 * 26 = 520 chars 1763 with self.assertCalls( 1764 self.call.device._WriteFileWithPush('/path/to/device/file', contents)): 1765 self.device.WriteFile('/path/to/device/file', contents) 1766 1767 def testWriteFile_withPushForced(self): 1768 contents = 'tiny contents' 1769 with self.assertCalls( 1770 self.call.device._WriteFileWithPush('/path/to/device/file', contents)): 1771 self.device.WriteFile('/path/to/device/file', contents, force_push=True) 1772 1773 def testWriteFile_withPushAndSU(self): 1774 contents = 'some large contents ' * 26 # 20 * 26 = 520 chars 1775 with self.assertCalls( 1776 (self.call.device.NeedsSU(), True), 1777 (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb), 1778 MockTempFile('/sdcard/tmp/on.device')), 1779 self.call.device._WriteFileWithPush('/sdcard/tmp/on.device', contents), 1780 self.call.device.RunShellCommand( 1781 ['cp', '/sdcard/tmp/on.device', '/path/to/device/file'], 1782 as_root=True, check_return=True)): 1783 self.device.WriteFile('/path/to/device/file', contents, as_root=True) 1784 1785 def testWriteFile_withEcho(self): 1786 with self.assertCall(self.call.adb.Shell( 1787 "echo -n the.contents > /test/file/to.write"), ''): 1788 self.device.WriteFile('/test/file/to.write', 'the.contents') 1789 1790 def testWriteFile_withEchoAndQuotes(self): 1791 with self.assertCall(self.call.adb.Shell( 1792 "echo -n 'the contents' > '/test/file/to write'"), ''): 1793 self.device.WriteFile('/test/file/to write', 'the contents') 1794 1795 def testWriteFile_withEchoAndSU(self): 1796 expected_cmd_without_su = "sh -c 'echo -n contents > /test/file'" 1797 expected_cmd = 'su -c %s' % expected_cmd_without_su 1798 with self.assertCalls( 1799 (self.call.device.NeedsSU(), True), 1800 (self.call.device._Su(expected_cmd_without_su), expected_cmd), 1801 (self.call.adb.Shell(expected_cmd), 1802 '')): 1803 self.device.WriteFile('/test/file', 'contents', as_root=True) 1804 1805 1806class DeviceUtilsStatDirectoryTest(DeviceUtilsTest): 1807 # Note: Also tests ListDirectory in testStatDirectory_fileList. 1808 1809 EXAMPLE_LS_OUTPUT = [ 1810 'total 12345', 1811 'drwxr-xr-x 19 root root 0 1970-04-06 18:03 .', 1812 'drwxr-xr-x 19 root root 0 1970-04-06 18:03 ..', 1813 'drwxr-xr-x 6 root root 1970-01-01 00:00 some_dir', 1814 '-rw-r--r-- 1 root root 723 1971-01-01 07:04 some_file', 1815 '-rw-r----- 1 root root 327 2009-02-13 23:30 My Music File', 1816 # Older Android versions do not print st_nlink 1817 'lrwxrwxrwx root root 1970-01-01 00:00 lnk -> /some/path', 1818 'srwxrwx--- system system 2016-05-31 17:25 a_socket1', 1819 'drwxrwxrwt system misc 1970-11-23 02:25 tmp', 1820 'drwxr-s--- system shell 1970-11-23 02:24 my_cmd', 1821 'cr--r----- root system 10, 183 1971-01-01 07:04 random', 1822 'brw------- root root 7, 0 1971-01-01 07:04 block_dev', 1823 '-rwS------ root shell 157404 2015-04-13 15:44 silly', 1824 ] 1825 1826 FILENAMES = [ 1827 'some_dir', 'some_file', 'My Music File', 'lnk', 'a_socket1', 1828 'tmp', 'my_cmd', 'random', 'block_dev', 'silly'] 1829 1830 def getStatEntries(self, path_given='/', path_listed='/'): 1831 with self.assertCall( 1832 self.call.device.RunShellCommand( 1833 ['ls', '-a', '-l', path_listed], 1834 check_return=True, as_root=False, env={'TZ': 'utc'}), 1835 self.EXAMPLE_LS_OUTPUT): 1836 entries = self.device.StatDirectory(path_given) 1837 return {f['filename']: f for f in entries} 1838 1839 def getListEntries(self): 1840 with self.assertCall( 1841 self.call.device.RunShellCommand( 1842 ['ls', '-a', '-l', '/'], 1843 check_return=True, as_root=False, env={'TZ': 'utc'}), 1844 self.EXAMPLE_LS_OUTPUT): 1845 return self.device.ListDirectory('/') 1846 1847 def testStatDirectory_forceTrailingSlash(self): 1848 self.getStatEntries(path_given='/foo/bar/', path_listed='/foo/bar/') 1849 self.getStatEntries(path_given='/foo/bar', path_listed='/foo/bar/') 1850 1851 def testStatDirectory_fileList(self): 1852 self.assertItemsEqual(self.getStatEntries().keys(), self.FILENAMES) 1853 self.assertItemsEqual(self.getListEntries(), self.FILENAMES) 1854 1855 def testStatDirectory_fileModes(self): 1856 expected_modes = ( 1857 ('some_dir', stat.S_ISDIR), 1858 ('some_file', stat.S_ISREG), 1859 ('lnk', stat.S_ISLNK), 1860 ('a_socket1', stat.S_ISSOCK), 1861 ('block_dev', stat.S_ISBLK), 1862 ('random', stat.S_ISCHR), 1863 ) 1864 entries = self.getStatEntries() 1865 for filename, check in expected_modes: 1866 self.assertTrue(check(entries[filename]['st_mode'])) 1867 1868 def testStatDirectory_filePermissions(self): 1869 should_have = ( 1870 ('some_file', stat.S_IWUSR), # Owner can write. 1871 ('tmp', stat.S_IXOTH), # Others can execute. 1872 ('tmp', stat.S_ISVTX), # Has sticky bit. 1873 ('my_cmd', stat.S_ISGID), # Has set-group-ID bit. 1874 ('silly', stat.S_ISUID), # Has set UID bit. 1875 ) 1876 should_not_have = ( 1877 ('some_file', stat.S_IWOTH), # Others can't write. 1878 ('block_dev', stat.S_IRGRP), # Group can't read. 1879 ('silly', stat.S_IXUSR), # Owner can't execute. 1880 ) 1881 entries = self.getStatEntries() 1882 for filename, bit in should_have: 1883 self.assertTrue(entries[filename]['st_mode'] & bit) 1884 for filename, bit in should_not_have: 1885 self.assertFalse(entries[filename]['st_mode'] & bit) 1886 1887 def testStatDirectory_numHardLinks(self): 1888 entries = self.getStatEntries() 1889 self.assertEqual(entries['some_dir']['st_nlink'], 6) 1890 self.assertEqual(entries['some_file']['st_nlink'], 1) 1891 self.assertFalse('st_nlink' in entries['tmp']) 1892 1893 def testStatDirectory_fileOwners(self): 1894 entries = self.getStatEntries() 1895 self.assertEqual(entries['some_dir']['st_owner'], 'root') 1896 self.assertEqual(entries['my_cmd']['st_owner'], 'system') 1897 self.assertEqual(entries['my_cmd']['st_group'], 'shell') 1898 self.assertEqual(entries['tmp']['st_group'], 'misc') 1899 1900 def testStatDirectory_fileSize(self): 1901 entries = self.getStatEntries() 1902 self.assertEqual(entries['some_file']['st_size'], 723) 1903 self.assertEqual(entries['My Music File']['st_size'], 327) 1904 # Sizes are sometimes not reported for non-regular files, don't try to 1905 # guess the size in those cases. 1906 self.assertFalse('st_size' in entries['some_dir']) 1907 1908 def testStatDirectory_fileDateTime(self): 1909 entries = self.getStatEntries() 1910 self.assertEqual(entries['some_dir']['st_mtime'], 0) # Epoch! 1911 self.assertEqual(entries['My Music File']['st_mtime'], 1234567800) 1912 1913 def testStatDirectory_deviceType(self): 1914 entries = self.getStatEntries() 1915 self.assertEqual(entries['random']['st_rdev_pair'], (10, 183)) 1916 self.assertEqual(entries['block_dev']['st_rdev_pair'], (7, 0)) 1917 1918 def testStatDirectory_symbolicLinks(self): 1919 entries = self.getStatEntries() 1920 self.assertEqual(entries['lnk']['symbolic_link_to'], '/some/path') 1921 for d in entries.itervalues(): 1922 self.assertEqual('symbolic_link_to' in d, stat.S_ISLNK(d['st_mode'])) 1923 1924 1925class DeviceUtilsStatPathTest(DeviceUtilsTest): 1926 1927 EXAMPLE_DIRECTORY = [ 1928 {'filename': 'foo.txt', 'st_size': 123, 'st_time': 456}, 1929 {'filename': 'some_dir', 'st_time': 0} 1930 ] 1931 INDEX = {e['filename']: e for e in EXAMPLE_DIRECTORY} 1932 1933 def testStatPath_file(self): 1934 with self.assertCall( 1935 self.call.device.StatDirectory('/data/local/tmp', as_root=False), 1936 self.EXAMPLE_DIRECTORY): 1937 self.assertEquals(self.INDEX['foo.txt'], 1938 self.device.StatPath('/data/local/tmp/foo.txt')) 1939 1940 def testStatPath_directory(self): 1941 with self.assertCall( 1942 self.call.device.StatDirectory('/data/local/tmp', as_root=False), 1943 self.EXAMPLE_DIRECTORY): 1944 self.assertEquals(self.INDEX['some_dir'], 1945 self.device.StatPath('/data/local/tmp/some_dir')) 1946 1947 def testStatPath_directoryWithTrailingSlash(self): 1948 with self.assertCall( 1949 self.call.device.StatDirectory('/data/local/tmp', as_root=False), 1950 self.EXAMPLE_DIRECTORY): 1951 self.assertEquals(self.INDEX['some_dir'], 1952 self.device.StatPath('/data/local/tmp/some_dir/')) 1953 1954 def testStatPath_doesNotExist(self): 1955 with self.assertCall( 1956 self.call.device.StatDirectory('/data/local/tmp', as_root=False), 1957 self.EXAMPLE_DIRECTORY): 1958 with self.assertRaises(device_errors.CommandFailedError): 1959 self.device.StatPath('/data/local/tmp/does.not.exist.txt') 1960 1961 1962class DeviceUtilsFileSizeTest(DeviceUtilsTest): 1963 1964 EXAMPLE_DIRECTORY = [ 1965 {'filename': 'foo.txt', 'st_size': 123, 'st_mtime': 456}, 1966 {'filename': 'some_dir', 'st_mtime': 0} 1967 ] 1968 1969 def testFileSize_file(self): 1970 with self.assertCall( 1971 self.call.device.StatDirectory('/data/local/tmp', as_root=False), 1972 self.EXAMPLE_DIRECTORY): 1973 self.assertEquals(123, 1974 self.device.FileSize('/data/local/tmp/foo.txt')) 1975 1976 def testFileSize_doesNotExist(self): 1977 with self.assertCall( 1978 self.call.device.StatDirectory('/data/local/tmp', as_root=False), 1979 self.EXAMPLE_DIRECTORY): 1980 with self.assertRaises(device_errors.CommandFailedError): 1981 self.device.FileSize('/data/local/tmp/does.not.exist.txt') 1982 1983 def testFileSize_directoryWithNoSize(self): 1984 with self.assertCall( 1985 self.call.device.StatDirectory('/data/local/tmp', as_root=False), 1986 self.EXAMPLE_DIRECTORY): 1987 with self.assertRaises(device_errors.CommandFailedError): 1988 self.device.FileSize('/data/local/tmp/some_dir') 1989 1990 1991class DeviceUtilsSetJavaAssertsTest(DeviceUtilsTest): 1992 1993 def testSetJavaAsserts_enable(self): 1994 with self.assertCalls( 1995 (self.call.device.ReadFile(self.device.LOCAL_PROPERTIES_PATH), 1996 'some.example.prop=with an example value\n' 1997 'some.other.prop=value_ok\n'), 1998 self.call.device.WriteFile( 1999 self.device.LOCAL_PROPERTIES_PATH, 2000 'some.example.prop=with an example value\n' 2001 'some.other.prop=value_ok\n' 2002 'dalvik.vm.enableassertions=all\n'), 2003 (self.call.device.GetProp('dalvik.vm.enableassertions'), ''), 2004 self.call.device.SetProp('dalvik.vm.enableassertions', 'all')): 2005 self.assertTrue(self.device.SetJavaAsserts(True)) 2006 2007 def testSetJavaAsserts_disable(self): 2008 with self.assertCalls( 2009 (self.call.device.ReadFile(self.device.LOCAL_PROPERTIES_PATH), 2010 'some.example.prop=with an example value\n' 2011 'dalvik.vm.enableassertions=all\n' 2012 'some.other.prop=value_ok\n'), 2013 self.call.device.WriteFile( 2014 self.device.LOCAL_PROPERTIES_PATH, 2015 'some.example.prop=with an example value\n' 2016 'some.other.prop=value_ok\n'), 2017 (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all'), 2018 self.call.device.SetProp('dalvik.vm.enableassertions', '')): 2019 self.assertTrue(self.device.SetJavaAsserts(False)) 2020 2021 def testSetJavaAsserts_alreadyEnabled(self): 2022 with self.assertCalls( 2023 (self.call.device.ReadFile(self.device.LOCAL_PROPERTIES_PATH), 2024 'some.example.prop=with an example value\n' 2025 'dalvik.vm.enableassertions=all\n' 2026 'some.other.prop=value_ok\n'), 2027 (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all')): 2028 self.assertFalse(self.device.SetJavaAsserts(True)) 2029 2030 def testSetJavaAsserts_malformedLocalProp(self): 2031 with self.assertCalls( 2032 (self.call.device.ReadFile(self.device.LOCAL_PROPERTIES_PATH), 2033 'some.example.prop=with an example value\n' 2034 'malformed_property\n' 2035 'dalvik.vm.enableassertions=all\n' 2036 'some.other.prop=value_ok\n'), 2037 (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all')): 2038 self.assertFalse(self.device.SetJavaAsserts(True)) 2039 2040 2041class DeviceUtilsEnsureCacheInitializedTest(DeviceUtilsTest): 2042 2043 def testEnsureCacheInitialized_noCache_success(self): 2044 self.assertIsNone(self.device._cache['token']) 2045 with self.assertCall( 2046 self.call.device.RunShellCommand( 2047 AnyStringWith('getprop'), check_return=True, large_output=True), 2048 ['/sdcard', 'TOKEN']): 2049 self.device._EnsureCacheInitialized() 2050 self.assertIsNotNone(self.device._cache['token']) 2051 2052 def testEnsureCacheInitialized_noCache_failure(self): 2053 self.assertIsNone(self.device._cache['token']) 2054 with self.assertCall( 2055 self.call.device.RunShellCommand( 2056 AnyStringWith('getprop'), check_return=True, large_output=True), 2057 self.TimeoutError()): 2058 with self.assertRaises(device_errors.CommandTimeoutError): 2059 self.device._EnsureCacheInitialized() 2060 self.assertIsNone(self.device._cache['token']) 2061 2062 def testEnsureCacheInitialized_cache(self): 2063 self.device._cache['token'] = 'TOKEN' 2064 with self.assertCalls(): 2065 self.device._EnsureCacheInitialized() 2066 self.assertIsNotNone(self.device._cache['token']) 2067 2068 2069class DeviceUtilsGetPropTest(DeviceUtilsTest): 2070 2071 def testGetProp_exists(self): 2072 with self.assertCall( 2073 self.call.device.RunShellCommand( 2074 ['getprop', 'test.property'], check_return=True, single_line=True, 2075 timeout=self.device._default_timeout, 2076 retries=self.device._default_retries), 2077 'property_value'): 2078 self.assertEqual('property_value', 2079 self.device.GetProp('test.property')) 2080 2081 def testGetProp_doesNotExist(self): 2082 with self.assertCall( 2083 self.call.device.RunShellCommand( 2084 ['getprop', 'property.does.not.exist'], 2085 check_return=True, single_line=True, 2086 timeout=self.device._default_timeout, 2087 retries=self.device._default_retries), 2088 ''): 2089 self.assertEqual('', self.device.GetProp('property.does.not.exist')) 2090 2091 def testGetProp_cachedRoProp(self): 2092 with self.assertCalls( 2093 self.EnsureCacheInitialized(props=['[ro.build.type]: [userdebug]'])): 2094 self.assertEqual('userdebug', 2095 self.device.GetProp('ro.build.type', cache=True)) 2096 self.assertEqual('userdebug', 2097 self.device.GetProp('ro.build.type', cache=True)) 2098 2099 2100class DeviceUtilsSetPropTest(DeviceUtilsTest): 2101 2102 def testSetProp(self): 2103 with self.assertCall( 2104 self.call.device.RunShellCommand( 2105 ['setprop', 'test.property', 'test value'], check_return=True)): 2106 self.device.SetProp('test.property', 'test value') 2107 2108 def testSetProp_check_succeeds(self): 2109 with self.assertCalls( 2110 (self.call.device.RunShellCommand( 2111 ['setprop', 'test.property', 'new_value'], check_return=True)), 2112 (self.call.device.GetProp('test.property', cache=False), 'new_value')): 2113 self.device.SetProp('test.property', 'new_value', check=True) 2114 2115 def testSetProp_check_fails(self): 2116 with self.assertCalls( 2117 (self.call.device.RunShellCommand( 2118 ['setprop', 'test.property', 'new_value'], check_return=True)), 2119 (self.call.device.GetProp('test.property', cache=False), 'old_value')): 2120 with self.assertRaises(device_errors.CommandFailedError): 2121 self.device.SetProp('test.property', 'new_value', check=True) 2122 2123 2124class DeviceUtilsGetPidsTest(DeviceUtilsTest): 2125 2126 def testGetPids_noMatches(self): 2127 with self.assertCall( 2128 self.call.device._RunPipedShellCommand('ps | grep -F does.not.match'), 2129 []): 2130 self.assertEqual({}, self.device.GetPids('does.not.match')) 2131 2132 def testGetPids_oneMatch(self): 2133 with self.assertCall( 2134 self.call.device._RunPipedShellCommand('ps | grep -F one.match'), 2135 ['user 1001 100 1024 1024 ffffffff 00000000 one.match']): 2136 self.assertEqual( 2137 {'one.match': ['1001']}, 2138 self.device.GetPids('one.match')) 2139 2140 def testGetPids_multipleMatches(self): 2141 with self.assertCall( 2142 self.call.device._RunPipedShellCommand('ps | grep -F match'), 2143 ['user 1001 100 1024 1024 ffffffff 00000000 one.match', 2144 'user 1002 100 1024 1024 ffffffff 00000000 two.match', 2145 'user 1003 100 1024 1024 ffffffff 00000000 three.match']): 2146 self.assertEqual( 2147 {'one.match': ['1001'], 2148 'two.match': ['1002'], 2149 'three.match': ['1003']}, 2150 self.device.GetPids('match')) 2151 2152 def testGetPids_exactMatch(self): 2153 with self.assertCall( 2154 self.call.device._RunPipedShellCommand('ps | grep -F exact.match'), 2155 ['user 1000 100 1024 1024 ffffffff 00000000 not.exact.match', 2156 'user 1234 100 1024 1024 ffffffff 00000000 exact.match']): 2157 self.assertEqual( 2158 {'not.exact.match': ['1000'], 'exact.match': ['1234']}, 2159 self.device.GetPids('exact.match')) 2160 2161 def testGetPids_quotable(self): 2162 with self.assertCall( 2163 self.call.device._RunPipedShellCommand("ps | grep -F 'my$process'"), 2164 ['user 1234 100 1024 1024 ffffffff 00000000 my$process']): 2165 self.assertEqual( 2166 {'my$process': ['1234']}, self.device.GetPids('my$process')) 2167 2168 def testGetPids_multipleInstances(self): 2169 with self.assertCall( 2170 self.call.device._RunPipedShellCommand('ps | grep -F foo'), 2171 ['user 1000 100 1024 1024 ffffffff 00000000 foo', 2172 'user 1234 100 1024 1024 ffffffff 00000000 foo']): 2173 self.assertEqual( 2174 {'foo': ['1000', '1234']}, 2175 self.device.GetPids('foo')) 2176 2177 2178class DeviceUtilsTakeScreenshotTest(DeviceUtilsTest): 2179 2180 def testTakeScreenshot_fileNameProvided(self): 2181 with self.assertCalls( 2182 (mock.call.devil.android.device_temp_file.DeviceTempFile( 2183 self.adb, suffix='.png'), 2184 MockTempFile('/tmp/path/temp-123.png')), 2185 (self.call.adb.Shell('/system/bin/screencap -p /tmp/path/temp-123.png'), 2186 ''), 2187 self.call.device.PullFile('/tmp/path/temp-123.png', 2188 '/test/host/screenshot.png')): 2189 self.device.TakeScreenshot('/test/host/screenshot.png') 2190 2191 2192class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsTest): 2193 2194 def setUp(self): 2195 super(DeviceUtilsGetMemoryUsageForPidTest, self).setUp() 2196 2197 def testGetMemoryUsageForPid_validPid(self): 2198 with self.assertCalls( 2199 (self.call.device._RunPipedShellCommand( 2200 'showmap 1234 | grep TOTAL', as_root=True), 2201 ['100 101 102 103 104 105 106 107 TOTAL']), 2202 (self.call.device.ReadFile('/proc/1234/status', as_root=True), 2203 'VmHWM: 1024 kB\n')): 2204 self.assertEqual( 2205 { 2206 'Size': 100, 2207 'Rss': 101, 2208 'Pss': 102, 2209 'Shared_Clean': 103, 2210 'Shared_Dirty': 104, 2211 'Private_Clean': 105, 2212 'Private_Dirty': 106, 2213 'VmHWM': 1024 2214 }, 2215 self.device.GetMemoryUsageForPid(1234)) 2216 2217 def testGetMemoryUsageForPid_noSmaps(self): 2218 with self.assertCalls( 2219 (self.call.device._RunPipedShellCommand( 2220 'showmap 4321 | grep TOTAL', as_root=True), 2221 ['cannot open /proc/4321/smaps: No such file or directory']), 2222 (self.call.device.ReadFile('/proc/4321/status', as_root=True), 2223 'VmHWM: 1024 kb\n')): 2224 self.assertEquals({'VmHWM': 1024}, self.device.GetMemoryUsageForPid(4321)) 2225 2226 def testGetMemoryUsageForPid_noStatus(self): 2227 with self.assertCalls( 2228 (self.call.device._RunPipedShellCommand( 2229 'showmap 4321 | grep TOTAL', as_root=True), 2230 ['100 101 102 103 104 105 106 107 TOTAL']), 2231 (self.call.device.ReadFile('/proc/4321/status', as_root=True), 2232 self.CommandError())): 2233 self.assertEquals( 2234 { 2235 'Size': 100, 2236 'Rss': 101, 2237 'Pss': 102, 2238 'Shared_Clean': 103, 2239 'Shared_Dirty': 104, 2240 'Private_Clean': 105, 2241 'Private_Dirty': 106, 2242 }, 2243 self.device.GetMemoryUsageForPid(4321)) 2244 2245 2246class DeviceUtilsDismissCrashDialogIfNeededTest(DeviceUtilsTest): 2247 2248 def testDismissCrashDialogIfNeeded_crashedPageckageNotFound(self): 2249 sample_dumpsys_output = ''' 2250WINDOW MANAGER WINDOWS (dumpsys window windows) 2251 Window #11 Window{f8b647a u0 SearchPanel}: 2252 mDisplayId=0 mSession=Session{8 94:122} mClient=android.os.BinderProxy@1ba5 2253 mOwnerUid=100 mShowToOwnerOnly=false package=com.android.systemui appop=NONE 2254 mAttrs=WM.LayoutParams{(0,0)(fillxfill) gr=#53 sim=#31 ty=2024 fl=100 2255 Requested w=1080 h=1920 mLayoutSeq=426 2256 mBaseLayer=211000 mSubLayer=0 mAnimLayer=211000+0=211000 mLastLayer=211000 2257''' 2258 with self.assertCalls( 2259 (self.call.device.RunShellCommand( 2260 ['dumpsys', 'window', 'windows'], check_return=True, 2261 large_output=True), sample_dumpsys_output.split('\n'))): 2262 package_name = self.device.DismissCrashDialogIfNeeded() 2263 self.assertIsNone(package_name) 2264 2265 def testDismissCrashDialogIfNeeded_crashedPageckageFound(self): 2266 sample_dumpsys_output = ''' 2267WINDOW MANAGER WINDOWS (dumpsys window windows) 2268 Window #11 Window{f8b647a u0 SearchPanel}: 2269 mDisplayId=0 mSession=Session{8 94:122} mClient=android.os.BinderProxy@1ba5 2270 mOwnerUid=102 mShowToOwnerOnly=false package=com.android.systemui appop=NONE 2271 mAttrs=WM.LayoutParams{(0,0)(fillxfill) gr=#53 sim=#31 ty=2024 fl=100 2272 Requested w=1080 h=1920 mLayoutSeq=426 2273 mBaseLayer=211000 mSubLayer=0 mAnimLayer=211000+0=211000 mLastLayer=211000 2274 mHasPermanentDpad=false 2275 mCurrentFocus=Window{3a27740f u0 Application Error: com.android.chrome} 2276 mFocusedApp=AppWindowToken{470af6f token=Token{272ec24e ActivityRecord{t894}}} 2277''' 2278 with self.assertCalls( 2279 (self.call.device.RunShellCommand( 2280 ['dumpsys', 'window', 'windows'], check_return=True, 2281 large_output=True), sample_dumpsys_output.split('\n')), 2282 (self.call.device.RunShellCommand( 2283 ['input', 'keyevent', '22'], check_return=True)), 2284 (self.call.device.RunShellCommand( 2285 ['input', 'keyevent', '22'], check_return=True)), 2286 (self.call.device.RunShellCommand( 2287 ['input', 'keyevent', '66'], check_return=True)), 2288 (self.call.device.RunShellCommand( 2289 ['dumpsys', 'window', 'windows'], check_return=True, 2290 large_output=True), [])): 2291 package_name = self.device.DismissCrashDialogIfNeeded() 2292 self.assertEqual(package_name, 'com.android.chrome') 2293 2294 2295class DeviceUtilsClientCache(DeviceUtilsTest): 2296 2297 def testClientCache_twoCaches(self): 2298 self.device._cache['test'] = 0 2299 client_cache_one = self.device.GetClientCache('ClientOne') 2300 client_cache_one['test'] = 1 2301 client_cache_two = self.device.GetClientCache('ClientTwo') 2302 client_cache_two['test'] = 2 2303 self.assertEqual(self.device._cache['test'], 0) 2304 self.assertEqual(client_cache_one, {'test': 1}) 2305 self.assertEqual(client_cache_two, {'test': 2}) 2306 self.device._ClearCache() 2307 self.assertTrue('test' not in self.device._cache) 2308 self.assertEqual(client_cache_one, {}) 2309 self.assertEqual(client_cache_two, {}) 2310 2311 def testClientCache_multipleInstances(self): 2312 client_cache_one = self.device.GetClientCache('ClientOne') 2313 client_cache_one['test'] = 1 2314 client_cache_two = self.device.GetClientCache('ClientOne') 2315 self.assertEqual(client_cache_one, {'test': 1}) 2316 self.assertEqual(client_cache_two, {'test': 1}) 2317 self.device._ClearCache() 2318 self.assertEqual(client_cache_one, {}) 2319 self.assertEqual(client_cache_two, {}) 2320 2321 2322class DeviceUtilsHealthyDevicesTest(mock_calls.TestCase): 2323 2324 def testHealthyDevices_emptyBlacklist_defaultDeviceArg(self): 2325 test_serials = ['0123456789abcdef', 'fedcba9876543210'] 2326 with self.assertCalls( 2327 (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(), 2328 [_AdbWrapperMock(s) for s in test_serials])): 2329 blacklist = mock.NonCallableMock(**{'Read.return_value': []}) 2330 devices = device_utils.DeviceUtils.HealthyDevices(blacklist) 2331 for serial, device in zip(test_serials, devices): 2332 self.assertTrue(isinstance(device, device_utils.DeviceUtils)) 2333 self.assertEquals(serial, device.adb.GetDeviceSerial()) 2334 2335 def testHealthyDevices_blacklist_defaultDeviceArg(self): 2336 test_serials = ['0123456789abcdef', 'fedcba9876543210'] 2337 with self.assertCalls( 2338 (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(), 2339 [_AdbWrapperMock(s) for s in test_serials])): 2340 blacklist = mock.NonCallableMock( 2341 **{'Read.return_value': ['fedcba9876543210']}) 2342 devices = device_utils.DeviceUtils.HealthyDevices(blacklist) 2343 self.assertEquals(1, len(devices)) 2344 self.assertTrue(isinstance(devices[0], device_utils.DeviceUtils)) 2345 self.assertEquals('0123456789abcdef', devices[0].adb.GetDeviceSerial()) 2346 2347 def testHealthyDevices_noneDeviceArg_multiple_attached(self): 2348 test_serials = ['0123456789abcdef', 'fedcba9876543210'] 2349 with self.assertCalls( 2350 (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(), 2351 [_AdbWrapperMock(s) for s in test_serials]), 2352 (mock.call.devil.android.device_errors.MultipleDevicesError(mock.ANY), 2353 _MockMultipleDevicesError())): 2354 with self.assertRaises(_MockMultipleDevicesError): 2355 device_utils.DeviceUtils.HealthyDevices(device_arg=None) 2356 2357 def testHealthyDevices_noneDeviceArg_one_attached(self): 2358 test_serials = ['0123456789abcdef'] 2359 with self.assertCalls( 2360 (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(), 2361 [_AdbWrapperMock(s) for s in test_serials])): 2362 devices = device_utils.DeviceUtils.HealthyDevices(device_arg=None) 2363 self.assertEquals(1, len(devices)) 2364 2365 def testHealthyDevices_noneDeviceArg_no_attached(self): 2366 test_serials = [] 2367 with self.assertCalls( 2368 (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(), 2369 [_AdbWrapperMock(s) for s in test_serials])): 2370 with self.assertRaises(device_errors.NoDevicesError): 2371 device_utils.DeviceUtils.HealthyDevices(device_arg=None) 2372 2373 def testHealthyDevices_noneDeviceArg_multiple_attached_ANDROID_SERIAL(self): 2374 try: 2375 os.environ['ANDROID_SERIAL'] = '0123456789abcdef' 2376 with self.assertCalls(): # Should skip adb devices when device is known. 2377 device_utils.DeviceUtils.HealthyDevices(device_arg=None) 2378 finally: 2379 del os.environ['ANDROID_SERIAL'] 2380 2381 def testHealthyDevices_stringDeviceArg(self): 2382 with self.assertCalls(): # Should skip adb devices when device is known. 2383 devices = device_utils.DeviceUtils.HealthyDevices( 2384 device_arg='0123456789abcdef') 2385 self.assertEquals(1, len(devices)) 2386 2387 def testHealthyDevices_EmptyListDeviceArg_multiple_attached(self): 2388 test_serials = ['0123456789abcdef', 'fedcba9876543210'] 2389 with self.assertCalls( 2390 (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(), 2391 [_AdbWrapperMock(s) for s in test_serials])): 2392 devices = device_utils.DeviceUtils.HealthyDevices(device_arg=()) 2393 self.assertEquals(2, len(devices)) 2394 2395 def testHealthyDevices_EmptyListDeviceArg_ANDROID_SERIAL(self): 2396 try: 2397 os.environ['ANDROID_SERIAL'] = '0123456789abcdef' 2398 with self.assertCalls(): # Should skip adb devices when device is known. 2399 devices = device_utils.DeviceUtils.HealthyDevices(device_arg=()) 2400 finally: 2401 del os.environ['ANDROID_SERIAL'] 2402 self.assertEquals(1, len(devices)) 2403 2404 def testHealthyDevices_EmptyListDeviceArg_no_attached(self): 2405 test_serials = [] 2406 with self.assertCalls( 2407 (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(), 2408 [_AdbWrapperMock(s) for s in test_serials])): 2409 with self.assertRaises(device_errors.NoDevicesError): 2410 device_utils.DeviceUtils.HealthyDevices(device_arg=[]) 2411 2412 def testHealthyDevices_ListDeviceArg(self): 2413 device_arg = ['0123456789abcdef', 'fedcba9876543210'] 2414 try: 2415 os.environ['ANDROID_SERIAL'] = 'should-not-apply' 2416 with self.assertCalls(): # Should skip adb devices when device is known. 2417 devices = device_utils.DeviceUtils.HealthyDevices(device_arg=device_arg) 2418 finally: 2419 del os.environ['ANDROID_SERIAL'] 2420 self.assertEquals(2, len(devices)) 2421 2422 2423class DeviceUtilsRestartAdbdTest(DeviceUtilsTest): 2424 2425 def testAdbdRestart(self): 2426 mock_temp_file = '/sdcard/temp-123.sh' 2427 with self.assertCalls( 2428 (mock.call.devil.android.device_temp_file.DeviceTempFile( 2429 self.adb, suffix='.sh'), MockTempFile(mock_temp_file)), 2430 self.call.device.WriteFile(mock.ANY, mock.ANY), 2431 (self.call.device.RunShellCommand( 2432 ['source', mock_temp_file], as_root=True)), 2433 self.call.adb.WaitForDevice()): 2434 self.device.RestartAdbd() 2435 2436 2437class DeviceUtilsGrantPermissionsTest(DeviceUtilsTest): 2438 2439 def testGrantPermissions_none(self): 2440 self.device.GrantPermissions('package', []) 2441 2442 def testGrantPermissions_underM(self): 2443 with self.patch_call(self.call.device.build_version_sdk, 2444 return_value=version_codes.LOLLIPOP): 2445 self.device.GrantPermissions('package', ['p1']) 2446 2447 def testGrantPermissions_one(self): 2448 permissions_cmd = 'pm grant package p1' 2449 with self.patch_call(self.call.device.build_version_sdk, 2450 return_value=version_codes.MARSHMALLOW): 2451 with self.assertCalls( 2452 (self.call.device.RunShellCommand( 2453 permissions_cmd, check_return=True), [])): 2454 self.device.GrantPermissions('package', ['p1']) 2455 2456 def testGrantPermissions_multiple(self): 2457 permissions_cmd = 'pm grant package p1&&pm grant package p2' 2458 with self.patch_call(self.call.device.build_version_sdk, 2459 return_value=version_codes.MARSHMALLOW): 2460 with self.assertCalls( 2461 (self.call.device.RunShellCommand( 2462 permissions_cmd, check_return=True), [])): 2463 self.device.GrantPermissions('package', ['p1', 'p2']) 2464 2465 def testGrantPermissions_WriteExtrnalStorage(self): 2466 permissions_cmd = ( 2467 'pm grant package android.permission.WRITE_EXTERNAL_STORAGE&&' 2468 'pm grant package android.permission.READ_EXTERNAL_STORAGE') 2469 with self.patch_call(self.call.device.build_version_sdk, 2470 return_value=version_codes.MARSHMALLOW): 2471 with self.assertCalls( 2472 (self.call.device.RunShellCommand( 2473 permissions_cmd, check_return=True), [])): 2474 self.device.GrantPermissions( 2475 'package', ['android.permission.WRITE_EXTERNAL_STORAGE']) 2476 2477 def testGrantPermissions_BlackList(self): 2478 with self.patch_call(self.call.device.build_version_sdk, 2479 return_value=version_codes.MARSHMALLOW): 2480 self.device.GrantPermissions( 2481 'package', ['android.permission.ACCESS_MOCK_LOCATION']) 2482 2483 2484class DeviecUtilsIsScreenOn(DeviceUtilsTest): 2485 2486 _L_SCREEN_ON = ['test=test mInteractive=true'] 2487 _K_SCREEN_ON = ['test=test mScreenOn=true'] 2488 _L_SCREEN_OFF = ['mInteractive=false'] 2489 _K_SCREEN_OFF = ['mScreenOn=false'] 2490 2491 def testIsScreenOn_onPreL(self): 2492 with self.patch_call(self.call.device.build_version_sdk, 2493 return_value=version_codes.KITKAT): 2494 with self.assertCalls( 2495 (self.call.device._RunPipedShellCommand( 2496 'dumpsys input_method | grep mScreenOn'), self._K_SCREEN_ON)): 2497 self.assertTrue(self.device.IsScreenOn()) 2498 2499 def testIsScreenOn_onL(self): 2500 with self.patch_call(self.call.device.build_version_sdk, 2501 return_value=version_codes.LOLLIPOP): 2502 with self.assertCalls( 2503 (self.call.device._RunPipedShellCommand( 2504 'dumpsys input_method | grep mInteractive'), self._L_SCREEN_ON)): 2505 self.assertTrue(self.device.IsScreenOn()) 2506 2507 def testIsScreenOn_offPreL(self): 2508 with self.patch_call(self.call.device.build_version_sdk, 2509 return_value=version_codes.KITKAT): 2510 with self.assertCalls( 2511 (self.call.device._RunPipedShellCommand( 2512 'dumpsys input_method | grep mScreenOn'), self._K_SCREEN_OFF)): 2513 self.assertFalse(self.device.IsScreenOn()) 2514 2515 def testIsScreenOn_offL(self): 2516 with self.patch_call(self.call.device.build_version_sdk, 2517 return_value=version_codes.LOLLIPOP): 2518 with self.assertCalls( 2519 (self.call.device._RunPipedShellCommand( 2520 'dumpsys input_method | grep mInteractive'), self._L_SCREEN_OFF)): 2521 self.assertFalse(self.device.IsScreenOn()) 2522 2523 def testIsScreenOn_noOutput(self): 2524 with self.patch_call(self.call.device.build_version_sdk, 2525 return_value=version_codes.LOLLIPOP): 2526 with self.assertCalls( 2527 (self.call.device._RunPipedShellCommand( 2528 'dumpsys input_method | grep mInteractive'), [])): 2529 with self.assertRaises(device_errors.CommandFailedError): 2530 self.device.IsScreenOn() 2531 2532 2533class DeviecUtilsSetScreen(DeviceUtilsTest): 2534 2535 @mock.patch('time.sleep', mock.Mock()) 2536 def testSetScren_alreadySet(self): 2537 with self.assertCalls( 2538 (self.call.device.IsScreenOn(), False)): 2539 self.device.SetScreen(False) 2540 2541 @mock.patch('time.sleep', mock.Mock()) 2542 def testSetScreen_on(self): 2543 with self.assertCalls( 2544 (self.call.device.IsScreenOn(), False), 2545 (self.call.device.RunShellCommand('input keyevent 26'), []), 2546 (self.call.device.IsScreenOn(), True)): 2547 self.device.SetScreen(True) 2548 2549 @mock.patch('time.sleep', mock.Mock()) 2550 def testSetScreen_off(self): 2551 with self.assertCalls( 2552 (self.call.device.IsScreenOn(), True), 2553 (self.call.device.RunShellCommand('input keyevent 26'), []), 2554 (self.call.device.IsScreenOn(), False)): 2555 self.device.SetScreen(False) 2556 2557 @mock.patch('time.sleep', mock.Mock()) 2558 def testSetScreen_slow(self): 2559 with self.assertCalls( 2560 (self.call.device.IsScreenOn(), True), 2561 (self.call.device.RunShellCommand('input keyevent 26'), []), 2562 (self.call.device.IsScreenOn(), True), 2563 (self.call.device.IsScreenOn(), True), 2564 (self.call.device.IsScreenOn(), False)): 2565 self.device.SetScreen(False) 2566 2567class DeviecUtilsLoadCacheData(DeviceUtilsTest): 2568 2569 def testTokenMissing(self): 2570 with self.assertCalls( 2571 self.EnsureCacheInitialized()): 2572 self.assertFalse(self.device.LoadCacheData('{}')) 2573 2574 def testTokenStale(self): 2575 with self.assertCalls( 2576 self.EnsureCacheInitialized()): 2577 self.assertFalse(self.device.LoadCacheData('{"token":"foo"}')) 2578 2579 def testTokenMatches(self): 2580 with self.assertCalls( 2581 self.EnsureCacheInitialized()): 2582 self.assertTrue(self.device.LoadCacheData('{"token":"TOKEN"}')) 2583 2584 def testDumpThenLoad(self): 2585 with self.assertCalls( 2586 self.EnsureCacheInitialized()): 2587 data = json.loads(self.device.DumpCacheData()) 2588 data['token'] = 'TOKEN' 2589 self.assertTrue(self.device.LoadCacheData(json.dumps(data))) 2590 2591 2592if __name__ == '__main__': 2593 logging.getLogger().setLevel(logging.DEBUG) 2594 unittest.main(verbosity=2) 2595