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.
7 Unit tests for the contents of device_utils.py (mostly DeviceUtils).
10 # pylint: disable=C0321
11 # pylint: disable=W0212
12 # pylint: disable=W0613
23 from pylib
import android_commands
24 from pylib
import constants
25 from pylib
.device
import adb_wrapper
26 from pylib
.device
import device_errors
27 from pylib
.device
import device_utils
28 from pylib
.device
import intent
30 # RunCommand from third_party/android_testrunner/run_command.py is mocked
31 # below, so its path needs to be in sys.path.
32 sys
.path
.append(os
.path
.join(
33 constants
.DIR_SOURCE_ROOT
, 'third_party', 'android_testrunner'))
35 sys
.path
.append(os
.path
.join(
36 constants
.DIR_SOURCE_ROOT
, 'third_party', 'pymock'))
37 import mock
# pylint: disable=F0401
40 class DeviceUtilsTest(unittest
.TestCase
):
42 def testInitWithStr(self
):
43 serial_as_str
= str('0123456789abcdef')
44 d
= device_utils
.DeviceUtils('0123456789abcdef')
45 self
.assertEqual(serial_as_str
, d
.old_interface
.GetDevice())
47 def testInitWithUnicode(self
):
48 serial_as_unicode
= unicode('fedcba9876543210')
49 d
= device_utils
.DeviceUtils(serial_as_unicode
)
50 self
.assertEqual(serial_as_unicode
, d
.old_interface
.GetDevice())
52 def testInitWithAdbWrapper(self
):
53 serial
= '123456789abcdef0'
54 a
= adb_wrapper
.AdbWrapper(serial
)
55 d
= device_utils
.DeviceUtils(a
)
56 self
.assertEqual(serial
, d
.old_interface
.GetDevice())
58 def testInitWithAndroidCommands(self
):
59 serial
= '0fedcba987654321'
60 a
= android_commands
.AndroidCommands(device
=serial
)
61 d
= device_utils
.DeviceUtils(a
)
62 self
.assertEqual(serial
, d
.old_interface
.GetDevice())
64 def testInitWithNone(self
):
65 d
= device_utils
.DeviceUtils(None)
66 self
.assertIsNone(d
.old_interface
.GetDevice())
69 class _PatchedFunction(object):
70 def __init__(self
, patched
=None, mocked
=None):
71 self
.patched
= patched
75 class MockFileSystem(object):
79 st_mode
=None, st_ino
=None, st_dev
=None, st_nlink
=None, st_uid
=None,
80 st_gid
=None, st_size
=None, st_atime
=None, st_mtime
=None, st_ctime
=None):
81 MockOSStatResult
= collections
.namedtuple('MockOSStatResult', [
82 'st_mode', 'st_ino', 'st_dev', 'st_nlink', 'st_uid', 'st_gid',
83 'st_size', 'st_atime', 'st_mtime', 'st_ctime'])
84 return MockOSStatResult(st_mode
, st_ino
, st_dev
, st_nlink
, st_uid
, st_gid
,
85 st_size
, st_atime
, st_mtime
, st_ctime
)
89 ('os.path.abspath', ''),
90 ('os.path.dirname', ''),
91 ('os.path.exists', False),
92 ('os.path.getsize', 0),
93 ('os.path.isdir', False),
94 ('os.stat', osStatResult
.__func
__()),
98 def _get(self
, mocked
, path
, default_val
):
100 logging
.debug('%s(%s)' % (mocked
, path
))
101 return (self
.mock_file_info
[path
][mocked
]
102 if path
in self
.mock_file_info
105 def _patched(self
, target
, default_val
=None):
106 r
= lambda f
: self
._get
(target
, f
, default_val
)
107 return _PatchedFunction(patched
=mock
.patch(target
, side_effect
=r
))
109 def __init__(self
, verbose
=False):
110 self
.mock_file_info
= {}
111 self
._patched
_functions
= [
112 self
._patched
(m
, d
) for m
, d
in type(self
).MOCKED_FUNCTIONS
]
113 self
._verbose
= verbose
115 def addMockFile(self
, path
, **kw
):
116 self
._addMockThing
(path
, False, **kw
)
118 def addMockDirectory(self
, path
, **kw
):
119 self
._addMockThing
(path
, True, **kw
)
121 def _addMockThing(self
, path
, is_dir
, listdir
=None, size
=0, stat
=None,
126 stat
= self
.osStatResult()
130 dirname
= os
.sep
.join(path
.rstrip(os
.sep
).split(os
.sep
)[:-1])
131 if dirname
and not dirname
in self
.mock_file_info
:
132 self
._addMockThing
(dirname
, True)
134 self
.mock_file_info
[path
] = {
135 'os.listdir': listdir
,
136 'os.path.abspath': path
,
137 'os.path.dirname': dirname
,
138 'os.path.exists': True,
139 'os.path.isdir': is_dir
,
140 'os.path.getsize': size
,
146 for p
in self
._patched
_functions
:
147 p
.mocked
= p
.patched
.__enter
__()
149 def __exit__(self
, exc_type
, exc_val
, exc_tb
):
150 for p
in self
._patched
_functions
:
154 class DeviceUtilsOldImplTest(unittest
.TestCase
):
156 class AndroidCommandsCalls(object):
158 def __init__(self
, test_case
, cmd_ret
, comp
):
161 self
._run
_command
= _PatchedFunction()
162 self
._test
_case
= test_case
163 self
._total
_received
= 0
166 self
._run
_command
.patched
= mock
.patch(
167 'run_command.RunCommand',
168 side_effect
=lambda c
, **kw
: self
._ret
(c
))
169 self
._run
_command
.mocked
= self
._run
_command
.patched
.__enter
__()
171 def _ret(self
, actual_cmd
):
172 if sys
.exc_info()[0] is None:
173 on_failure_fmt
= ('\n'
174 ' received command: %s\n'
175 ' expected command: %s')
176 self
._test
_case
.assertGreater(
177 len(self
._cmds
), self
._total
_received
,
178 msg
=on_failure_fmt
% (actual_cmd
, None))
179 expected_cmd
, ret
= self
._cmds
[self
._total
_received
]
180 self
._total
_received
+= 1
181 self
._test
_case
.assertTrue(
182 self
._comp
(expected_cmd
, actual_cmd
),
183 msg
=on_failure_fmt
% (actual_cmd
, expected_cmd
))
187 def __exit__(self
, exc_type
, exc_val
, exc_tb
):
188 self
._run
_command
.patched
.__exit
__(exc_type
, exc_val
, exc_tb
)
190 on_failure
= "adb commands don't match.\nExpected:%s\nActual:%s" % (
191 ''.join('\n %s' % c
for c
, _
in self
._cmds
),
192 ''.join('\n %s' % a
[0]
193 for _
, a
, kw
in self
._run
_command
.mocked
.mock_calls
))
194 self
._test
_case
.assertEqual(
195 len(self
._cmds
), len(self
._run
_command
.mocked
.mock_calls
),
197 for (expected_cmd
, _r
), (_n
, actual_args
, actual_kwargs
) in zip(
198 self
._cmds
, self
._run
_command
.mocked
.mock_calls
):
199 self
._test
_case
.assertEqual(1, len(actual_args
), msg
=on_failure
)
200 self
._test
_case
.assertTrue(self
._comp
(expected_cmd
, actual_args
[0]),
202 self
._test
_case
.assertTrue('timeout_time' in actual_kwargs
,
204 self
._test
_case
.assertTrue('retry_count' in actual_kwargs
,
207 def assertNoAdbCalls(self
):
208 return type(self
).AndroidCommandsCalls(self
, [], str.__eq
__)
210 def assertCalls(self
, cmd
, ret
, comp
=str.__eq
__):
211 return type(self
).AndroidCommandsCalls(self
, [(cmd
, ret
)], comp
)
213 def assertCallsSequence(self
, cmd_ret
, comp
=str.__eq
__):
214 return type(self
).AndroidCommandsCalls(self
, cmd_ret
, comp
)
217 self
.device
= device_utils
.DeviceUtils(
218 '0123456789abcdef', default_timeout
=1, default_retries
=0)
221 class DeviceUtilsNewImplTest(unittest
.TestCase
):
224 test_serial
= '0123456789abcdef'
225 self
.adb
= mock
.Mock(spec
=adb_wrapper
.AdbWrapper
)
226 self
.adb
.__str
__ = mock
.Mock(return_value
=test_serial
)
227 self
.adb
.GetDeviceSerial
.return_value
= test_serial
228 self
.device
= device_utils
.DeviceUtils(
229 self
.adb
, default_timeout
=1, default_retries
=0)
232 class DeviceUtilsHybridImplTest(DeviceUtilsOldImplTest
):
235 super(DeviceUtilsHybridImplTest
, self
).setUp()
236 self
.device
.adb
= self
.adb
= mock
.Mock(spec
=adb_wrapper
.AdbWrapper
)
239 class DeviceUtilsIsOnlineTest(DeviceUtilsOldImplTest
):
241 def testIsOnline_true(self
):
242 with self
.assertCalls('adb -s 0123456789abcdef devices',
243 '00123456789abcdef device\r\n'):
244 self
.assertTrue(self
.device
.IsOnline())
246 def testIsOnline_false(self
):
247 with self
.assertCalls('adb -s 0123456789abcdef devices', '\r\n'):
248 self
.assertFalse(self
.device
.IsOnline())
251 class DeviceUtilsHasRootTest(DeviceUtilsOldImplTest
):
253 def testHasRoot_true(self
):
254 with self
.assertCalls("adb -s 0123456789abcdef shell 'ls /root'",
256 self
.assertTrue(self
.device
.HasRoot())
258 def testHasRoot_false(self
):
259 with self
.assertCalls("adb -s 0123456789abcdef shell 'ls /root'",
260 'Permission denied\r\n'):
261 self
.assertFalse(self
.device
.HasRoot())
264 class DeviceUtilsEnableRootTest(DeviceUtilsOldImplTest
):
266 def testEnableRoot_succeeds(self
):
267 with self
.assertCallsSequence([
268 ('adb -s 0123456789abcdef shell getprop ro.build.type',
270 ('adb -s 0123456789abcdef root', 'restarting adbd as root\r\n'),
271 ('adb -s 0123456789abcdef wait-for-device', ''),
272 ('adb -s 0123456789abcdef wait-for-device', '')]):
273 self
.device
.EnableRoot()
275 def testEnableRoot_userBuild(self
):
276 with self
.assertCallsSequence([
277 ('adb -s 0123456789abcdef shell getprop ro.build.type', 'user\r\n')]):
278 with self
.assertRaises(device_errors
.CommandFailedError
):
279 self
.device
.EnableRoot()
281 def testEnableRoot_rootFails(self
):
282 with self
.assertCallsSequence([
283 ('adb -s 0123456789abcdef shell getprop ro.build.type',
285 ('adb -s 0123456789abcdef root', 'no\r\n'),
286 ('adb -s 0123456789abcdef wait-for-device', '')]):
287 with self
.assertRaises(device_errors
.CommandFailedError
):
288 self
.device
.EnableRoot()
291 class DeviceUtilsGetExternalStoragePathTest(DeviceUtilsOldImplTest
):
293 def testGetExternalStoragePath_succeeds(self
):
294 fakeStoragePath
= '/fake/storage/path'
295 with self
.assertCalls(
296 "adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
297 '%s\r\n' % fakeStoragePath
):
298 self
.assertEquals(fakeStoragePath
,
299 self
.device
.GetExternalStoragePath())
301 def testGetExternalStoragePath_fails(self
):
302 with self
.assertCalls(
303 "adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'", '\r\n'):
304 with self
.assertRaises(device_errors
.CommandFailedError
):
305 self
.device
.GetExternalStoragePath()
308 class DeviceUtilsWaitUntilFullyBootedTest(DeviceUtilsOldImplTest
):
310 def testWaitUntilFullyBooted_succeedsNoWifi(self
):
311 with self
.assertCallsSequence([
312 # AndroidCommands.WaitForSystemBootCompleted
313 ('adb -s 0123456789abcdef wait-for-device', ''),
314 ('adb -s 0123456789abcdef shell getprop sys.boot_completed', '1\r\n'),
315 # AndroidCommands.WaitForDevicePm
316 ('adb -s 0123456789abcdef wait-for-device', ''),
317 ('adb -s 0123456789abcdef shell pm path android',
318 'package:this.is.a.test.package'),
319 # AndroidCommands.WaitForSdCardReady
320 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
321 '/fake/storage/path'),
322 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
325 self
.device
.WaitUntilFullyBooted(wifi
=False)
327 def testWaitUntilFullyBooted_succeedsWithWifi(self
):
328 with self
.assertCallsSequence([
329 # AndroidCommands.WaitForSystemBootCompleted
330 ('adb -s 0123456789abcdef wait-for-device', ''),
331 ('adb -s 0123456789abcdef shell getprop sys.boot_completed', '1\r\n'),
332 # AndroidCommands.WaitForDevicePm
333 ('adb -s 0123456789abcdef wait-for-device', ''),
334 ('adb -s 0123456789abcdef shell pm path android',
335 'package:this.is.a.test.package'),
336 # AndroidCommands.WaitForSdCardReady
337 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
338 '/fake/storage/path'),
339 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
342 ("adb -s 0123456789abcdef shell 'dumpsys wifi'", 'Wi-Fi is enabled')]):
343 self
.device
.WaitUntilFullyBooted(wifi
=True)
345 def testWaitUntilFullyBooted_bootFails(self
):
346 with mock
.patch('time.sleep'):
347 with self
.assertCallsSequence([
348 # AndroidCommands.WaitForSystemBootCompleted
349 ('adb -s 0123456789abcdef wait-for-device', ''),
350 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
352 with self
.assertRaises(device_errors
.CommandTimeoutError
):
353 self
.device
.WaitUntilFullyBooted(wifi
=False)
355 def testWaitUntilFullyBooted_devicePmFails(self
):
356 with mock
.patch('time.sleep'):
357 with self
.assertCallsSequence([
358 # AndroidCommands.WaitForSystemBootCompleted
359 ('adb -s 0123456789abcdef wait-for-device', ''),
360 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
362 # AndroidCommands.WaitForDevicePm
363 + 3 * ([('adb -s 0123456789abcdef wait-for-device', '')]
364 + 24 * [('adb -s 0123456789abcdef shell pm path android', '\r\n')]
365 + [("adb -s 0123456789abcdef shell 'stop'", '\r\n'),
366 ("adb -s 0123456789abcdef shell 'start'", '\r\n')])):
367 with self
.assertRaises(device_errors
.CommandTimeoutError
):
368 self
.device
.WaitUntilFullyBooted(wifi
=False)
370 def testWaitUntilFullyBooted_sdCardReadyFails_noPath(self
):
371 with mock
.patch('time.sleep'):
372 with self
.assertCallsSequence([
373 # AndroidCommands.WaitForSystemBootCompleted
374 ('adb -s 0123456789abcdef wait-for-device', ''),
375 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
377 # AndroidCommands.WaitForDevicePm
378 ('adb -s 0123456789abcdef wait-for-device', ''),
379 ('adb -s 0123456789abcdef shell pm path android',
380 'package:this.is.a.test.package'),
381 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'", '\r\n')]):
382 with self
.assertRaises(device_errors
.CommandFailedError
):
383 self
.device
.WaitUntilFullyBooted(wifi
=False)
385 def testWaitUntilFullyBooted_sdCardReadyFails_emptyPath(self
):
386 with mock
.patch('time.sleep'):
387 with self
.assertCallsSequence([
388 # AndroidCommands.WaitForSystemBootCompleted
389 ('adb -s 0123456789abcdef wait-for-device', ''),
390 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
392 # AndroidCommands.WaitForDevicePm
393 ('adb -s 0123456789abcdef wait-for-device', ''),
394 ('adb -s 0123456789abcdef shell pm path android',
395 'package:this.is.a.test.package'),
396 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
397 '/fake/storage/path\r\n'),
398 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'", '')]):
399 with self
.assertRaises(device_errors
.CommandTimeoutError
):
400 self
.device
.WaitUntilFullyBooted(wifi
=False)
403 class DeviceUtilsRebootTest(DeviceUtilsOldImplTest
):
405 def testReboot_nonBlocking(self
):
406 with mock
.patch('time.sleep'):
407 with self
.assertCallsSequence([
408 ('adb -s 0123456789abcdef reboot', ''),
409 ('adb -s 0123456789abcdef devices', 'unknown\r\n'),
410 ('adb -s 0123456789abcdef wait-for-device', ''),
411 ('adb -s 0123456789abcdef shell pm path android',
412 'package:this.is.a.test.package'),
413 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
414 '/fake/storage/path\r\n'),
415 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
417 self
.device
.Reboot(block
=False)
419 def testReboot_blocking(self
):
420 with mock
.patch('time.sleep'):
421 with self
.assertCallsSequence([
422 ('adb -s 0123456789abcdef reboot', ''),
423 ('adb -s 0123456789abcdef devices', 'unknown\r\n'),
424 ('adb -s 0123456789abcdef wait-for-device', ''),
425 ('adb -s 0123456789abcdef shell pm path android',
426 'package:this.is.a.test.package'),
427 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
428 '/fake/storage/path\r\n'),
429 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
431 ('adb -s 0123456789abcdef wait-for-device', ''),
432 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
434 ('adb -s 0123456789abcdef wait-for-device', ''),
435 ('adb -s 0123456789abcdef shell pm path android',
436 'package:this.is.a.test.package'),
437 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
439 self
.device
.Reboot(block
=True)
442 class DeviceUtilsInstallTest(DeviceUtilsOldImplTest
):
444 def testInstall_noPriorInstall(self
):
445 with mock
.patch('os.path.isfile', return_value
=True), (
446 mock
.patch('pylib.utils.apk_helper.GetPackageName',
447 return_value
='this.is.a.test.package')):
448 with self
.assertCallsSequence([
449 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
451 ("adb -s 0123456789abcdef install /fake/test/app.apk",
453 self
.device
.Install('/fake/test/app.apk', retries
=0)
455 def testInstall_differentPriorInstall(self
):
456 def mockGetFilesChanged(host_path
, device_path
, ignore_filenames
):
457 return [(host_path
, device_path
)]
459 # Pylint raises a false positive "operator not preceded by a space"
461 # pylint: disable=C0322
462 with mock
.patch('os.path.isfile', return_value
=True), (
463 mock
.patch('os.path.exists', return_value
=True)), (
464 mock
.patch('pylib.utils.apk_helper.GetPackageName',
465 return_value
='this.is.a.test.package')), (
466 mock
.patch('pylib.constants.GetOutDirectory',
467 return_value
='/fake/test/out')), (
468 mock
.patch('pylib.android_commands.AndroidCommands.GetFilesChanged',
469 side_effect
=mockGetFilesChanged
)):
470 # pylint: enable=C0322
471 with self
.assertCallsSequence([
472 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
473 'package:/fake/data/app/this.is.a.test.package.apk\r\n'),
474 # GetFilesChanged is mocked, so its adb calls are omitted.
475 ('adb -s 0123456789abcdef uninstall this.is.a.test.package',
477 ('adb -s 0123456789abcdef install /fake/test/app.apk',
479 self
.device
.Install('/fake/test/app.apk', retries
=0)
481 def testInstall_differentPriorInstall_reinstall(self
):
482 def mockGetFilesChanged(host_path
, device_path
, ignore_filenames
):
483 return [(host_path
, device_path
)]
485 # Pylint raises a false positive "operator not preceded by a space"
487 # pylint: disable=C0322
488 with mock
.patch('os.path.isfile', return_value
=True), (
489 mock
.patch('pylib.utils.apk_helper.GetPackageName',
490 return_value
='this.is.a.test.package')), (
491 mock
.patch('pylib.constants.GetOutDirectory',
492 return_value
='/fake/test/out')), (
493 mock
.patch('pylib.android_commands.AndroidCommands.GetFilesChanged',
494 side_effect
=mockGetFilesChanged
)):
495 # pylint: enable=C0322
496 with self
.assertCallsSequence([
497 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
498 'package:/fake/data/app/this.is.a.test.package.apk\r\n'),
499 # GetFilesChanged is mocked, so its adb calls are omitted.
500 ('adb -s 0123456789abcdef install -r /fake/test/app.apk',
502 self
.device
.Install('/fake/test/app.apk', reinstall
=True, retries
=0)
504 def testInstall_identicalPriorInstall(self
):
505 def mockGetFilesChanged(host_path
, device_path
, ignore_filenames
):
508 with mock
.patch('pylib.utils.apk_helper.GetPackageName',
509 return_value
='this.is.a.test.package'), (
510 mock
.patch('pylib.android_commands.AndroidCommands.GetFilesChanged',
511 side_effect
=mockGetFilesChanged
)):
512 with self
.assertCallsSequence([
513 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
514 'package:/fake/data/app/this.is.a.test.package.apk\r\n')
515 # GetFilesChanged is mocked, so its adb calls are omitted.
517 self
.device
.Install('/fake/test/app.apk', retries
=0)
519 def testInstall_fails(self
):
520 with mock
.patch('os.path.isfile', return_value
=True), (
521 mock
.patch('pylib.utils.apk_helper.GetPackageName',
522 return_value
='this.is.a.test.package')):
523 with self
.assertCallsSequence([
524 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
526 ("adb -s 0123456789abcdef install /fake/test/app.apk",
528 with self
.assertRaises(device_errors
.CommandFailedError
):
529 self
.device
.Install('/fake/test/app.apk', retries
=0)
532 class DeviceUtilsRunShellCommandTest(DeviceUtilsOldImplTest
):
534 def testRunShellCommand_commandAsList(self
):
535 with self
.assertCalls(
536 "adb -s 0123456789abcdef shell 'pm list packages'",
537 'pacakge:android\r\n'):
538 self
.device
.RunShellCommand(['pm', 'list', 'packages'])
540 def testRunShellCommand_commandAsString(self
):
541 with self
.assertCalls(
542 "adb -s 0123456789abcdef shell 'dumpsys wifi'",
543 'Wi-Fi is enabled\r\n'):
544 self
.device
.RunShellCommand('dumpsys wifi')
546 def testRunShellCommand_withSu(self
):
547 with self
.assertCallsSequence([
548 ("adb -s 0123456789abcdef shell 'ls /root'", 'Permission denied\r\n'),
549 ("adb -s 0123456789abcdef shell 'su -c setprop service.adb.root 0'",
551 self
.device
.RunShellCommand('setprop service.adb.root 0', as_root
=True)
553 def testRunShellCommand_withRoot(self
):
554 with self
.assertCallsSequence([
555 ("adb -s 0123456789abcdef shell 'ls /root'", 'hello\r\nworld\r\n'),
556 ("adb -s 0123456789abcdef shell 'setprop service.adb.root 0'", '')]):
557 self
.device
.RunShellCommand('setprop service.adb.root 0', as_root
=True)
559 def testRunShellCommand_checkReturn_success(self
):
560 with self
.assertCalls(
561 "adb -s 0123456789abcdef shell 'echo $ANDROID_DATA; echo %$?'",
563 self
.device
.RunShellCommand('echo $ANDROID_DATA', check_return
=True)
565 def testRunShellCommand_checkReturn_failure(self
):
566 with self
.assertCalls(
567 "adb -s 0123456789abcdef shell 'echo $ANDROID_DATA; echo %$?'",
569 with self
.assertRaises(device_errors
.CommandFailedError
):
570 self
.device
.RunShellCommand('echo $ANDROID_DATA', check_return
=True)
573 class DeviceUtilsKillAllTest(DeviceUtilsOldImplTest
):
575 def testKillAll_noMatchingProcesses(self
):
576 with self
.assertCalls(
577 "adb -s 0123456789abcdef shell 'ps'",
578 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'):
579 with self
.assertRaises(device_errors
.CommandFailedError
):
580 self
.device
.KillAll('test_process')
582 def testKillAll_nonblocking(self
):
583 with self
.assertCallsSequence([
584 ("adb -s 0123456789abcdef shell 'ps'",
585 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
586 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
587 'this.is.a.test.process\r\n'),
588 ("adb -s 0123456789abcdef shell 'kill -9 1234'", '')]):
590 self
.device
.KillAll('this.is.a.test.process', blocking
=False))
592 def testKillAll_blocking(self
):
593 with mock
.patch('time.sleep'):
594 with self
.assertCallsSequence([
595 ("adb -s 0123456789abcdef shell 'ps'",
596 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
597 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
598 'this.is.a.test.process\r\n'),
599 ("adb -s 0123456789abcdef shell 'kill -9 1234'", ''),
600 ("adb -s 0123456789abcdef shell 'ps'",
601 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
602 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
603 'this.is.a.test.process\r\n'),
604 ("adb -s 0123456789abcdef shell 'ps'",
605 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n')]):
607 self
.device
.KillAll('this.is.a.test.process', blocking
=True))
609 def testKillAll_root(self
):
610 with self
.assertCallsSequence([
611 ("adb -s 0123456789abcdef shell 'ps'",
612 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
613 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
614 'this.is.a.test.process\r\n'),
615 ("adb -s 0123456789abcdef shell 'ls /root'", 'Permission denied\r\n'),
616 ("adb -s 0123456789abcdef shell 'su -c kill -9 1234'", '')]):
618 self
.device
.KillAll('this.is.a.test.process', as_root
=True))
620 def testKillAll_sigterm(self
):
621 with self
.assertCallsSequence([
622 ("adb -s 0123456789abcdef shell 'ps'",
623 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
624 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
625 'this.is.a.test.process\r\n'),
626 ("adb -s 0123456789abcdef shell 'kill -15 1234'", '')]):
628 self
.device
.KillAll('this.is.a.test.process', signum
=signal
.SIGTERM
))
631 class DeviceUtilsStartActivityTest(DeviceUtilsOldImplTest
):
633 def testStartActivity_actionOnly(self
):
634 test_intent
= intent
.Intent(action
='android.intent.action.VIEW')
635 with self
.assertCalls(
636 "adb -s 0123456789abcdef shell 'am start "
637 "-a android.intent.action.VIEW'",
638 'Starting: Intent { act=android.intent.action.VIEW }'):
639 self
.device
.StartActivity(test_intent
)
641 def testStartActivity_success(self
):
642 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
643 package
='this.is.a.test.package',
645 with self
.assertCalls(
646 "adb -s 0123456789abcdef shell 'am start "
647 "-a android.intent.action.VIEW "
648 "-n this.is.a.test.package/.Main'",
649 'Starting: Intent { act=android.intent.action.VIEW }'):
650 self
.device
.StartActivity(test_intent
)
652 def testStartActivity_failure(self
):
653 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
654 package
='this.is.a.test.package',
656 with self
.assertCalls(
657 "adb -s 0123456789abcdef shell 'am start "
658 "-a android.intent.action.VIEW "
659 "-n this.is.a.test.package/.Main'",
660 'Error: Failed to start test activity'):
661 with self
.assertRaises(device_errors
.CommandFailedError
):
662 self
.device
.StartActivity(test_intent
)
664 def testStartActivity_blocking(self
):
665 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
666 package
='this.is.a.test.package',
668 with self
.assertCalls(
669 "adb -s 0123456789abcdef shell 'am start "
670 "-a android.intent.action.VIEW "
672 "-n this.is.a.test.package/.Main'",
673 'Starting: Intent { act=android.intent.action.VIEW }'):
674 self
.device
.StartActivity(test_intent
, blocking
=True)
676 def testStartActivity_withCategory(self
):
677 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
678 package
='this.is.a.test.package',
680 category
='android.intent.category.HOME')
681 with self
.assertCalls(
682 "adb -s 0123456789abcdef shell 'am start "
683 "-a android.intent.action.VIEW "
684 "-c android.intent.category.HOME "
685 "-n this.is.a.test.package/.Main'",
686 'Starting: Intent { act=android.intent.action.VIEW }'):
687 self
.device
.StartActivity(test_intent
)
689 def testStartActivity_withMultipleCategories(self
):
690 # The new implementation will start the activity with all provided
691 # categories. The old one only uses the first category.
692 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
693 package
='this.is.a.test.package',
695 category
=['android.intent.category.HOME',
696 'android.intent.category.BROWSABLE'])
697 with self
.assertCalls(
698 "adb -s 0123456789abcdef shell 'am start "
699 "-a android.intent.action.VIEW "
700 "-c android.intent.category.HOME "
701 "-n this.is.a.test.package/.Main'",
702 'Starting: Intent { act=android.intent.action.VIEW }'):
703 self
.device
.StartActivity(test_intent
)
705 def testStartActivity_withData(self
):
706 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
707 package
='this.is.a.test.package',
709 data
='http://www.google.com/')
710 with self
.assertCalls(
711 "adb -s 0123456789abcdef shell 'am start "
712 "-a android.intent.action.VIEW "
713 "-n this.is.a.test.package/.Main "
714 "-d \"http://www.google.com/\"'",
715 'Starting: Intent { act=android.intent.action.VIEW }'):
716 self
.device
.StartActivity(test_intent
)
718 def testStartActivity_withStringExtra(self
):
719 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
720 package
='this.is.a.test.package',
722 extras
={'foo': 'test'})
723 with self
.assertCalls(
724 "adb -s 0123456789abcdef shell 'am start "
725 "-a android.intent.action.VIEW "
726 "-n this.is.a.test.package/.Main "
728 'Starting: Intent { act=android.intent.action.VIEW }'):
729 self
.device
.StartActivity(test_intent
)
731 def testStartActivity_withBoolExtra(self
):
732 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
733 package
='this.is.a.test.package',
735 extras
={'foo': True})
736 with self
.assertCalls(
737 "adb -s 0123456789abcdef shell 'am start "
738 "-a android.intent.action.VIEW "
739 "-n this.is.a.test.package/.Main "
741 'Starting: Intent { act=android.intent.action.VIEW }'):
742 self
.device
.StartActivity(test_intent
)
744 def testStartActivity_withIntExtra(self
):
745 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
746 package
='this.is.a.test.package',
749 with self
.assertCalls(
750 "adb -s 0123456789abcdef shell 'am start "
751 "-a android.intent.action.VIEW "
752 "-n this.is.a.test.package/.Main "
754 'Starting: Intent { act=android.intent.action.VIEW }'):
755 self
.device
.StartActivity(test_intent
)
757 def testStartActivity_withTraceFile(self
):
758 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
759 package
='this.is.a.test.package',
761 with self
.assertCalls(
762 "adb -s 0123456789abcdef shell 'am start "
763 "-a android.intent.action.VIEW "
764 "-n this.is.a.test.package/.Main "
765 "--start-profiler test_trace_file.out'",
766 'Starting: Intent { act=android.intent.action.VIEW }'):
767 self
.device
.StartActivity(test_intent
,
768 trace_file_name
='test_trace_file.out')
770 def testStartActivity_withForceStop(self
):
771 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
772 package
='this.is.a.test.package',
774 with self
.assertCalls(
775 "adb -s 0123456789abcdef shell 'am start "
776 "-a android.intent.action.VIEW "
778 "-n this.is.a.test.package/.Main'",
779 'Starting: Intent { act=android.intent.action.VIEW }'):
780 self
.device
.StartActivity(test_intent
, force_stop
=True)
782 def testStartActivity_withFlags(self
):
783 test_intent
= intent
.Intent(action
='android.intent.action.VIEW',
784 package
='this.is.a.test.package',
787 with self
.assertCalls(
788 "adb -s 0123456789abcdef shell 'am start "
789 "-a android.intent.action.VIEW "
790 "-n this.is.a.test.package/.Main "
792 'Starting: Intent { act=android.intent.action.VIEW }'):
793 self
.device
.StartActivity(test_intent
)
796 class DeviceUtilsBroadcastIntentTest(DeviceUtilsOldImplTest
):
798 def testBroadcastIntent_noExtras(self
):
799 test_intent
= intent
.Intent(action
='test.package.with.an.INTENT')
800 with self
.assertCalls(
801 "adb -s 0123456789abcdef shell 'am broadcast "
802 "-a test.package.with.an.INTENT '",
803 'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
804 self
.device
.BroadcastIntent(test_intent
)
806 def testBroadcastIntent_withExtra(self
):
807 test_intent
= intent
.Intent(action
='test.package.with.an.INTENT',
808 extras
={'foo': 'bar'})
809 with self
.assertCalls(
810 "adb -s 0123456789abcdef shell 'am broadcast "
811 "-a test.package.with.an.INTENT "
813 'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
814 self
.device
.BroadcastIntent(test_intent
)
816 def testBroadcastIntent_withExtra_noValue(self
):
817 test_intent
= intent
.Intent(action
='test.package.with.an.INTENT',
818 extras
={'foo': None})
819 with self
.assertCalls(
820 "adb -s 0123456789abcdef shell 'am broadcast "
821 "-a test.package.with.an.INTENT "
823 'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
824 self
.device
.BroadcastIntent(test_intent
)
827 class DeviceUtilsGoHomeTest(DeviceUtilsOldImplTest
):
829 def testGoHome(self
):
830 with self
.assertCalls(
831 "adb -s 0123456789abcdef shell 'am start "
833 "-a android.intent.action.MAIN "
834 "-c android.intent.category.HOME'",
835 'Starting: Intent { act=android.intent.action.MAIN }\r\n'):
839 class DeviceUtilsForceStopTest(DeviceUtilsOldImplTest
):
841 def testForceStop(self
):
842 with self
.assertCalls(
843 "adb -s 0123456789abcdef shell 'am force-stop this.is.a.test.package'",
845 self
.device
.ForceStop('this.is.a.test.package')
848 class DeviceUtilsClearApplicationStateTest(DeviceUtilsOldImplTest
):
850 def testClearApplicationState_packageExists(self
):
851 with self
.assertCalls(
852 "adb -s 0123456789abcdef shell 'pm path this.package.does.not.exist'",
854 self
.device
.ClearApplicationState('this.package.does.not.exist')
856 def testClearApplicationState_packageDoesntExist(self
):
857 with self
.assertCallsSequence([
858 ("adb -s 0123456789abcdef shell 'pm path this.package.exists'",
859 'package:/data/app/this.package.exists.apk'),
860 ("adb -s 0123456789abcdef shell 'pm clear this.package.exists'",
862 self
.device
.ClearApplicationState('this.package.exists')
865 class DeviceUtilsSendKeyEventTest(DeviceUtilsOldImplTest
):
867 def testSendKeyEvent(self
):
868 with self
.assertCalls(
869 "adb -s 0123456789abcdef shell 'input keyevent 66'",
871 self
.device
.SendKeyEvent(66)
874 class DeviceUtilsPushChangedFilesIndividuallyTest(DeviceUtilsNewImplTest
):
876 def testPushChangedFilesIndividually_empty(self
):
878 self
.device
._PushChangedFilesIndividually
(test_files
)
879 self
.assertEqual(0, self
.adb
.Push
.call_count
)
881 def testPushChangedFilesIndividually_single(self
):
882 test_files
= [('/test/host/path', '/test/device/path')]
883 self
.device
._PushChangedFilesIndividually
(test_files
)
884 self
.adb
.Push
.assert_called_once_with(
885 '/test/host/path', '/test/device/path')
887 def testPushChangedFilesIndividually_multiple(self
):
889 ('/test/host/path/file1', '/test/device/path/file1'),
890 ('/test/host/path/file2', '/test/device/path/file2')]
891 self
.device
._PushChangedFilesIndividually
(test_files
)
892 self
.assertEqual(2, self
.adb
.Push
.call_count
)
893 self
.adb
.Push
.assert_any_call(
894 '/test/host/path/file1', '/test/device/path/file1')
895 self
.adb
.Push
.assert_any_call(
896 '/test/host/path/file2', '/test/device/path/file2')
899 class DeviceUtilsPushChangedFilesZippedTest(DeviceUtilsHybridImplTest
):
902 super(DeviceUtilsPushChangedFilesZippedTest
, self
).setUp()
903 self
.original_install_commands
= self
.device
._InstallCommands
904 self
.device
._InstallCommands
= mock
.Mock()
906 def testPushChangedFilesZipped_empty(self
):
908 self
.device
._PushChangedFilesZipped
(test_files
)
909 self
.assertEqual(0, self
.adb
.Push
.call_count
)
911 def testPushChangedFilesZipped_single(self
):
912 test_files
= [('/test/host/path/file1', '/test/device/path/file1')]
914 self
.device
._GetExternalStoragePathImpl
= mock
.Mock(
915 return_value
='/test/device/external_dir')
916 self
.device
._IsOnlineImpl
= mock
.Mock(return_value
=True)
917 self
.device
._RunShellCommandImpl
= mock
.Mock()
918 mock_zip_temp
= mock
.mock_open()
919 mock_zip_temp
.return_value
.name
= '/test/temp/file/tmp.zip'
920 with mock
.patch('multiprocessing.Process') as mock_zip_proc
, (
921 mock
.patch('tempfile.NamedTemporaryFile', mock_zip_temp
)):
922 self
.device
._PushChangedFilesZipped
(test_files
)
924 mock_zip_proc
.assert_called_once_with(
925 target
=device_utils
.DeviceUtils
._CreateDeviceZip
,
926 args
=('/test/temp/file/tmp.zip', test_files
))
927 self
.adb
.Push
.assert_called_once_with(
928 '/test/temp/file/tmp.zip', '/test/device/external_dir/tmp.zip')
929 self
.assertEqual(2, self
.device
._RunShellCommandImpl
.call_count
)
930 self
.device
._RunShellCommandImpl
.assert_any_call(
931 ['unzip', '/test/device/external_dir/tmp.zip'],
932 as_root
=True, check_return
=True,
933 env
={'PATH': '$PATH:/data/local/tmp/bin'})
934 self
.device
._RunShellCommandImpl
.assert_any_call(
935 ['rm', '/test/device/external_dir/tmp.zip'])
937 def testPushChangedFilesZipped_multiple(self
):
938 test_files
= [('/test/host/path/file1', '/test/device/path/file1'),
939 ('/test/host/path/file2', '/test/device/path/file2')]
941 self
.device
._GetExternalStoragePathImpl
= mock
.Mock(
942 return_value
='/test/device/external_dir')
943 self
.device
._IsOnlineImpl
= mock
.Mock(return_value
=True)
944 self
.device
._RunShellCommandImpl
= mock
.Mock()
945 mock_zip_temp
= mock
.mock_open()
946 mock_zip_temp
.return_value
.name
= '/test/temp/file/tmp.zip'
947 with mock
.patch('multiprocessing.Process') as mock_zip_proc
, (
948 mock
.patch('tempfile.NamedTemporaryFile', mock_zip_temp
)):
949 self
.device
._PushChangedFilesZipped
(test_files
)
951 mock_zip_proc
.assert_called_once_with(
952 target
=device_utils
.DeviceUtils
._CreateDeviceZip
,
953 args
=('/test/temp/file/tmp.zip', test_files
))
954 self
.adb
.Push
.assert_called_once_with(
955 '/test/temp/file/tmp.zip', '/test/device/external_dir/tmp.zip')
956 self
.assertEqual(2, self
.device
._RunShellCommandImpl
.call_count
)
957 self
.device
._RunShellCommandImpl
.assert_any_call(
958 ['unzip', '/test/device/external_dir/tmp.zip'],
959 as_root
=True, check_return
=True,
960 env
={'PATH': '$PATH:/data/local/tmp/bin'})
961 self
.device
._RunShellCommandImpl
.assert_any_call(
962 ['rm', '/test/device/external_dir/tmp.zip'])
965 class DeviceUtilsFileExistsTest(DeviceUtilsOldImplTest
):
967 def testFileExists_usingTest_fileExists(self
):
968 with self
.assertCalls(
969 "adb -s 0123456789abcdef shell "
970 "'test -e \"/data/app/test.file.exists\"; echo $?'",
972 self
.assertTrue(self
.device
.FileExists('/data/app/test.file.exists'))
974 def testFileExists_usingTest_fileDoesntExist(self
):
975 with self
.assertCalls(
976 "adb -s 0123456789abcdef shell "
977 "'test -e \"/data/app/test.file.does.not.exist\"; echo $?'",
979 self
.assertFalse(self
.device
.FileExists(
980 '/data/app/test.file.does.not.exist'))
982 def testFileExists_usingLs_fileExists(self
):
983 with self
.assertCallsSequence([
984 ("adb -s 0123456789abcdef shell "
985 "'test -e \"/data/app/test.file.exists\"; echo $?'",
986 'test: not found\r\n'),
987 ("adb -s 0123456789abcdef shell "
988 "'ls \"/data/app/test.file.exists\" >/dev/null 2>&1; echo $?'",
990 self
.assertTrue(self
.device
.FileExists('/data/app/test.file.exists'))
992 def testFileExists_usingLs_fileDoesntExist(self
):
993 with self
.assertCallsSequence([
994 ("adb -s 0123456789abcdef shell "
995 "'test -e \"/data/app/test.file.does.not.exist\"; echo $?'",
996 'test: not found\r\n'),
997 ("adb -s 0123456789abcdef shell "
998 "'ls \"/data/app/test.file.does.not.exist\" "
999 ">/dev/null 2>&1; echo $?'",
1001 self
.assertFalse(self
.device
.FileExists(
1002 '/data/app/test.file.does.not.exist'))
1005 class DeviceUtilsPullFileTest(DeviceUtilsOldImplTest
):
1007 def testPullFile_existsOnDevice(self
):
1008 with mock
.patch('os.path.exists', return_value
=True):
1009 with self
.assertCallsSequence([
1010 ('adb -s 0123456789abcdef shell '
1011 'ls /data/app/test.file.exists',
1012 '/data/app/test.file.exists'),
1013 ('adb -s 0123456789abcdef pull '
1014 '/data/app/test.file.exists /test/file/host/path',
1015 '100 B/s (100 bytes in 1.000s)\r\n')]):
1016 self
.device
.PullFile('/data/app/test.file.exists',
1017 '/test/file/host/path')
1019 def testPullFile_doesntExistOnDevice(self
):
1020 with mock
.patch('os.path.exists', return_value
=True):
1021 with self
.assertCalls(
1022 'adb -s 0123456789abcdef shell '
1023 'ls /data/app/test.file.does.not.exist',
1024 '/data/app/test.file.does.not.exist: No such file or directory\r\n'):
1025 with self
.assertRaises(device_errors
.CommandFailedError
):
1026 self
.device
.PullFile('/data/app/test.file.does.not.exist',
1027 '/test/file/host/path')
1030 class DeviceUtilsReadFileTest(DeviceUtilsOldImplTest
):
1032 def testReadFile_exists(self
):
1033 with self
.assertCallsSequence([
1034 ("adb -s 0123456789abcdef shell "
1035 "'cat \"/read/this/test/file\" 2>/dev/null'",
1036 'this is a test file')]):
1037 self
.assertEqual(['this is a test file'],
1038 self
.device
.ReadFile('/read/this/test/file'))
1040 def testReadFile_doesNotExist(self
):
1041 with self
.assertCalls(
1042 "adb -s 0123456789abcdef shell "
1043 "'cat \"/this/file/does.not.exist\" 2>/dev/null'",
1045 self
.device
.ReadFile('/this/file/does.not.exist')
1047 def testReadFile_asRoot_withRoot(self
):
1048 self
.device
.old_interface
._privileged
_command
_runner
= (
1049 self
.device
.old_interface
.RunShellCommand
)
1050 self
.device
.old_interface
._protected
_file
_access
_method
_initialized
= True
1051 with self
.assertCallsSequence([
1052 ("adb -s 0123456789abcdef shell "
1053 "'cat \"/this/file/must.be.read.by.root\" 2> /dev/null'",
1054 'this is a test file\nread by root')]):
1056 ['this is a test file', 'read by root'],
1057 self
.device
.ReadFile('/this/file/must.be.read.by.root',
1060 def testReadFile_asRoot_withSu(self
):
1061 self
.device
.old_interface
._privileged
_command
_runner
= (
1062 self
.device
.old_interface
.RunShellCommandWithSU
)
1063 self
.device
.old_interface
._protected
_file
_access
_method
_initialized
= True
1064 with self
.assertCallsSequence([
1065 ("adb -s 0123456789abcdef shell "
1066 "'su -c cat \"/this/file/can.be.read.with.su\" 2> /dev/null'",
1067 'this is a test file\nread with su')]):
1069 ['this is a test file', 'read with su'],
1070 self
.device
.ReadFile('/this/file/can.be.read.with.su',
1073 def testReadFile_asRoot_rejected(self
):
1074 self
.device
.old_interface
._privileged
_command
_runner
= None
1075 self
.device
.old_interface
._protected
_file
_access
_method
_initialized
= True
1076 with self
.assertRaises(device_errors
.CommandFailedError
):
1077 self
.device
.ReadFile('/this/file/cannot.be.read.by.user',
1081 class DeviceUtilsWriteFileTest(DeviceUtilsOldImplTest
):
1083 def testWriteFile_basic(self
):
1084 mock_file
= mock
.MagicMock(spec
=file)
1085 mock_file
.name
= '/tmp/file/to.be.pushed'
1086 mock_file
.__enter
__.return_value
= mock_file
1087 with mock
.patch('tempfile.NamedTemporaryFile',
1088 return_value
=mock_file
):
1089 with self
.assertCalls(
1090 'adb -s 0123456789abcdef push '
1091 '/tmp/file/to.be.pushed /test/file/written.to.device',
1092 '100 B/s (100 bytes in 1.000s)\r\n'):
1093 self
.device
.WriteFile('/test/file/written.to.device',
1094 'new test file contents')
1095 mock_file
.write
.assert_called_once_with('new test file contents')
1097 def testWriteFile_asRoot_withRoot(self
):
1098 self
.device
.old_interface
._external
_storage
= '/fake/storage/path'
1099 self
.device
.old_interface
._privileged
_command
_runner
= (
1100 self
.device
.old_interface
.RunShellCommand
)
1101 self
.device
.old_interface
._protected
_file
_access
_method
_initialized
= True
1103 mock_file
= mock
.MagicMock(spec
=file)
1104 mock_file
.name
= '/tmp/file/to.be.pushed'
1105 mock_file
.__enter
__.return_value
= mock_file
1106 with mock
.patch('tempfile.NamedTemporaryFile',
1107 return_value
=mock_file
):
1108 with self
.assertCallsSequence(
1110 # Create temporary contents file
1111 (r
"adb -s 0123456789abcdef shell "
1112 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1115 # Create temporary script file
1116 (r
"adb -s 0123456789abcdef shell "
1117 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1121 (r
'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1122 '/fake/storage/path/temp_file-\d+\d+',
1123 '100 B/s (100 bytes in 1.000s)\r\n'),
1125 (r
'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1126 '/fake/storage/path/temp_file-\d+\d+',
1127 '100 B/s (100 bytes in 1.000s)\r\n'),
1129 (r
"adb -s 0123456789abcdef shell "
1130 "'sh /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1131 # Remove device temporaries
1132 (r
"adb -s 0123456789abcdef shell "
1133 "'rm /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1134 (r
"adb -s 0123456789abcdef shell "
1135 "'rm /fake/storage/path/temp_file-\d+-\d+'", '')],
1137 self
.device
.WriteFile('/test/file/written.to.device',
1138 'new test file contents', as_root
=True)
1140 def testWriteFile_asRoot_withSu(self
):
1141 self
.device
.old_interface
._external
_storage
= '/fake/storage/path'
1142 self
.device
.old_interface
._privileged
_command
_runner
= (
1143 self
.device
.old_interface
.RunShellCommandWithSU
)
1144 self
.device
.old_interface
._protected
_file
_access
_method
_initialized
= True
1146 mock_file
= mock
.MagicMock(spec
=file)
1147 mock_file
.name
= '/tmp/file/to.be.pushed'
1148 mock_file
.__enter
__.return_value
= mock_file
1149 with mock
.patch('tempfile.NamedTemporaryFile',
1150 return_value
=mock_file
):
1151 with self
.assertCallsSequence(
1153 # Create temporary contents file
1154 (r
"adb -s 0123456789abcdef shell "
1155 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1158 # Create temporary script file
1159 (r
"adb -s 0123456789abcdef shell "
1160 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1164 (r
'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1165 '/fake/storage/path/temp_file-\d+\d+',
1166 '100 B/s (100 bytes in 1.000s)\r\n'),
1168 (r
'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1169 '/fake/storage/path/temp_file-\d+\d+',
1170 '100 B/s (100 bytes in 1.000s)\r\n'),
1172 (r
"adb -s 0123456789abcdef shell "
1173 "'su -c sh /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1174 # Remove device temporaries
1175 (r
"adb -s 0123456789abcdef shell "
1176 "'rm /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1177 (r
"adb -s 0123456789abcdef shell "
1178 "'rm /fake/storage/path/temp_file-\d+-\d+'", '')],
1180 self
.device
.WriteFile('/test/file/written.to.device',
1181 'new test file contents', as_root
=True)
1183 def testWriteFile_asRoot_rejected(self
):
1184 self
.device
.old_interface
._privileged
_command
_runner
= None
1185 self
.device
.old_interface
._protected
_file
_access
_method
_initialized
= True
1186 with self
.assertRaises(device_errors
.CommandFailedError
):
1187 self
.device
.WriteFile('/test/file/no.permissions.to.write',
1188 'new test file contents', as_root
=True)
1190 class DeviceUtilsWriteTextFileTest(DeviceUtilsOldImplTest
):
1192 def testWriteTextFileTest_basic(self
):
1193 with self
.assertCalls(
1194 "adb -s 0123456789abcdef shell 'echo some.string"
1195 " > /test/file/to.write; echo %$?'", '%0\r\n'):
1196 self
.device
.WriteTextFile('/test/file/to.write', 'some.string')
1198 def testWriteTextFileTest_stringWithSpaces(self
):
1199 with self
.assertCalls(
1200 "adb -s 0123456789abcdef shell 'echo '\\''some other string'\\''"
1201 " > /test/file/to.write; echo %$?'", '%0\r\n'):
1202 self
.device
.WriteTextFile('/test/file/to.write', 'some other string')
1204 def testWriteTextFileTest_asRoot_withSu(self
):
1205 with self
.assertCallsSequence([
1206 ("adb -s 0123456789abcdef shell 'ls /root'", 'Permission denied\r\n'),
1207 ("adb -s 0123456789abcdef shell 'su -c echo some.string"
1208 " > /test/file/to.write; echo %$?'", '%0\r\n')]):
1209 self
.device
.WriteTextFile('/test/file/to.write', 'some.string',
1212 def testWriteTextFileTest_asRoot_withRoot(self
):
1213 with self
.assertCallsSequence([
1214 ("adb -s 0123456789abcdef shell 'ls /root'", 'hello\r\nworld\r\n'),
1215 ("adb -s 0123456789abcdef shell 'echo some.string"
1216 " > /test/file/to.write; echo %$?'", '%0\r\n')]):
1217 self
.device
.WriteTextFile('/test/file/to.write', 'some.string',
1220 def testWriteTextFileTest_asRoot_rejected(self
):
1221 with self
.assertCallsSequence([
1222 ("adb -s 0123456789abcdef shell 'ls /root'", 'Permission denied\r\n'),
1223 ("adb -s 0123456789abcdef shell 'su -c echo some.string"
1224 " > /test/file/to.write; echo %$?'", '%1\r\n')]):
1225 with self
.assertRaises(device_errors
.CommandFailedError
):
1226 self
.device
.WriteTextFile('/test/file/to.write', 'some.string',
1229 class DeviceUtilsLsTest(DeviceUtilsOldImplTest
):
1231 def testLs_nothing(self
):
1232 with self
.assertCallsSequence([
1233 ("adb -s 0123456789abcdef shell 'ls -lR /this/file/does.not.exist'",
1234 '/this/file/does.not.exist: No such file or directory\r\n'),
1235 ("adb -s 0123456789abcdef shell 'date +%z'", '+0000')]):
1236 self
.assertEqual({}, self
.device
.Ls('/this/file/does.not.exist'))
1238 def testLs_file(self
):
1239 with self
.assertCallsSequence([
1240 ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.file'",
1241 '-rw-rw---- testuser testgroup 4096 1970-01-01 00:00 test.file\r\n'),
1242 ("adb -s 0123456789abcdef shell 'date +%z'", '+0000')]):
1244 {'test.file': (4096, datetime
.datetime(1970, 1, 1))},
1245 self
.device
.Ls('/this/is/a/test.file'))
1247 def testLs_directory(self
):
1248 with self
.assertCallsSequence([
1249 ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.directory'",
1251 '/this/is/a/test.directory:\r\n'
1252 '-rw-rw---- testuser testgroup 4096 1970-01-01 18:19 test.file\r\n'),
1253 ("adb -s 0123456789abcdef shell 'date +%z'", '+0000')]):
1255 {'test.file': (4096, datetime
.datetime(1970, 1, 1, 18, 19))},
1256 self
.device
.Ls('/this/is/a/test.directory'))
1258 def testLs_directories(self
):
1259 with self
.assertCallsSequence([
1260 ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.directory'",
1262 '/this/is/a/test.directory:\r\n'
1263 'drwxr-xr-x testuser testgroup 1970-01-01 00:00 test.subdirectory\r\n'
1265 '/this/is/a/test.directory/test.subdirectory:\r\n'
1266 '-rw-rw---- testuser testgroup 4096 1970-01-01 00:00 test.file\r\n'),
1267 ("adb -s 0123456789abcdef shell 'date +%z'", '-0700')]):
1269 {'test.subdirectory/test.file':
1270 (4096, datetime
.datetime(1970, 1, 1, 7, 0, 0))},
1271 self
.device
.Ls('/this/is/a/test.directory'))
1274 class DeviceUtilsSetJavaAssertsTest(DeviceUtilsOldImplTest
):
1277 def mockNamedTemporary(name
='/tmp/file/property.file',
1279 mock_file
= mock
.MagicMock(spec
=file)
1280 mock_file
.name
= name
1281 mock_file
.__enter
__.return_value
= mock_file
1282 mock_file
.read
.return_value
= read_contents
1285 def testSetJavaAsserts_enable(self
):
1286 mock_file
= self
.mockNamedTemporary()
1287 with mock
.patch('tempfile.NamedTemporaryFile',
1288 return_value
=mock_file
), (
1289 mock
.patch('__builtin__.open', return_value
=mock_file
)):
1290 with self
.assertCallsSequence(
1291 [('adb -s 0123456789abcdef shell ls %s' %
1292 constants
.DEVICE_LOCAL_PROPERTIES_PATH
,
1293 '%s\r\n' % constants
.DEVICE_LOCAL_PROPERTIES_PATH
),
1294 ('adb -s 0123456789abcdef pull %s %s' %
1295 (constants
.DEVICE_LOCAL_PROPERTIES_PATH
, mock_file
.name
),
1296 '100 B/s (100 bytes in 1.000s)\r\n'),
1297 ('adb -s 0123456789abcdef push %s %s' %
1298 (mock_file
.name
, constants
.DEVICE_LOCAL_PROPERTIES_PATH
),
1299 '100 B/s (100 bytes in 1.000s)\r\n'),
1300 ('adb -s 0123456789abcdef shell '
1301 'getprop dalvik.vm.enableassertions',
1303 ('adb -s 0123456789abcdef shell '
1304 'setprop dalvik.vm.enableassertions "all"',
1306 self
.assertTrue(self
.device
.SetJavaAsserts(True))
1308 def testSetJavaAsserts_disable(self
):
1309 mock_file
= self
.mockNamedTemporary(
1310 read_contents
='dalvik.vm.enableassertions=all\n')
1311 with mock
.patch('tempfile.NamedTemporaryFile',
1312 return_value
=mock_file
), (
1313 mock
.patch('__builtin__.open', return_value
=mock_file
)):
1314 with self
.assertCallsSequence(
1315 [('adb -s 0123456789abcdef shell ls %s' %
1316 constants
.DEVICE_LOCAL_PROPERTIES_PATH
,
1317 '%s\r\n' % constants
.DEVICE_LOCAL_PROPERTIES_PATH
),
1318 ('adb -s 0123456789abcdef pull %s %s' %
1319 (constants
.DEVICE_LOCAL_PROPERTIES_PATH
, mock_file
.name
),
1320 '100 B/s (100 bytes in 1.000s)\r\n'),
1321 ('adb -s 0123456789abcdef push %s %s' %
1322 (mock_file
.name
, constants
.DEVICE_LOCAL_PROPERTIES_PATH
),
1323 '100 B/s (100 bytes in 1.000s)\r\n'),
1324 ('adb -s 0123456789abcdef shell '
1325 'getprop dalvik.vm.enableassertions',
1327 ('adb -s 0123456789abcdef shell '
1328 'setprop dalvik.vm.enableassertions ""',
1330 self
.assertTrue(self
.device
.SetJavaAsserts(False))
1332 def testSetJavaAsserts_alreadyEnabled(self
):
1333 mock_file
= self
.mockNamedTemporary(
1334 read_contents
='dalvik.vm.enableassertions=all\n')
1335 with mock
.patch('tempfile.NamedTemporaryFile',
1336 return_value
=mock_file
), (
1337 mock
.patch('__builtin__.open', return_value
=mock_file
)):
1338 with self
.assertCallsSequence(
1339 [('adb -s 0123456789abcdef shell ls %s' %
1340 constants
.DEVICE_LOCAL_PROPERTIES_PATH
,
1341 '%s\r\n' % constants
.DEVICE_LOCAL_PROPERTIES_PATH
),
1342 ('adb -s 0123456789abcdef pull %s %s' %
1343 (constants
.DEVICE_LOCAL_PROPERTIES_PATH
, mock_file
.name
),
1344 '100 B/s (100 bytes in 1.000s)\r\n'),
1345 ('adb -s 0123456789abcdef shell '
1346 'getprop dalvik.vm.enableassertions',
1348 self
.assertFalse(self
.device
.SetJavaAsserts(True))
1351 class DeviceUtilsGetPropTest(DeviceUtilsOldImplTest
):
1353 def testGetProp_exists(self
):
1354 with self
.assertCalls(
1355 'adb -s 0123456789abcdef shell getprop this.is.a.test.property',
1356 'test_property_value\r\n'):
1357 self
.assertEqual('test_property_value',
1358 self
.device
.GetProp('this.is.a.test.property'))
1360 def testGetProp_doesNotExist(self
):
1361 with self
.assertCalls(
1362 'adb -s 0123456789abcdef shell '
1363 'getprop this.property.does.not.exist', ''):
1364 self
.assertEqual('', self
.device
.GetProp('this.property.does.not.exist'))
1366 def testGetProp_cachedRoProp(self
):
1367 with self
.assertCalls(
1368 'adb -s 0123456789abcdef shell '
1369 'getprop ro.build.type', 'userdebug'):
1370 self
.assertEqual('userdebug', self
.device
.GetProp('ro.build.type'))
1371 self
.assertEqual('userdebug', self
.device
.GetProp('ro.build.type'))
1374 class DeviceUtilsSetPropTest(DeviceUtilsOldImplTest
):
1376 def testSetProp(self
):
1377 with self
.assertCalls(
1378 'adb -s 0123456789abcdef shell '
1379 'setprop this.is.a.test.property "test_property_value"',
1381 self
.device
.SetProp('this.is.a.test.property', 'test_property_value')
1384 class DeviceUtilsGetPidsTest(DeviceUtilsOldImplTest
):
1386 def testGetPids_noMatches(self
):
1387 with self
.assertCalls(
1388 "adb -s 0123456789abcdef shell 'ps'",
1389 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
1390 'user 1000 100 1024 1024 ffffffff 00000000 no.match\r\n'):
1391 self
.assertEqual({}, self
.device
.GetPids('does.not.match'))
1393 def testGetPids_oneMatch(self
):
1394 with self
.assertCalls(
1395 "adb -s 0123456789abcdef shell 'ps'",
1396 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
1397 'user 1000 100 1024 1024 ffffffff 00000000 not.a.match\r\n'
1398 'user 1001 100 1024 1024 ffffffff 00000000 one.match\r\n'):
1399 self
.assertEqual({'one.match': '1001'}, self
.device
.GetPids('one.match'))
1401 def testGetPids_mutlipleMatches(self
):
1402 with self
.assertCalls(
1403 "adb -s 0123456789abcdef shell 'ps'",
1404 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
1405 'user 1000 100 1024 1024 ffffffff 00000000 not\r\n'
1406 'user 1001 100 1024 1024 ffffffff 00000000 one.match\r\n'
1407 'user 1002 100 1024 1024 ffffffff 00000000 two.match\r\n'
1408 'user 1003 100 1024 1024 ffffffff 00000000 three.match\r\n'):
1410 {'one.match': '1001', 'two.match': '1002', 'three.match': '1003'},
1411 self
.device
.GetPids('match'))
1413 def testGetPids_exactMatch(self
):
1414 with self
.assertCalls(
1415 "adb -s 0123456789abcdef shell 'ps'",
1416 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
1417 'user 1000 100 1024 1024 ffffffff 00000000 not.exact.match\r\n'
1418 'user 1234 100 1024 1024 ffffffff 00000000 exact.match\r\n'):
1420 {'not.exact.match': '1000', 'exact.match': '1234'},
1421 self
.device
.GetPids('exact.match'))
1424 class DeviceUtilsTakeScreenshotTest(DeviceUtilsOldImplTest
):
1426 def testTakeScreenshot_fileNameProvided(self
):
1427 mock_fs
= MockFileSystem()
1428 mock_fs
.addMockDirectory('/test/host')
1429 mock_fs
.addMockFile('/test/host/screenshot.png')
1432 with self
.assertCallsSequence(
1434 (r
"adb -s 0123456789abcdef shell 'echo \$EXTERNAL_STORAGE'",
1435 '/test/external/storage\r\n'),
1436 (r
"adb -s 0123456789abcdef shell '/system/bin/screencap -p \S+'",
1438 (r
"adb -s 0123456789abcdef shell ls \S+",
1439 '/test/external/storage/screenshot.png\r\n'),
1440 (r
'adb -s 0123456789abcdef pull \S+ /test/host/screenshot.png',
1441 '100 B/s (100 B in 1.000s)\r\n'),
1442 (r
"adb -s 0123456789abcdef shell 'rm -f \S+'", '')
1445 self
.device
.TakeScreenshot('/test/host/screenshot.png')
1448 class DeviceUtilsGetIOStatsTest(DeviceUtilsOldImplTest
):
1450 def testGetIOStats(self
):
1451 with self
.assertCalls(
1452 "adb -s 0123456789abcdef shell 'cat \"/proc/diskstats\" 2>/dev/null'",
1453 '179 0 mmcblk0 1 2 3 4 5 6 7 8 9 10 11\r\n'):
1461 self
.device
.GetIOStats())
1464 class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsOldImplTest
):
1467 super(DeviceUtilsGetMemoryUsageForPidTest
, self
).setUp()
1468 self
.device
.old_interface
._privileged
_command
_runner
= (
1469 self
.device
.old_interface
.RunShellCommand
)
1470 self
.device
.old_interface
._protected
_file
_access
_method
_initialized
= True
1472 def testGetMemoryUsageForPid_validPid(self
):
1473 with self
.assertCallsSequence([
1474 ("adb -s 0123456789abcdef shell 'showmap 1234'",
1475 '100 101 102 103 104 105 106 107 TOTAL\r\n'),
1476 ("adb -s 0123456789abcdef shell "
1477 "'cat \"/proc/1234/status\" 2> /dev/null'",
1485 'Shared_Clean': 103,
1486 'Shared_Dirty': 104,
1487 'Private_Clean': 105,
1488 'Private_Dirty': 106,
1491 self
.device
.GetMemoryUsageForPid(1234))
1493 def testGetMemoryUsageForPid_invalidPid(self
):
1494 with self
.assertCalls(
1495 "adb -s 0123456789abcdef shell 'showmap 4321'",
1496 'cannot open /proc/4321/smaps: No such file or directory\r\n'):
1497 self
.assertEqual({}, self
.device
.GetMemoryUsageForPid(4321))
1500 class DeviceUtilsStrTest(DeviceUtilsOldImplTest
):
1501 def testStr_noAdbCalls(self
):
1502 with self
.assertNoAdbCalls():
1503 self
.assertEqual('0123456789abcdef', str(self
.device
))
1505 def testStr_noSerial(self
):
1506 self
.device
= device_utils
.DeviceUtils(None)
1507 with self
.assertCalls('adb get-serialno', '0123456789abcdef'):
1508 self
.assertEqual('0123456789abcdef', str(self
.device
))
1510 def testStr_noSerial_noDevices(self
):
1511 self
.device
= device_utils
.DeviceUtils(None)
1512 with self
.assertCalls('adb get-serialno', 'unknown'), (
1513 self
.assertRaises(device_errors
.NoDevicesError
)):
1517 if __name__
== '__main__':
1518 logging
.getLogger().setLevel(logging
.DEBUG
)
1519 unittest
.main(verbosity
=2)