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)
88 ('os.path.abspath', ''),
89 ('os.path.dirname', ''),
90 ('os.path.exists', False),
91 ('os.path.getsize', 0),
92 ('os.path.isdir', False),
93 ('os.stat', osStatResult.__func__()),
97 def _get(self, mocked, path, default_val):
99 logging.debug('%s(%s)' % (mocked, path))
100 return (self.mock_file_info[path][mocked]
101 if path in self.mock_file_info
104 def _patched(self, target, default_val=None):
105 r = lambda f: self._get(target, f, default_val)
106 return _PatchedFunction(patched=mock.patch(target, side_effect=r))
108 def __init__(self, verbose=False):
109 self.mock_file_info = {}
110 self._patched_functions = [
111 self._patched(m, d) for m, d in type(self).MOCKED_FUNCTIONS]
112 self._verbose = verbose
114 def addMockFile(self, path, **kw):
115 self._addMockThing(path, False, **kw)
117 def addMockDirectory(self, path, **kw):
118 self._addMockThing(path, True, **kw)
120 def _addMockThing(self, path, is_dir, size=0, stat=None, walk=None):
122 stat = self.osStatResult()
125 self.mock_file_info[path] = {
126 'os.path.abspath': path,
127 'os.path.dirname': '/' + '/'.join(path.strip('/').split('/')[:-1]),
128 'os.path.exists': True,
129 'os.path.isdir': is_dir,
130 'os.path.getsize': size,
136 for p in self._patched_functions:
137 p.mocked = p.patched.__enter__()
139 def __exit__(self, exc_type, exc_val, exc_tb):
140 for p in self._patched_functions:
144 class DeviceUtilsOldImplTest(unittest.TestCase):
146 class AndroidCommandsCalls(object):
148 def __init__(self, test_case, cmd_ret, comp):
151 self._run_command = _PatchedFunction()
152 self._test_case = test_case
153 self._total_received = 0
156 self._run_command.patched = mock.patch(
157 'run_command.RunCommand',
158 side_effect=lambda c, **kw: self._ret(c))
159 self._run_command.mocked = self._run_command.patched.__enter__()
161 def _ret(self, actual_cmd):
162 if sys.exc_info()[0] is None:
163 on_failure_fmt = ('\n'
164 ' received command: %s\n'
165 ' expected command: %s')
166 self._test_case.assertGreater(
167 len(self._cmds), self._total_received,
168 msg=on_failure_fmt % (actual_cmd, None))
169 expected_cmd, ret = self._cmds[self._total_received]
170 self._total_received += 1
171 self._test_case.assertTrue(
172 self._comp(expected_cmd, actual_cmd),
173 msg=on_failure_fmt % (actual_cmd, expected_cmd))
177 def __exit__(self, exc_type, exc_val, exc_tb):
178 self._run_command.patched.__exit__(exc_type, exc_val, exc_tb)
180 on_failure = "adb commands don't match.\nExpected:%s\nActual:%s" % (
181 ''.join('\n %s' % c for c, _ in self._cmds),
182 ''.join('\n %s' % a[0]
183 for _, a, kw in self._run_command.mocked.mock_calls))
184 self._test_case.assertEqual(
185 len(self._cmds), len(self._run_command.mocked.mock_calls),
187 for (expected_cmd, _r), (_n, actual_args, actual_kwargs) in zip(
188 self._cmds, self._run_command.mocked.mock_calls):
189 self._test_case.assertEqual(1, len(actual_args), msg=on_failure)
190 self._test_case.assertTrue(self._comp(expected_cmd, actual_args[0]),
192 self._test_case.assertTrue('timeout_time' in actual_kwargs,
194 self._test_case.assertTrue('retry_count' in actual_kwargs,
197 def assertNoAdbCalls(self):
198 return type(self).AndroidCommandsCalls(self, [], str.__eq__)
200 def assertCalls(self, cmd, ret, comp=str.__eq__):
201 return type(self).AndroidCommandsCalls(self, [(cmd, ret)], comp)
203 def assertCallsSequence(self, cmd_ret, comp=str.__eq__):
204 return type(self).AndroidCommandsCalls(self, cmd_ret, comp)
207 self.device = device_utils.DeviceUtils(
208 '0123456789abcdef', default_timeout=1, default_retries=0)
211 class DeviceUtilsIsOnlineTest(DeviceUtilsOldImplTest):
213 def testIsOnline_true(self):
214 with self.assertCalls('adb -s 0123456789abcdef devices',
215 '00123456789abcdef device\r\n'):
216 self.assertTrue(self.device.IsOnline())
218 def testIsOnline_false(self):
219 with self.assertCalls('adb -s 0123456789abcdef devices', '\r\n'):
220 self.assertFalse(self.device.IsOnline())
223 class DeviceUtilsHasRootTest(DeviceUtilsOldImplTest):
225 def testHasRoot_true(self):
226 with self.assertCalls("adb -s 0123456789abcdef shell 'ls /root'",
228 self.assertTrue(self.device.HasRoot())
230 def testHasRoot_false(self):
231 with self.assertCalls("adb -s 0123456789abcdef shell 'ls /root'",
232 'Permission denied\r\n'):
233 self.assertFalse(self.device.HasRoot())
236 class DeviceUtilsEnableRootTest(DeviceUtilsOldImplTest):
238 def testEnableRoot_succeeds(self):
239 with self.assertCallsSequence([
240 ('adb -s 0123456789abcdef shell getprop ro.build.type',
242 ('adb -s 0123456789abcdef root', 'restarting adbd as root\r\n'),
243 ('adb -s 0123456789abcdef wait-for-device', ''),
244 ('adb -s 0123456789abcdef wait-for-device', '')]):
245 self.device.EnableRoot()
247 def testEnableRoot_userBuild(self):
248 with self.assertCallsSequence([
249 ('adb -s 0123456789abcdef shell getprop ro.build.type', 'user\r\n')]):
250 with self.assertRaises(device_errors.CommandFailedError):
251 self.device.EnableRoot()
253 def testEnableRoot_rootFails(self):
254 with self.assertCallsSequence([
255 ('adb -s 0123456789abcdef shell getprop ro.build.type',
257 ('adb -s 0123456789abcdef root', 'no\r\n'),
258 ('adb -s 0123456789abcdef wait-for-device', '')]):
259 with self.assertRaises(device_errors.CommandFailedError):
260 self.device.EnableRoot()
263 class DeviceUtilsGetExternalStoragePathTest(DeviceUtilsOldImplTest):
265 def testGetExternalStoragePath_succeeds(self):
266 fakeStoragePath = '/fake/storage/path'
267 with self.assertCalls(
268 "adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
269 '%s\r\n' % fakeStoragePath):
270 self.assertEquals(fakeStoragePath,
271 self.device.GetExternalStoragePath())
273 def testGetExternalStoragePath_fails(self):
274 with self.assertCalls(
275 "adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'", '\r\n'):
276 with self.assertRaises(device_errors.CommandFailedError):
277 self.device.GetExternalStoragePath()
280 class DeviceUtilsWaitUntilFullyBootedTest(DeviceUtilsOldImplTest):
282 def testWaitUntilFullyBooted_succeedsNoWifi(self):
283 with self.assertCallsSequence([
284 # AndroidCommands.WaitForSystemBootCompleted
285 ('adb -s 0123456789abcdef wait-for-device', ''),
286 ('adb -s 0123456789abcdef shell getprop sys.boot_completed', '1\r\n'),
287 # AndroidCommands.WaitForDevicePm
288 ('adb -s 0123456789abcdef wait-for-device', ''),
289 ('adb -s 0123456789abcdef shell pm path android',
290 'package:this.is.a.test.package'),
291 # AndroidCommands.WaitForSdCardReady
292 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
293 '/fake/storage/path'),
294 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
297 self.device.WaitUntilFullyBooted(wifi=False)
299 def testWaitUntilFullyBooted_succeedsWithWifi(self):
300 with self.assertCallsSequence([
301 # AndroidCommands.WaitForSystemBootCompleted
302 ('adb -s 0123456789abcdef wait-for-device', ''),
303 ('adb -s 0123456789abcdef shell getprop sys.boot_completed', '1\r\n'),
304 # AndroidCommands.WaitForDevicePm
305 ('adb -s 0123456789abcdef wait-for-device', ''),
306 ('adb -s 0123456789abcdef shell pm path android',
307 'package:this.is.a.test.package'),
308 # AndroidCommands.WaitForSdCardReady
309 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
310 '/fake/storage/path'),
311 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
314 ("adb -s 0123456789abcdef shell 'dumpsys wifi'", 'Wi-Fi is enabled')]):
315 self.device.WaitUntilFullyBooted(wifi=True)
317 def testWaitUntilFullyBooted_bootFails(self):
318 with mock.patch('time.sleep'):
319 with self.assertCallsSequence([
320 # AndroidCommands.WaitForSystemBootCompleted
321 ('adb -s 0123456789abcdef wait-for-device', ''),
322 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
324 with self.assertRaises(device_errors.CommandTimeoutError):
325 self.device.WaitUntilFullyBooted(wifi=False)
327 def testWaitUntilFullyBooted_devicePmFails(self):
328 with mock.patch('time.sleep'):
329 with self.assertCallsSequence([
330 # AndroidCommands.WaitForSystemBootCompleted
331 ('adb -s 0123456789abcdef wait-for-device', ''),
332 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
334 # AndroidCommands.WaitForDevicePm
335 + 3 * ([('adb -s 0123456789abcdef wait-for-device', '')]
336 + 24 * [('adb -s 0123456789abcdef shell pm path android', '\r\n')]
337 + [("adb -s 0123456789abcdef shell 'stop'", '\r\n'),
338 ("adb -s 0123456789abcdef shell 'start'", '\r\n')])):
339 with self.assertRaises(device_errors.CommandTimeoutError):
340 self.device.WaitUntilFullyBooted(wifi=False)
342 def testWaitUntilFullyBooted_sdCardReadyFails_noPath(self):
343 with mock.patch('time.sleep'):
344 with self.assertCallsSequence([
345 # AndroidCommands.WaitForSystemBootCompleted
346 ('adb -s 0123456789abcdef wait-for-device', ''),
347 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
349 # AndroidCommands.WaitForDevicePm
350 ('adb -s 0123456789abcdef wait-for-device', ''),
351 ('adb -s 0123456789abcdef shell pm path android',
352 'package:this.is.a.test.package'),
353 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'", '\r\n')]):
354 with self.assertRaises(device_errors.CommandFailedError):
355 self.device.WaitUntilFullyBooted(wifi=False)
357 def testWaitUntilFullyBooted_sdCardReadyFails_emptyPath(self):
358 with mock.patch('time.sleep'):
359 with self.assertCallsSequence([
360 # AndroidCommands.WaitForSystemBootCompleted
361 ('adb -s 0123456789abcdef wait-for-device', ''),
362 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
364 # AndroidCommands.WaitForDevicePm
365 ('adb -s 0123456789abcdef wait-for-device', ''),
366 ('adb -s 0123456789abcdef shell pm path android',
367 'package:this.is.a.test.package'),
368 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
369 '/fake/storage/path\r\n'),
370 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'", '')]):
371 with self.assertRaises(device_errors.CommandTimeoutError):
372 self.device.WaitUntilFullyBooted(wifi=False)
375 class DeviceUtilsRebootTest(DeviceUtilsOldImplTest):
377 def testReboot_nonBlocking(self):
378 with mock.patch('time.sleep'):
379 with self.assertCallsSequence([
380 ('adb -s 0123456789abcdef reboot', ''),
381 ('adb -s 0123456789abcdef devices', 'unknown\r\n'),
382 ('adb -s 0123456789abcdef wait-for-device', ''),
383 ('adb -s 0123456789abcdef shell pm path android',
384 'package:this.is.a.test.package'),
385 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
386 '/fake/storage/path\r\n'),
387 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
389 self.device.Reboot(block=False)
391 def testReboot_blocking(self):
392 with mock.patch('time.sleep'):
393 with self.assertCallsSequence([
394 ('adb -s 0123456789abcdef reboot', ''),
395 ('adb -s 0123456789abcdef devices', 'unknown\r\n'),
396 ('adb -s 0123456789abcdef wait-for-device', ''),
397 ('adb -s 0123456789abcdef shell pm path android',
398 'package:this.is.a.test.package'),
399 ("adb -s 0123456789abcdef shell 'echo $EXTERNAL_STORAGE'",
400 '/fake/storage/path\r\n'),
401 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
403 ('adb -s 0123456789abcdef wait-for-device', ''),
404 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
406 ('adb -s 0123456789abcdef wait-for-device', ''),
407 ('adb -s 0123456789abcdef shell pm path android',
408 'package:this.is.a.test.package'),
409 ("adb -s 0123456789abcdef shell 'ls /fake/storage/path'",
411 self.device.Reboot(block=True)
414 class DeviceUtilsInstallTest(DeviceUtilsOldImplTest):
416 def testInstall_noPriorInstall(self):
417 with mock.patch('os.path.isfile', return_value=True), (
418 mock.patch('pylib.utils.apk_helper.GetPackageName',
419 return_value='this.is.a.test.package')):
420 with self.assertCallsSequence([
421 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
423 ("adb -s 0123456789abcdef install /fake/test/app.apk",
425 self.device.Install('/fake/test/app.apk', retries=0)
427 def testInstall_differentPriorInstall(self):
428 def mockGetFilesChanged(host_path, device_path, ignore_filenames):
429 return [(host_path, device_path)]
431 # Pylint raises a false positive "operator not preceded by a space"
433 # pylint: disable=C0322
434 with mock.patch('os.path.isfile', return_value=True), (
435 mock.patch('os.path.exists', return_value=True)), (
436 mock.patch('pylib.utils.apk_helper.GetPackageName',
437 return_value='this.is.a.test.package')), (
438 mock.patch('pylib.constants.GetOutDirectory',
439 return_value='/fake/test/out')), (
440 mock.patch('pylib.android_commands.AndroidCommands.GetFilesChanged',
441 side_effect=mockGetFilesChanged)):
442 # pylint: enable=C0322
443 with self.assertCallsSequence([
444 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
445 'package:/fake/data/app/this.is.a.test.package.apk\r\n'),
446 # GetFilesChanged is mocked, so its adb calls are omitted.
447 ('adb -s 0123456789abcdef uninstall this.is.a.test.package',
449 ('adb -s 0123456789abcdef install /fake/test/app.apk',
451 self.device.Install('/fake/test/app.apk', retries=0)
453 def testInstall_differentPriorInstall_reinstall(self):
454 def mockGetFilesChanged(host_path, device_path, ignore_filenames):
455 return [(host_path, device_path)]
457 # Pylint raises a false positive "operator not preceded by a space"
459 # pylint: disable=C0322
460 with mock.patch('os.path.isfile', return_value=True), (
461 mock.patch('pylib.utils.apk_helper.GetPackageName',
462 return_value='this.is.a.test.package')), (
463 mock.patch('pylib.constants.GetOutDirectory',
464 return_value='/fake/test/out')), (
465 mock.patch('pylib.android_commands.AndroidCommands.GetFilesChanged',
466 side_effect=mockGetFilesChanged)):
467 # pylint: enable=C0322
468 with self.assertCallsSequence([
469 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
470 'package:/fake/data/app/this.is.a.test.package.apk\r\n'),
471 # GetFilesChanged is mocked, so its adb calls are omitted.
472 ('adb -s 0123456789abcdef install -r /fake/test/app.apk',
474 self.device.Install('/fake/test/app.apk', reinstall=True, retries=0)
476 def testInstall_identicalPriorInstall(self):
477 def mockGetFilesChanged(host_path, device_path, ignore_filenames):
480 with mock.patch('pylib.utils.apk_helper.GetPackageName',
481 return_value='this.is.a.test.package'), (
482 mock.patch('pylib.android_commands.AndroidCommands.GetFilesChanged',
483 side_effect=mockGetFilesChanged)):
484 with self.assertCallsSequence([
485 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
486 'package:/fake/data/app/this.is.a.test.package.apk\r\n')
487 # GetFilesChanged is mocked, so its adb calls are omitted.
489 self.device.Install('/fake/test/app.apk', retries=0)
491 def testInstall_fails(self):
492 with mock.patch('os.path.isfile', return_value=True), (
493 mock.patch('pylib.utils.apk_helper.GetPackageName',
494 return_value='this.is.a.test.package')):
495 with self.assertCallsSequence([
496 ("adb -s 0123456789abcdef shell 'pm path this.is.a.test.package'",
498 ("adb -s 0123456789abcdef install /fake/test/app.apk",
500 with self.assertRaises(device_errors.CommandFailedError):
501 self.device.Install('/fake/test/app.apk', retries=0)
504 class DeviceUtilsRunShellCommandTest(DeviceUtilsOldImplTest):
506 def testRunShellCommand_commandAsList(self):
507 with self.assertCalls(
508 "adb -s 0123456789abcdef shell 'pm list packages'",
509 'pacakge:android\r\n'):
510 self.device.RunShellCommand(['pm', 'list', 'packages'])
512 def testRunShellCommand_commandAsString(self):
513 with self.assertCalls(
514 "adb -s 0123456789abcdef shell 'dumpsys wifi'",
515 'Wi-Fi is enabled\r\n'):
516 self.device.RunShellCommand('dumpsys wifi')
518 def testRunShellCommand_withSu(self):
519 with self.assertCallsSequence([
520 ("adb -s 0123456789abcdef shell 'ls /root'", 'Permission denied\r\n'),
521 ("adb -s 0123456789abcdef shell 'su -c setprop service.adb.root 0'",
523 self.device.RunShellCommand('setprop service.adb.root 0', as_root=True)
525 def testRunShellCommand_withRoot(self):
526 with self.assertCallsSequence([
527 ("adb -s 0123456789abcdef shell 'ls /root'", 'hello\r\nworld\r\n'),
528 ("adb -s 0123456789abcdef shell 'setprop service.adb.root 0'", '')]):
529 self.device.RunShellCommand('setprop service.adb.root 0', as_root=True)
531 def testRunShellCommand_checkReturn_success(self):
532 with self.assertCalls(
533 "adb -s 0123456789abcdef shell 'echo $ANDROID_DATA; echo %$?'",
535 self.device.RunShellCommand('echo $ANDROID_DATA', check_return=True)
537 def testRunShellCommand_checkReturn_failure(self):
538 with self.assertCalls(
539 "adb -s 0123456789abcdef shell 'echo $ANDROID_DATA; echo %$?'",
541 with self.assertRaises(device_errors.CommandFailedError):
542 self.device.RunShellCommand('echo $ANDROID_DATA', check_return=True)
545 class DeviceUtilsKillAllTest(DeviceUtilsOldImplTest):
547 def testKillAll_noMatchingProcesses(self):
548 with self.assertCalls(
549 "adb -s 0123456789abcdef shell 'ps'",
550 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'):
551 with self.assertRaises(device_errors.CommandFailedError):
552 self.device.KillAll('test_process')
554 def testKillAll_nonblocking(self):
555 with self.assertCallsSequence([
556 ("adb -s 0123456789abcdef shell 'ps'",
557 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
558 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
559 'this.is.a.test.process\r\n'),
560 ("adb -s 0123456789abcdef shell 'kill -9 1234'", '')]):
562 self.device.KillAll('this.is.a.test.process', blocking=False))
564 def testKillAll_blocking(self):
565 with mock.patch('time.sleep'):
566 with self.assertCallsSequence([
567 ("adb -s 0123456789abcdef shell 'ps'",
568 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
569 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
570 'this.is.a.test.process\r\n'),
571 ("adb -s 0123456789abcdef shell 'kill -9 1234'", ''),
572 ("adb -s 0123456789abcdef shell 'ps'",
573 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
574 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
575 'this.is.a.test.process\r\n'),
576 ("adb -s 0123456789abcdef shell 'ps'",
577 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n')]):
579 self.device.KillAll('this.is.a.test.process', blocking=True))
581 def testKillAll_root(self):
582 with self.assertCallsSequence([
583 ("adb -s 0123456789abcdef shell 'ps'",
584 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
585 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
586 'this.is.a.test.process\r\n'),
587 ("adb -s 0123456789abcdef shell 'ls /root'", 'Permission denied\r\n'),
588 ("adb -s 0123456789abcdef shell 'su -c kill -9 1234'", '')]):
590 self.device.KillAll('this.is.a.test.process', as_root=True))
592 def testKillAll_sigterm(self):
593 with self.assertCallsSequence([
594 ("adb -s 0123456789abcdef shell 'ps'",
595 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
596 'u0_a1 1234 174 123456 54321 ffffffff 456789ab '
597 'this.is.a.test.process\r\n'),
598 ("adb -s 0123456789abcdef shell 'kill -15 1234'", '')]):
600 self.device.KillAll('this.is.a.test.process', signum=signal.SIGTERM))
603 class DeviceUtilsStartActivityTest(DeviceUtilsOldImplTest):
605 def testStartActivity_actionOnly(self):
606 test_intent = intent.Intent(action='android.intent.action.VIEW')
607 with self.assertCalls(
608 "adb -s 0123456789abcdef shell 'am start "
609 "-a android.intent.action.VIEW'",
610 'Starting: Intent { act=android.intent.action.VIEW }'):
611 self.device.StartActivity(test_intent)
613 def testStartActivity_success(self):
614 test_intent = intent.Intent(action='android.intent.action.VIEW',
615 package='this.is.a.test.package',
617 with self.assertCalls(
618 "adb -s 0123456789abcdef shell 'am start "
619 "-a android.intent.action.VIEW "
620 "-n this.is.a.test.package/.Main'",
621 'Starting: Intent { act=android.intent.action.VIEW }'):
622 self.device.StartActivity(test_intent)
624 def testStartActivity_failure(self):
625 test_intent = intent.Intent(action='android.intent.action.VIEW',
626 package='this.is.a.test.package',
628 with self.assertCalls(
629 "adb -s 0123456789abcdef shell 'am start "
630 "-a android.intent.action.VIEW "
631 "-n this.is.a.test.package/.Main'",
632 'Error: Failed to start test activity'):
633 with self.assertRaises(device_errors.CommandFailedError):
634 self.device.StartActivity(test_intent)
636 def testStartActivity_blocking(self):
637 test_intent = intent.Intent(action='android.intent.action.VIEW',
638 package='this.is.a.test.package',
640 with self.assertCalls(
641 "adb -s 0123456789abcdef shell 'am start "
642 "-a android.intent.action.VIEW "
644 "-n this.is.a.test.package/.Main'",
645 'Starting: Intent { act=android.intent.action.VIEW }'):
646 self.device.StartActivity(test_intent, blocking=True)
648 def testStartActivity_withCategory(self):
649 test_intent = intent.Intent(action='android.intent.action.VIEW',
650 package='this.is.a.test.package',
652 category='android.intent.category.HOME')
653 with self.assertCalls(
654 "adb -s 0123456789abcdef shell 'am start "
655 "-a android.intent.action.VIEW "
656 "-c android.intent.category.HOME "
657 "-n this.is.a.test.package/.Main'",
658 'Starting: Intent { act=android.intent.action.VIEW }'):
659 self.device.StartActivity(test_intent)
661 def testStartActivity_withMultipleCategories(self):
662 # The new implementation will start the activity with all provided
663 # categories. The old one only uses the first category.
664 test_intent = intent.Intent(action='android.intent.action.VIEW',
665 package='this.is.a.test.package',
667 category=['android.intent.category.HOME',
668 'android.intent.category.BROWSABLE'])
669 with self.assertCalls(
670 "adb -s 0123456789abcdef shell 'am start "
671 "-a android.intent.action.VIEW "
672 "-c android.intent.category.HOME "
673 "-n this.is.a.test.package/.Main'",
674 'Starting: Intent { act=android.intent.action.VIEW }'):
675 self.device.StartActivity(test_intent)
677 def testStartActivity_withData(self):
678 test_intent = intent.Intent(action='android.intent.action.VIEW',
679 package='this.is.a.test.package',
681 data='http://www.google.com/')
682 with self.assertCalls(
683 "adb -s 0123456789abcdef shell 'am start "
684 "-a android.intent.action.VIEW "
685 "-n this.is.a.test.package/.Main "
686 "-d \"http://www.google.com/\"'",
687 'Starting: Intent { act=android.intent.action.VIEW }'):
688 self.device.StartActivity(test_intent)
690 def testStartActivity_withStringExtra(self):
691 test_intent = intent.Intent(action='android.intent.action.VIEW',
692 package='this.is.a.test.package',
694 extras={'foo': 'test'})
695 with self.assertCalls(
696 "adb -s 0123456789abcdef shell 'am start "
697 "-a android.intent.action.VIEW "
698 "-n this.is.a.test.package/.Main "
700 'Starting: Intent { act=android.intent.action.VIEW }'):
701 self.device.StartActivity(test_intent)
703 def testStartActivity_withBoolExtra(self):
704 test_intent = intent.Intent(action='android.intent.action.VIEW',
705 package='this.is.a.test.package',
707 extras={'foo': True})
708 with self.assertCalls(
709 "adb -s 0123456789abcdef shell 'am start "
710 "-a android.intent.action.VIEW "
711 "-n this.is.a.test.package/.Main "
713 'Starting: Intent { act=android.intent.action.VIEW }'):
714 self.device.StartActivity(test_intent)
716 def testStartActivity_withIntExtra(self):
717 test_intent = intent.Intent(action='android.intent.action.VIEW',
718 package='this.is.a.test.package',
721 with self.assertCalls(
722 "adb -s 0123456789abcdef shell 'am start "
723 "-a android.intent.action.VIEW "
724 "-n this.is.a.test.package/.Main "
726 'Starting: Intent { act=android.intent.action.VIEW }'):
727 self.device.StartActivity(test_intent)
729 def testStartActivity_withTraceFile(self):
730 test_intent = intent.Intent(action='android.intent.action.VIEW',
731 package='this.is.a.test.package',
733 with self.assertCalls(
734 "adb -s 0123456789abcdef shell 'am start "
735 "-a android.intent.action.VIEW "
736 "-n this.is.a.test.package/.Main "
737 "--start-profiler test_trace_file.out'",
738 'Starting: Intent { act=android.intent.action.VIEW }'):
739 self.device.StartActivity(test_intent,
740 trace_file_name='test_trace_file.out')
742 def testStartActivity_withForceStop(self):
743 test_intent = intent.Intent(action='android.intent.action.VIEW',
744 package='this.is.a.test.package',
746 with self.assertCalls(
747 "adb -s 0123456789abcdef shell 'am start "
748 "-a android.intent.action.VIEW "
750 "-n this.is.a.test.package/.Main'",
751 'Starting: Intent { act=android.intent.action.VIEW }'):
752 self.device.StartActivity(test_intent, force_stop=True)
754 def testStartActivity_withFlags(self):
755 test_intent = intent.Intent(action='android.intent.action.VIEW',
756 package='this.is.a.test.package',
759 with self.assertCalls(
760 "adb -s 0123456789abcdef shell 'am start "
761 "-a android.intent.action.VIEW "
762 "-n this.is.a.test.package/.Main "
764 'Starting: Intent { act=android.intent.action.VIEW }'):
765 self.device.StartActivity(test_intent)
768 class DeviceUtilsBroadcastIntentTest(DeviceUtilsOldImplTest):
770 def testBroadcastIntent_noExtras(self):
771 test_intent = intent.Intent(action='test.package.with.an.INTENT')
772 with self.assertCalls(
773 "adb -s 0123456789abcdef shell 'am broadcast "
774 "-a test.package.with.an.INTENT '",
775 'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
776 self.device.BroadcastIntent(test_intent)
778 def testBroadcastIntent_withExtra(self):
779 test_intent = intent.Intent(action='test.package.with.an.INTENT',
780 extras={'foo': 'bar'})
781 with self.assertCalls(
782 "adb -s 0123456789abcdef shell 'am broadcast "
783 "-a test.package.with.an.INTENT "
785 'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
786 self.device.BroadcastIntent(test_intent)
788 def testBroadcastIntent_withExtra_noValue(self):
789 test_intent = intent.Intent(action='test.package.with.an.INTENT',
790 extras={'foo': None})
791 with self.assertCalls(
792 "adb -s 0123456789abcdef shell 'am broadcast "
793 "-a test.package.with.an.INTENT "
795 'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
796 self.device.BroadcastIntent(test_intent)
799 class DeviceUtilsGoHomeTest(DeviceUtilsOldImplTest):
801 def testGoHome(self):
802 with self.assertCalls(
803 "adb -s 0123456789abcdef shell 'am start "
805 "-a android.intent.action.MAIN "
806 "-c android.intent.category.HOME'",
807 'Starting: Intent { act=android.intent.action.MAIN }\r\n'):
811 class DeviceUtilsForceStopTest(DeviceUtilsOldImplTest):
813 def testForceStop(self):
814 with self.assertCalls(
815 "adb -s 0123456789abcdef shell 'am force-stop this.is.a.test.package'",
817 self.device.ForceStop('this.is.a.test.package')
820 class DeviceUtilsClearApplicationStateTest(DeviceUtilsOldImplTest):
822 def testClearApplicationState_packageExists(self):
823 with self.assertCalls(
824 "adb -s 0123456789abcdef shell 'pm path this.package.does.not.exist'",
826 self.device.ClearApplicationState('this.package.does.not.exist')
828 def testClearApplicationState_packageDoesntExist(self):
829 with self.assertCallsSequence([
830 ("adb -s 0123456789abcdef shell 'pm path this.package.exists'",
831 'package:/data/app/this.package.exists.apk'),
832 ("adb -s 0123456789abcdef shell 'pm clear this.package.exists'",
834 self.device.ClearApplicationState('this.package.exists')
837 class DeviceUtilsSendKeyEventTest(DeviceUtilsOldImplTest):
839 def testSendKeyEvent(self):
840 with self.assertCalls(
841 "adb -s 0123456789abcdef shell 'input keyevent 66'",
843 self.device.SendKeyEvent(66)
846 class DeviceUtilsPushChangedFilesTest(DeviceUtilsOldImplTest):
849 def testPushChangedFiles_noHostPath(self):
850 with mock.patch('os.path.exists', return_value=False):
851 with self.assertRaises(device_errors.CommandFailedError):
852 self.device.PushChangedFiles('/test/host/path', '/test/device/path')
854 def testPushChangedFiles_file_noChange(self):
855 self.device.old_interface._push_if_needed_cache = {}
857 host_file_path = '/test/host/path'
858 device_file_path = '/test/device/path'
860 mock_fs = MockFileSystem()
861 mock_fs.addMockFile(host_file_path, size=100)
863 self.device.old_interface.GetFilesChanged = mock.Mock(return_value=[])
866 # GetFilesChanged is mocked, so its adb calls are omitted.
867 with self.assertNoAdbCalls():
868 self.device.PushChangedFiles(host_file_path, device_file_path)
870 def testPushChangedFiles_file_changed(self):
871 self.device.old_interface._push_if_needed_cache = {}
873 host_file_path = '/test/host/path'
874 device_file_path = '/test/device/path'
876 mock_fs = MockFileSystem()
878 host_file_path, size=100,
879 stat=MockFileSystem.osStatResult(st_mtime=1000000000))
881 self.device.old_interface.GetFilesChanged = mock.Mock(
882 return_value=[('/test/host/path', '/test/device/path')])
885 with self.assertCalls('adb -s 0123456789abcdef push '
886 '/test/host/path /test/device/path', '100 B/s (100 B in 1.000s)\r\n'):
887 self.device.PushChangedFiles(host_file_path, device_file_path)
889 def testPushChangedFiles_directory_nothingChanged(self):
890 self.device.old_interface._push_if_needed_cache = {}
892 host_file_path = '/test/host/path'
893 device_file_path = '/test/device/path'
895 mock_fs = MockFileSystem()
896 mock_fs.addMockDirectory(
897 host_file_path, size=256,
898 stat=MockFileSystem.osStatResult(st_mtime=1000000000))
900 host_file_path + '/file1', size=251,
901 stat=MockFileSystem.osStatResult(st_mtime=1000000001))
903 host_file_path + '/file2', size=252,
904 stat=MockFileSystem.osStatResult(st_mtime=1000000002))
906 self.device.old_interface.GetFilesChanged = mock.Mock(return_value=[])
909 with self.assertCallsSequence([
910 ("adb -s 0123456789abcdef shell 'mkdir -p \"/test/device/path\"'",
912 self.device.PushChangedFiles(host_file_path, device_file_path)
914 def testPushChangedFiles_directory_somethingChanged(self):
915 self.device.old_interface._push_if_needed_cache = {}
917 host_file_path = '/test/host/path'
918 device_file_path = '/test/device/path'
920 mock_fs = MockFileSystem()
921 mock_fs.addMockDirectory(
922 host_file_path, size=256,
923 stat=MockFileSystem.osStatResult(st_mtime=1000000000),
924 walk=[('/test/host/path', [], ['file1', 'file2'])])
926 host_file_path + '/file1', size=256,
927 stat=MockFileSystem.osStatResult(st_mtime=1000000001))
929 host_file_path + '/file2', size=256,
930 stat=MockFileSystem.osStatResult(st_mtime=1000000002))
932 self.device.old_interface.GetFilesChanged = mock.Mock(
933 return_value=[('/test/host/path/file1', '/test/device/path/file1')])
936 with self.assertCallsSequence([
937 ("adb -s 0123456789abcdef shell 'mkdir -p \"/test/device/path\"'",
939 ('adb -s 0123456789abcdef push '
940 '/test/host/path/file1 /test/device/path/file1',
941 '256 B/s (256 B in 1.000s)\r\n')]):
942 self.device.PushChangedFiles(host_file_path, device_file_path)
944 def testPushChangedFiles_directory_everythingChanged(self):
945 self.device.old_interface._push_if_needed_cache = {}
947 host_file_path = '/test/host/path'
948 device_file_path = '/test/device/path'
950 mock_fs = MockFileSystem()
951 mock_fs.addMockDirectory(
952 host_file_path, size=256,
953 stat=MockFileSystem.osStatResult(st_mtime=1000000000))
955 host_file_path + '/file1', size=256,
956 stat=MockFileSystem.osStatResult(st_mtime=1000000001))
958 host_file_path + '/file2', size=256,
959 stat=MockFileSystem.osStatResult(st_mtime=1000000002))
961 self.device.old_interface.GetFilesChanged = mock.Mock(
962 return_value=[('/test/host/path/file1', '/test/device/path/file1'),
963 ('/test/host/path/file2', '/test/device/path/file2')])
966 with self.assertCallsSequence([
967 ("adb -s 0123456789abcdef shell 'mkdir -p \"/test/device/path\"'",
969 ('adb -s 0123456789abcdef push /test/host/path /test/device/path',
970 '768 B/s (768 B in 1.000s)\r\n')]):
971 self.device.PushChangedFiles(host_file_path, device_file_path)
974 class DeviceUtilsFileExistsTest(DeviceUtilsOldImplTest):
976 def testFileExists_usingTest_fileExists(self):
977 with self.assertCalls(
978 "adb -s 0123456789abcdef shell "
979 "'test -e \"/data/app/test.file.exists\"; echo $?'",
981 self.assertTrue(self.device.FileExists('/data/app/test.file.exists'))
983 def testFileExists_usingTest_fileDoesntExist(self):
984 with self.assertCalls(
985 "adb -s 0123456789abcdef shell "
986 "'test -e \"/data/app/test.file.does.not.exist\"; echo $?'",
988 self.assertFalse(self.device.FileExists(
989 '/data/app/test.file.does.not.exist'))
991 def testFileExists_usingLs_fileExists(self):
992 with self.assertCallsSequence([
993 ("adb -s 0123456789abcdef shell "
994 "'test -e \"/data/app/test.file.exists\"; echo $?'",
995 'test: not found\r\n'),
996 ("adb -s 0123456789abcdef shell "
997 "'ls \"/data/app/test.file.exists\" >/dev/null 2>&1; echo $?'",
999 self.assertTrue(self.device.FileExists('/data/app/test.file.exists'))
1001 def testFileExists_usingLs_fileDoesntExist(self):
1002 with self.assertCallsSequence([
1003 ("adb -s 0123456789abcdef shell "
1004 "'test -e \"/data/app/test.file.does.not.exist\"; echo $?'",
1005 'test: not found\r\n'),
1006 ("adb -s 0123456789abcdef shell "
1007 "'ls \"/data/app/test.file.does.not.exist\" "
1008 ">/dev/null 2>&1; echo $?'",
1010 self.assertFalse(self.device.FileExists(
1011 '/data/app/test.file.does.not.exist'))
1014 class DeviceUtilsPullFileTest(DeviceUtilsOldImplTest):
1016 def testPullFile_existsOnDevice(self):
1017 with mock.patch('os.path.exists', return_value=True):
1018 with self.assertCallsSequence([
1019 ('adb -s 0123456789abcdef shell '
1020 'ls /data/app/test.file.exists',
1021 '/data/app/test.file.exists'),
1022 ('adb -s 0123456789abcdef pull '
1023 '/data/app/test.file.exists /test/file/host/path',
1024 '100 B/s (100 bytes in 1.000s)\r\n')]):
1025 self.device.PullFile('/data/app/test.file.exists',
1026 '/test/file/host/path')
1028 def testPullFile_doesntExistOnDevice(self):
1029 with mock.patch('os.path.exists', return_value=True):
1030 with self.assertCalls(
1031 'adb -s 0123456789abcdef shell '
1032 'ls /data/app/test.file.does.not.exist',
1033 '/data/app/test.file.does.not.exist: No such file or directory\r\n'):
1034 with self.assertRaises(device_errors.CommandFailedError):
1035 self.device.PullFile('/data/app/test.file.does.not.exist',
1036 '/test/file/host/path')
1039 class DeviceUtilsReadFileTest(DeviceUtilsOldImplTest):
1041 def testReadFile_exists(self):
1042 with self.assertCallsSequence([
1043 ("adb -s 0123456789abcdef shell "
1044 "'cat \"/read/this/test/file\" 2>/dev/null'",
1045 'this is a test file')]):
1046 self.assertEqual(['this is a test file'],
1047 self.device.ReadFile('/read/this/test/file'))
1049 def testReadFile_doesNotExist(self):
1050 with self.assertCalls(
1051 "adb -s 0123456789abcdef shell "
1052 "'cat \"/this/file/does.not.exist\" 2>/dev/null'",
1054 self.device.ReadFile('/this/file/does.not.exist')
1056 def testReadFile_asRoot_withRoot(self):
1057 self.device.old_interface._privileged_command_runner = (
1058 self.device.old_interface.RunShellCommand)
1059 self.device.old_interface._protected_file_access_method_initialized = True
1060 with self.assertCallsSequence([
1061 ("adb -s 0123456789abcdef shell "
1062 "'cat \"/this/file/must.be.read.by.root\" 2> /dev/null'",
1063 'this is a test file\nread by root')]):
1065 ['this is a test file', 'read by root'],
1066 self.device.ReadFile('/this/file/must.be.read.by.root',
1069 def testReadFile_asRoot_withSu(self):
1070 self.device.old_interface._privileged_command_runner = (
1071 self.device.old_interface.RunShellCommandWithSU)
1072 self.device.old_interface._protected_file_access_method_initialized = True
1073 with self.assertCallsSequence([
1074 ("adb -s 0123456789abcdef shell "
1075 "'su -c cat \"/this/file/can.be.read.with.su\" 2> /dev/null'",
1076 'this is a test file\nread with su')]):
1078 ['this is a test file', 'read with su'],
1079 self.device.ReadFile('/this/file/can.be.read.with.su',
1082 def testReadFile_asRoot_rejected(self):
1083 self.device.old_interface._privileged_command_runner = None
1084 self.device.old_interface._protected_file_access_method_initialized = True
1085 with self.assertRaises(device_errors.CommandFailedError):
1086 self.device.ReadFile('/this/file/cannot.be.read.by.user',
1090 class DeviceUtilsWriteFileTest(DeviceUtilsOldImplTest):
1092 def testWriteFile_basic(self):
1093 mock_file = mock.MagicMock(spec=file)
1094 mock_file.name = '/tmp/file/to.be.pushed'
1095 mock_file.__enter__.return_value = mock_file
1096 with mock.patch('tempfile.NamedTemporaryFile',
1097 return_value=mock_file):
1098 with self.assertCalls(
1099 'adb -s 0123456789abcdef push '
1100 '/tmp/file/to.be.pushed /test/file/written.to.device',
1101 '100 B/s (100 bytes in 1.000s)\r\n'):
1102 self.device.WriteFile('/test/file/written.to.device',
1103 'new test file contents')
1104 mock_file.write.assert_called_once_with('new test file contents')
1106 def testWriteFile_asRoot_withRoot(self):
1107 self.device.old_interface._external_storage = '/fake/storage/path'
1108 self.device.old_interface._privileged_command_runner = (
1109 self.device.old_interface.RunShellCommand)
1110 self.device.old_interface._protected_file_access_method_initialized = True
1112 mock_file = mock.MagicMock(spec=file)
1113 mock_file.name = '/tmp/file/to.be.pushed'
1114 mock_file.__enter__.return_value = mock_file
1115 with mock.patch('tempfile.NamedTemporaryFile',
1116 return_value=mock_file):
1117 with self.assertCallsSequence(
1119 # Create temporary contents file
1120 (r"adb -s 0123456789abcdef shell "
1121 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1124 # Create temporary script file
1125 (r"adb -s 0123456789abcdef shell "
1126 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1130 (r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1131 '/fake/storage/path/temp_file-\d+\d+',
1132 '100 B/s (100 bytes in 1.000s)\r\n'),
1134 (r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1135 '/fake/storage/path/temp_file-\d+\d+',
1136 '100 B/s (100 bytes in 1.000s)\r\n'),
1138 (r"adb -s 0123456789abcdef shell "
1139 "'sh /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1140 # Remove device temporaries
1141 (r"adb -s 0123456789abcdef shell "
1142 "'rm /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1143 (r"adb -s 0123456789abcdef shell "
1144 "'rm /fake/storage/path/temp_file-\d+-\d+'", '')],
1146 self.device.WriteFile('/test/file/written.to.device',
1147 'new test file contents', as_root=True)
1149 def testWriteFile_asRoot_withSu(self):
1150 self.device.old_interface._external_storage = '/fake/storage/path'
1151 self.device.old_interface._privileged_command_runner = (
1152 self.device.old_interface.RunShellCommandWithSU)
1153 self.device.old_interface._protected_file_access_method_initialized = True
1155 mock_file = mock.MagicMock(spec=file)
1156 mock_file.name = '/tmp/file/to.be.pushed'
1157 mock_file.__enter__.return_value = mock_file
1158 with mock.patch('tempfile.NamedTemporaryFile',
1159 return_value=mock_file):
1160 with self.assertCallsSequence(
1162 # Create temporary contents file
1163 (r"adb -s 0123456789abcdef shell "
1164 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1167 # Create temporary script file
1168 (r"adb -s 0123456789abcdef shell "
1169 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1173 (r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1174 '/fake/storage/path/temp_file-\d+\d+',
1175 '100 B/s (100 bytes in 1.000s)\r\n'),
1177 (r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1178 '/fake/storage/path/temp_file-\d+\d+',
1179 '100 B/s (100 bytes in 1.000s)\r\n'),
1181 (r"adb -s 0123456789abcdef shell "
1182 "'su -c sh /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1183 # Remove device temporaries
1184 (r"adb -s 0123456789abcdef shell "
1185 "'rm /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1186 (r"adb -s 0123456789abcdef shell "
1187 "'rm /fake/storage/path/temp_file-\d+-\d+'", '')],
1189 self.device.WriteFile('/test/file/written.to.device',
1190 'new test file contents', as_root=True)
1192 def testWriteFile_asRoot_rejected(self):
1193 self.device.old_interface._privileged_command_runner = None
1194 self.device.old_interface._protected_file_access_method_initialized = True
1195 with self.assertRaises(device_errors.CommandFailedError):
1196 self.device.WriteFile('/test/file/no.permissions.to.write',
1197 'new test file contents', as_root=True)
1199 class DeviceUtilsWriteTextFileTest(DeviceUtilsOldImplTest):
1201 def testWriteTextFileTest_basic(self):
1202 with self.assertCalls(
1203 "adb -s 0123456789abcdef shell 'echo some.string"
1204 " > /test/file/to.write; echo %$?'", '%0\r\n'):
1205 self.device.WriteTextFile('/test/file/to.write', 'some.string')
1207 def testWriteTextFileTest_stringWithSpaces(self):
1208 with self.assertCalls(
1209 "adb -s 0123456789abcdef shell 'echo '\\''some other string'\\''"
1210 " > /test/file/to.write; echo %$?'", '%0\r\n'):
1211 self.device.WriteTextFile('/test/file/to.write', 'some other string')
1213 def testWriteTextFileTest_asRoot_withSu(self):
1214 with self.assertCallsSequence([
1215 ("adb -s 0123456789abcdef shell 'ls /root'", 'Permission denied\r\n'),
1216 ("adb -s 0123456789abcdef shell 'su -c echo some.string"
1217 " > /test/file/to.write; echo %$?'", '%0\r\n')]):
1218 self.device.WriteTextFile('/test/file/to.write', 'some.string',
1221 def testWriteTextFileTest_asRoot_withRoot(self):
1222 with self.assertCallsSequence([
1223 ("adb -s 0123456789abcdef shell 'ls /root'", 'hello\r\nworld\r\n'),
1224 ("adb -s 0123456789abcdef shell 'echo some.string"
1225 " > /test/file/to.write; echo %$?'", '%0\r\n')]):
1226 self.device.WriteTextFile('/test/file/to.write', 'some.string',
1229 def testWriteTextFileTest_asRoot_rejected(self):
1230 with self.assertCallsSequence([
1231 ("adb -s 0123456789abcdef shell 'ls /root'", 'Permission denied\r\n'),
1232 ("adb -s 0123456789abcdef shell 'su -c echo some.string"
1233 " > /test/file/to.write; echo %$?'", '%1\r\n')]):
1234 with self.assertRaises(device_errors.CommandFailedError):
1235 self.device.WriteTextFile('/test/file/to.write', 'some.string',
1238 class DeviceUtilsLsTest(DeviceUtilsOldImplTest):
1240 def testLs_nothing(self):
1241 with self.assertCallsSequence([
1242 ("adb -s 0123456789abcdef shell 'ls -lR /this/file/does.not.exist'",
1243 '/this/file/does.not.exist: No such file or directory\r\n'),
1244 ("adb -s 0123456789abcdef shell 'date +%z'", '+0000')]):
1245 self.assertEqual({}, self.device.Ls('/this/file/does.not.exist'))
1247 def testLs_file(self):
1248 with self.assertCallsSequence([
1249 ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.file'",
1250 '-rw-rw---- testuser testgroup 4096 1970-01-01 00:00 test.file\r\n'),
1251 ("adb -s 0123456789abcdef shell 'date +%z'", '+0000')]):
1253 {'test.file': (4096, datetime.datetime(1970, 1, 1))},
1254 self.device.Ls('/this/is/a/test.file'))
1256 def testLs_directory(self):
1257 with self.assertCallsSequence([
1258 ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.directory'",
1260 '/this/is/a/test.directory:\r\n'
1261 '-rw-rw---- testuser testgroup 4096 1970-01-01 18:19 test.file\r\n'),
1262 ("adb -s 0123456789abcdef shell 'date +%z'", '+0000')]):
1264 {'test.file': (4096, datetime.datetime(1970, 1, 1, 18, 19))},
1265 self.device.Ls('/this/is/a/test.directory'))
1267 def testLs_directories(self):
1268 with self.assertCallsSequence([
1269 ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.directory'",
1271 '/this/is/a/test.directory:\r\n'
1272 'drwxr-xr-x testuser testgroup 1970-01-01 00:00 test.subdirectory\r\n'
1274 '/this/is/a/test.directory/test.subdirectory:\r\n'
1275 '-rw-rw---- testuser testgroup 4096 1970-01-01 00:00 test.file\r\n'),
1276 ("adb -s 0123456789abcdef shell 'date +%z'", '-0700')]):
1278 {'test.subdirectory/test.file':
1279 (4096, datetime.datetime(1970, 1, 1, 7, 0, 0))},
1280 self.device.Ls('/this/is/a/test.directory'))
1283 class DeviceUtilsSetJavaAssertsTest(DeviceUtilsOldImplTest):
1286 def mockNamedTemporary(name='/tmp/file/property.file',
1288 mock_file = mock.MagicMock(spec=file)
1289 mock_file.name = name
1290 mock_file.__enter__.return_value = mock_file
1291 mock_file.read.return_value = read_contents
1294 def testSetJavaAsserts_enable(self):
1295 mock_file = self.mockNamedTemporary()
1296 with mock.patch('tempfile.NamedTemporaryFile',
1297 return_value=mock_file), (
1298 mock.patch('__builtin__.open', return_value=mock_file)):
1299 with self.assertCallsSequence(
1300 [('adb -s 0123456789abcdef shell ls %s' %
1301 constants.DEVICE_LOCAL_PROPERTIES_PATH,
1302 '%s\r\n' % constants.DEVICE_LOCAL_PROPERTIES_PATH),
1303 ('adb -s 0123456789abcdef pull %s %s' %
1304 (constants.DEVICE_LOCAL_PROPERTIES_PATH, mock_file.name),
1305 '100 B/s (100 bytes in 1.000s)\r\n'),
1306 ('adb -s 0123456789abcdef push %s %s' %
1307 (mock_file.name, constants.DEVICE_LOCAL_PROPERTIES_PATH),
1308 '100 B/s (100 bytes in 1.000s)\r\n'),
1309 ('adb -s 0123456789abcdef shell '
1310 'getprop dalvik.vm.enableassertions',
1312 ('adb -s 0123456789abcdef shell '
1313 'setprop dalvik.vm.enableassertions "all"',
1315 self.assertTrue(self.device.SetJavaAsserts(True))
1317 def testSetJavaAsserts_disable(self):
1318 mock_file = self.mockNamedTemporary(
1319 read_contents='dalvik.vm.enableassertions=all\n')
1320 with mock.patch('tempfile.NamedTemporaryFile',
1321 return_value=mock_file), (
1322 mock.patch('__builtin__.open', return_value=mock_file)):
1323 with self.assertCallsSequence(
1324 [('adb -s 0123456789abcdef shell ls %s' %
1325 constants.DEVICE_LOCAL_PROPERTIES_PATH,
1326 '%s\r\n' % constants.DEVICE_LOCAL_PROPERTIES_PATH),
1327 ('adb -s 0123456789abcdef pull %s %s' %
1328 (constants.DEVICE_LOCAL_PROPERTIES_PATH, mock_file.name),
1329 '100 B/s (100 bytes in 1.000s)\r\n'),
1330 ('adb -s 0123456789abcdef push %s %s' %
1331 (mock_file.name, constants.DEVICE_LOCAL_PROPERTIES_PATH),
1332 '100 B/s (100 bytes in 1.000s)\r\n'),
1333 ('adb -s 0123456789abcdef shell '
1334 'getprop dalvik.vm.enableassertions',
1336 ('adb -s 0123456789abcdef shell '
1337 'setprop dalvik.vm.enableassertions ""',
1339 self.assertTrue(self.device.SetJavaAsserts(False))
1341 def testSetJavaAsserts_alreadyEnabled(self):
1342 mock_file = self.mockNamedTemporary(
1343 read_contents='dalvik.vm.enableassertions=all\n')
1344 with mock.patch('tempfile.NamedTemporaryFile',
1345 return_value=mock_file), (
1346 mock.patch('__builtin__.open', return_value=mock_file)):
1347 with self.assertCallsSequence(
1348 [('adb -s 0123456789abcdef shell ls %s' %
1349 constants.DEVICE_LOCAL_PROPERTIES_PATH,
1350 '%s\r\n' % constants.DEVICE_LOCAL_PROPERTIES_PATH),
1351 ('adb -s 0123456789abcdef pull %s %s' %
1352 (constants.DEVICE_LOCAL_PROPERTIES_PATH, mock_file.name),
1353 '100 B/s (100 bytes in 1.000s)\r\n'),
1354 ('adb -s 0123456789abcdef shell '
1355 'getprop dalvik.vm.enableassertions',
1357 self.assertFalse(self.device.SetJavaAsserts(True))
1360 class DeviceUtilsGetPropTest(DeviceUtilsOldImplTest):
1362 def testGetProp_exists(self):
1363 with self.assertCalls(
1364 'adb -s 0123456789abcdef shell getprop this.is.a.test.property',
1365 'test_property_value\r\n'):
1366 self.assertEqual('test_property_value',
1367 self.device.GetProp('this.is.a.test.property'))
1369 def testGetProp_doesNotExist(self):
1370 with self.assertCalls(
1371 'adb -s 0123456789abcdef shell '
1372 'getprop this.property.does.not.exist', ''):
1373 self.assertEqual('', self.device.GetProp('this.property.does.not.exist'))
1375 def testGetProp_cachedRoProp(self):
1376 with self.assertCalls(
1377 'adb -s 0123456789abcdef shell '
1378 'getprop ro.build.type', 'userdebug'):
1379 self.assertEqual('userdebug', self.device.GetProp('ro.build.type'))
1380 self.assertEqual('userdebug', self.device.GetProp('ro.build.type'))
1383 class DeviceUtilsSetPropTest(DeviceUtilsOldImplTest):
1385 def testSetProp(self):
1386 with self.assertCalls(
1387 'adb -s 0123456789abcdef shell '
1388 'setprop this.is.a.test.property "test_property_value"',
1390 self.device.SetProp('this.is.a.test.property', 'test_property_value')
1393 class DeviceUtilsGetPidsTest(DeviceUtilsOldImplTest):
1395 def testGetPids_noMatches(self):
1396 with self.assertCalls(
1397 "adb -s 0123456789abcdef shell 'ps'",
1398 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
1399 'user 1000 100 1024 1024 ffffffff 00000000 no.match\r\n'):
1400 self.assertEqual({}, self.device.GetPids('does.not.match'))
1402 def testGetPids_oneMatch(self):
1403 with self.assertCalls(
1404 "adb -s 0123456789abcdef shell 'ps'",
1405 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
1406 'user 1000 100 1024 1024 ffffffff 00000000 not.a.match\r\n'
1407 'user 1001 100 1024 1024 ffffffff 00000000 one.match\r\n'):
1408 self.assertEqual({'one.match': '1001'}, self.device.GetPids('one.match'))
1410 def testGetPids_mutlipleMatches(self):
1411 with self.assertCalls(
1412 "adb -s 0123456789abcdef shell 'ps'",
1413 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
1414 'user 1000 100 1024 1024 ffffffff 00000000 not\r\n'
1415 'user 1001 100 1024 1024 ffffffff 00000000 one.match\r\n'
1416 'user 1002 100 1024 1024 ffffffff 00000000 two.match\r\n'
1417 'user 1003 100 1024 1024 ffffffff 00000000 three.match\r\n'):
1419 {'one.match': '1001', 'two.match': '1002', 'three.match': '1003'},
1420 self.device.GetPids('match'))
1422 def testGetPids_exactMatch(self):
1423 with self.assertCalls(
1424 "adb -s 0123456789abcdef shell 'ps'",
1425 'USER PID PPID VSIZE RSS WCHAN PC NAME\r\n'
1426 'user 1000 100 1024 1024 ffffffff 00000000 not.exact.match\r\n'
1427 'user 1234 100 1024 1024 ffffffff 00000000 exact.match\r\n'):
1429 {'not.exact.match': '1000', 'exact.match': '1234'},
1430 self.device.GetPids('exact.match'))
1433 class DeviceUtilsTakeScreenshotTest(DeviceUtilsOldImplTest):
1435 def testTakeScreenshot_fileNameProvided(self):
1436 mock_fs = MockFileSystem()
1437 mock_fs.addMockDirectory('/test/host')
1438 mock_fs.addMockFile('/test/host/screenshot.png')
1441 with self.assertCallsSequence(
1443 (r"adb -s 0123456789abcdef shell 'echo \$EXTERNAL_STORAGE'",
1444 '/test/external/storage\r\n'),
1445 (r"adb -s 0123456789abcdef shell '/system/bin/screencap -p \S+'",
1447 (r"adb -s 0123456789abcdef shell ls \S+",
1448 '/test/external/storage/screenshot.png\r\n'),
1449 (r'adb -s 0123456789abcdef pull \S+ /test/host/screenshot.png',
1450 '100 B/s (100 B in 1.000s)\r\n'),
1451 (r"adb -s 0123456789abcdef shell 'rm -f \S+'", '')
1454 self.device.TakeScreenshot('/test/host/screenshot.png')
1457 class DeviceUtilsGetIOStatsTest(DeviceUtilsOldImplTest):
1459 def testGetIOStats(self):
1460 with self.assertCalls(
1461 "adb -s 0123456789abcdef shell 'cat \"/proc/diskstats\" 2>/dev/null'",
1462 '179 0 mmcblk0 1 2 3 4 5 6 7 8 9 10 11\r\n'):
1470 self.device.GetIOStats())
1473 class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsOldImplTest):
1476 super(DeviceUtilsGetMemoryUsageForPidTest, self).setUp()
1477 self.device.old_interface._privileged_command_runner = (
1478 self.device.old_interface.RunShellCommand)
1479 self.device.old_interface._protected_file_access_method_initialized = True
1481 def testGetMemoryUsageForPid_validPid(self):
1482 with self.assertCallsSequence([
1483 ("adb -s 0123456789abcdef shell 'showmap 1234'",
1484 '100 101 102 103 104 105 106 107 TOTAL\r\n'),
1485 ("adb -s 0123456789abcdef shell "
1486 "'cat \"/proc/1234/status\" 2> /dev/null'",
1494 'Shared_Clean': 103,
1495 'Shared_Dirty': 104,
1496 'Private_Clean': 105,
1497 'Private_Dirty': 106,
1500 self.device.GetMemoryUsageForPid(1234))
1502 def testGetMemoryUsageForPid_invalidPid(self):
1503 with self.assertCalls(
1504 "adb -s 0123456789abcdef shell 'showmap 4321'",
1505 'cannot open /proc/4321/smaps: No such file or directory\r\n'):
1506 self.assertEqual({}, self.device.GetMemoryUsageForPid(4321))
1509 class DeviceUtilsStrTest(DeviceUtilsOldImplTest):
1510 def testStr_noAdbCalls(self):
1511 with self.assertNoAdbCalls():
1512 self.assertEqual('0123456789abcdef', str(self.device))
1514 def testStr_noSerial(self):
1515 self.device = device_utils.DeviceUtils(None)
1516 with self.assertCalls('adb get-serialno', '0123456789abcdef'):
1517 self.assertEqual('0123456789abcdef', str(self.device))
1519 def testStr_noSerial_noDevices(self):
1520 self.device = device_utils.DeviceUtils(None)
1521 with self.assertCalls('adb get-serialno', 'unknown'), (
1522 self.assertRaises(device_errors.NoDevicesError)):
1526 if __name__ == '__main__':
1527 logging.getLogger().setLevel(logging.DEBUG)
1528 unittest.main(verbosity=2)