Upstream version 9.38.198.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 'ps'",
561          'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
562          'u0_a1  1234  174   123456 54321 ffffffff 456789ab '
563               'this.is.a.test.process\r\n'),
564         ("adb -s 0123456789abcdef shell 'kill -9 1234'", '')]):
565       self.device.KillAll('this.is.a.test.process', blocking=False)
566
567   def testKillAll_blocking(self):
568     with mock.patch('time.sleep'):
569       with self.assertCallsSequence([
570           ("adb -s 0123456789abcdef shell 'ps'",
571            'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
572            'u0_a1  1234  174   123456 54321 ffffffff 456789ab '
573                 'this.is.a.test.process\r\n'),
574           ("adb -s 0123456789abcdef shell 'ps'",
575            'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
576            'u0_a1  1234  174   123456 54321 ffffffff 456789ab '
577                 'this.is.a.test.process\r\n'),
578           ("adb -s 0123456789abcdef shell 'kill -9 1234'", ''),
579           ("adb -s 0123456789abcdef shell 'ps'",
580            'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
581            'u0_a1  1234  174   123456 54321 ffffffff 456789ab '
582                 'this.is.a.test.process\r\n'),
583           ("adb -s 0123456789abcdef shell 'ps'",
584            'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n')]):
585         self.device.KillAll('this.is.a.test.process', blocking=True)
586
587   def testKillAll_root(self):
588     with self.assertCallsSequence([
589           ("adb -s 0123456789abcdef shell 'ps'",
590            'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
591            'u0_a1  1234  174   123456 54321 ffffffff 456789ab '
592                 'this.is.a.test.process\r\n'),
593           ("adb -s 0123456789abcdef shell 'ps'",
594            'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
595            'u0_a1  1234  174   123456 54321 ffffffff 456789ab '
596                 'this.is.a.test.process\r\n'),
597           ("adb -s 0123456789abcdef shell 'su -c kill -9 1234'", '')]):
598       self.device.KillAll('this.is.a.test.process', as_root=True)
599
600   def testKillAll_sigterm(self):
601     with self.assertCallsSequence([
602         ("adb -s 0123456789abcdef shell 'ps'",
603          'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
604          'u0_a1  1234  174   123456 54321 ffffffff 456789ab '
605               'this.is.a.test.process\r\n'),
606         ("adb -s 0123456789abcdef shell 'ps'",
607          'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
608          'u0_a1  1234  174   123456 54321 ffffffff 456789ab '
609               'this.is.a.test.process\r\n'),
610         ("adb -s 0123456789abcdef shell 'kill -15 1234'", '')]):
611       self.device.KillAll('this.is.a.test.process', signum=signal.SIGTERM)
612
613
614 class DeviceUtilsStartActivityTest(DeviceUtilsOldImplTest):
615
616   def testStartActivity_actionOnly(self):
617     test_intent = intent.Intent(action='android.intent.action.VIEW')
618     with self.assertCalls(
619         "adb -s 0123456789abcdef shell 'am start "
620             "-a android.intent.action.VIEW'",
621         'Starting: Intent { act=android.intent.action.VIEW }'):
622       self.device.StartActivity(test_intent)
623
624   def testStartActivity_success(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         'Starting: Intent { act=android.intent.action.VIEW }'):
633       self.device.StartActivity(test_intent)
634
635   def testStartActivity_failure(self):
636     test_intent = intent.Intent(action='android.intent.action.VIEW',
637                                 package='this.is.a.test.package',
638                                 activity='.Main')
639     with self.assertCalls(
640         "adb -s 0123456789abcdef shell 'am start "
641             "-a android.intent.action.VIEW "
642             "-n this.is.a.test.package/.Main'",
643         'Error: Failed to start test activity'):
644       with self.assertRaises(device_errors.CommandFailedError):
645         self.device.StartActivity(test_intent)
646
647   def testStartActivity_blocking(self):
648     test_intent = intent.Intent(action='android.intent.action.VIEW',
649                                 package='this.is.a.test.package',
650                                 activity='.Main')
651     with self.assertCalls(
652         "adb -s 0123456789abcdef shell 'am start "
653             "-a android.intent.action.VIEW "
654             "-W "
655             "-n this.is.a.test.package/.Main'",
656         'Starting: Intent { act=android.intent.action.VIEW }'):
657       self.device.StartActivity(test_intent, blocking=True)
658
659   def testStartActivity_withCategory(self):
660     test_intent = intent.Intent(action='android.intent.action.VIEW',
661                                 package='this.is.a.test.package',
662                                 activity='.Main',
663                                 category='android.intent.category.HOME')
664     with self.assertCalls(
665         "adb -s 0123456789abcdef shell 'am start "
666             "-a android.intent.action.VIEW "
667             "-c android.intent.category.HOME "
668             "-n this.is.a.test.package/.Main'",
669         'Starting: Intent { act=android.intent.action.VIEW }'):
670       self.device.StartActivity(test_intent)
671
672   def testStartActivity_withMultipleCategories(self):
673     # The new implementation will start the activity with all provided
674     # categories. The old one only uses the first category.
675     test_intent = intent.Intent(action='android.intent.action.VIEW',
676                                 package='this.is.a.test.package',
677                                 activity='.Main',
678                                 category=['android.intent.category.HOME',
679                                           'android.intent.category.BROWSABLE'])
680     with self.assertCalls(
681         "adb -s 0123456789abcdef shell 'am start "
682             "-a android.intent.action.VIEW "
683             "-c android.intent.category.HOME "
684             "-n this.is.a.test.package/.Main'",
685         'Starting: Intent { act=android.intent.action.VIEW }'):
686       self.device.StartActivity(test_intent)
687
688   def testStartActivity_withData(self):
689     test_intent = intent.Intent(action='android.intent.action.VIEW',
690                                 package='this.is.a.test.package',
691                                 activity='.Main',
692                                 data='http://www.google.com/')
693     with self.assertCalls(
694         "adb -s 0123456789abcdef shell 'am start "
695             "-a android.intent.action.VIEW "
696             "-n this.is.a.test.package/.Main "
697             "-d \"http://www.google.com/\"'",
698         'Starting: Intent { act=android.intent.action.VIEW }'):
699       self.device.StartActivity(test_intent)
700
701   def testStartActivity_withStringExtra(self):
702     test_intent = intent.Intent(action='android.intent.action.VIEW',
703                                 package='this.is.a.test.package',
704                                 activity='.Main',
705                                 extras={'foo': 'test'})
706     with self.assertCalls(
707         "adb -s 0123456789abcdef shell 'am start "
708             "-a android.intent.action.VIEW "
709             "-n this.is.a.test.package/.Main "
710             "--es foo test'",
711         'Starting: Intent { act=android.intent.action.VIEW }'):
712       self.device.StartActivity(test_intent)
713
714   def testStartActivity_withBoolExtra(self):
715     test_intent = intent.Intent(action='android.intent.action.VIEW',
716                                 package='this.is.a.test.package',
717                                 activity='.Main',
718                                 extras={'foo': True})
719     with self.assertCalls(
720         "adb -s 0123456789abcdef shell 'am start "
721             "-a android.intent.action.VIEW "
722             "-n this.is.a.test.package/.Main "
723             "--ez foo True'",
724         'Starting: Intent { act=android.intent.action.VIEW }'):
725       self.device.StartActivity(test_intent)
726
727   def testStartActivity_withIntExtra(self):
728     test_intent = intent.Intent(action='android.intent.action.VIEW',
729                                 package='this.is.a.test.package',
730                                 activity='.Main',
731                                 extras={'foo': 123})
732     with self.assertCalls(
733         "adb -s 0123456789abcdef shell 'am start "
734             "-a android.intent.action.VIEW "
735             "-n this.is.a.test.package/.Main "
736             "--ei foo 123'",
737         'Starting: Intent { act=android.intent.action.VIEW }'):
738       self.device.StartActivity(test_intent)
739
740   def testStartActivity_withTraceFile(self):
741     test_intent = intent.Intent(action='android.intent.action.VIEW',
742                                 package='this.is.a.test.package',
743                                 activity='.Main')
744     with self.assertCalls(
745         "adb -s 0123456789abcdef shell 'am start "
746             "-a android.intent.action.VIEW "
747             "-n this.is.a.test.package/.Main "
748             "--start-profiler test_trace_file.out'",
749         'Starting: Intent { act=android.intent.action.VIEW }'):
750       self.device.StartActivity(test_intent,
751                                 trace_file_name='test_trace_file.out')
752
753   def testStartActivity_withForceStop(self):
754     test_intent = intent.Intent(action='android.intent.action.VIEW',
755                                 package='this.is.a.test.package',
756                                 activity='.Main')
757     with self.assertCalls(
758         "adb -s 0123456789abcdef shell 'am start "
759             "-a android.intent.action.VIEW "
760             "-S "
761             "-n this.is.a.test.package/.Main'",
762         'Starting: Intent { act=android.intent.action.VIEW }'):
763       self.device.StartActivity(test_intent, force_stop=True)
764
765   def testStartActivity_withFlags(self):
766     test_intent = intent.Intent(action='android.intent.action.VIEW',
767                                 package='this.is.a.test.package',
768                                 activity='.Main',
769                                 flags='0x10000000')
770     with self.assertCalls(
771         "adb -s 0123456789abcdef shell 'am start "
772             "-a android.intent.action.VIEW "
773             "-n this.is.a.test.package/.Main "
774             "-f 0x10000000'",
775         'Starting: Intent { act=android.intent.action.VIEW }'):
776       self.device.StartActivity(test_intent)
777
778
779 class DeviceUtilsBroadcastIntentTest(DeviceUtilsOldImplTest):
780
781   def testBroadcastIntent_noExtras(self):
782     test_intent = intent.Intent(action='test.package.with.an.INTENT')
783     with self.assertCalls(
784         "adb -s 0123456789abcdef shell 'am broadcast "
785             "-a test.package.with.an.INTENT '",
786         'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
787       self.device.BroadcastIntent(test_intent)
788
789   def testBroadcastIntent_withExtra(self):
790     test_intent = intent.Intent(action='test.package.with.an.INTENT',
791                                 extras={'foo': 'bar'})
792     with self.assertCalls(
793         "adb -s 0123456789abcdef shell 'am broadcast "
794             "-a test.package.with.an.INTENT "
795             "-e foo \"bar\"'",
796         'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
797       self.device.BroadcastIntent(test_intent)
798
799   def testBroadcastIntent_withExtra_noValue(self):
800     test_intent = intent.Intent(action='test.package.with.an.INTENT',
801                                 extras={'foo': None})
802     with self.assertCalls(
803         "adb -s 0123456789abcdef shell 'am broadcast "
804             "-a test.package.with.an.INTENT "
805             "-e foo'",
806         'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
807       self.device.BroadcastIntent(test_intent)
808
809
810 class DeviceUtilsGoHomeTest(DeviceUtilsOldImplTest):
811
812   def testGoHome(self):
813     with self.assertCalls(
814         "adb -s 0123456789abcdef shell 'am start "
815             "-W "
816             "-a android.intent.action.MAIN "
817             "-c android.intent.category.HOME'",
818         'Starting: Intent { act=android.intent.action.MAIN }\r\n'):
819       self.device.GoHome()
820
821
822 class DeviceUtilsForceStopTest(DeviceUtilsOldImplTest):
823
824   def testForceStop(self):
825     with self.assertCalls(
826         "adb -s 0123456789abcdef shell 'am force-stop this.is.a.test.package'",
827         ''):
828       self.device.ForceStop('this.is.a.test.package')
829
830
831 class DeviceUtilsClearApplicationStateTest(DeviceUtilsOldImplTest):
832
833   def testClearApplicationState_packageExists(self):
834     with self.assertCalls(
835         "adb -s 0123456789abcdef shell 'pm path this.package.does.not.exist'",
836         ''):
837       self.device.ClearApplicationState('this.package.does.not.exist')
838
839   def testClearApplicationState_packageDoesntExist(self):
840     with self.assertCallsSequence([
841         ("adb -s 0123456789abcdef shell 'pm path this.package.exists'",
842          'package:/data/app/this.package.exists.apk'),
843         ("adb -s 0123456789abcdef shell 'pm clear this.package.exists'",
844          'Success\r\n')]):
845       self.device.ClearApplicationState('this.package.exists')
846
847
848 class DeviceUtilsSendKeyEventTest(DeviceUtilsOldImplTest):
849
850   def testSendKeyEvent(self):
851     with self.assertCalls(
852         "adb -s 0123456789abcdef shell 'input keyevent 66'",
853         ''):
854       self.device.SendKeyEvent(66)
855
856
857 class DeviceUtilsPushChangedFilesTest(DeviceUtilsOldImplTest):
858
859
860   def testPushChangedFiles_noHostPath(self):
861     with mock.patch('os.path.exists', return_value=False):
862       with self.assertRaises(device_errors.CommandFailedError):
863         self.device.PushChangedFiles('/test/host/path', '/test/device/path')
864
865   def testPushChangedFiles_file_noChange(self):
866     self.device.old_interface._push_if_needed_cache = {}
867
868     host_file_path = '/test/host/path'
869     device_file_path = '/test/device/path'
870
871     mock_fs = MockFileSystem()
872     mock_fs.addMockFile(host_file_path, size=100)
873
874     self.device.old_interface.GetFilesChanged = mock.Mock(return_value=[])
875
876     with mock_fs:
877       # GetFilesChanged is mocked, so its adb calls are omitted.
878       with self.assertNoAdbCalls():
879         self.device.PushChangedFiles(host_file_path, device_file_path)
880
881   def testPushChangedFiles_file_changed(self):
882     self.device.old_interface._push_if_needed_cache = {}
883
884     host_file_path = '/test/host/path'
885     device_file_path = '/test/device/path'
886
887     mock_fs = MockFileSystem()
888     mock_fs.addMockFile(
889         host_file_path, size=100,
890         stat=MockFileSystem.osStatResult(st_mtime=1000000000))
891
892     self.device.old_interface.GetFilesChanged = mock.Mock(
893         return_value=[('/test/host/path', '/test/device/path')])
894
895     with mock_fs:
896       with self.assertCalls('adb -s 0123456789abcdef push '
897           '/test/host/path /test/device/path', '100 B/s (100 B in 1.000s)\r\n'):
898         self.device.PushChangedFiles(host_file_path, device_file_path)
899
900   def testPushChangedFiles_directory_nothingChanged(self):
901     self.device.old_interface._push_if_needed_cache = {}
902
903     host_file_path = '/test/host/path'
904     device_file_path = '/test/device/path'
905
906     mock_fs = MockFileSystem()
907     mock_fs.addMockDirectory(
908         host_file_path, size=256,
909         stat=MockFileSystem.osStatResult(st_mtime=1000000000))
910     mock_fs.addMockFile(
911         host_file_path + '/file1', size=251,
912         stat=MockFileSystem.osStatResult(st_mtime=1000000001))
913     mock_fs.addMockFile(
914         host_file_path + '/file2', size=252,
915         stat=MockFileSystem.osStatResult(st_mtime=1000000002))
916
917     self.device.old_interface.GetFilesChanged = mock.Mock(return_value=[])
918
919     with mock_fs:
920       with self.assertCallsSequence([
921           ("adb -s 0123456789abcdef shell 'mkdir -p \"/test/device/path\"'",
922            '')]):
923         self.device.PushChangedFiles(host_file_path, device_file_path)
924
925   def testPushChangedFiles_directory_somethingChanged(self):
926     self.device.old_interface._push_if_needed_cache = {}
927
928     host_file_path = '/test/host/path'
929     device_file_path = '/test/device/path'
930
931     mock_fs = MockFileSystem()
932     mock_fs.addMockDirectory(
933         host_file_path, size=256,
934         stat=MockFileSystem.osStatResult(st_mtime=1000000000),
935         walk=[('/test/host/path', [], ['file1', 'file2'])])
936     mock_fs.addMockFile(
937         host_file_path + '/file1', size=256,
938         stat=MockFileSystem.osStatResult(st_mtime=1000000001))
939     mock_fs.addMockFile(
940         host_file_path + '/file2', size=256,
941         stat=MockFileSystem.osStatResult(st_mtime=1000000002))
942
943     self.device.old_interface.GetFilesChanged = mock.Mock(
944         return_value=[('/test/host/path/file1', '/test/device/path/file1')])
945
946     with mock_fs:
947       with self.assertCallsSequence([
948           ("adb -s 0123456789abcdef shell 'mkdir -p \"/test/device/path\"'",
949            ''),
950           ('adb -s 0123456789abcdef push '
951               '/test/host/path/file1 /test/device/path/file1',
952            '256 B/s (256 B in 1.000s)\r\n')]):
953         self.device.PushChangedFiles(host_file_path, device_file_path)
954
955   def testPushChangedFiles_directory_everythingChanged(self):
956     self.device.old_interface._push_if_needed_cache = {}
957
958     host_file_path = '/test/host/path'
959     device_file_path = '/test/device/path'
960
961     mock_fs = MockFileSystem()
962     mock_fs.addMockDirectory(
963         host_file_path, size=256,
964         stat=MockFileSystem.osStatResult(st_mtime=1000000000))
965     mock_fs.addMockFile(
966         host_file_path + '/file1', size=256,
967         stat=MockFileSystem.osStatResult(st_mtime=1000000001))
968     mock_fs.addMockFile(
969         host_file_path + '/file2', size=256,
970         stat=MockFileSystem.osStatResult(st_mtime=1000000002))
971
972     self.device.old_interface.GetFilesChanged = mock.Mock(
973         return_value=[('/test/host/path/file1', '/test/device/path/file1'),
974                       ('/test/host/path/file2', '/test/device/path/file2')])
975
976     with mock_fs:
977       with self.assertCallsSequence([
978           ("adb -s 0123456789abcdef shell 'mkdir -p \"/test/device/path\"'",
979            ''),
980           ('adb -s 0123456789abcdef push /test/host/path /test/device/path',
981            '768 B/s (768 B in 1.000s)\r\n')]):
982         self.device.PushChangedFiles(host_file_path, device_file_path)
983
984
985 class DeviceUtilsFileExistsTest(DeviceUtilsOldImplTest):
986
987   def testFileExists_usingTest_fileExists(self):
988     with self.assertCalls(
989         "adb -s 0123456789abcdef shell "
990             "'test -e \"/data/app/test.file.exists\"; echo $?'",
991         '0\r\n'):
992       self.assertTrue(self.device.FileExists('/data/app/test.file.exists'))
993
994   def testFileExists_usingTest_fileDoesntExist(self):
995     with self.assertCalls(
996         "adb -s 0123456789abcdef shell "
997             "'test -e \"/data/app/test.file.does.not.exist\"; echo $?'",
998         '1\r\n'):
999       self.assertFalse(self.device.FileExists(
1000           '/data/app/test.file.does.not.exist'))
1001
1002   def testFileExists_usingLs_fileExists(self):
1003     with self.assertCallsSequence([
1004         ("adb -s 0123456789abcdef shell "
1005             "'test -e \"/data/app/test.file.exists\"; echo $?'",
1006          'test: not found\r\n'),
1007         ("adb -s 0123456789abcdef shell "
1008             "'ls \"/data/app/test.file.exists\" >/dev/null 2>&1; echo $?'",
1009          '0\r\n')]):
1010       self.assertTrue(self.device.FileExists('/data/app/test.file.exists'))
1011
1012   def testFileExists_usingLs_fileDoesntExist(self):
1013     with self.assertCallsSequence([
1014         ("adb -s 0123456789abcdef shell "
1015             "'test -e \"/data/app/test.file.does.not.exist\"; echo $?'",
1016          'test: not found\r\n'),
1017         ("adb -s 0123456789abcdef shell "
1018             "'ls \"/data/app/test.file.does.not.exist\" "
1019             ">/dev/null 2>&1; echo $?'",
1020          '1\r\n')]):
1021       self.assertFalse(self.device.FileExists(
1022           '/data/app/test.file.does.not.exist'))
1023
1024
1025 class DeviceUtilsPullFileTest(DeviceUtilsOldImplTest):
1026
1027   def testPullFile_existsOnDevice(self):
1028     with mock.patch('os.path.exists', return_value=True):
1029       with self.assertCallsSequence([
1030           ('adb -s 0123456789abcdef shell '
1031               'ls /data/app/test.file.exists',
1032            '/data/app/test.file.exists'),
1033           ('adb -s 0123456789abcdef pull '
1034               '/data/app/test.file.exists /test/file/host/path',
1035            '100 B/s (100 bytes in 1.000s)\r\n')]):
1036         self.device.PullFile('/data/app/test.file.exists',
1037                              '/test/file/host/path')
1038
1039   def testPullFile_doesntExistOnDevice(self):
1040     with mock.patch('os.path.exists', return_value=True):
1041       with self.assertCalls(
1042           'adb -s 0123456789abcdef shell '
1043               'ls /data/app/test.file.does.not.exist',
1044           '/data/app/test.file.does.not.exist: No such file or directory\r\n'):
1045         with self.assertRaises(device_errors.CommandFailedError):
1046           self.device.PullFile('/data/app/test.file.does.not.exist',
1047                                '/test/file/host/path')
1048
1049
1050 class DeviceUtilsReadFileTest(DeviceUtilsOldImplTest):
1051
1052   def testReadFile_exists(self):
1053     with self.assertCallsSequence([
1054         ("adb -s 0123456789abcdef shell "
1055             "'cat \"/read/this/test/file\" 2>/dev/null'",
1056          'this is a test file')]):
1057       self.assertEqual(['this is a test file'],
1058                        self.device.ReadFile('/read/this/test/file'))
1059
1060   def testReadFile_doesNotExist(self):
1061     with self.assertCalls(
1062         "adb -s 0123456789abcdef shell "
1063             "'cat \"/this/file/does.not.exist\" 2>/dev/null'",
1064          ''):
1065       self.device.ReadFile('/this/file/does.not.exist')
1066
1067   def testReadFile_asRoot_withRoot(self):
1068     self.device.old_interface._privileged_command_runner = (
1069         self.device.old_interface.RunShellCommand)
1070     self.device.old_interface._protected_file_access_method_initialized = True
1071     with self.assertCallsSequence([
1072         ("adb -s 0123456789abcdef shell "
1073             "'cat \"/this/file/must.be.read.by.root\" 2> /dev/null'",
1074          'this is a test file\nread by root')]):
1075       self.assertEqual(
1076           ['this is a test file', 'read by root'],
1077           self.device.ReadFile('/this/file/must.be.read.by.root',
1078                                as_root=True))
1079
1080   def testReadFile_asRoot_withSu(self):
1081     self.device.old_interface._privileged_command_runner = (
1082         self.device.old_interface.RunShellCommandWithSU)
1083     self.device.old_interface._protected_file_access_method_initialized = True
1084     with self.assertCallsSequence([
1085         ("adb -s 0123456789abcdef shell "
1086             "'su -c cat \"/this/file/can.be.read.with.su\" 2> /dev/null'",
1087          'this is a test file\nread with su')]):
1088       self.assertEqual(
1089           ['this is a test file', 'read with su'],
1090           self.device.ReadFile('/this/file/can.be.read.with.su',
1091                                as_root=True))
1092
1093   def testReadFile_asRoot_rejected(self):
1094     self.device.old_interface._privileged_command_runner = None
1095     self.device.old_interface._protected_file_access_method_initialized = True
1096     with self.assertRaises(device_errors.CommandFailedError):
1097       self.device.ReadFile('/this/file/cannot.be.read.by.user',
1098                            as_root=True)
1099
1100
1101 class DeviceUtilsWriteFileTest(DeviceUtilsOldImplTest):
1102
1103   def testWriteFile_basic(self):
1104     mock_file = mock.MagicMock(spec=file)
1105     mock_file.name = '/tmp/file/to.be.pushed'
1106     mock_file.__enter__.return_value = mock_file
1107     with mock.patch('tempfile.NamedTemporaryFile',
1108                     return_value=mock_file):
1109       with self.assertCalls(
1110           'adb -s 0123456789abcdef push '
1111               '/tmp/file/to.be.pushed /test/file/written.to.device',
1112           '100 B/s (100 bytes in 1.000s)\r\n'):
1113         self.device.WriteFile('/test/file/written.to.device',
1114                               'new test file contents')
1115     mock_file.write.assert_called_once_with('new test file contents')
1116
1117   def testWriteFile_asRoot_withRoot(self):
1118     self.device.old_interface._external_storage = '/fake/storage/path'
1119     self.device.old_interface._privileged_command_runner = (
1120         self.device.old_interface.RunShellCommand)
1121     self.device.old_interface._protected_file_access_method_initialized = True
1122
1123     mock_file = mock.MagicMock(spec=file)
1124     mock_file.name = '/tmp/file/to.be.pushed'
1125     mock_file.__enter__.return_value = mock_file
1126     with mock.patch('tempfile.NamedTemporaryFile',
1127                     return_value=mock_file):
1128       with self.assertCallsSequence(
1129           cmd_ret=[
1130               # Create temporary contents file
1131               (r"adb -s 0123456789abcdef shell "
1132                   "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1133                   "echo \$\?'",
1134                '1\r\n'),
1135               # Create temporary script file
1136               (r"adb -s 0123456789abcdef shell "
1137                   "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1138                   "echo \$\?'",
1139                '1\r\n'),
1140               # Set contents file
1141               (r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1142                   '/fake/storage/path/temp_file-\d+\d+',
1143                '100 B/s (100 bytes in 1.000s)\r\n'),
1144               # Set script file
1145               (r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1146                   '/fake/storage/path/temp_file-\d+\d+',
1147                '100 B/s (100 bytes in 1.000s)\r\n'),
1148               # Call script
1149               (r"adb -s 0123456789abcdef shell "
1150                   "'sh /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1151               # Remove device temporaries
1152               (r"adb -s 0123456789abcdef shell "
1153                   "'rm /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1154               (r"adb -s 0123456789abcdef shell "
1155                   "'rm /fake/storage/path/temp_file-\d+-\d+'", '')],
1156           comp=re.match):
1157         self.device.WriteFile('/test/file/written.to.device',
1158                               'new test file contents', as_root=True)
1159
1160   def testWriteFile_asRoot_withSu(self):
1161     self.device.old_interface._external_storage = '/fake/storage/path'
1162     self.device.old_interface._privileged_command_runner = (
1163         self.device.old_interface.RunShellCommandWithSU)
1164     self.device.old_interface._protected_file_access_method_initialized = True
1165
1166     mock_file = mock.MagicMock(spec=file)
1167     mock_file.name = '/tmp/file/to.be.pushed'
1168     mock_file.__enter__.return_value = mock_file
1169     with mock.patch('tempfile.NamedTemporaryFile',
1170                     return_value=mock_file):
1171       with self.assertCallsSequence(
1172           cmd_ret=[
1173               # Create temporary contents file
1174               (r"adb -s 0123456789abcdef shell "
1175                   "'test -e \"/fake/storage/path/temp_file-\d+-\d+\"; "
1176                   "echo \$\?'",
1177                '1\r\n'),
1178               # Create temporary script file
1179               (r"adb -s 0123456789abcdef shell "
1180                   "'test -e \"/fake/storage/path/temp_file-\d+-\d+\.sh\"; "
1181                   "echo \$\?'",
1182                '1\r\n'),
1183               # Set contents file
1184               (r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1185                   '/fake/storage/path/temp_file-\d+\d+',
1186                '100 B/s (100 bytes in 1.000s)\r\n'),
1187               # Set script file
1188               (r'adb -s 0123456789abcdef push /tmp/file/to\.be\.pushed '
1189                   '/fake/storage/path/temp_file-\d+\d+',
1190                '100 B/s (100 bytes in 1.000s)\r\n'),
1191               # Call script
1192               (r"adb -s 0123456789abcdef shell "
1193                   "'su -c sh /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1194               # Remove device temporaries
1195               (r"adb -s 0123456789abcdef shell "
1196                   "'rm /fake/storage/path/temp_file-\d+-\d+\.sh'", ''),
1197               (r"adb -s 0123456789abcdef shell "
1198                   "'rm /fake/storage/path/temp_file-\d+-\d+'", '')],
1199           comp=re.match):
1200         self.device.WriteFile('/test/file/written.to.device',
1201                               'new test file contents', as_root=True)
1202
1203   def testWriteFile_asRoot_rejected(self):
1204     self.device.old_interface._privileged_command_runner = None
1205     self.device.old_interface._protected_file_access_method_initialized = True
1206     with self.assertRaises(device_errors.CommandFailedError):
1207       self.device.WriteFile('/test/file/no.permissions.to.write',
1208                             'new test file contents', as_root=True)
1209
1210
1211 class DeviceUtilsLsTest(DeviceUtilsOldImplTest):
1212
1213   def testLs_nothing(self):
1214     with self.assertCallsSequence([
1215         ("adb -s 0123456789abcdef shell 'ls -lR /this/file/does.not.exist'",
1216          '/this/file/does.not.exist: No such file or directory\r\n'),
1217         ("adb -s 0123456789abcdef shell 'date +%z'", '+0000')]):
1218       self.assertEqual({}, self.device.Ls('/this/file/does.not.exist'))
1219
1220   def testLs_file(self):
1221     with self.assertCallsSequence([
1222         ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.file'",
1223          '-rw-rw---- testuser testgroup 4096 1970-01-01 00:00 test.file\r\n'),
1224         ("adb -s 0123456789abcdef shell 'date +%z'", '+0000')]):
1225       self.assertEqual(
1226           {'test.file': (4096, datetime.datetime(1970, 1, 1))},
1227           self.device.Ls('/this/is/a/test.file'))
1228
1229   def testLs_directory(self):
1230     with self.assertCallsSequence([
1231         ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.directory'",
1232          '\r\n'
1233          '/this/is/a/test.directory:\r\n'
1234          '-rw-rw---- testuser testgroup 4096 1970-01-01 18:19 test.file\r\n'),
1235         ("adb -s 0123456789abcdef shell 'date +%z'", '+0000')]):
1236       self.assertEqual(
1237           {'test.file': (4096, datetime.datetime(1970, 1, 1, 18, 19))},
1238           self.device.Ls('/this/is/a/test.directory'))
1239
1240   def testLs_directories(self):
1241     with self.assertCallsSequence([
1242         ("adb -s 0123456789abcdef shell 'ls -lR /this/is/a/test.directory'",
1243          '\r\n'
1244          '/this/is/a/test.directory:\r\n'
1245          'drwxr-xr-x testuser testgroup 1970-01-01 00:00 test.subdirectory\r\n'
1246          '\r\n'
1247          '/this/is/a/test.directory/test.subdirectory:\r\n'
1248          '-rw-rw---- testuser testgroup 4096 1970-01-01 00:00 test.file\r\n'),
1249         ("adb -s 0123456789abcdef shell 'date +%z'", '-0700')]):
1250       self.assertEqual(
1251           {'test.subdirectory/test.file':
1252               (4096, datetime.datetime(1970, 1, 1, 7, 0, 0))},
1253           self.device.Ls('/this/is/a/test.directory'))
1254
1255
1256 class DeviceUtilsSetJavaAssertsTest(DeviceUtilsOldImplTest):
1257
1258   @staticmethod
1259   def mockNamedTemporary(name='/tmp/file/property.file',
1260                          read_contents=''):
1261     mock_file = mock.MagicMock(spec=file)
1262     mock_file.name = name
1263     mock_file.__enter__.return_value = mock_file
1264     mock_file.read.return_value = read_contents
1265     return mock_file
1266
1267   def testSetJavaAsserts_enable(self):
1268     mock_file = self.mockNamedTemporary()
1269     with mock.patch('tempfile.NamedTemporaryFile',
1270                     return_value=mock_file), (
1271          mock.patch('__builtin__.open', return_value=mock_file)):
1272       with self.assertCallsSequence(
1273           [('adb -s 0123456789abcdef shell ls %s' %
1274                 constants.DEVICE_LOCAL_PROPERTIES_PATH,
1275             '%s\r\n' % constants.DEVICE_LOCAL_PROPERTIES_PATH),
1276            ('adb -s 0123456789abcdef pull %s %s' %
1277                 (constants.DEVICE_LOCAL_PROPERTIES_PATH, mock_file.name),
1278             '100 B/s (100 bytes in 1.000s)\r\n'),
1279            ('adb -s 0123456789abcdef push %s %s' %
1280                 (mock_file.name, constants.DEVICE_LOCAL_PROPERTIES_PATH),
1281             '100 B/s (100 bytes in 1.000s)\r\n'),
1282            ('adb -s 0123456789abcdef shell '
1283                 'getprop dalvik.vm.enableassertions',
1284             '\r\n'),
1285            ('adb -s 0123456789abcdef shell '
1286                 'setprop dalvik.vm.enableassertions "all"',
1287             '')]):
1288         self.device.SetJavaAsserts(True)
1289
1290   def testSetJavaAsserts_disable(self):
1291     mock_file = self.mockNamedTemporary(
1292         read_contents='dalvik.vm.enableassertions=all\n')
1293     with mock.patch('tempfile.NamedTemporaryFile',
1294                     return_value=mock_file), (
1295          mock.patch('__builtin__.open', return_value=mock_file)):
1296       with self.assertCallsSequence(
1297           [('adb -s 0123456789abcdef shell ls %s' %
1298                 constants.DEVICE_LOCAL_PROPERTIES_PATH,
1299             '%s\r\n' % constants.DEVICE_LOCAL_PROPERTIES_PATH),
1300            ('adb -s 0123456789abcdef pull %s %s' %
1301                 (constants.DEVICE_LOCAL_PROPERTIES_PATH, mock_file.name),
1302             '100 B/s (100 bytes in 1.000s)\r\n'),
1303            ('adb -s 0123456789abcdef push %s %s' %
1304                 (mock_file.name, constants.DEVICE_LOCAL_PROPERTIES_PATH),
1305             '100 B/s (100 bytes in 1.000s)\r\n'),
1306            ('adb -s 0123456789abcdef shell '
1307                 'getprop dalvik.vm.enableassertions',
1308             'all\r\n'),
1309            ('adb -s 0123456789abcdef shell '
1310                 'setprop dalvik.vm.enableassertions ""',
1311             '')]):
1312         self.device.SetJavaAsserts(False)
1313
1314   def testSetJavaAsserts_alreadyEnabled(self):
1315     mock_file = self.mockNamedTemporary(
1316         read_contents='dalvik.vm.enableassertions=all\n')
1317     with mock.patch('tempfile.NamedTemporaryFile',
1318                     return_value=mock_file), (
1319          mock.patch('__builtin__.open', return_value=mock_file)):
1320       with self.assertCallsSequence(
1321           [('adb -s 0123456789abcdef shell ls %s' %
1322                 constants.DEVICE_LOCAL_PROPERTIES_PATH,
1323             '%s\r\n' % constants.DEVICE_LOCAL_PROPERTIES_PATH),
1324            ('adb -s 0123456789abcdef pull %s %s' %
1325                 (constants.DEVICE_LOCAL_PROPERTIES_PATH, mock_file.name),
1326             '100 B/s (100 bytes in 1.000s)\r\n'),
1327            ('adb -s 0123456789abcdef shell '
1328                 'getprop dalvik.vm.enableassertions',
1329             'all\r\n')]):
1330         self.assertFalse(self.device.SetJavaAsserts(True))
1331
1332
1333 class DeviceUtilsGetPropTest(DeviceUtilsOldImplTest):
1334
1335   def testGetProp_exists(self):
1336     with self.assertCalls(
1337         'adb -s 0123456789abcdef shell getprop this.is.a.test.property',
1338         'test_property_value\r\n'):
1339       self.assertEqual('test_property_value',
1340                        self.device.GetProp('this.is.a.test.property'))
1341
1342   def testGetProp_doesNotExist(self):
1343     with self.assertCalls(
1344         'adb -s 0123456789abcdef shell '
1345             'getprop this.property.does.not.exist', ''):
1346       self.assertEqual('', self.device.GetProp('this.property.does.not.exist'))
1347
1348   def testGetProp_cachedRoProp(self):
1349     with self.assertCalls(
1350         'adb -s 0123456789abcdef shell '
1351             'getprop ro.build.type', 'userdebug'):
1352       self.assertEqual('userdebug', self.device.GetProp('ro.build.type'))
1353       self.assertEqual('userdebug', self.device.GetProp('ro.build.type'))
1354
1355
1356 class DeviceUtilsSetPropTest(DeviceUtilsOldImplTest):
1357
1358   def testSetProp(self):
1359     with self.assertCalls(
1360         'adb -s 0123456789abcdef shell '
1361             'setprop this.is.a.test.property "test_property_value"',
1362         ''):
1363       self.device.SetProp('this.is.a.test.property', 'test_property_value')
1364
1365
1366 class DeviceUtilsGetPidsTest(DeviceUtilsOldImplTest):
1367
1368   def testGetPids_noMatches(self):
1369     with self.assertCalls(
1370         "adb -s 0123456789abcdef shell 'ps'",
1371         'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
1372         'user  1000    100   1024 1024   ffffffff 00000000 no.match\r\n'):
1373       self.assertEqual({}, self.device.GetPids('does.not.match'))
1374
1375   def testGetPids_oneMatch(self):
1376     with self.assertCalls(
1377         "adb -s 0123456789abcdef shell 'ps'",
1378         'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
1379         'user  1000    100   1024 1024   ffffffff 00000000 not.a.match\r\n'
1380         'user  1001    100   1024 1024   ffffffff 00000000 one.match\r\n'):
1381       self.assertEqual({'one.match': '1001'}, self.device.GetPids('one.match'))
1382
1383   def testGetPids_mutlipleMatches(self):
1384     with self.assertCalls(
1385         "adb -s 0123456789abcdef shell 'ps'",
1386         'USER   PID   PPID  VSIZE  RSS   WCHAN    PC       NAME\r\n'
1387         'user  1000    100   1024 1024   ffffffff 00000000 not\r\n'
1388         'user  1001    100   1024 1024   ffffffff 00000000 one.match\r\n'
1389         'user  1002    100   1024 1024   ffffffff 00000000 two.match\r\n'
1390         'user  1003    100   1024 1024   ffffffff 00000000 three.match\r\n'):
1391       self.assertEqual(
1392           {'one.match': '1001', 'two.match': '1002', 'three.match': '1003'},
1393           self.device.GetPids('match'))
1394
1395   def testGetPids_exactMatch(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 not.exact.match\r\n'
1400         'user  1234    100   1024 1024   ffffffff 00000000 exact.match\r\n'):
1401       self.assertEqual(
1402           {'not.exact.match': '1000', 'exact.match': '1234'},
1403           self.device.GetPids('exact.match'))
1404
1405
1406 class DeviceUtilsTakeScreenshotTest(DeviceUtilsOldImplTest):
1407
1408   def testTakeScreenshot_fileNameProvided(self):
1409     mock_fs = MockFileSystem()
1410     mock_fs.addMockDirectory('/test/host')
1411     mock_fs.addMockFile('/test/host/screenshot.png')
1412
1413     with mock_fs:
1414       with self.assertCallsSequence(
1415           cmd_ret=[
1416               (r"adb -s 0123456789abcdef shell 'echo \$EXTERNAL_STORAGE'",
1417                '/test/external/storage\r\n'),
1418               (r"adb -s 0123456789abcdef shell '/system/bin/screencap -p \S+'",
1419                ''),
1420               (r"adb -s 0123456789abcdef shell ls \S+",
1421                '/test/external/storage/screenshot.png\r\n'),
1422               (r'adb -s 0123456789abcdef pull \S+ /test/host/screenshot.png',
1423                '100 B/s (100 B in 1.000s)\r\n'),
1424               (r"adb -s 0123456789abcdef shell 'rm -f \S+'", '')
1425           ],
1426           comp=re.match):
1427         self.device.TakeScreenshot('/test/host/screenshot.png')
1428
1429
1430 class DeviceUtilsGetIOStatsTest(DeviceUtilsOldImplTest):
1431
1432   def testGetIOStats(self):
1433     with self.assertCalls(
1434         "adb -s 0123456789abcdef shell 'cat \"/proc/diskstats\" 2>/dev/null'",
1435         '179 0 mmcblk0 1 2 3 4 5 6 7 8 9 10 11\r\n'):
1436       self.assertEqual(
1437           {
1438             'num_reads': 1,
1439             'num_writes': 5,
1440             'read_ms': 4,
1441             'write_ms': 8,
1442           },
1443           self.device.GetIOStats())
1444
1445
1446 class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsOldImplTest):
1447
1448   def setUp(self):
1449     super(DeviceUtilsGetMemoryUsageForPidTest, self).setUp()
1450     self.device.old_interface._privileged_command_runner = (
1451         self.device.old_interface.RunShellCommand)
1452     self.device.old_interface._protected_file_access_method_initialized = True
1453
1454   def testGetMemoryUsageForPid_validPid(self):
1455     with self.assertCallsSequence([
1456         ("adb -s 0123456789abcdef shell 'showmap 1234'",
1457          '100 101 102 103 104 105 106 107 TOTAL\r\n'),
1458         ("adb -s 0123456789abcdef shell "
1459             "'cat \"/proc/1234/status\" 2> /dev/null'",
1460          'VmHWM: 1024 kB')
1461         ]):
1462       self.assertEqual(
1463           {
1464             'Size': 100,
1465             'Rss': 101,
1466             'Pss': 102,
1467             'Shared_Clean': 103,
1468             'Shared_Dirty': 104,
1469             'Private_Clean': 105,
1470             'Private_Dirty': 106,
1471             'VmHWM': 1024
1472           },
1473           self.device.GetMemoryUsageForPid(1234))
1474
1475   def testGetMemoryUsageForPid_invalidPid(self):
1476     with self.assertCalls(
1477         "adb -s 0123456789abcdef shell 'showmap 4321'",
1478         'cannot open /proc/4321/smaps: No such file or directory\r\n'):
1479       self.assertEqual({}, self.device.GetMemoryUsageForPid(4321))
1480
1481
1482 class DeviceUtilsStrTest(DeviceUtilsOldImplTest):
1483   def testStr_noAdbCalls(self):
1484     with self.assertNoAdbCalls():
1485       self.assertEqual('0123456789abcdef', str(self.device))
1486
1487   def testStr_noSerial(self):
1488     self.device = device_utils.DeviceUtils(None)
1489     with self.assertCalls('adb  get-serialno', '0123456789abcdef'):
1490       self.assertEqual('0123456789abcdef', str(self.device))
1491
1492   def testStr_noSerial_noDevices(self):
1493     self.device = device_utils.DeviceUtils(None)
1494     with self.assertCalls('adb  get-serialno', 'unknown'), (
1495          self.assertRaises(device_errors.NoDevicesError)):
1496       str(self.device)
1497
1498
1499 if __name__ == '__main__':
1500   logging.getLogger().setLevel(logging.DEBUG)
1501   unittest.main(verbosity=2)
1502