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