OLD | NEW |
| (Empty) |
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 sys | |
20 import unittest | |
21 | |
22 from pylib import android_commands | |
23 from pylib import cmd_helper | |
24 from pylib import constants | |
25 from pylib import device_signal | |
26 from pylib.device import adb_wrapper | |
27 from pylib.device import device_errors | |
28 from pylib.device import device_utils | |
29 from pylib.device import intent | |
30 from pylib.sdk import split_select | |
31 from pylib.utils import mock_calls | |
32 | |
33 # RunCommand from third_party/android_testrunner/run_command.py is mocked | |
34 # below, so its path needs to be in sys.path. | |
35 sys.path.append(os.path.join( | |
36 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner')) | |
37 | |
38 sys.path.append(os.path.join( | |
39 constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) | |
40 import mock # pylint: disable=F0401 | |
41 | |
42 | |
43 class DeviceUtilsInitTest(unittest.TestCase): | |
44 | |
45 def testInitWithStr(self): | |
46 serial_as_str = str('0123456789abcdef') | |
47 d = device_utils.DeviceUtils('0123456789abcdef') | |
48 self.assertEqual(serial_as_str, d.adb.GetDeviceSerial()) | |
49 | |
50 def testInitWithUnicode(self): | |
51 serial_as_unicode = unicode('fedcba9876543210') | |
52 d = device_utils.DeviceUtils(serial_as_unicode) | |
53 self.assertEqual(serial_as_unicode, d.adb.GetDeviceSerial()) | |
54 | |
55 def testInitWithAdbWrapper(self): | |
56 serial = '123456789abcdef0' | |
57 a = adb_wrapper.AdbWrapper(serial) | |
58 d = device_utils.DeviceUtils(a) | |
59 self.assertEqual(serial, d.adb.GetDeviceSerial()) | |
60 | |
61 def testInitWithAndroidCommands(self): | |
62 serial = '0fedcba987654321' | |
63 a = android_commands.AndroidCommands(device=serial) | |
64 d = device_utils.DeviceUtils(a) | |
65 self.assertEqual(serial, d.adb.GetDeviceSerial()) | |
66 | |
67 def testInitWithMissing_fails(self): | |
68 with self.assertRaises(ValueError): | |
69 device_utils.DeviceUtils(None) | |
70 with self.assertRaises(ValueError): | |
71 device_utils.DeviceUtils('') | |
72 | |
73 | |
74 class DeviceUtilsGetAVDsTest(mock_calls.TestCase): | |
75 | |
76 def testGetAVDs(self): | |
77 with self.assertCall( | |
78 mock.call.pylib.cmd_helper.GetCmdOutput([mock.ANY, 'list', 'avd']), | |
79 'Available Android Virtual Devices:\n' | |
80 ' Name: my_android5.0\n' | |
81 ' Path: /some/path/to/.android/avd/my_android5.0.avd\n' | |
82 ' Target: Android 5.0 (API level 21)\n' | |
83 ' Tag/ABI: default/x86\n' | |
84 ' Skin: WVGA800\n'): | |
85 self.assertEquals(['my_android5.0'], | |
86 device_utils.GetAVDs()) | |
87 | |
88 | |
89 class DeviceUtilsRestartServerTest(mock_calls.TestCase): | |
90 | |
91 @mock.patch('time.sleep', mock.Mock()) | |
92 def testRestartServer_succeeds(self): | |
93 with self.assertCalls( | |
94 mock.call.pylib.device.adb_wrapper.AdbWrapper.KillServer(), | |
95 (mock.call.pylib.cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb']), | |
96 (1, '')), | |
97 mock.call.pylib.device.adb_wrapper.AdbWrapper.StartServer(), | |
98 (mock.call.pylib.cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb']), | |
99 (1, '')), | |
100 (mock.call.pylib.cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb']), | |
101 (0, '123\n'))): | |
102 device_utils.RestartServer() | |
103 | |
104 | |
105 class MockTempFile(object): | |
106 | |
107 def __init__(self, name='/tmp/some/file'): | |
108 self.file = mock.MagicMock(spec=file) | |
109 self.file.name = name | |
110 self.file.name_quoted = cmd_helper.SingleQuote(name) | |
111 | |
112 def __enter__(self): | |
113 return self.file | |
114 | |
115 def __exit__(self, exc_type, exc_val, exc_tb): | |
116 pass | |
117 | |
118 @property | |
119 def name(self): | |
120 return self.file.name | |
121 | |
122 | |
123 class _PatchedFunction(object): | |
124 def __init__(self, patched=None, mocked=None): | |
125 self.patched = patched | |
126 self.mocked = mocked | |
127 | |
128 | |
129 def _AdbWrapperMock(test_serial): | |
130 adb = mock.Mock(spec=adb_wrapper.AdbWrapper) | |
131 adb.__str__ = mock.Mock(return_value=test_serial) | |
132 adb.GetDeviceSerial.return_value = test_serial | |
133 return adb | |
134 | |
135 | |
136 class DeviceUtilsTest(mock_calls.TestCase): | |
137 | |
138 def setUp(self): | |
139 self.adb = _AdbWrapperMock('0123456789abcdef') | |
140 self.device = device_utils.DeviceUtils( | |
141 self.adb, default_timeout=10, default_retries=0) | |
142 self.watchMethodCalls(self.call.adb, ignore=['GetDeviceSerial']) | |
143 | |
144 def AdbCommandError(self, args=None, output=None, status=None, msg=None): | |
145 if args is None: | |
146 args = ['[unspecified]'] | |
147 return mock.Mock(side_effect=device_errors.AdbCommandFailedError( | |
148 args, output, status, msg, str(self.device))) | |
149 | |
150 def CommandError(self, msg=None): | |
151 if msg is None: | |
152 msg = 'Command failed' | |
153 return mock.Mock(side_effect=device_errors.CommandFailedError( | |
154 msg, str(self.device))) | |
155 | |
156 def ShellError(self, output=None, status=1): | |
157 def action(cmd, *args, **kwargs): | |
158 raise device_errors.AdbShellCommandFailedError( | |
159 cmd, output, status, str(self.device)) | |
160 if output is None: | |
161 output = 'Permission denied\n' | |
162 return action | |
163 | |
164 def TimeoutError(self, msg=None): | |
165 if msg is None: | |
166 msg = 'Operation timed out' | |
167 return mock.Mock(side_effect=device_errors.CommandTimeoutError( | |
168 msg, str(self.device))) | |
169 | |
170 | |
171 class DeviceUtilsEqTest(DeviceUtilsTest): | |
172 | |
173 def testEq_equal_deviceUtils(self): | |
174 other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef')) | |
175 self.assertTrue(self.device == other) | |
176 self.assertTrue(other == self.device) | |
177 | |
178 def testEq_equal_adbWrapper(self): | |
179 other = adb_wrapper.AdbWrapper('0123456789abcdef') | |
180 self.assertTrue(self.device == other) | |
181 self.assertTrue(other == self.device) | |
182 | |
183 def testEq_equal_string(self): | |
184 other = '0123456789abcdef' | |
185 self.assertTrue(self.device == other) | |
186 self.assertTrue(other == self.device) | |
187 | |
188 def testEq_devicesNotEqual(self): | |
189 other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdee')) | |
190 self.assertFalse(self.device == other) | |
191 self.assertFalse(other == self.device) | |
192 | |
193 def testEq_identity(self): | |
194 self.assertTrue(self.device == self.device) | |
195 | |
196 def testEq_serialInList(self): | |
197 devices = [self.device] | |
198 self.assertTrue('0123456789abcdef' in devices) | |
199 | |
200 | |
201 class DeviceUtilsLtTest(DeviceUtilsTest): | |
202 | |
203 def testLt_lessThan(self): | |
204 other = device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff')) | |
205 self.assertTrue(self.device < other) | |
206 self.assertTrue(other > self.device) | |
207 | |
208 def testLt_greaterThan_lhs(self): | |
209 other = device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000')) | |
210 self.assertFalse(self.device < other) | |
211 self.assertFalse(other > self.device) | |
212 | |
213 def testLt_equal(self): | |
214 other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef')) | |
215 self.assertFalse(self.device < other) | |
216 self.assertFalse(other > self.device) | |
217 | |
218 def testLt_sorted(self): | |
219 devices = [ | |
220 device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff')), | |
221 device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000')), | |
222 ] | |
223 sorted_devices = sorted(devices) | |
224 self.assertEquals('0000000000000000', | |
225 sorted_devices[0].adb.GetDeviceSerial()) | |
226 self.assertEquals('ffffffffffffffff', | |
227 sorted_devices[1].adb.GetDeviceSerial()) | |
228 | |
229 | |
230 class DeviceUtilsStrTest(DeviceUtilsTest): | |
231 | |
232 def testStr_returnsSerial(self): | |
233 with self.assertCalls( | |
234 (self.call.adb.GetDeviceSerial(), '0123456789abcdef')): | |
235 self.assertEqual('0123456789abcdef', str(self.device)) | |
236 | |
237 | |
238 class DeviceUtilsIsOnlineTest(DeviceUtilsTest): | |
239 | |
240 def testIsOnline_true(self): | |
241 with self.assertCall(self.call.adb.GetState(), 'device'): | |
242 self.assertTrue(self.device.IsOnline()) | |
243 | |
244 def testIsOnline_false(self): | |
245 with self.assertCall(self.call.adb.GetState(), 'offline'): | |
246 self.assertFalse(self.device.IsOnline()) | |
247 | |
248 def testIsOnline_error(self): | |
249 with self.assertCall(self.call.adb.GetState(), self.CommandError()): | |
250 self.assertFalse(self.device.IsOnline()) | |
251 | |
252 | |
253 class DeviceUtilsHasRootTest(DeviceUtilsTest): | |
254 | |
255 def testHasRoot_true(self): | |
256 with self.assertCall(self.call.adb.Shell('ls /root'), 'foo\n'): | |
257 self.assertTrue(self.device.HasRoot()) | |
258 | |
259 def testHasRoot_false(self): | |
260 with self.assertCall(self.call.adb.Shell('ls /root'), self.ShellError()): | |
261 self.assertFalse(self.device.HasRoot()) | |
262 | |
263 | |
264 class DeviceUtilsEnableRootTest(DeviceUtilsTest): | |
265 | |
266 def testEnableRoot_succeeds(self): | |
267 with self.assertCalls( | |
268 (self.call.device.IsUserBuild(), False), | |
269 self.call.adb.Root(), | |
270 self.call.device.WaitUntilFullyBooted()): | |
271 self.device.EnableRoot() | |
272 | |
273 def testEnableRoot_userBuild(self): | |
274 with self.assertCalls( | |
275 (self.call.device.IsUserBuild(), True)): | |
276 with self.assertRaises(device_errors.CommandFailedError): | |
277 self.device.EnableRoot() | |
278 | |
279 def testEnableRoot_rootFails(self): | |
280 with self.assertCalls( | |
281 (self.call.device.IsUserBuild(), False), | |
282 (self.call.adb.Root(), self.CommandError())): | |
283 with self.assertRaises(device_errors.CommandFailedError): | |
284 self.device.EnableRoot() | |
285 | |
286 | |
287 class DeviceUtilsIsUserBuildTest(DeviceUtilsTest): | |
288 | |
289 def testIsUserBuild_yes(self): | |
290 with self.assertCall( | |
291 self.call.device.GetProp('ro.build.type', cache=True), 'user'): | |
292 self.assertTrue(self.device.IsUserBuild()) | |
293 | |
294 def testIsUserBuild_no(self): | |
295 with self.assertCall( | |
296 self.call.device.GetProp('ro.build.type', cache=True), 'userdebug'): | |
297 self.assertFalse(self.device.IsUserBuild()) | |
298 | |
299 | |
300 class DeviceUtilsGetExternalStoragePathTest(DeviceUtilsTest): | |
301 | |
302 def testGetExternalStoragePath_succeeds(self): | |
303 with self.assertCall( | |
304 self.call.adb.Shell('echo $EXTERNAL_STORAGE'), '/fake/storage/path\n'): | |
305 self.assertEquals('/fake/storage/path', | |
306 self.device.GetExternalStoragePath()) | |
307 | |
308 def testGetExternalStoragePath_fails(self): | |
309 with self.assertCall(self.call.adb.Shell('echo $EXTERNAL_STORAGE'), '\n'): | |
310 with self.assertRaises(device_errors.CommandFailedError): | |
311 self.device.GetExternalStoragePath() | |
312 | |
313 | |
314 class DeviceUtilsGetApplicationPathsTest(DeviceUtilsTest): | |
315 | |
316 def testGetApplicationPaths_exists(self): | |
317 with self.assertCalls( | |
318 (self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'), | |
319 (self.call.adb.Shell('pm path android'), | |
320 'package:/path/to/android.apk\n')): | |
321 self.assertEquals(['/path/to/android.apk'], | |
322 self.device.GetApplicationPaths('android')) | |
323 | |
324 def testGetApplicationPaths_notExists(self): | |
325 with self.assertCalls( | |
326 (self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'), | |
327 (self.call.adb.Shell('pm path not.installed.app'), '')): | |
328 self.assertEquals([], | |
329 self.device.GetApplicationPaths('not.installed.app')) | |
330 | |
331 def testGetApplicationPaths_fails(self): | |
332 with self.assertCalls( | |
333 (self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'), | |
334 (self.call.adb.Shell('pm path android'), | |
335 self.CommandError('ERROR. Is package manager running?\n'))): | |
336 with self.assertRaises(device_errors.CommandFailedError): | |
337 self.device.GetApplicationPaths('android') | |
338 | |
339 | |
340 class DeviceUtilsGetApplicationDataDirectoryTest(DeviceUtilsTest): | |
341 | |
342 def testGetApplicationDataDirectory_exists(self): | |
343 with self.assertCall( | |
344 self.call.device._RunPipedShellCommand( | |
345 'pm dump foo.bar.baz | grep dataDir='), | |
346 ['dataDir=/data/data/foo.bar.baz']): | |
347 self.assertEquals( | |
348 '/data/data/foo.bar.baz', | |
349 self.device.GetApplicationDataDirectory('foo.bar.baz')) | |
350 | |
351 def testGetApplicationDataDirectory_notExists(self): | |
352 with self.assertCall( | |
353 self.call.device._RunPipedShellCommand( | |
354 'pm dump foo.bar.baz | grep dataDir='), | |
355 self.ShellError()): | |
356 self.assertIsNone(self.device.GetApplicationDataDirectory('foo.bar.baz')) | |
357 | |
358 | |
359 @mock.patch('time.sleep', mock.Mock()) | |
360 class DeviceUtilsWaitUntilFullyBootedTest(DeviceUtilsTest): | |
361 | |
362 def testWaitUntilFullyBooted_succeedsNoWifi(self): | |
363 with self.assertCalls( | |
364 self.call.adb.WaitForDevice(), | |
365 # sd_card_ready | |
366 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), | |
367 (self.call.adb.Shell('test -d /fake/storage/path'), ''), | |
368 # pm_ready | |
369 (self.call.device.GetApplicationPaths('android'), | |
370 ['package:/some/fake/path']), | |
371 # boot_completed | |
372 (self.call.device.GetProp('sys.boot_completed'), '1')): | |
373 self.device.WaitUntilFullyBooted(wifi=False) | |
374 | |
375 def testWaitUntilFullyBooted_succeedsWithWifi(self): | |
376 with self.assertCalls( | |
377 self.call.adb.WaitForDevice(), | |
378 # sd_card_ready | |
379 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), | |
380 (self.call.adb.Shell('test -d /fake/storage/path'), ''), | |
381 # pm_ready | |
382 (self.call.device.GetApplicationPaths('android'), | |
383 ['package:/some/fake/path']), | |
384 # boot_completed | |
385 (self.call.device.GetProp('sys.boot_completed'), '1'), | |
386 # wifi_enabled | |
387 (self.call.adb.Shell('dumpsys wifi'), | |
388 'stuff\nWi-Fi is enabled\nmore stuff\n')): | |
389 self.device.WaitUntilFullyBooted(wifi=True) | |
390 | |
391 def testWaitUntilFullyBooted_deviceNotInitiallyAvailable(self): | |
392 with self.assertCalls( | |
393 self.call.adb.WaitForDevice(), | |
394 # sd_card_ready | |
395 (self.call.device.GetExternalStoragePath(), self.AdbCommandError()), | |
396 # sd_card_ready | |
397 (self.call.device.GetExternalStoragePath(), self.AdbCommandError()), | |
398 # sd_card_ready | |
399 (self.call.device.GetExternalStoragePath(), self.AdbCommandError()), | |
400 # sd_card_ready | |
401 (self.call.device.GetExternalStoragePath(), self.AdbCommandError()), | |
402 # sd_card_ready | |
403 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), | |
404 (self.call.adb.Shell('test -d /fake/storage/path'), ''), | |
405 # pm_ready | |
406 (self.call.device.GetApplicationPaths('android'), | |
407 ['package:/some/fake/path']), | |
408 # boot_completed | |
409 (self.call.device.GetProp('sys.boot_completed'), '1')): | |
410 self.device.WaitUntilFullyBooted(wifi=False) | |
411 | |
412 def testWaitUntilFullyBooted_sdCardReadyFails_noPath(self): | |
413 with self.assertCalls( | |
414 self.call.adb.WaitForDevice(), | |
415 # sd_card_ready | |
416 (self.call.device.GetExternalStoragePath(), self.CommandError())): | |
417 with self.assertRaises(device_errors.CommandFailedError): | |
418 self.device.WaitUntilFullyBooted(wifi=False) | |
419 | |
420 def testWaitUntilFullyBooted_sdCardReadyFails_notExists(self): | |
421 with self.assertCalls( | |
422 self.call.adb.WaitForDevice(), | |
423 # sd_card_ready | |
424 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), | |
425 (self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()), | |
426 # sd_card_ready | |
427 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), | |
428 (self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()), | |
429 # sd_card_ready | |
430 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), | |
431 (self.call.adb.Shell('test -d /fake/storage/path'), | |
432 self.TimeoutError())): | |
433 with self.assertRaises(device_errors.CommandTimeoutError): | |
434 self.device.WaitUntilFullyBooted(wifi=False) | |
435 | |
436 def testWaitUntilFullyBooted_devicePmFails(self): | |
437 with self.assertCalls( | |
438 self.call.adb.WaitForDevice(), | |
439 # sd_card_ready | |
440 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), | |
441 (self.call.adb.Shell('test -d /fake/storage/path'), ''), | |
442 # pm_ready | |
443 (self.call.device.GetApplicationPaths('android'), self.CommandError()), | |
444 # pm_ready | |
445 (self.call.device.GetApplicationPaths('android'), self.CommandError()), | |
446 # pm_ready | |
447 (self.call.device.GetApplicationPaths('android'), self.TimeoutError())): | |
448 with self.assertRaises(device_errors.CommandTimeoutError): | |
449 self.device.WaitUntilFullyBooted(wifi=False) | |
450 | |
451 def testWaitUntilFullyBooted_bootFails(self): | |
452 with self.assertCalls( | |
453 self.call.adb.WaitForDevice(), | |
454 # sd_card_ready | |
455 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), | |
456 (self.call.adb.Shell('test -d /fake/storage/path'), ''), | |
457 # pm_ready | |
458 (self.call.device.GetApplicationPaths('android'), | |
459 ['package:/some/fake/path']), | |
460 # boot_completed | |
461 (self.call.device.GetProp('sys.boot_completed'), '0'), | |
462 # boot_completed | |
463 (self.call.device.GetProp('sys.boot_completed'), '0'), | |
464 # boot_completed | |
465 (self.call.device.GetProp('sys.boot_completed'), self.TimeoutError())): | |
466 with self.assertRaises(device_errors.CommandTimeoutError): | |
467 self.device.WaitUntilFullyBooted(wifi=False) | |
468 | |
469 def testWaitUntilFullyBooted_wifiFails(self): | |
470 with self.assertCalls( | |
471 self.call.adb.WaitForDevice(), | |
472 # sd_card_ready | |
473 (self.call.device.GetExternalStoragePath(), '/fake/storage/path'), | |
474 (self.call.adb.Shell('test -d /fake/storage/path'), ''), | |
475 # pm_ready | |
476 (self.call.device.GetApplicationPaths('android'), | |
477 ['package:/some/fake/path']), | |
478 # boot_completed | |
479 (self.call.device.GetProp('sys.boot_completed'), '1'), | |
480 # wifi_enabled | |
481 (self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'), | |
482 # wifi_enabled | |
483 (self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'), | |
484 # wifi_enabled | |
485 (self.call.adb.Shell('dumpsys wifi'), self.TimeoutError())): | |
486 with self.assertRaises(device_errors.CommandTimeoutError): | |
487 self.device.WaitUntilFullyBooted(wifi=True) | |
488 | |
489 | |
490 @mock.patch('time.sleep', mock.Mock()) | |
491 class DeviceUtilsRebootTest(DeviceUtilsTest): | |
492 | |
493 def testReboot_nonBlocking(self): | |
494 with self.assertCalls( | |
495 self.call.adb.Reboot(), | |
496 (self.call.device.IsOnline(), True), | |
497 (self.call.device.IsOnline(), False)): | |
498 self.device.Reboot(block=False) | |
499 | |
500 def testReboot_blocking(self): | |
501 with self.assertCalls( | |
502 self.call.adb.Reboot(), | |
503 (self.call.device.IsOnline(), True), | |
504 (self.call.device.IsOnline(), False), | |
505 self.call.device.WaitUntilFullyBooted(wifi=False)): | |
506 self.device.Reboot(block=True) | |
507 | |
508 def testReboot_blockUntilWifi(self): | |
509 with self.assertCalls( | |
510 self.call.adb.Reboot(), | |
511 (self.call.device.IsOnline(), True), | |
512 (self.call.device.IsOnline(), False), | |
513 self.call.device.WaitUntilFullyBooted(wifi=True)): | |
514 self.device.Reboot(block=True, wifi=True) | |
515 | |
516 | |
517 class DeviceUtilsInstallTest(DeviceUtilsTest): | |
518 | |
519 def testInstall_noPriorInstall(self): | |
520 with self.assertCalls( | |
521 (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'), | |
522 'this.is.a.test.package'), | |
523 (self.call.device.GetApplicationPaths('this.is.a.test.package'), []), | |
524 self.call.adb.Install('/fake/test/app.apk', reinstall=False)): | |
525 self.device.Install('/fake/test/app.apk', retries=0) | |
526 | |
527 def testInstall_differentPriorInstall(self): | |
528 with self.assertCalls( | |
529 (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'), | |
530 'this.is.a.test.package'), | |
531 (self.call.device.GetApplicationPaths('this.is.a.test.package'), | |
532 ['/fake/data/app/this.is.a.test.package.apk']), | |
533 (self.call.device._GetChangedAndStaleFiles( | |
534 '/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk'), | |
535 ([('/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk')], | |
536 [])), | |
537 self.call.adb.Uninstall('this.is.a.test.package'), | |
538 self.call.adb.Install('/fake/test/app.apk', reinstall=False)): | |
539 self.device.Install('/fake/test/app.apk', retries=0) | |
540 | |
541 def testInstall_differentPriorInstall_reinstall(self): | |
542 with self.assertCalls( | |
543 (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'), | |
544 'this.is.a.test.package'), | |
545 (self.call.device.GetApplicationPaths('this.is.a.test.package'), | |
546 ['/fake/data/app/this.is.a.test.package.apk']), | |
547 (self.call.device._GetChangedAndStaleFiles( | |
548 '/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk'), | |
549 ([('/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk')], | |
550 [])), | |
551 self.call.adb.Install('/fake/test/app.apk', reinstall=True)): | |
552 self.device.Install('/fake/test/app.apk', reinstall=True, retries=0) | |
553 | |
554 def testInstall_identicalPriorInstall(self): | |
555 with self.assertCalls( | |
556 (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'), | |
557 'this.is.a.test.package'), | |
558 (self.call.device.GetApplicationPaths('this.is.a.test.package'), | |
559 ['/fake/data/app/this.is.a.test.package.apk']), | |
560 (self.call.device._GetChangedAndStaleFiles( | |
561 '/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk'), | |
562 ([], []))): | |
563 self.device.Install('/fake/test/app.apk', retries=0) | |
564 | |
565 def testInstall_fails(self): | |
566 with self.assertCalls( | |
567 (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'), | |
568 'this.is.a.test.package'), | |
569 (self.call.device.GetApplicationPaths('this.is.a.test.package'), []), | |
570 (self.call.adb.Install('/fake/test/app.apk', reinstall=False), | |
571 self.CommandError('Failure\r\n'))): | |
572 with self.assertRaises(device_errors.CommandFailedError): | |
573 self.device.Install('/fake/test/app.apk', retries=0) | |
574 | |
575 class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest): | |
576 | |
577 def testInstallSplitApk_noPriorInstall(self): | |
578 with self.assertCalls( | |
579 (self.call.device._CheckSdkLevel(21)), | |
580 (mock.call.pylib.sdk.split_select.SelectSplits( | |
581 self.device, 'base.apk', | |
582 ['split1.apk', 'split2.apk', 'split3.apk']), | |
583 ['split2.apk']), | |
584 (mock.call.pylib.utils.apk_helper.GetPackageName('base.apk'), | |
585 'this.is.a.test.package'), | |
586 (self.call.device.GetApplicationPaths('this.is.a.test.package'), []), | |
587 (self.call.adb.InstallMultiple( | |
588 ['base.apk', 'split2.apk'], partial=None, reinstall=False))): | |
589 self.device.InstallSplitApk('base.apk', | |
590 ['split1.apk', 'split2.apk', 'split3.apk'], retries=0) | |
591 | |
592 def testInstallSplitApk_partialInstall(self): | |
593 with self.assertCalls( | |
594 (self.call.device._CheckSdkLevel(21)), | |
595 (mock.call.pylib.sdk.split_select.SelectSplits( | |
596 self.device, 'base.apk', | |
597 ['split1.apk', 'split2.apk', 'split3.apk']), | |
598 ['split2.apk']), | |
599 (mock.call.pylib.utils.apk_helper.GetPackageName('base.apk'), | |
600 'test.package'), | |
601 (self.call.device.GetApplicationPaths('test.package'), | |
602 ['base-on-device.apk', 'split2-on-device.apk']), | |
603 (mock.call.pylib.utils.md5sum.CalculateDeviceMd5Sums( | |
604 ['base-on-device.apk', 'split2-on-device.apk'], self.device), | |
605 {'base-on-device.apk': 'AAA', 'split2-on-device.apk': 'BBB'}), | |
606 (mock.call.pylib.utils.md5sum.CalculateHostMd5Sums( | |
607 ['base.apk', 'split2.apk']), | |
608 {'base.apk': 'AAA', 'split2.apk': 'CCC'}), | |
609 (self.call.adb.InstallMultiple( | |
610 ['split2.apk'], partial='test.package', reinstall=True))): | |
611 self.device.InstallSplitApk('base.apk', | |
612 ['split1.apk', 'split2.apk', 'split3.apk'], reinstall=True, retries=0) | |
613 | |
614 | |
615 class DeviceUtilsRunShellCommandTest(DeviceUtilsTest): | |
616 | |
617 def setUp(self): | |
618 super(DeviceUtilsRunShellCommandTest, self).setUp() | |
619 self.device.NeedsSU = mock.Mock(return_value=False) | |
620 | |
621 def testRunShellCommand_commandAsList(self): | |
622 with self.assertCall(self.call.adb.Shell('pm list packages'), ''): | |
623 self.device.RunShellCommand(['pm', 'list', 'packages']) | |
624 | |
625 def testRunShellCommand_commandAsListQuoted(self): | |
626 with self.assertCall(self.call.adb.Shell("echo 'hello world' '$10'"), ''): | |
627 self.device.RunShellCommand(['echo', 'hello world', '$10']) | |
628 | |
629 def testRunShellCommand_commandAsString(self): | |
630 with self.assertCall(self.call.adb.Shell('echo "$VAR"'), ''): | |
631 self.device.RunShellCommand('echo "$VAR"') | |
632 | |
633 def testNewRunShellImpl_withEnv(self): | |
634 with self.assertCall( | |
635 self.call.adb.Shell('VAR=some_string echo "$VAR"'), ''): | |
636 self.device.RunShellCommand('echo "$VAR"', env={'VAR': 'some_string'}) | |
637 | |
638 def testNewRunShellImpl_withEnvQuoted(self): | |
639 with self.assertCall( | |
640 self.call.adb.Shell('PATH="$PATH:/other/path" run_this'), ''): | |
641 self.device.RunShellCommand('run_this', env={'PATH': '$PATH:/other/path'}) | |
642 | |
643 def testNewRunShellImpl_withEnv_failure(self): | |
644 with self.assertRaises(KeyError): | |
645 self.device.RunShellCommand('some_cmd', env={'INVALID NAME': 'value'}) | |
646 | |
647 def testNewRunShellImpl_withCwd(self): | |
648 with self.assertCall(self.call.adb.Shell('cd /some/test/path && ls'), ''): | |
649 self.device.RunShellCommand('ls', cwd='/some/test/path') | |
650 | |
651 def testNewRunShellImpl_withCwdQuoted(self): | |
652 with self.assertCall( | |
653 self.call.adb.Shell("cd '/some test/path with/spaces' && ls"), ''): | |
654 self.device.RunShellCommand('ls', cwd='/some test/path with/spaces') | |
655 | |
656 def testRunShellCommand_withHugeCmd(self): | |
657 payload = 'hi! ' * 1024 | |
658 expected_cmd = "echo '%s'" % payload | |
659 with self.assertCalls( | |
660 (mock.call.pylib.utils.device_temp_file.DeviceTempFile( | |
661 self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')), | |
662 self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd), | |
663 (self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')): | |
664 self.assertEquals([payload], | |
665 self.device.RunShellCommand(['echo', payload])) | |
666 | |
667 def testRunShellCommand_withHugeCmdAmdSU(self): | |
668 payload = 'hi! ' * 1024 | |
669 expected_cmd = """su -c sh -c 'echo '"'"'%s'"'"''""" % payload | |
670 with self.assertCalls( | |
671 (self.call.device.NeedsSU(), True), | |
672 (mock.call.pylib.utils.device_temp_file.DeviceTempFile( | |
673 self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')), | |
674 self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd), | |
675 (self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')): | |
676 self.assertEquals( | |
677 [payload], | |
678 self.device.RunShellCommand(['echo', payload], as_root=True)) | |
679 | |
680 def testRunShellCommand_withSu(self): | |
681 with self.assertCalls( | |
682 (self.call.device.NeedsSU(), True), | |
683 (self.call.adb.Shell("su -c sh -c 'setprop service.adb.root 0'"), '')): | |
684 self.device.RunShellCommand('setprop service.adb.root 0', as_root=True) | |
685 | |
686 def testRunShellCommand_manyLines(self): | |
687 cmd = 'ls /some/path' | |
688 with self.assertCall(self.call.adb.Shell(cmd), 'file1\nfile2\nfile3\n'): | |
689 self.assertEquals(['file1', 'file2', 'file3'], | |
690 self.device.RunShellCommand(cmd)) | |
691 | |
692 def testRunShellCommand_singleLine_success(self): | |
693 cmd = 'echo $VALUE' | |
694 with self.assertCall(self.call.adb.Shell(cmd), 'some value\n'): | |
695 self.assertEquals('some value', | |
696 self.device.RunShellCommand(cmd, single_line=True)) | |
697 | |
698 def testRunShellCommand_singleLine_successEmptyLine(self): | |
699 cmd = 'echo $VALUE' | |
700 with self.assertCall(self.call.adb.Shell(cmd), '\n'): | |
701 self.assertEquals('', | |
702 self.device.RunShellCommand(cmd, single_line=True)) | |
703 | |
704 def testRunShellCommand_singleLine_successWithoutEndLine(self): | |
705 cmd = 'echo -n $VALUE' | |
706 with self.assertCall(self.call.adb.Shell(cmd), 'some value'): | |
707 self.assertEquals('some value', | |
708 self.device.RunShellCommand(cmd, single_line=True)) | |
709 | |
710 def testRunShellCommand_singleLine_successNoOutput(self): | |
711 cmd = 'echo -n $VALUE' | |
712 with self.assertCall(self.call.adb.Shell(cmd), ''): | |
713 self.assertEquals('', | |
714 self.device.RunShellCommand(cmd, single_line=True)) | |
715 | |
716 def testRunShellCommand_singleLine_failTooManyLines(self): | |
717 cmd = 'echo $VALUE' | |
718 with self.assertCall(self.call.adb.Shell(cmd), | |
719 'some value\nanother value\n'): | |
720 with self.assertRaises(device_errors.CommandFailedError): | |
721 self.device.RunShellCommand(cmd, single_line=True) | |
722 | |
723 def testRunShellCommand_checkReturn_success(self): | |
724 cmd = 'echo $ANDROID_DATA' | |
725 output = '/data\n' | |
726 with self.assertCall(self.call.adb.Shell(cmd), output): | |
727 self.assertEquals([output.rstrip()], | |
728 self.device.RunShellCommand(cmd, check_return=True)) | |
729 | |
730 def testRunShellCommand_checkReturn_failure(self): | |
731 cmd = 'ls /root' | |
732 output = 'opendir failed, Permission denied\n' | |
733 with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)): | |
734 with self.assertRaises(device_errors.AdbCommandFailedError): | |
735 self.device.RunShellCommand(cmd, check_return=True) | |
736 | |
737 def testRunShellCommand_checkReturn_disabled(self): | |
738 cmd = 'ls /root' | |
739 output = 'opendir failed, Permission denied\n' | |
740 with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)): | |
741 self.assertEquals([output.rstrip()], | |
742 self.device.RunShellCommand(cmd, check_return=False)) | |
743 | |
744 def testRunShellCommand_largeOutput_enabled(self): | |
745 cmd = 'echo $VALUE' | |
746 temp_file = MockTempFile('/sdcard/temp-123') | |
747 cmd_redirect = '%s > %s' % (cmd, temp_file.name) | |
748 with self.assertCalls( | |
749 (mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb), | |
750 temp_file), | |
751 (self.call.adb.Shell(cmd_redirect)), | |
752 (self.call.device.ReadFile(temp_file.name, force_pull=True), | |
753 'something')): | |
754 self.assertEquals( | |
755 ['something'], | |
756 self.device.RunShellCommand( | |
757 cmd, large_output=True, check_return=True)) | |
758 | |
759 def testRunShellCommand_largeOutput_disabledNoTrigger(self): | |
760 cmd = 'something' | |
761 with self.assertCall(self.call.adb.Shell(cmd), self.ShellError('')): | |
762 with self.assertRaises(device_errors.AdbCommandFailedError): | |
763 self.device.RunShellCommand(cmd, check_return=True) | |
764 | |
765 def testRunShellCommand_largeOutput_disabledTrigger(self): | |
766 cmd = 'echo $VALUE' | |
767 temp_file = MockTempFile('/sdcard/temp-123') | |
768 cmd_redirect = '%s > %s' % (cmd, temp_file.name) | |
769 with self.assertCalls( | |
770 (self.call.adb.Shell(cmd), self.ShellError('', None)), | |
771 (mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb), | |
772 temp_file), | |
773 (self.call.adb.Shell(cmd_redirect)), | |
774 (self.call.device.ReadFile(mock.ANY, force_pull=True), | |
775 'something')): | |
776 self.assertEquals(['something'], | |
777 self.device.RunShellCommand(cmd, check_return=True)) | |
778 | |
779 | |
780 class DeviceUtilsRunPipedShellCommandTest(DeviceUtilsTest): | |
781 | |
782 def testRunPipedShellCommand_success(self): | |
783 with self.assertCall( | |
784 self.call.device.RunShellCommand( | |
785 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"', | |
786 check_return=True), | |
787 ['This line contains foo', 'PIPESTATUS: 0 0']): | |
788 self.assertEquals(['This line contains foo'], | |
789 self.device._RunPipedShellCommand('ps | grep foo')) | |
790 | |
791 def testRunPipedShellCommand_firstCommandFails(self): | |
792 with self.assertCall( | |
793 self.call.device.RunShellCommand( | |
794 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"', | |
795 check_return=True), | |
796 ['PIPESTATUS: 1 0']): | |
797 with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec: | |
798 self.device._RunPipedShellCommand('ps | grep foo') | |
799 self.assertEquals([1, 0], ec.exception.status) | |
800 | |
801 def testRunPipedShellCommand_secondCommandFails(self): | |
802 with self.assertCall( | |
803 self.call.device.RunShellCommand( | |
804 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"', | |
805 check_return=True), | |
806 ['PIPESTATUS: 0 1']): | |
807 with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec: | |
808 self.device._RunPipedShellCommand('ps | grep foo') | |
809 self.assertEquals([0, 1], ec.exception.status) | |
810 | |
811 def testRunPipedShellCommand_outputCutOff(self): | |
812 with self.assertCall( | |
813 self.call.device.RunShellCommand( | |
814 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"', | |
815 check_return=True), | |
816 ['foo.bar'] * 256 + ['foo.ba']): | |
817 with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec: | |
818 self.device._RunPipedShellCommand('ps | grep foo') | |
819 self.assertIs(None, ec.exception.status) | |
820 | |
821 | |
822 @mock.patch('time.sleep', mock.Mock()) | |
823 class DeviceUtilsKillAllTest(DeviceUtilsTest): | |
824 | |
825 def testKillAll_noMatchingProcessesFailure(self): | |
826 with self.assertCall(self.call.device.GetPids('test_process'), {}): | |
827 with self.assertRaises(device_errors.CommandFailedError): | |
828 self.device.KillAll('test_process') | |
829 | |
830 def testKillAll_noMatchingProcessesQuiet(self): | |
831 with self.assertCall(self.call.device.GetPids('test_process'), {}): | |
832 self.assertEqual(0, self.device.KillAll('test_process', quiet=True)) | |
833 | |
834 def testKillAll_nonblocking(self): | |
835 with self.assertCalls( | |
836 (self.call.device.GetPids('some.process'), {'some.process': '1234'}), | |
837 (self.call.adb.Shell('kill -9 1234'), '')): | |
838 self.assertEquals( | |
839 1, self.device.KillAll('some.process', blocking=False)) | |
840 | |
841 def testKillAll_blocking(self): | |
842 with self.assertCalls( | |
843 (self.call.device.GetPids('some.process'), {'some.process': '1234'}), | |
844 (self.call.adb.Shell('kill -9 1234'), ''), | |
845 (self.call.device.GetPids('some.process'), {'some.process': '1234'}), | |
846 (self.call.device.GetPids('some.process'), [])): | |
847 self.assertEquals( | |
848 1, self.device.KillAll('some.process', blocking=True)) | |
849 | |
850 def testKillAll_root(self): | |
851 with self.assertCalls( | |
852 (self.call.device.GetPids('some.process'), {'some.process': '1234'}), | |
853 (self.call.device.NeedsSU(), True), | |
854 (self.call.adb.Shell("su -c sh -c 'kill -9 1234'"), '')): | |
855 self.assertEquals( | |
856 1, self.device.KillAll('some.process', as_root=True)) | |
857 | |
858 def testKillAll_sigterm(self): | |
859 with self.assertCalls( | |
860 (self.call.device.GetPids('some.process'), {'some.process': '1234'}), | |
861 (self.call.adb.Shell('kill -15 1234'), '')): | |
862 self.assertEquals( | |
863 1, self.device.KillAll('some.process', signum=device_signal.SIGTERM)) | |
864 | |
865 | |
866 class DeviceUtilsStartActivityTest(DeviceUtilsTest): | |
867 | |
868 def testStartActivity_actionOnly(self): | |
869 test_intent = intent.Intent(action='android.intent.action.VIEW') | |
870 with self.assertCall( | |
871 self.call.adb.Shell('am start ' | |
872 '-a android.intent.action.VIEW'), | |
873 'Starting: Intent { act=android.intent.action.VIEW }'): | |
874 self.device.StartActivity(test_intent) | |
875 | |
876 def testStartActivity_success(self): | |
877 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
878 package='this.is.a.test.package', | |
879 activity='.Main') | |
880 with self.assertCall( | |
881 self.call.adb.Shell('am start ' | |
882 '-a android.intent.action.VIEW ' | |
883 '-n this.is.a.test.package/.Main'), | |
884 'Starting: Intent { act=android.intent.action.VIEW }'): | |
885 self.device.StartActivity(test_intent) | |
886 | |
887 def testStartActivity_failure(self): | |
888 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
889 package='this.is.a.test.package', | |
890 activity='.Main') | |
891 with self.assertCall( | |
892 self.call.adb.Shell('am start ' | |
893 '-a android.intent.action.VIEW ' | |
894 '-n this.is.a.test.package/.Main'), | |
895 'Error: Failed to start test activity'): | |
896 with self.assertRaises(device_errors.CommandFailedError): | |
897 self.device.StartActivity(test_intent) | |
898 | |
899 def testStartActivity_blocking(self): | |
900 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
901 package='this.is.a.test.package', | |
902 activity='.Main') | |
903 with self.assertCall( | |
904 self.call.adb.Shell('am start ' | |
905 '-W ' | |
906 '-a android.intent.action.VIEW ' | |
907 '-n this.is.a.test.package/.Main'), | |
908 'Starting: Intent { act=android.intent.action.VIEW }'): | |
909 self.device.StartActivity(test_intent, blocking=True) | |
910 | |
911 def testStartActivity_withCategory(self): | |
912 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
913 package='this.is.a.test.package', | |
914 activity='.Main', | |
915 category='android.intent.category.HOME') | |
916 with self.assertCall( | |
917 self.call.adb.Shell('am start ' | |
918 '-a android.intent.action.VIEW ' | |
919 '-c android.intent.category.HOME ' | |
920 '-n this.is.a.test.package/.Main'), | |
921 'Starting: Intent { act=android.intent.action.VIEW }'): | |
922 self.device.StartActivity(test_intent) | |
923 | |
924 def testStartActivity_withMultipleCategories(self): | |
925 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
926 package='this.is.a.test.package', | |
927 activity='.Main', | |
928 category=['android.intent.category.HOME', | |
929 'android.intent.category.BROWSABLE']) | |
930 with self.assertCall( | |
931 self.call.adb.Shell('am start ' | |
932 '-a android.intent.action.VIEW ' | |
933 '-c android.intent.category.HOME ' | |
934 '-c android.intent.category.BROWSABLE ' | |
935 '-n this.is.a.test.package/.Main'), | |
936 'Starting: Intent { act=android.intent.action.VIEW }'): | |
937 self.device.StartActivity(test_intent) | |
938 | |
939 def testStartActivity_withData(self): | |
940 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
941 package='this.is.a.test.package', | |
942 activity='.Main', | |
943 data='http://www.google.com/') | |
944 with self.assertCall( | |
945 self.call.adb.Shell('am start ' | |
946 '-a android.intent.action.VIEW ' | |
947 '-d http://www.google.com/ ' | |
948 '-n this.is.a.test.package/.Main'), | |
949 'Starting: Intent { act=android.intent.action.VIEW }'): | |
950 self.device.StartActivity(test_intent) | |
951 | |
952 def testStartActivity_withStringExtra(self): | |
953 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
954 package='this.is.a.test.package', | |
955 activity='.Main', | |
956 extras={'foo': 'test'}) | |
957 with self.assertCall( | |
958 self.call.adb.Shell('am start ' | |
959 '-a android.intent.action.VIEW ' | |
960 '-n this.is.a.test.package/.Main ' | |
961 '--es foo test'), | |
962 'Starting: Intent { act=android.intent.action.VIEW }'): | |
963 self.device.StartActivity(test_intent) | |
964 | |
965 def testStartActivity_withBoolExtra(self): | |
966 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
967 package='this.is.a.test.package', | |
968 activity='.Main', | |
969 extras={'foo': True}) | |
970 with self.assertCall( | |
971 self.call.adb.Shell('am start ' | |
972 '-a android.intent.action.VIEW ' | |
973 '-n this.is.a.test.package/.Main ' | |
974 '--ez foo True'), | |
975 'Starting: Intent { act=android.intent.action.VIEW }'): | |
976 self.device.StartActivity(test_intent) | |
977 | |
978 def testStartActivity_withIntExtra(self): | |
979 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
980 package='this.is.a.test.package', | |
981 activity='.Main', | |
982 extras={'foo': 123}) | |
983 with self.assertCall( | |
984 self.call.adb.Shell('am start ' | |
985 '-a android.intent.action.VIEW ' | |
986 '-n this.is.a.test.package/.Main ' | |
987 '--ei foo 123'), | |
988 'Starting: Intent { act=android.intent.action.VIEW }'): | |
989 self.device.StartActivity(test_intent) | |
990 | |
991 def testStartActivity_withTraceFile(self): | |
992 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
993 package='this.is.a.test.package', | |
994 activity='.Main') | |
995 with self.assertCall( | |
996 self.call.adb.Shell('am start ' | |
997 '--start-profiler test_trace_file.out ' | |
998 '-a android.intent.action.VIEW ' | |
999 '-n this.is.a.test.package/.Main'), | |
1000 'Starting: Intent { act=android.intent.action.VIEW }'): | |
1001 self.device.StartActivity(test_intent, | |
1002 trace_file_name='test_trace_file.out') | |
1003 | |
1004 def testStartActivity_withForceStop(self): | |
1005 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
1006 package='this.is.a.test.package', | |
1007 activity='.Main') | |
1008 with self.assertCall( | |
1009 self.call.adb.Shell('am start ' | |
1010 '-S ' | |
1011 '-a android.intent.action.VIEW ' | |
1012 '-n this.is.a.test.package/.Main'), | |
1013 'Starting: Intent { act=android.intent.action.VIEW }'): | |
1014 self.device.StartActivity(test_intent, force_stop=True) | |
1015 | |
1016 def testStartActivity_withFlags(self): | |
1017 test_intent = intent.Intent(action='android.intent.action.VIEW', | |
1018 package='this.is.a.test.package', | |
1019 activity='.Main', | |
1020 flags='0x10000000') | |
1021 with self.assertCall( | |
1022 self.call.adb.Shell('am start ' | |
1023 '-a android.intent.action.VIEW ' | |
1024 '-n this.is.a.test.package/.Main ' | |
1025 '-f 0x10000000'), | |
1026 'Starting: Intent { act=android.intent.action.VIEW }'): | |
1027 self.device.StartActivity(test_intent) | |
1028 | |
1029 | |
1030 class DeviceUtilsStartInstrumentationTest(DeviceUtilsTest): | |
1031 | |
1032 def testStartInstrumentation_nothing(self): | |
1033 with self.assertCalls( | |
1034 self.call.device.RunShellCommand( | |
1035 ['am', 'instrument', 'test.package/.TestInstrumentation'], | |
1036 check_return=True, large_output=True)): | |
1037 self.device.StartInstrumentation( | |
1038 'test.package/.TestInstrumentation', | |
1039 finish=False, raw=False, extras=None) | |
1040 | |
1041 def testStartInstrumentation_finish(self): | |
1042 with self.assertCalls( | |
1043 (self.call.device.RunShellCommand( | |
1044 ['am', 'instrument', '-w', 'test.package/.TestInstrumentation'], | |
1045 check_return=True, large_output=True), | |
1046 ['OK (1 test)'])): | |
1047 output = self.device.StartInstrumentation( | |
1048 'test.package/.TestInstrumentation', | |
1049 finish=True, raw=False, extras=None) | |
1050 self.assertEquals(['OK (1 test)'], output) | |
1051 | |
1052 def testStartInstrumentation_raw(self): | |
1053 with self.assertCalls( | |
1054 self.call.device.RunShellCommand( | |
1055 ['am', 'instrument', '-r', 'test.package/.TestInstrumentation'], | |
1056 check_return=True, large_output=True)): | |
1057 self.device.StartInstrumentation( | |
1058 'test.package/.TestInstrumentation', | |
1059 finish=False, raw=True, extras=None) | |
1060 | |
1061 def testStartInstrumentation_extras(self): | |
1062 with self.assertCalls( | |
1063 self.call.device.RunShellCommand( | |
1064 ['am', 'instrument', '-e', 'foo', 'Foo', '-e', 'bar', 'Bar', | |
1065 'test.package/.TestInstrumentation'], | |
1066 check_return=True, large_output=True)): | |
1067 self.device.StartInstrumentation( | |
1068 'test.package/.TestInstrumentation', | |
1069 finish=False, raw=False, extras={'foo': 'Foo', 'bar': 'Bar'}) | |
1070 | |
1071 | |
1072 class DeviceUtilsBroadcastIntentTest(DeviceUtilsTest): | |
1073 | |
1074 def testBroadcastIntent_noExtras(self): | |
1075 test_intent = intent.Intent(action='test.package.with.an.INTENT') | |
1076 with self.assertCall( | |
1077 self.call.adb.Shell('am broadcast -a test.package.with.an.INTENT'), | |
1078 'Broadcasting: Intent { act=test.package.with.an.INTENT } '): | |
1079 self.device.BroadcastIntent(test_intent) | |
1080 | |
1081 def testBroadcastIntent_withExtra(self): | |
1082 test_intent = intent.Intent(action='test.package.with.an.INTENT', | |
1083 extras={'foo': 'bar value'}) | |
1084 with self.assertCall( | |
1085 self.call.adb.Shell( | |
1086 "am broadcast -a test.package.with.an.INTENT --es foo 'bar value'"), | |
1087 'Broadcasting: Intent { act=test.package.with.an.INTENT } '): | |
1088 self.device.BroadcastIntent(test_intent) | |
1089 | |
1090 def testBroadcastIntent_withExtra_noValue(self): | |
1091 test_intent = intent.Intent(action='test.package.with.an.INTENT', | |
1092 extras={'foo': None}) | |
1093 with self.assertCall( | |
1094 self.call.adb.Shell( | |
1095 'am broadcast -a test.package.with.an.INTENT --esn foo'), | |
1096 'Broadcasting: Intent { act=test.package.with.an.INTENT } '): | |
1097 self.device.BroadcastIntent(test_intent) | |
1098 | |
1099 | |
1100 class DeviceUtilsGoHomeTest(DeviceUtilsTest): | |
1101 | |
1102 def testGoHome_popupsExist(self): | |
1103 with self.assertCalls( | |
1104 (self.call.device.RunShellCommand( | |
1105 ['dumpsys', 'window', 'windows'], check_return=True, | |
1106 large_output=True), []), | |
1107 (self.call.device.RunShellCommand( | |
1108 ['am', 'start', '-W', '-a', 'android.intent.action.MAIN', | |
1109 '-c', 'android.intent.category.HOME'], check_return=True), | |
1110 'Starting: Intent { act=android.intent.action.MAIN }\r\n'''), | |
1111 (self.call.device.RunShellCommand( | |
1112 ['dumpsys', 'window', 'windows'], check_return=True, | |
1113 large_output=True), []), | |
1114 (self.call.device.RunShellCommand( | |
1115 ['input', 'keyevent', '66'], check_return=True)), | |
1116 (self.call.device.RunShellCommand( | |
1117 ['input', 'keyevent', '4'], check_return=True)), | |
1118 (self.call.device.RunShellCommand( | |
1119 ['dumpsys', 'window', 'windows'], check_return=True, | |
1120 large_output=True), | |
1121 ['mCurrentFocus Launcher'])): | |
1122 self.device.GoHome() | |
1123 | |
1124 def testGoHome_willRetry(self): | |
1125 with self.assertCalls( | |
1126 (self.call.device.RunShellCommand( | |
1127 ['dumpsys', 'window', 'windows'], check_return=True, | |
1128 large_output=True), []), | |
1129 (self.call.device.RunShellCommand( | |
1130 ['am', 'start', '-W', '-a', 'android.intent.action.MAIN', | |
1131 '-c', 'android.intent.category.HOME'], check_return=True), | |
1132 'Starting: Intent { act=android.intent.action.MAIN }\r\n'''), | |
1133 (self.call.device.RunShellCommand( | |
1134 ['dumpsys', 'window', 'windows'], check_return=True, | |
1135 large_output=True), []), | |
1136 (self.call.device.RunShellCommand( | |
1137 ['input', 'keyevent', '66'], check_return=True,)), | |
1138 (self.call.device.RunShellCommand( | |
1139 ['input', 'keyevent', '4'], check_return=True)), | |
1140 (self.call.device.RunShellCommand( | |
1141 ['dumpsys', 'window', 'windows'], check_return=True, | |
1142 large_output=True), []), | |
1143 (self.call.device.RunShellCommand( | |
1144 ['input', 'keyevent', '66'], check_return=True)), | |
1145 (self.call.device.RunShellCommand( | |
1146 ['input', 'keyevent', '4'], check_return=True)), | |
1147 (self.call.device.RunShellCommand( | |
1148 ['dumpsys', 'window', 'windows'], check_return=True, | |
1149 large_output=True), | |
1150 self.TimeoutError())): | |
1151 with self.assertRaises(device_errors.CommandTimeoutError): | |
1152 self.device.GoHome() | |
1153 | |
1154 def testGoHome_alreadyFocused(self): | |
1155 with self.assertCall( | |
1156 self.call.device.RunShellCommand( | |
1157 ['dumpsys', 'window', 'windows'], check_return=True, | |
1158 large_output=True), | |
1159 ['mCurrentFocus Launcher']): | |
1160 self.device.GoHome() | |
1161 | |
1162 def testGoHome_alreadyFocusedAlternateCase(self): | |
1163 with self.assertCall( | |
1164 self.call.device.RunShellCommand( | |
1165 ['dumpsys', 'window', 'windows'], check_return=True, | |
1166 large_output=True), | |
1167 [' mCurrentFocus .launcher/.']): | |
1168 self.device.GoHome() | |
1169 | |
1170 def testGoHome_obtainsFocusAfterGoingHome(self): | |
1171 with self.assertCalls( | |
1172 (self.call.device.RunShellCommand( | |
1173 ['dumpsys', 'window', 'windows'], check_return=True, | |
1174 large_output=True), []), | |
1175 (self.call.device.RunShellCommand( | |
1176 ['am', 'start', '-W', '-a', 'android.intent.action.MAIN', | |
1177 '-c', 'android.intent.category.HOME'], check_return=True), | |
1178 'Starting: Intent { act=android.intent.action.MAIN }\r\n'''), | |
1179 (self.call.device.RunShellCommand( | |
1180 ['dumpsys', 'window', 'windows'], check_return=True, | |
1181 large_output=True), | |
1182 ['mCurrentFocus Launcher'])): | |
1183 self.device.GoHome() | |
1184 | |
1185 class DeviceUtilsForceStopTest(DeviceUtilsTest): | |
1186 | |
1187 def testForceStop(self): | |
1188 with self.assertCall( | |
1189 self.call.adb.Shell('am force-stop this.is.a.test.package'), | |
1190 ''): | |
1191 self.device.ForceStop('this.is.a.test.package') | |
1192 | |
1193 | |
1194 class DeviceUtilsClearApplicationStateTest(DeviceUtilsTest): | |
1195 | |
1196 def testClearApplicationState_packageDoesntExist(self): | |
1197 with self.assertCalls( | |
1198 (self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'), | |
1199 (self.call.device.GetApplicationPaths('this.package.does.not.exist'), | |
1200 [])): | |
1201 self.device.ClearApplicationState('this.package.does.not.exist') | |
1202 | |
1203 def testClearApplicationState_packageDoesntExistOnAndroidJBMR2OrAbove(self): | |
1204 with self.assertCalls( | |
1205 (self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'), | |
1206 (self.call.adb.Shell('pm clear this.package.does.not.exist'), | |
1207 'Failed\r\n')): | |
1208 self.device.ClearApplicationState('this.package.does.not.exist') | |
1209 | |
1210 def testClearApplicationState_packageExists(self): | |
1211 with self.assertCalls( | |
1212 (self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'), | |
1213 (self.call.device.GetApplicationPaths('this.package.exists'), | |
1214 ['/data/app/this.package.exists.apk']), | |
1215 (self.call.adb.Shell('pm clear this.package.exists'), | |
1216 'Success\r\n')): | |
1217 self.device.ClearApplicationState('this.package.exists') | |
1218 | |
1219 def testClearApplicationState_packageExistsOnAndroidJBMR2OrAbove(self): | |
1220 with self.assertCalls( | |
1221 (self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'), | |
1222 (self.call.adb.Shell('pm clear this.package.exists'), | |
1223 'Success\r\n')): | |
1224 self.device.ClearApplicationState('this.package.exists') | |
1225 | |
1226 | |
1227 class DeviceUtilsSendKeyEventTest(DeviceUtilsTest): | |
1228 | |
1229 def testSendKeyEvent(self): | |
1230 with self.assertCall(self.call.adb.Shell('input keyevent 66'), ''): | |
1231 self.device.SendKeyEvent(66) | |
1232 | |
1233 | |
1234 class DeviceUtilsPushChangedFilesIndividuallyTest(DeviceUtilsTest): | |
1235 | |
1236 def testPushChangedFilesIndividually_empty(self): | |
1237 test_files = [] | |
1238 with self.assertCalls(): | |
1239 self.device._PushChangedFilesIndividually(test_files) | |
1240 | |
1241 def testPushChangedFilesIndividually_single(self): | |
1242 test_files = [('/test/host/path', '/test/device/path')] | |
1243 with self.assertCalls(self.call.adb.Push(*test_files[0])): | |
1244 self.device._PushChangedFilesIndividually(test_files) | |
1245 | |
1246 def testPushChangedFilesIndividually_multiple(self): | |
1247 test_files = [ | |
1248 ('/test/host/path/file1', '/test/device/path/file1'), | |
1249 ('/test/host/path/file2', '/test/device/path/file2')] | |
1250 with self.assertCalls( | |
1251 self.call.adb.Push(*test_files[0]), | |
1252 self.call.adb.Push(*test_files[1])): | |
1253 self.device._PushChangedFilesIndividually(test_files) | |
1254 | |
1255 | |
1256 class DeviceUtilsPushChangedFilesZippedTest(DeviceUtilsTest): | |
1257 | |
1258 def testPushChangedFilesZipped_empty(self): | |
1259 test_files = [] | |
1260 with self.assertCalls(): | |
1261 self.device._PushChangedFilesZipped(test_files) | |
1262 | |
1263 def _testPushChangedFilesZipped_spec(self, test_files): | |
1264 mock_zip_temp = mock.mock_open() | |
1265 mock_zip_temp.return_value.name = '/test/temp/file/tmp.zip' | |
1266 with self.assertCalls( | |
1267 (mock.call.tempfile.NamedTemporaryFile(suffix='.zip'), mock_zip_temp), | |
1268 (mock.call.multiprocessing.Process( | |
1269 target=device_utils.DeviceUtils._CreateDeviceZip, | |
1270 args=('/test/temp/file/tmp.zip', test_files)), mock.Mock()), | |
1271 (self.call.device.GetExternalStoragePath(), | |
1272 '/test/device/external_dir'), | |
1273 self.call.adb.Push( | |
1274 '/test/temp/file/tmp.zip', '/test/device/external_dir/tmp.zip'), | |
1275 self.call.device.RunShellCommand( | |
1276 ['unzip', '/test/device/external_dir/tmp.zip'], | |
1277 as_root=True, | |
1278 env={'PATH': '/data/local/tmp/bin:$PATH'}, | |
1279 check_return=True), | |
1280 (self.call.device.IsOnline(), True), | |
1281 self.call.device.RunShellCommand( | |
1282 ['rm', '/test/device/external_dir/tmp.zip'], check_return=True)): | |
1283 self.device._PushChangedFilesZipped(test_files) | |
1284 | |
1285 def testPushChangedFilesZipped_single(self): | |
1286 self._testPushChangedFilesZipped_spec( | |
1287 [('/test/host/path/file1', '/test/device/path/file1')]) | |
1288 | |
1289 def testPushChangedFilesZipped_multiple(self): | |
1290 self._testPushChangedFilesZipped_spec( | |
1291 [('/test/host/path/file1', '/test/device/path/file1'), | |
1292 ('/test/host/path/file2', '/test/device/path/file2')]) | |
1293 | |
1294 | |
1295 class DeviceUtilsFileExistsTest(DeviceUtilsTest): | |
1296 | |
1297 def testFileExists_usingTest_fileExists(self): | |
1298 with self.assertCall( | |
1299 self.call.device.RunShellCommand( | |
1300 ['test', '-e', '/path/file.exists'], check_return=True), ''): | |
1301 self.assertTrue(self.device.FileExists('/path/file.exists')) | |
1302 | |
1303 def testFileExists_usingTest_fileDoesntExist(self): | |
1304 with self.assertCall( | |
1305 self.call.device.RunShellCommand( | |
1306 ['test', '-e', '/does/not/exist'], check_return=True), | |
1307 self.ShellError('', 1)): | |
1308 self.assertFalse(self.device.FileExists('/does/not/exist')) | |
1309 | |
1310 | |
1311 class DeviceUtilsPullFileTest(DeviceUtilsTest): | |
1312 | |
1313 def testPullFile_existsOnDevice(self): | |
1314 with mock.patch('os.path.exists', return_value=True): | |
1315 with self.assertCall( | |
1316 self.call.adb.Pull('/data/app/test.file.exists', | |
1317 '/test/file/host/path')): | |
1318 self.device.PullFile('/data/app/test.file.exists', | |
1319 '/test/file/host/path') | |
1320 | |
1321 def testPullFile_doesntExistOnDevice(self): | |
1322 with mock.patch('os.path.exists', return_value=True): | |
1323 with self.assertCall( | |
1324 self.call.adb.Pull('/data/app/test.file.does.not.exist', | |
1325 '/test/file/host/path'), | |
1326 self.CommandError('remote object does not exist')): | |
1327 with self.assertRaises(device_errors.CommandFailedError): | |
1328 self.device.PullFile('/data/app/test.file.does.not.exist', | |
1329 '/test/file/host/path') | |
1330 | |
1331 | |
1332 class DeviceUtilsReadFileTest(DeviceUtilsTest): | |
1333 | |
1334 def testReadFileWithPull_success(self): | |
1335 tmp_host_dir = '/tmp/dir/on.host/' | |
1336 tmp_host = MockTempFile('/tmp/dir/on.host/tmp_ReadFileWithPull') | |
1337 tmp_host.file.read.return_value = 'some interesting contents' | |
1338 with self.assertCalls( | |
1339 (mock.call.tempfile.mkdtemp(), tmp_host_dir), | |
1340 (self.call.adb.Pull('/path/to/device/file', mock.ANY)), | |
1341 (mock.call.__builtin__.open(mock.ANY, 'r'), tmp_host), | |
1342 (mock.call.os.path.exists(tmp_host_dir), True), | |
1343 (mock.call.shutil.rmtree(tmp_host_dir), None)): | |
1344 self.assertEquals('some interesting contents', | |
1345 self.device._ReadFileWithPull('/path/to/device/file')) | |
1346 tmp_host.file.read.assert_called_once_with() | |
1347 | |
1348 def testReadFileWithPull_rejected(self): | |
1349 tmp_host_dir = '/tmp/dir/on.host/' | |
1350 with self.assertCalls( | |
1351 (mock.call.tempfile.mkdtemp(), tmp_host_dir), | |
1352 (self.call.adb.Pull('/path/to/device/file', mock.ANY), | |
1353 self.CommandError()), | |
1354 (mock.call.os.path.exists(tmp_host_dir), True), | |
1355 (mock.call.shutil.rmtree(tmp_host_dir), None)): | |
1356 with self.assertRaises(device_errors.CommandFailedError): | |
1357 self.device._ReadFileWithPull('/path/to/device/file') | |
1358 | |
1359 def testReadFile_exists(self): | |
1360 with self.assertCalls( | |
1361 (self.call.device.RunShellCommand( | |
1362 ['ls', '-l', '/read/this/test/file'], | |
1363 as_root=False, check_return=True), | |
1364 ['-rw-rw---- root foo 256 1970-01-01 00:00 file']), | |
1365 (self.call.device.RunShellCommand( | |
1366 ['cat', '/read/this/test/file'], | |
1367 as_root=False, check_return=True), | |
1368 ['this is a test file'])): | |
1369 self.assertEqual('this is a test file\n', | |
1370 self.device.ReadFile('/read/this/test/file')) | |
1371 | |
1372 def testReadFile_doesNotExist(self): | |
1373 with self.assertCall( | |
1374 self.call.device.RunShellCommand( | |
1375 ['ls', '-l', '/this/file/does.not.exist'], | |
1376 as_root=False, check_return=True), | |
1377 self.CommandError('File does not exist')): | |
1378 with self.assertRaises(device_errors.CommandFailedError): | |
1379 self.device.ReadFile('/this/file/does.not.exist') | |
1380 | |
1381 def testReadFile_zeroSize(self): | |
1382 with self.assertCalls( | |
1383 (self.call.device.RunShellCommand( | |
1384 ['ls', '-l', '/this/file/has/zero/size'], | |
1385 as_root=False, check_return=True), | |
1386 ['-r--r--r-- root foo 0 1970-01-01 00:00 zero_size_file']), | |
1387 (self.call.device._ReadFileWithPull('/this/file/has/zero/size'), | |
1388 'but it has contents\n')): | |
1389 self.assertEqual('but it has contents\n', | |
1390 self.device.ReadFile('/this/file/has/zero/size')) | |
1391 | |
1392 def testReadFile_withSU(self): | |
1393 with self.assertCalls( | |
1394 (self.call.device.RunShellCommand( | |
1395 ['ls', '-l', '/this/file/can.be.read.with.su'], | |
1396 as_root=True, check_return=True), | |
1397 ['-rw------- root root 256 1970-01-01 00:00 can.be.read.with.su']), | |
1398 (self.call.device.RunShellCommand( | |
1399 ['cat', '/this/file/can.be.read.with.su'], | |
1400 as_root=True, check_return=True), | |
1401 ['this is a test file', 'read with su'])): | |
1402 self.assertEqual( | |
1403 'this is a test file\nread with su\n', | |
1404 self.device.ReadFile('/this/file/can.be.read.with.su', | |
1405 as_root=True)) | |
1406 | |
1407 def testReadFile_withPull(self): | |
1408 contents = 'a' * 123456 | |
1409 with self.assertCalls( | |
1410 (self.call.device.RunShellCommand( | |
1411 ['ls', '-l', '/read/this/big/test/file'], | |
1412 as_root=False, check_return=True), | |
1413 ['-rw-rw---- root foo 123456 1970-01-01 00:00 file']), | |
1414 (self.call.device._ReadFileWithPull('/read/this/big/test/file'), | |
1415 contents)): | |
1416 self.assertEqual( | |
1417 contents, self.device.ReadFile('/read/this/big/test/file')) | |
1418 | |
1419 def testReadFile_withPullAndSU(self): | |
1420 contents = 'b' * 123456 | |
1421 with self.assertCalls( | |
1422 (self.call.device.RunShellCommand( | |
1423 ['ls', '-l', '/this/big/file/can.be.read.with.su'], | |
1424 as_root=True, check_return=True), | |
1425 ['-rw------- root root 123456 1970-01-01 00:00 can.be.read.with.su']), | |
1426 (self.call.device.NeedsSU(), True), | |
1427 (mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb), | |
1428 MockTempFile('/sdcard/tmp/on.device')), | |
1429 self.call.device.RunShellCommand( | |
1430 ['cp', '/this/big/file/can.be.read.with.su', | |
1431 '/sdcard/tmp/on.device'], | |
1432 as_root=True, check_return=True), | |
1433 (self.call.device._ReadFileWithPull('/sdcard/tmp/on.device'), | |
1434 contents)): | |
1435 self.assertEqual( | |
1436 contents, | |
1437 self.device.ReadFile('/this/big/file/can.be.read.with.su', | |
1438 as_root=True)) | |
1439 | |
1440 def testReadFile_forcePull(self): | |
1441 contents = 'a' * 123456 | |
1442 with self.assertCall( | |
1443 self.call.device._ReadFileWithPull('/read/this/big/test/file'), | |
1444 contents): | |
1445 self.assertEqual( | |
1446 contents, | |
1447 self.device.ReadFile('/read/this/big/test/file', force_pull=True)) | |
1448 | |
1449 | |
1450 class DeviceUtilsWriteFileTest(DeviceUtilsTest): | |
1451 | |
1452 def testWriteFileWithPush_success(self): | |
1453 tmp_host = MockTempFile('/tmp/file/on.host') | |
1454 contents = 'some interesting contents' | |
1455 with self.assertCalls( | |
1456 (mock.call.tempfile.NamedTemporaryFile(), tmp_host), | |
1457 self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file')): | |
1458 self.device._WriteFileWithPush('/path/to/device/file', contents) | |
1459 tmp_host.file.write.assert_called_once_with(contents) | |
1460 | |
1461 def testWriteFileWithPush_rejected(self): | |
1462 tmp_host = MockTempFile('/tmp/file/on.host') | |
1463 contents = 'some interesting contents' | |
1464 with self.assertCalls( | |
1465 (mock.call.tempfile.NamedTemporaryFile(), tmp_host), | |
1466 (self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file'), | |
1467 self.CommandError())): | |
1468 with self.assertRaises(device_errors.CommandFailedError): | |
1469 self.device._WriteFileWithPush('/path/to/device/file', contents) | |
1470 | |
1471 def testWriteFile_withPush(self): | |
1472 contents = 'some large contents ' * 26 # 20 * 26 = 520 chars | |
1473 with self.assertCalls( | |
1474 self.call.device._WriteFileWithPush('/path/to/device/file', contents)): | |
1475 self.device.WriteFile('/path/to/device/file', contents) | |
1476 | |
1477 def testWriteFile_withPushForced(self): | |
1478 contents = 'tiny contents' | |
1479 with self.assertCalls( | |
1480 self.call.device._WriteFileWithPush('/path/to/device/file', contents)): | |
1481 self.device.WriteFile('/path/to/device/file', contents, force_push=True) | |
1482 | |
1483 def testWriteFile_withPushAndSU(self): | |
1484 contents = 'some large contents ' * 26 # 20 * 26 = 520 chars | |
1485 with self.assertCalls( | |
1486 (self.call.device.NeedsSU(), True), | |
1487 (mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb), | |
1488 MockTempFile('/sdcard/tmp/on.device')), | |
1489 self.call.device._WriteFileWithPush('/sdcard/tmp/on.device', contents), | |
1490 self.call.device.RunShellCommand( | |
1491 ['cp', '/sdcard/tmp/on.device', '/path/to/device/file'], | |
1492 as_root=True, check_return=True)): | |
1493 self.device.WriteFile('/path/to/device/file', contents, as_root=True) | |
1494 | |
1495 def testWriteFile_withEcho(self): | |
1496 with self.assertCall(self.call.adb.Shell( | |
1497 "echo -n the.contents > /test/file/to.write"), ''): | |
1498 self.device.WriteFile('/test/file/to.write', 'the.contents') | |
1499 | |
1500 def testWriteFile_withEchoAndQuotes(self): | |
1501 with self.assertCall(self.call.adb.Shell( | |
1502 "echo -n 'the contents' > '/test/file/to write'"), ''): | |
1503 self.device.WriteFile('/test/file/to write', 'the contents') | |
1504 | |
1505 def testWriteFile_withEchoAndSU(self): | |
1506 with self.assertCalls( | |
1507 (self.call.device.NeedsSU(), True), | |
1508 (self.call.adb.Shell("su -c sh -c 'echo -n contents > /test/file'"), | |
1509 '')): | |
1510 self.device.WriteFile('/test/file', 'contents', as_root=True) | |
1511 | |
1512 | |
1513 class DeviceUtilsLsTest(DeviceUtilsTest): | |
1514 | |
1515 def testLs_directory(self): | |
1516 result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)), | |
1517 ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)), | |
1518 ('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))] | |
1519 with self.assertCalls( | |
1520 (self.call.adb.Ls('/data/local/tmp'), result)): | |
1521 self.assertEquals(result, | |
1522 self.device.Ls('/data/local/tmp')) | |
1523 | |
1524 def testLs_nothing(self): | |
1525 with self.assertCalls( | |
1526 (self.call.adb.Ls('/data/local/tmp/testfile.txt'), [])): | |
1527 self.assertEquals([], | |
1528 self.device.Ls('/data/local/tmp/testfile.txt')) | |
1529 | |
1530 | |
1531 class DeviceUtilsStatTest(DeviceUtilsTest): | |
1532 | |
1533 def testStat_file(self): | |
1534 result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)), | |
1535 ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)), | |
1536 ('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))] | |
1537 with self.assertCalls( | |
1538 (self.call.adb.Ls('/data/local/tmp'), result)): | |
1539 self.assertEquals(adb_wrapper.DeviceStat(33206, 3, 1417436122), | |
1540 self.device.Stat('/data/local/tmp/testfile.txt')) | |
1541 | |
1542 def testStat_directory(self): | |
1543 result = [('.', adb_wrapper.DeviceStat(16873, 4096, 12382237)), | |
1544 ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)), | |
1545 ('tmp', adb_wrapper.DeviceStat(16889, 4096, 1417436123))] | |
1546 with self.assertCalls( | |
1547 (self.call.adb.Ls('/data/local'), result)): | |
1548 self.assertEquals(adb_wrapper.DeviceStat(16889, 4096, 1417436123), | |
1549 self.device.Stat('/data/local/tmp')) | |
1550 | |
1551 def testStat_doesNotExist(self): | |
1552 result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)), | |
1553 ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)), | |
1554 ('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))] | |
1555 with self.assertCalls( | |
1556 (self.call.adb.Ls('/data/local/tmp'), result)): | |
1557 with self.assertRaises(device_errors.CommandFailedError): | |
1558 self.device.Stat('/data/local/tmp/does.not.exist.txt') | |
1559 | |
1560 | |
1561 class DeviceUtilsSetJavaAssertsTest(DeviceUtilsTest): | |
1562 | |
1563 def testSetJavaAsserts_enable(self): | |
1564 with self.assertCalls( | |
1565 (self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH), | |
1566 'some.example.prop=with an example value\n' | |
1567 'some.other.prop=value_ok\n'), | |
1568 self.call.device.WriteFile( | |
1569 constants.DEVICE_LOCAL_PROPERTIES_PATH, | |
1570 'some.example.prop=with an example value\n' | |
1571 'some.other.prop=value_ok\n' | |
1572 'dalvik.vm.enableassertions=all\n'), | |
1573 (self.call.device.GetProp('dalvik.vm.enableassertions'), ''), | |
1574 self.call.device.SetProp('dalvik.vm.enableassertions', 'all')): | |
1575 self.assertTrue(self.device.SetJavaAsserts(True)) | |
1576 | |
1577 def testSetJavaAsserts_disable(self): | |
1578 with self.assertCalls( | |
1579 (self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH), | |
1580 'some.example.prop=with an example value\n' | |
1581 'dalvik.vm.enableassertions=all\n' | |
1582 'some.other.prop=value_ok\n'), | |
1583 self.call.device.WriteFile( | |
1584 constants.DEVICE_LOCAL_PROPERTIES_PATH, | |
1585 'some.example.prop=with an example value\n' | |
1586 'some.other.prop=value_ok\n'), | |
1587 (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all'), | |
1588 self.call.device.SetProp('dalvik.vm.enableassertions', '')): | |
1589 self.assertTrue(self.device.SetJavaAsserts(False)) | |
1590 | |
1591 def testSetJavaAsserts_alreadyEnabled(self): | |
1592 with self.assertCalls( | |
1593 (self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH), | |
1594 'some.example.prop=with an example value\n' | |
1595 'dalvik.vm.enableassertions=all\n' | |
1596 'some.other.prop=value_ok\n'), | |
1597 (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all')): | |
1598 self.assertFalse(self.device.SetJavaAsserts(True)) | |
1599 | |
1600 | |
1601 class DeviceUtilsGetPropTest(DeviceUtilsTest): | |
1602 | |
1603 def testGetProp_exists(self): | |
1604 with self.assertCall( | |
1605 self.call.adb.Shell('getprop test.property'), 'property_value\n'): | |
1606 self.assertEqual('property_value', | |
1607 self.device.GetProp('test.property')) | |
1608 | |
1609 def testGetProp_doesNotExist(self): | |
1610 with self.assertCall( | |
1611 self.call.adb.Shell('getprop property.does.not.exist'), '\n'): | |
1612 self.assertEqual('', self.device.GetProp('property.does.not.exist')) | |
1613 | |
1614 def testGetProp_cachedRoProp(self): | |
1615 with self.assertCall( | |
1616 self.call.adb.Shell('getprop ro.build.type'), 'userdebug\n'): | |
1617 self.assertEqual('userdebug', | |
1618 self.device.GetProp('ro.build.type', cache=True)) | |
1619 self.assertEqual('userdebug', | |
1620 self.device.GetProp('ro.build.type', cache=True)) | |
1621 | |
1622 def testGetProp_retryAndCache(self): | |
1623 with self.assertCalls( | |
1624 (self.call.adb.Shell('getprop ro.build.type'), self.ShellError()), | |
1625 (self.call.adb.Shell('getprop ro.build.type'), self.ShellError()), | |
1626 (self.call.adb.Shell('getprop ro.build.type'), 'userdebug\n')): | |
1627 self.assertEqual('userdebug', | |
1628 self.device.GetProp('ro.build.type', | |
1629 cache=True, retries=3)) | |
1630 self.assertEqual('userdebug', | |
1631 self.device.GetProp('ro.build.type', | |
1632 cache=True, retries=3)) | |
1633 | |
1634 | |
1635 class DeviceUtilsSetPropTest(DeviceUtilsTest): | |
1636 | |
1637 def testSetProp(self): | |
1638 with self.assertCall( | |
1639 self.call.adb.Shell("setprop test.property 'test value'"), ''): | |
1640 self.device.SetProp('test.property', 'test value') | |
1641 | |
1642 def testSetProp_check_succeeds(self): | |
1643 with self.assertCalls( | |
1644 (self.call.adb.Shell('setprop test.property new_value'), ''), | |
1645 (self.call.adb.Shell('getprop test.property'), 'new_value')): | |
1646 self.device.SetProp('test.property', 'new_value', check=True) | |
1647 | |
1648 def testSetProp_check_fails(self): | |
1649 with self.assertCalls( | |
1650 (self.call.adb.Shell('setprop test.property new_value'), ''), | |
1651 (self.call.adb.Shell('getprop test.property'), 'old_value')): | |
1652 with self.assertRaises(device_errors.CommandFailedError): | |
1653 self.device.SetProp('test.property', 'new_value', check=True) | |
1654 | |
1655 | |
1656 class DeviceUtilsGetPidsTest(DeviceUtilsTest): | |
1657 | |
1658 def testGetPids_noMatches(self): | |
1659 with self.assertCall( | |
1660 self.call.device._RunPipedShellCommand('ps | grep -F does.not.match'), | |
1661 []): | |
1662 self.assertEqual({}, self.device.GetPids('does.not.match')) | |
1663 | |
1664 def testGetPids_oneMatch(self): | |
1665 with self.assertCall( | |
1666 self.call.device._RunPipedShellCommand('ps | grep -F one.match'), | |
1667 ['user 1001 100 1024 1024 ffffffff 00000000 one.match']): | |
1668 self.assertEqual({'one.match': '1001'}, self.device.GetPids('one.match')) | |
1669 | |
1670 def testGetPids_mutlipleMatches(self): | |
1671 with self.assertCall( | |
1672 self.call.device._RunPipedShellCommand('ps | grep -F match'), | |
1673 ['user 1001 100 1024 1024 ffffffff 00000000 one.match', | |
1674 'user 1002 100 1024 1024 ffffffff 00000000 two.match', | |
1675 'user 1003 100 1024 1024 ffffffff 00000000 three.match']): | |
1676 self.assertEqual( | |
1677 {'one.match': '1001', 'two.match': '1002', 'three.match': '1003'}, | |
1678 self.device.GetPids('match')) | |
1679 | |
1680 def testGetPids_exactMatch(self): | |
1681 with self.assertCall( | |
1682 self.call.device._RunPipedShellCommand('ps | grep -F exact.match'), | |
1683 ['user 1000 100 1024 1024 ffffffff 00000000 not.exact.match', | |
1684 'user 1234 100 1024 1024 ffffffff 00000000 exact.match']): | |
1685 self.assertEqual( | |
1686 {'not.exact.match': '1000', 'exact.match': '1234'}, | |
1687 self.device.GetPids('exact.match')) | |
1688 | |
1689 def testGetPids_quotable(self): | |
1690 with self.assertCall( | |
1691 self.call.device._RunPipedShellCommand("ps | grep -F 'my$process'"), | |
1692 ['user 1234 100 1024 1024 ffffffff 00000000 my$process']): | |
1693 self.assertEqual( | |
1694 {'my$process': '1234'}, self.device.GetPids('my$process')) | |
1695 | |
1696 | |
1697 class DeviceUtilsTakeScreenshotTest(DeviceUtilsTest): | |
1698 | |
1699 def testTakeScreenshot_fileNameProvided(self): | |
1700 with self.assertCalls( | |
1701 (mock.call.pylib.utils.device_temp_file.DeviceTempFile( | |
1702 self.adb, suffix='.png'), | |
1703 MockTempFile('/tmp/path/temp-123.png')), | |
1704 (self.call.adb.Shell('/system/bin/screencap -p /tmp/path/temp-123.png'), | |
1705 ''), | |
1706 self.call.device.PullFile('/tmp/path/temp-123.png', | |
1707 '/test/host/screenshot.png')): | |
1708 self.device.TakeScreenshot('/test/host/screenshot.png') | |
1709 | |
1710 | |
1711 class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsTest): | |
1712 | |
1713 def setUp(self): | |
1714 super(DeviceUtilsGetMemoryUsageForPidTest, self).setUp() | |
1715 | |
1716 def testGetMemoryUsageForPid_validPid(self): | |
1717 with self.assertCalls( | |
1718 (self.call.device._RunPipedShellCommand( | |
1719 'showmap 1234 | grep TOTAL', as_root=True), | |
1720 ['100 101 102 103 104 105 106 107 TOTAL']), | |
1721 (self.call.device.ReadFile('/proc/1234/status', as_root=True), | |
1722 'VmHWM: 1024 kB\n')): | |
1723 self.assertEqual( | |
1724 { | |
1725 'Size': 100, | |
1726 'Rss': 101, | |
1727 'Pss': 102, | |
1728 'Shared_Clean': 103, | |
1729 'Shared_Dirty': 104, | |
1730 'Private_Clean': 105, | |
1731 'Private_Dirty': 106, | |
1732 'VmHWM': 1024 | |
1733 }, | |
1734 self.device.GetMemoryUsageForPid(1234)) | |
1735 | |
1736 def testGetMemoryUsageForPid_noSmaps(self): | |
1737 with self.assertCalls( | |
1738 (self.call.device._RunPipedShellCommand( | |
1739 'showmap 4321 | grep TOTAL', as_root=True), | |
1740 ['cannot open /proc/4321/smaps: No such file or directory']), | |
1741 (self.call.device.ReadFile('/proc/4321/status', as_root=True), | |
1742 'VmHWM: 1024 kb\n')): | |
1743 self.assertEquals({'VmHWM': 1024}, self.device.GetMemoryUsageForPid(4321)) | |
1744 | |
1745 def testGetMemoryUsageForPid_noStatus(self): | |
1746 with self.assertCalls( | |
1747 (self.call.device._RunPipedShellCommand( | |
1748 'showmap 4321 | grep TOTAL', as_root=True), | |
1749 ['100 101 102 103 104 105 106 107 TOTAL']), | |
1750 (self.call.device.ReadFile('/proc/4321/status', as_root=True), | |
1751 self.CommandError())): | |
1752 self.assertEquals( | |
1753 { | |
1754 'Size': 100, | |
1755 'Rss': 101, | |
1756 'Pss': 102, | |
1757 'Shared_Clean': 103, | |
1758 'Shared_Dirty': 104, | |
1759 'Private_Clean': 105, | |
1760 'Private_Dirty': 106, | |
1761 }, | |
1762 self.device.GetMemoryUsageForPid(4321)) | |
1763 | |
1764 | |
1765 class DeviceUtilsClientCache(DeviceUtilsTest): | |
1766 | |
1767 def testClientCache_twoCaches(self): | |
1768 self.device._cache['test'] = 0 | |
1769 client_cache_one = self.device.GetClientCache('ClientOne') | |
1770 client_cache_one['test'] = 1 | |
1771 client_cache_two = self.device.GetClientCache('ClientTwo') | |
1772 client_cache_two['test'] = 2 | |
1773 self.assertEqual(self.device._cache, {'test': 0}) | |
1774 self.assertEqual(client_cache_one, {'test': 1}) | |
1775 self.assertEqual(client_cache_two, {'test': 2}) | |
1776 self.device._ClearCache() | |
1777 self.assertEqual(self.device._cache, {}) | |
1778 self.assertEqual(client_cache_one, {}) | |
1779 self.assertEqual(client_cache_two, {}) | |
1780 | |
1781 def testClientCache_multipleInstances(self): | |
1782 client_cache_one = self.device.GetClientCache('ClientOne') | |
1783 client_cache_one['test'] = 1 | |
1784 client_cache_two = self.device.GetClientCache('ClientOne') | |
1785 self.assertEqual(client_cache_one, {'test': 1}) | |
1786 self.assertEqual(client_cache_two, {'test': 1}) | |
1787 self.device._ClearCache() | |
1788 self.assertEqual(client_cache_one, {}) | |
1789 self.assertEqual(client_cache_two, {}) | |
1790 | |
1791 | |
1792 class DeviceUtilsParallelTest(mock_calls.TestCase): | |
1793 | |
1794 def testParallel_default(self): | |
1795 test_serials = ['0123456789abcdef', 'fedcba9876543210'] | |
1796 with self.assertCall( | |
1797 mock.call.pylib.device.device_utils.DeviceUtils.HealthyDevices(), | |
1798 [device_utils.DeviceUtils(s) for s in test_serials]): | |
1799 parallel_devices = device_utils.DeviceUtils.parallel() | |
1800 for serial, device in zip(test_serials, parallel_devices.pGet(None)): | |
1801 self.assertTrue(isinstance(device, device_utils.DeviceUtils)) | |
1802 self.assertEquals(serial, device.adb.GetDeviceSerial()) | |
1803 | |
1804 def testParallel_noDevices(self): | |
1805 with self.assertCall( | |
1806 mock.call.pylib.device.device_utils.DeviceUtils.HealthyDevices(), []): | |
1807 with self.assertRaises(device_errors.NoDevicesError): | |
1808 device_utils.DeviceUtils.parallel() | |
1809 | |
1810 | |
1811 class DeviceUtilsHealthyDevicesTest(mock_calls.TestCase): | |
1812 | |
1813 def _createAdbWrapperMock(self, serial, is_ready=True): | |
1814 adb = _AdbWrapperMock(serial) | |
1815 adb.is_ready = is_ready | |
1816 return adb | |
1817 | |
1818 def testHealthyDevices_default(self): | |
1819 test_serials = ['0123456789abcdef', 'fedcba9876543210'] | |
1820 with self.assertCalls( | |
1821 (mock.call.pylib.device.device_blacklist.ReadBlacklist(), []), | |
1822 (mock.call.pylib.device.adb_wrapper.AdbWrapper.Devices(), | |
1823 [self._createAdbWrapperMock(s) for s in test_serials])): | |
1824 devices = device_utils.DeviceUtils.HealthyDevices() | |
1825 for serial, device in zip(test_serials, devices): | |
1826 self.assertTrue(isinstance(device, device_utils.DeviceUtils)) | |
1827 self.assertEquals(serial, device.adb.GetDeviceSerial()) | |
1828 | |
1829 def testHealthyDevices_blacklisted(self): | |
1830 test_serials = ['0123456789abcdef', 'fedcba9876543210'] | |
1831 with self.assertCalls( | |
1832 (mock.call.pylib.device.device_blacklist.ReadBlacklist(), | |
1833 ['fedcba9876543210']), | |
1834 (mock.call.pylib.device.adb_wrapper.AdbWrapper.Devices(), | |
1835 [self._createAdbWrapperMock(s) for s in test_serials])): | |
1836 devices = device_utils.DeviceUtils.HealthyDevices() | |
1837 self.assertEquals(1, len(devices)) | |
1838 self.assertTrue(isinstance(devices[0], device_utils.DeviceUtils)) | |
1839 self.assertEquals('0123456789abcdef', devices[0].adb.GetDeviceSerial()) | |
1840 | |
1841 | |
1842 if __name__ == '__main__': | |
1843 logging.getLogger().setLevel(logging.DEBUG) | |
1844 unittest.main(verbosity=2) | |
1845 | |
OLD | NEW |