Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / build / android / pylib / device / device_utils_test.py
1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """
7 Unit tests for the contents of device_utils.py (mostly DeviceUtils).
8 """
9
10 # pylint: disable=C0321
11 # pylint: disable=W0212
12 # pylint: disable=W0613
13
14 import collections
15 import datetime
16 import logging
17 import os
18 import re
19 import signal
20 import sys
21 import unittest
22
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
29
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'))
34
35 sys.path.append(os.path.join(
36     constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
37 import mock # pylint: disable=F0401
38
39
40 class DeviceUtilsTest(unittest.TestCase):
41
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())
46
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())
51
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())
57
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())
63
64   def testInitWithNone(self):
65     d = device_utils.DeviceUtils(None)
66     self.assertIsNone(d.old_interface.GetDevice())
67
68
69 class _PatchedFunction(object):
70   def __init__(self, patched=None, mocked=None):
71     self.patched = patched
72     self.mocked = mocked
73
74
75 class MockFileSystem(object):
76
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)
86
87   MOCKED_FUNCTIONS = [
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__()),
94     ('os.walk', []),
95   ]
96
97   def _get(self, mocked, path, default_val):
98     if self._verbose:
99       logging.debug('%s(%s)' % (mocked, path))
100     return (self.mock_file_info[path][mocked]
101             if path in self.mock_file_info
102             else default_val)
103
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))
107
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
113
114   def addMockFile(self, path, **kw):
115     self._addMockThing(path, False, **kw)
116
117   def addMockDirectory(self, path, **kw):
118     self._addMockThing(path, True, **kw)
119
120   def _addMockThing(self, path, is_dir, size=0, stat=None, walk=None):
121     if stat is None:
122       stat = self.osStatResult()
123     if walk is None:
124       walk = []
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,
131       'os.stat': stat,
132       'os.walk': walk,
133     }
134
135   def __enter__(self):
136     for p in self._patched_functions:
137       p.mocked = p.patched.__enter__()
138
139   def __exit__(self, exc_type, exc_val, exc_tb):
140     for p in self._patched_functions:
141       p.patched.__exit__()
142
143
144 class DeviceUtilsOldImplTest(unittest.TestCase):
145
146   class AndroidCommandsCalls(object):
147
148     def __init__(self, test_case, cmd_ret, comp):
149       self._cmds = cmd_ret
150       self._comp = comp
151       self._run_command = _PatchedFunction()
152       self._test_case = test_case
153       self._total_received = 0
154
155     def __enter__(self):
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__()
160
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))
174         return ret
175       return ''
176
177     def __exit__(self, exc_type, exc_val, exc_tb):
178       self._run_command.patched.__exit__(exc_type, exc_val, exc_tb)
179       if exc_type is None:
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),
186           msg=on_failure)
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]),
191                                      msg=on_failure)
192           self._test_case.assertTrue('timeout_time' in actual_kwargs,
193                                      msg=on_failure)
194           self._test_case.assertTrue('retry_count' in actual_kwargs,
195                                      msg=on_failure)
196
197   def assertNoAdbCalls(self):
198     return type(self).AndroidCommandsCalls(self, [], str.__eq__)
199
200   def assertCalls(self, cmd, ret, comp=str.__eq__):
201     return type(self).AndroidCommandsCalls(self, [(cmd, ret)], comp)
202
203   def assertCallsSequence(self, cmd_ret, comp=str.__eq__):
204     return type(self).AndroidCommandsCalls(self, cmd_ret, comp)
205
206   def setUp(self):
207     self.device = device_utils.DeviceUtils(
208         '0123456789abcdef', default_timeout=1, default_retries=0)
209
210
211 class DeviceUtilsIsOnlineTest(DeviceUtilsOldImplTest):
212
213   def testIsOnline_true(self):
214     with self.assertCalls('adb -s 0123456789abcdef devices',
215                                  '00123456789abcdef  device\r\n'):
216       self.assertTrue(self.device.IsOnline())
217
218   def testIsOnline_false(self):
219     with self.assertCalls('adb -s 0123456789abcdef devices', '\r\n'):
220       self.assertFalse(self.device.IsOnline())
221
222
223 class DeviceUtilsHasRootTest(DeviceUtilsOldImplTest):
224
225   def testHasRoot_true(self):
226     with self.assertCalls("adb -s 0123456789abcdef shell 'ls /root'",
227                                  'foo\r\n'):
228       self.assertTrue(self.device.HasRoot())
229
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())
234
235
236 class DeviceUtilsEnableRootTest(DeviceUtilsOldImplTest):
237
238   def testEnableRoot_succeeds(self):
239     with self.assertCallsSequence([
240         ('adb -s 0123456789abcdef shell getprop ro.build.type',
241          'userdebug\r\n'),
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()
246
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()
252
253   def testEnableRoot_rootFails(self):
254     with self.assertCallsSequence([
255         ('adb -s 0123456789abcdef shell getprop ro.build.type',
256          'userdebug\r\n'),
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()
261
262
263 class DeviceUtilsGetExternalStoragePathTest(DeviceUtilsOldImplTest):
264
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())
272
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()
278
279
280 class DeviceUtilsWaitUntilFullyBootedTest(DeviceUtilsOldImplTest):
281
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'",
295          'nothing\r\n')
296         ]):
297       self.device.WaitUntilFullyBooted(wifi=False)
298
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'",
312          'nothing\r\n'),
313         # wait for wifi
314         ("adb -s 0123456789abcdef shell 'dumpsys wifi'", 'Wi-Fi is enabled')]):
315       self.device.WaitUntilFullyBooted(wifi=True)
316
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',
323            '0\r\n')]):
324         with self.assertRaises(device_errors.CommandTimeoutError):
325           self.device.WaitUntilFullyBooted(wifi=False)
326
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',
333            '1\r\n')]
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)
341
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',
348            '1\r\n'),
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)
356
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',
363            '1\r\n'),
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)
373
374
375 class DeviceUtilsRebootTest(DeviceUtilsOldImplTest):
376
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'",
388              'nothing\r\n')]):
389         self.device.Reboot(block=False)
390
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'",
402              'nothing\r\n'),
403             ('adb -s 0123456789abcdef wait-for-device', ''),
404             ('adb -s 0123456789abcdef shell getprop sys.boot_completed',
405              '1\r\n'),
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'",
410              'nothing\r\n')]):
411         self.device.Reboot(block=True)
412
413
414 class DeviceUtilsInstallTest(DeviceUtilsOldImplTest):
415
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'",
422            ''),
423           ("adb -s 0123456789abcdef install /fake/test/app.apk",
424            'Success\r\n')]):
425         self.device.Install('/fake/test/app.apk', retries=0)
426
427   def testInstall_differentPriorInstall(self):
428     def mockGetFilesChanged(host_path, device_path, ignore_filenames):
429       return [(host_path, device_path)]
430
431     # Pylint raises a false positive "operator not preceded by a space"
432     # warning below.
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',
448            'Success\r\n'),
449           ('adb -s 0123456789abcdef install /fake/test/app.apk',
450            'Success\r\n')]):
451         self.device.Install('/fake/test/app.apk', retries=0)
452
453   def testInstall_differentPriorInstall_reinstall(self):
454     def mockGetFilesChanged(host_path, device_path, ignore_filenames):
455       return [(host_path, device_path)]
456
457     # Pylint raises a false positive "operator not preceded by a space"
458     # warning below.
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',
473            'Success\r\n')]):
474         self.device.Install('/fake/test/app.apk', reinstall=True, retries=0)
475
476   def testInstall_identicalPriorInstall(self):
477     def mockGetFilesChanged(host_path, device_path, ignore_filenames):
478       return []
479
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.
488           ]):
489         self.device.Install('/fake/test/app.apk', retries=0)
490
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'",
497            ''),
498           ("adb -s 0123456789abcdef install /fake/test/app.apk",
499            'Failure\r\n')]):
500         with self.assertRaises(device_errors.CommandFailedError):
501           self.device.Install('/fake/test/app.apk', retries=0)
502
503
504 class DeviceUtilsRunShellCommandTest(DeviceUtilsOldImplTest):
505
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'])
511
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')
517
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'",
522          '')]):
523       self.device.RunShellCommand('setprop service.adb.root 0', as_root=True)
524
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)
530
531   def testRunShellCommand_checkReturn_success(self):
532     with self.assertCalls(
533         "adb -s 0123456789abcdef shell 'echo $ANDROID_DATA; echo %$?'",
534         '/data\r\n%0\r\n'):
535       self.device.RunShellCommand('echo $ANDROID_DATA', check_return=True)
536
537   def testRunShellCommand_checkReturn_failure(self):
538     with self.assertCalls(
539         "adb -s 0123456789abcdef shell 'echo $ANDROID_DATA; echo %$?'",
540         '\r\n%1\r\n'):
541       with self.assertRaises(device_errors.CommandFailedError):
542         self.device.RunShellCommand('echo $ANDROID_DATA', check_return=True)
543
544
545 class DeviceUtilsKillAllTest(DeviceUtilsOldImplTest):
546
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')
553
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'", '')]):
561       self.assertEquals(1,
562           self.device.KillAll('this.is.a.test.process', blocking=False))
563
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')]):
578         self.assertEquals(1,
579             self.device.KillAll('this.is.a.test.process', blocking=True))
580
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'", '')]):
589       self.assertEquals(1,
590           self.device.KillAll('this.is.a.test.process', as_root=True))
591
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'", '')]):
599       self.assertEquals(1,
600           self.device.KillAll('this.is.a.test.process', signum=signal.SIGTERM))
601
602
603 class DeviceUtilsStartActivityTest(DeviceUtilsOldImplTest):
604
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)
612
613   def testStartActivity_success(self):
614     test_intent = intent.Intent(action='android.intent.action.VIEW',
615                                 package='this.is.a.test.package',
616                                 activity='.Main')
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)
623
624   def testStartActivity_failure(self):
625     test_intent = intent.Intent(action='android.intent.action.VIEW',
626                                 package='this.is.a.test.package',
627                                 activity='.Main')
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)
635
636   def testStartActivity_blocking(self):
637     test_intent = intent.Intent(action='android.intent.action.VIEW',
638                                 package='this.is.a.test.package',
639                                 activity='.Main')
640     with self.assertCalls(
641         "adb -s 0123456789abcdef shell 'am start "
642             "-a android.intent.action.VIEW "
643             "-W "
644             "-n this.is.a.test.package/.Main'",
645         'Starting: Intent { act=android.intent.action.VIEW }'):
646       self.device.StartActivity(test_intent, blocking=True)
647
648   def testStartActivity_withCategory(self):
649     test_intent = intent.Intent(action='android.intent.action.VIEW',
650                                 package='this.is.a.test.package',
651                                 activity='.Main',
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)
660
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',
666                                 activity='.Main',
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)
676
677   def testStartActivity_withData(self):
678     test_intent = intent.Intent(action='android.intent.action.VIEW',
679                                 package='this.is.a.test.package',
680                                 activity='.Main',
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)
689
690   def testStartActivity_withStringExtra(self):
691     test_intent = intent.Intent(action='android.intent.action.VIEW',
692                                 package='this.is.a.test.package',
693                                 activity='.Main',
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 "
699             "--es foo test'",
700         'Starting: Intent { act=android.intent.action.VIEW }'):
701       self.device.StartActivity(test_intent)
702
703   def testStartActivity_withBoolExtra(self):
704     test_intent = intent.Intent(action='android.intent.action.VIEW',
705                                 package='this.is.a.test.package',
706                                 activity='.Main',
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 "
712             "--ez foo True'",
713         'Starting: Intent { act=android.intent.action.VIEW }'):
714       self.device.StartActivity(test_intent)
715
716   def testStartActivity_withIntExtra(self):
717     test_intent = intent.Intent(action='android.intent.action.VIEW',
718                                 package='this.is.a.test.package',
719                                 activity='.Main',
720                                 extras={'foo': 123})
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 "
725             "--ei foo 123'",
726         'Starting: Intent { act=android.intent.action.VIEW }'):
727       self.device.StartActivity(test_intent)
728
729   def testStartActivity_withTraceFile(self):
730     test_intent = intent.Intent(action='android.intent.action.VIEW',
731                                 package='this.is.a.test.package',
732                                 activity='.Main')
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')
741
742   def testStartActivity_withForceStop(self):
743     test_intent = intent.Intent(action='android.intent.action.VIEW',
744                                 package='this.is.a.test.package',
745                                 activity='.Main')
746     with self.assertCalls(
747         "adb -s 0123456789abcdef shell 'am start "
748             "-a android.intent.action.VIEW "
749             "-S "
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)
753
754   def testStartActivity_withFlags(self):
755     test_intent = intent.Intent(action='android.intent.action.VIEW',
756                                 package='this.is.a.test.package',
757                                 activity='.Main',
758                                 flags='0x10000000')
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 "
763             "-f 0x10000000'",
764         'Starting: Intent { act=android.intent.action.VIEW }'):
765       self.device.StartActivity(test_intent)
766
767
768 class DeviceUtilsBroadcastIntentTest(DeviceUtilsOldImplTest):
769
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)
777
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 "
784             "-e foo \"bar\"'",
785         'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
786       self.device.BroadcastIntent(test_intent)
787
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 "
794             "-e foo'",
795         'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
796       self.device.BroadcastIntent(test_intent)
797
798
799 class DeviceUtilsGoHomeTest(DeviceUtilsOldImplTest):
800
801   def testGoHome(self):
802     with self.assertCalls(
803         "adb -s 0123456789abcdef shell 'am start "
804             "-W "
805             "-a android.intent.action.MAIN "
806             "-c android.intent.category.HOME'",
807         'Starting: Intent { act=android.intent.action.MAIN }\r\n'):
808       self.device.GoHome()
809
810
811 class DeviceUtilsForceStopTest(DeviceUtilsOldImplTest):
812
813   def testForceStop(self):
814     with self.assertCalls(
815         "adb -s 0123456789abcdef shell 'am force-stop this.is.a.test.package'",
816         ''):
817       self.device.ForceStop('this.is.a.test.package')
818
819
820 class DeviceUtilsClearApplicationStateTest(DeviceUtilsOldImplTest):
821
822   def testClearApplicationState_packageExists(self):
823     with self.assertCalls(
824         "adb -s 0123456789abcdef shell 'pm path this.package.does.not.exist'",
825         ''):
826       self.device.ClearApplicationState('this.package.does.not.exist')
827
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'",
833          'Success\r\n')]):
834       self.device.ClearApplicationState('this.package.exists')
835
836
837 class DeviceUtilsSendKeyEventTest(DeviceUtilsOldImplTest):
838
839   def testSendKeyEvent(self):
840     with self.assertCalls(
841         "adb -s 0123456789abcdef shell 'input keyevent 66'",
842         ''):
843       self.device.SendKeyEvent(66)
844
845
846 class DeviceUtilsPushChangedFilesTest(DeviceUtilsOldImplTest):
847
848
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')
853
854   def testPushChangedFiles_file_noChange(self):
855     self.device.old_interface._push_if_needed_cache = {}
856
857     host_file_path = '/test/host/path'
858     device_file_path = '/test/device/path'
859
860     mock_fs = MockFileSystem()
861     mock_fs.addMockFile(host_file_path, size=100)
862
863     self.device.old_interface.GetFilesChanged = mock.Mock(return_value=[])
864
865     with mock_fs:
866       # GetFilesChanged is mocked, so its adb calls are omitted.
867       with self.assertNoAdbCalls():
868         self.device.PushChangedFiles(host_file_path, device_file_path)
869
870   def testPushChangedFiles_file_changed(self):
871     self.device.old_interface._push_if_needed_cache = {}
872
873     host_file_path = '/test/host/path'
874     device_file_path = '/test/device/path'
875
876     mock_fs = MockFileSystem()
877     mock_fs.addMockFile(
878         host_file_path, size=100,
879         stat=MockFileSystem.osStatResult(st_mtime=1000000000))
880
881     self.device.old_interface.GetFilesChanged = mock.Mock(
882         return_value=[('/test/host/path', '/test/device/path')])
883
884     with mock_fs:
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)
888
889   def testPushChangedFiles_directory_nothingChanged(self):
890     self.device.old_interface._push_if_needed_cache = {}
891
892     host_file_path = '/test/host/path'
893     device_file_path = '/test/device/path'
894
895     mock_fs = MockFileSystem()
896     mock_fs.addMockDirectory(
897         host_file_path, size=256,
898         stat=MockFileSystem.osStatResult(st_mtime=1000000000))
899     mock_fs.addMockFile(
900         host_file_path + '/file1', size=251,
901         stat=MockFileSystem.osStatResult(st_mtime=1000000001))
902     mock_fs.addMockFile(
903         host_file_path + '/file2', size=252,
904         stat=MockFileSystem.osStatResult(st_mtime=1000000002))
905
906     self.device.old_interface.GetFilesChanged = mock.Mock(return_value=[])
907
908     with mock_fs:
909       with self.assertCallsSequence([
910           ("adb -s 0123456789abcdef shell 'mkdir -p \"/test/device/path\"'",
911            '')]):
912         self.device.PushChangedFiles(host_file_path, device_file_path)
913
914   def testPushChangedFiles_directory_somethingChanged(self):
915     self.device.old_interface._push_if_needed_cache = {}
916
917     host_file_path = '/test/host/path'
918     device_file_path = '/test/device/path'
919
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'])])
925     mock_fs.addMockFile(
926         host_file_path + '/file1', size=256,
927         stat=MockFileSystem.osStatResult(st_mtime=1000000001))
928     mock_fs.addMockFile(
929         host_file_path + '/file2', size=256,
930         stat=MockFileSystem.osStatResult(st_mtime=1000000002))
931
932     self.device.old_interface.GetFilesChanged = mock.Mock(
933         return_value=[('/test/host/path/file1', '/test/device/path/file1')])
934
935     with mock_fs:
936       with self.assertCallsSequence([
937           ("adb -s 0123456789abcdef shell 'mkdir -p \"/test/device/path\"'",
938            ''),
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)
943
944   def testPushChangedFiles_directory_everythingChanged(self):
945     self.device.old_interface._push_if_needed_cache = {}
946
947     host_file_path = '/test/host/path'
948     device_file_path = '/test/device/path'
949
950     mock_fs = MockFileSystem()
951     mock_fs.addMockDirectory(
952         host_file_path, size=256,
953         stat=MockFileSystem.osStatResult(st_mtime=1000000000))
954     mock_fs.addMockFile(
955         host_file_path + '/file1', size=256,
956         stat=MockFileSystem.osStatResult(st_mtime=1000000001))
957     mock_fs.addMockFile(
958         host_file_path + '/file2', size=256,
959         stat=MockFileSystem.osStatResult(st_mtime=1000000002))
960
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')])
964
965     with mock_fs:
966       with self.assertCallsSequence([
967           ("adb -s 0123456789abcdef shell 'mkdir -p \"/test/device/path\"'",
968            ''),
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)
972
973
974 class DeviceUtilsFileExistsTest(DeviceUtilsOldImplTest):
975
976   def testFileExists_usingTest_fileExists(self):
977     with self.assertCalls(
978         "adb -s 0123456789abcdef shell "
979             "'test -e \"/data/app/test.file.exists\"; echo $?'",
980         '0\r\n'):
981       self.assertTrue(self.device.FileExists('/data/app/test.file.exists'))
982
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 $?'",
987         '1\r\n'):
988       self.assertFalse(self.device.FileExists(
989           '/data/app/test.file.does.not.exist'))
990
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 $?'",
998          '0\r\n')]):
999       self.assertTrue(self.device.FileExists('/data/app/test.file.exists'))
1000
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 $?'",
1009          '1\r\n')]):
1010       self.assertFalse(self.device.FileExists(
1011           '/data/app/test.file.does.not.exist'))
1012
1013
1014 class DeviceUtilsPullFileTest(DeviceUtilsOldImplTest):
1015
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')
1027
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')
1037
1038
1039 class DeviceUtilsReadFileTest(DeviceUtilsOldImplTest):
1040
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'))
1048
1049   def testReadFile_doesNotExist(self):
1050     with self.assertCalls(
1051         "adb -s 0123456789abcdef shell "
1052             "'cat \"/this/file/does.not.exist\" 2>/dev/null'",
1053          ''):
1054       self.device.ReadFile('/this/file/does.not.exist')
1055
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')]):
1064       self.assertEqual(
1065           ['this is a test file', 'read by root'],
1066           self.device.ReadFile('/this/file/must.be.read.by.root',
1067                                as_root=True))
1068
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')]):
1077       self.assertEqual(
1078           ['this is a test file', 'read with su'],
1079           self.device.ReadFile('/this/file/can.be.read.with.su',
1080                                as_root=True))
1081
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',
1087                            as_root=True)
1088
1089
1090 class DeviceUtilsWriteFileTest(DeviceUtilsOldImplTest):
1091
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')
1105
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
1111
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(
1118           cmd_ret=[
1119               # Create temporary contents file
1120               (r"adb -s 0123456789abcdef shell "
1121                   "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1122                   "echo \$\?'",
1123                '1\r\n'),
1124               # Create temporary script file
1125               (r"adb -s 0123456789abcdef shell "
1126                   "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1127                   "echo \$\?'",
1128                '1\r\n'),
1129               # Set contents file
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'),
1133               # Set script file
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'),
1137               # Call script
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+'", '')],
1145           comp=re.match):
1146         self.device.WriteFile('/test/file/written.to.device',
1147                               'new test file contents', as_root=True)
1148
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
1154
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(
1161           cmd_ret=[
1162               # Create temporary contents file
1163               (r"adb -s 0123456789abcdef shell "
1164                   "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1165                   "echo \$\?'",
1166                '1\r\n'),
1167               # Create temporary script file
1168               (r"adb -s 0123456789abcdef shell "
1169                   "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1170                   "echo \$\?'",
1171                '1\r\n'),
1172               # Set contents file
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'),
1176               # Set script file
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'),
1180               # Call script
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+'", '')],
1188           comp=re.match):
1189         self.device.WriteFile('/test/file/written.to.device',
1190                               'new test file contents', as_root=True)
1191
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)
1198
1199 class DeviceUtilsWriteTextFileTest(DeviceUtilsOldImplTest):
1200
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')
1206
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')
1212
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',
1219                                 as_root=True)
1220
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',
1227                                 as_root=True)
1228
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',
1236                                   as_root=True)
1237
1238 class DeviceUtilsLsTest(DeviceUtilsOldImplTest):
1239
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'))
1246
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')]):
1252       self.assertEqual(
1253           {'test.file': (4096, datetime.datetime(1970, 1, 1))},
1254           self.device.Ls('/this/is/a/test.file'))
1255
1256   def testLs_directory(self):
1257     with self.assertCallsSequence([
1258         ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.directory'",
1259          '\r\n'
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')]):
1263       self.assertEqual(
1264           {'test.file': (4096, datetime.datetime(1970, 1, 1, 18, 19))},
1265           self.device.Ls('/this/is/a/test.directory'))
1266
1267   def testLs_directories(self):
1268     with self.assertCallsSequence([
1269         ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.directory'",
1270          '\r\n'
1271          '/this/is/a/test.directory:\r\n'
1272          'drwxr-xr-x testuser testgroup 1970-01-01 00:00 test.subdirectory\r\n'
1273          '\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')]):
1277       self.assertEqual(
1278           {'test.subdirectory/test.file':
1279               (4096, datetime.datetime(1970, 1, 1, 7, 0, 0))},
1280           self.device.Ls('/this/is/a/test.directory'))
1281
1282
1283 class DeviceUtilsSetJavaAssertsTest(DeviceUtilsOldImplTest):
1284
1285   @staticmethod
1286   def mockNamedTemporary(name='/tmp/file/property.file',
1287                          read_contents=''):
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
1292     return mock_file
1293
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',
1311             '\r\n'),
1312            ('adb -s 0123456789abcdef shell '
1313                 'setprop dalvik.vm.enableassertions "all"',
1314             '')]):
1315         self.assertTrue(self.device.SetJavaAsserts(True))
1316
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',
1335             'all\r\n'),
1336            ('adb -s 0123456789abcdef shell '
1337                 'setprop dalvik.vm.enableassertions ""',
1338             '')]):
1339         self.assertTrue(self.device.SetJavaAsserts(False))
1340
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',
1356             'all\r\n')]):
1357         self.assertFalse(self.device.SetJavaAsserts(True))
1358
1359
1360 class DeviceUtilsGetPropTest(DeviceUtilsOldImplTest):
1361
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'))
1368
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'))
1374
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'))
1381
1382
1383 class DeviceUtilsSetPropTest(DeviceUtilsOldImplTest):
1384
1385   def testSetProp(self):
1386     with self.assertCalls(
1387         'adb -s 0123456789abcdef shell '
1388             'setprop this.is.a.test.property "test_property_value"',
1389         ''):
1390       self.device.SetProp('this.is.a.test.property', 'test_property_value')
1391
1392
1393 class DeviceUtilsGetPidsTest(DeviceUtilsOldImplTest):
1394
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'))
1401
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'))
1409
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'):
1418       self.assertEqual(
1419           {'one.match': '1001', 'two.match': '1002', 'three.match': '1003'},
1420           self.device.GetPids('match'))
1421
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'):
1428       self.assertEqual(
1429           {'not.exact.match': '1000', 'exact.match': '1234'},
1430           self.device.GetPids('exact.match'))
1431
1432
1433 class DeviceUtilsTakeScreenshotTest(DeviceUtilsOldImplTest):
1434
1435   def testTakeScreenshot_fileNameProvided(self):
1436     mock_fs = MockFileSystem()
1437     mock_fs.addMockDirectory('/test/host')
1438     mock_fs.addMockFile('/test/host/screenshot.png')
1439
1440     with mock_fs:
1441       with self.assertCallsSequence(
1442           cmd_ret=[
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+'",
1446                ''),
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+'", '')
1452           ],
1453           comp=re.match):
1454         self.device.TakeScreenshot('/test/host/screenshot.png')
1455
1456
1457 class DeviceUtilsGetIOStatsTest(DeviceUtilsOldImplTest):
1458
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'):
1463       self.assertEqual(
1464           {
1465             'num_reads': 1,
1466             'num_writes': 5,
1467             'read_ms': 4,
1468             'write_ms': 8,
1469           },
1470           self.device.GetIOStats())
1471
1472
1473 class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsOldImplTest):
1474
1475   def setUp(self):
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
1480
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'",
1487          'VmHWM: 1024 kB')
1488         ]):
1489       self.assertEqual(
1490           {
1491             'Size': 100,
1492             'Rss': 101,
1493             'Pss': 102,
1494             'Shared_Clean': 103,
1495             'Shared_Dirty': 104,
1496             'Private_Clean': 105,
1497             'Private_Dirty': 106,
1498             'VmHWM': 1024
1499           },
1500           self.device.GetMemoryUsageForPid(1234))
1501
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))
1507
1508
1509 class DeviceUtilsStrTest(DeviceUtilsOldImplTest):
1510   def testStr_noAdbCalls(self):
1511     with self.assertNoAdbCalls():
1512       self.assertEqual('0123456789abcdef', str(self.device))
1513
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))
1518
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)):
1523       str(self.device)
1524
1525
1526 if __name__ == '__main__':
1527   logging.getLogger().setLevel(logging.DEBUG)
1528   unittest.main(verbosity=2)
1529