[Android] Reland of 'Add zip pushing and refine push mode selection.'
[chromium-blink-merge.git] / build / android / pylib / device / device_utils_test.py
blob52aef0ac3f7eba3d2cca87788efd579ad28913e8
1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """
7 Unit tests for the contents of device_utils.py (mostly DeviceUtils).
8 """
10 # pylint: disable=C0321
11 # pylint: disable=W0212
12 # pylint: disable=W0613
14 import collections
15 import datetime
16 import logging
17 import os
18 import re
19 import signal
20 import sys
21 import unittest
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
72 self.mocked = mocked
75 class MockFileSystem(object):
77 @staticmethod
78 def osStatResult(
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)
87 MOCKED_FUNCTIONS = [
88 ('os.listdir', []),
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__()),
95 ('os.walk', []),
98 def _get(self, mocked, path, default_val):
99 if self._verbose:
100 logging.debug('%s(%s)' % (mocked, path))
101 return (self.mock_file_info[path][mocked]
102 if path in self.mock_file_info
103 else default_val)
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,
122 walk=None):
123 if listdir is None:
124 listdir = []
125 if stat is None:
126 stat = self.osStatResult()
127 if walk is None:
128 walk = []
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,
141 'os.stat': stat,
142 'os.walk': walk,
145 def __enter__(self):
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:
151 p.patched.__exit__()
154 class DeviceUtilsOldImplTest(unittest.TestCase):
156 class AndroidCommandsCalls(object):
158 def __init__(self, test_case, cmd_ret, comp):
159 self._cmds = cmd_ret
160 self._comp = comp
161 self._run_command = _PatchedFunction()
162 self._test_case = test_case
163 self._total_received = 0
165 def __enter__(self):
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))
184 return ret
185 return ''
187 def __exit__(self, exc_type, exc_val, exc_tb):
188 self._run_command.patched.__exit__(exc_type, exc_val, exc_tb)
189 if exc_type is None:
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),
196 msg=on_failure)
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]),
201 msg=on_failure)
202 self._test_case.assertTrue('timeout_time' in actual_kwargs,
203 msg=on_failure)
204 self._test_case.assertTrue('retry_count' in actual_kwargs,
205 msg=on_failure)
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)
216 def setUp(self):
217 self.device = device_utils.DeviceUtils(
218 '0123456789abcdef', default_timeout=1, default_retries=0)
221 class DeviceUtilsNewImplTest(unittest.TestCase):
223 def setUp(self):
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):
234 def setUp(self):
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'",
255 'foo\r\n'):
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',
269 'userdebug\r\n'),
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',
284 'userdebug\r\n'),
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'",
323 'nothing\r\n')
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'",
340 'nothing\r\n'),
341 # wait for wifi
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',
351 '0\r\n')]):
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',
361 '1\r\n')]
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',
376 '1\r\n'),
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',
391 '1\r\n'),
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'",
416 'nothing\r\n')]):
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'",
430 'nothing\r\n'),
431 ('adb -s 0123456789abcdef wait-for-device', ''),
432 ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
433 '1\r\n'),
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'",
438 'nothing\r\n')]):
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'",
450 ''),
451 ("adb -s 0123456789abcdef install /fake/test/app.apk",
452 'Success\r\n')]):
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"
460 # warning below.
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',
476 'Success\r\n'),
477 ('adb -s 0123456789abcdef install /fake/test/app.apk',
478 'Success\r\n')]):
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"
486 # warning below.
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',
501 'Success\r\n')]):
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):
506 return []
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'",
525 ''),
526 ("adb -s 0123456789abcdef install /fake/test/app.apk",
527 'Failure\r\n')]):
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'",
550 '')]):
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 %$?'",
562 '/data\r\n%0\r\n'):
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 %$?'",
568 '\r\n%1\r\n'):
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'", '')]):
589 self.assertEquals(1,
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')]):
606 self.assertEquals(1,
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'", '')]):
617 self.assertEquals(1,
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'", '')]):
627 self.assertEquals(1,
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',
644 activity='.Main')
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',
655 activity='.Main')
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',
667 activity='.Main')
668 with self.assertCalls(
669 "adb -s 0123456789abcdef shell 'am start "
670 "-a android.intent.action.VIEW "
671 "-W "
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',
679 activity='.Main',
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',
694 activity='.Main',
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',
708 activity='.Main',
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',
721 activity='.Main',
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 "
727 "--es foo test'",
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',
734 activity='.Main',
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 "
740 "--ez foo True'",
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',
747 activity='.Main',
748 extras={'foo': 123})
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 "
753 "--ei foo 123'",
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',
760 activity='.Main')
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',
773 activity='.Main')
774 with self.assertCalls(
775 "adb -s 0123456789abcdef shell 'am start "
776 "-a android.intent.action.VIEW "
777 "-S "
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',
785 activity='.Main',
786 flags='0x10000000')
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 "
791 "-f 0x10000000'",
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 "
812 "-e foo \"bar\"'",
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 "
822 "-e foo'",
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 "
832 "-W "
833 "-a android.intent.action.MAIN "
834 "-c android.intent.category.HOME'",
835 'Starting: Intent { act=android.intent.action.MAIN }\r\n'):
836 self.device.GoHome()
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'",
844 ''):
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'",
853 ''):
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'",
861 'Success\r\n')]):
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'",
870 ''):
871 self.device.SendKeyEvent(66)
874 class DeviceUtilsPushChangedFilesIndividuallyTest(DeviceUtilsNewImplTest):
876 def testPushChangedFilesIndividually_empty(self):
877 test_files = []
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):
888 test_files = [
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):
901 def setUp(self):
902 super(DeviceUtilsPushChangedFilesZippedTest, self).setUp()
903 self.original_install_commands = self.device._InstallCommands
904 self.device._InstallCommands = mock.Mock()
906 def testPushChangedFilesZipped_empty(self):
907 test_files = []
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 $?'",
971 '0\r\n'):
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 $?'",
978 '1\r\n'):
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 $?'",
989 '0\r\n')]):
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 $?'",
1000 '1\r\n')]):
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'",
1044 ''):
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')]):
1055 self.assertEqual(
1056 ['this is a test file', 'read by root'],
1057 self.device.ReadFile('/this/file/must.be.read.by.root',
1058 as_root=True))
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')]):
1068 self.assertEqual(
1069 ['this is a test file', 'read with su'],
1070 self.device.ReadFile('/this/file/can.be.read.with.su',
1071 as_root=True))
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',
1078 as_root=True)
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(
1109 cmd_ret=[
1110 # Create temporary contents file
1111 (r"adb -s 0123456789abcdef shell "
1112 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1113 "echo \$\?'",
1114 '1\r\n'),
1115 # Create temporary script file
1116 (r"adb -s 0123456789abcdef shell "
1117 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1118 "echo \$\?'",
1119 '1\r\n'),
1120 # Set contents file
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'),
1124 # Set script file
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'),
1128 # Call script
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+'", '')],
1136 comp=re.match):
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(
1152 cmd_ret=[
1153 # Create temporary contents file
1154 (r"adb -s 0123456789abcdef shell "
1155 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1156 "echo \$\?'",
1157 '1\r\n'),
1158 # Create temporary script file
1159 (r"adb -s 0123456789abcdef shell "
1160 "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1161 "echo \$\?'",
1162 '1\r\n'),
1163 # Set contents file
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'),
1167 # Set script file
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'),
1171 # Call script
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+'", '')],
1179 comp=re.match):
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',
1210 as_root=True)
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',
1218 as_root=True)
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',
1227 as_root=True)
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')]):
1243 self.assertEqual(
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'",
1250 '\r\n'
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')]):
1254 self.assertEqual(
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'",
1261 '\r\n'
1262 '/this/is/a/test.directory:\r\n'
1263 'drwxr-xr-x testuser testgroup 1970-01-01 00:00 test.subdirectory\r\n'
1264 '\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')]):
1268 self.assertEqual(
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):
1276 @staticmethod
1277 def mockNamedTemporary(name='/tmp/file/property.file',
1278 read_contents=''):
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
1283 return mock_file
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',
1302 '\r\n'),
1303 ('adb -s 0123456789abcdef shell '
1304 'setprop dalvik.vm.enableassertions "all"',
1305 '')]):
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',
1326 'all\r\n'),
1327 ('adb -s 0123456789abcdef shell '
1328 'setprop dalvik.vm.enableassertions ""',
1329 '')]):
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',
1347 'all\r\n')]):
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"',
1380 ''):
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'):
1409 self.assertEqual(
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'):
1419 self.assertEqual(
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')
1431 with mock_fs:
1432 with self.assertCallsSequence(
1433 cmd_ret=[
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+'",
1437 ''),
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+'", '')
1444 comp=re.match):
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'):
1454 self.assertEqual(
1456 'num_reads': 1,
1457 'num_writes': 5,
1458 'read_ms': 4,
1459 'write_ms': 8,
1461 self.device.GetIOStats())
1464 class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsOldImplTest):
1466 def setUp(self):
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'",
1478 'VmHWM: 1024 kB')
1480 self.assertEqual(
1482 'Size': 100,
1483 'Rss': 101,
1484 'Pss': 102,
1485 'Shared_Clean': 103,
1486 'Shared_Dirty': 104,
1487 'Private_Clean': 105,
1488 'Private_Dirty': 106,
1489 'VmHWM': 1024
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)):
1514 str(self.device)
1517 if __name__ == '__main__':
1518 logging.getLogger().setLevel(logging.DEBUG)
1519 unittest.main(verbosity=2)