• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# Copyright (C) 2024 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17import builtins
18import unittest
19import os
20import subprocess
21from unittest import mock
22from src.command import ProfilerCommand
23from src.device import AdbDevice
24
25TEST_DEVICE_SERIAL = "test-device-serial"
26TEST_DEVICE_SERIAL2 = "test-device-serial2"
27TEST_FILE_PATH = "test-file-path"
28TEST_STRING_FILE = "test-string-file"
29TEST_FAILURE_MSG = "test-failure"
30TEST_EXCEPTION = Exception(TEST_FAILURE_MSG)
31TEST_USER_ID_1 = 0
32TEST_USER_ID_2 = 1
33TEST_USER_ID_3 = 2
34TEST_PACKAGE_1 = "test-package-1"
35TEST_PACKAGE_2 = "test-package-2"
36TEST_PROP = "test-prop"
37TEST_PROP_VALUE = "test-prop-value"
38TEST_PID_OUTPUT = b"8241\n"
39BOOT_COMPLETE_OUTPUT = b"1\n"
40ANDROID_SDK_VERSION_T = 33
41
42class DeviceUnitTest(unittest.TestCase):
43
44  @staticmethod
45  def generate_adb_devices_result(devices, adb_started=True):
46    devices = [device.encode('utf-8') for device in devices]
47    stdout_string = b'List of devices attached\n'
48    if not adb_started:
49      stdout_string = (b'* daemon not running; starting now at tcp:1234\n'
50                       b'* daemon started successfully\n') + stdout_string
51    if len(devices) > 0:
52      stdout_string += b'\tdevice\n'.join(devices) + b'\tdevice\n'
53      stdout_string += b'\n'
54    return subprocess.CompletedProcess(args=['adb', 'devices'], returncode=0,
55                                       stdout=stdout_string)
56
57  @staticmethod
58  def generate_mock_completed_process(stdout_string=b'\n', stderr_string=b'\n'):
59    return mock.create_autospec(subprocess.CompletedProcess, instance=True,
60                                stdout=stdout_string, stderr=stderr_string)
61
62  @staticmethod
63  def subprocess_output(first_return_value, polling_return_value):
64    # Mocking the return value of a call to adb root and the return values of
65    # many followup calls to adb devices
66    yield first_return_value
67    while True:
68      yield polling_return_value
69
70  @staticmethod
71  def mock_users():
72    return mock.create_autospec(subprocess.CompletedProcess, instance=True,
73                                stdout=(b'Users:\n\tUserInfo{%d:Driver:813}'
74                                        b' running\n\tUserInfo{%d:Driver:412}\n'
75                                        % (TEST_USER_ID_1, TEST_USER_ID_2)))
76
77  @staticmethod
78  def mock_packages():
79    return mock.create_autospec(subprocess.CompletedProcess, instance=True,
80                                stdout=(b'package:%b\npackage:%b\n'
81                                        % (TEST_PACKAGE_1.encode("utf-8"),
82                                           TEST_PACKAGE_2.encode("utf-8"))))
83
84  @mock.patch.object(subprocess, "run", autospec=True)
85  def test_get_adb_devices_returns_devices(self, mock_subprocess_run):
86    mock_subprocess_run.return_value = (
87        self.generate_adb_devices_result([TEST_DEVICE_SERIAL,
88                                          TEST_DEVICE_SERIAL2]))
89    adbDevice = AdbDevice(None)
90
91    devices = adbDevice.get_adb_devices()
92
93    self.assertEqual(len(devices), 2)
94    self.assertEqual(devices[0], TEST_DEVICE_SERIAL)
95    self.assertEqual(devices[1], TEST_DEVICE_SERIAL2)
96
97  @mock.patch.object(subprocess, "run", autospec=True)
98  def test_get_adb_devices_returns_devices_and_adb_not_started(self,
99      mock_subprocess_run):
100    mock_subprocess_run.return_value = (
101        self.generate_adb_devices_result([TEST_DEVICE_SERIAL,
102                                          TEST_DEVICE_SERIAL2], False))
103    adbDevice = AdbDevice(None)
104
105    devices = adbDevice.get_adb_devices()
106
107    self.assertEqual(len(devices), 2)
108    self.assertEqual(devices[0], TEST_DEVICE_SERIAL)
109    self.assertEqual(devices[1], TEST_DEVICE_SERIAL2)
110
111  @mock.patch.object(subprocess, "run", autospec=True)
112  def test_get_adb_devices_returns_no_device(self, mock_subprocess_run):
113    mock_subprocess_run.return_value = self.generate_adb_devices_result([])
114    adbDevice = AdbDevice(None)
115
116    devices = adbDevice.get_adb_devices()
117
118    self.assertEqual(devices, [])
119
120  @mock.patch.object(subprocess, "run", autospec=True)
121  def test_get_adb_devices_returns_no_device_and_adb_not_started(self,
122      mock_subprocess_run):
123    mock_subprocess_run.return_value = (
124        self.generate_adb_devices_result([], False))
125    adbDevice = AdbDevice(None)
126
127    devices = adbDevice.get_adb_devices()
128
129    self.assertEqual(devices, [])
130
131  @mock.patch.object(subprocess, "run", autospec=True)
132  def test_get_adb_devices_command_failure_error(self, mock_subprocess_run):
133    mock_subprocess_run.side_effect = TEST_EXCEPTION
134    adbDevice = AdbDevice(None)
135
136    with self.assertRaises(Exception) as e:
137      adbDevice.get_adb_devices()
138
139    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
140
141  @mock.patch.object(subprocess, "run", autospec=True)
142  def test_check_device_connection_serial_arg_in_devices(self,
143      mock_subprocess_run):
144    mock_subprocess_run.return_value = (
145        self.generate_adb_devices_result([TEST_DEVICE_SERIAL]))
146    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
147
148    error = adbDevice.check_device_connection()
149
150    self.assertEqual(error, None)
151
152  @mock.patch.object(subprocess, "run", autospec=True)
153  def test_check_device_connection_serial_arg_not_in_devices_error(self,
154      mock_subprocess_run):
155    mock_subprocess_run.return_value = (
156        self.generate_adb_devices_result([TEST_DEVICE_SERIAL]))
157    invalid_device_serial = "invalid-device-serial"
158    adbDevice = AdbDevice(invalid_device_serial)
159
160    error = adbDevice.check_device_connection()
161
162    self.assertNotEqual(error, None)
163    self.assertEqual(error.message, ("Device with serial %s is not connected."
164                                     % invalid_device_serial))
165    self.assertEqual(error.suggestion, None)
166
167  @mock.patch.dict(os.environ, {"ANDROID_SERIAL": TEST_DEVICE_SERIAL},
168                   clear=True)
169  @mock.patch.object(subprocess, "run", autospec=True)
170  def test_check_device_connection_env_variable_in_devices(self,
171      mock_subprocess_run):
172    mock_subprocess_run.return_value = (
173        self.generate_adb_devices_result([TEST_DEVICE_SERIAL]))
174    adbDevice = AdbDevice(None)
175
176    error = adbDevice.check_device_connection()
177
178    self.assertEqual(error, None)
179    self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL)
180
181  @mock.patch.dict(os.environ, {"ANDROID_SERIAL": "invalid-device-serial"},
182                   clear=True)
183  @mock.patch.object(subprocess, "run", autospec=True)
184  def test_check_device_connection_env_variable_not_in_devices_error(self,
185      mock_subprocess_run):
186    mock_subprocess_run.return_value = (
187        self.generate_adb_devices_result([TEST_DEVICE_SERIAL]))
188    adbDevice = AdbDevice(None)
189
190    error = adbDevice.check_device_connection()
191
192    self.assertNotEqual(error, None)
193    self.assertEqual(error.message, ("Device with serial invalid-device-serial"
194                                     " is set as environment variable,"
195                                     " ANDROID_SERIAL, but is not connected."))
196    self.assertEqual(error.suggestion, None)
197
198  @mock.patch.object(subprocess, "run", autospec=True)
199  def test_check_device_connection_adb_devices_command_fails_error(self,
200      mock_subprocess_run):
201    mock_subprocess_run.side_effect = TEST_EXCEPTION
202    adbDevice = AdbDevice(None)
203
204    with self.assertRaises(Exception) as e:
205      adbDevice.check_device_connection()
206
207    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
208
209  @mock.patch.object(subprocess, "run", autospec=True)
210  def test_check_device_connection_no_devices_connected_error(self,
211      mock_subprocess_run):
212    mock_subprocess_run.return_value = (self.generate_adb_devices_result([]))
213    adbDevice = AdbDevice(None)
214
215    error = adbDevice.check_device_connection()
216
217    self.assertNotEqual(error, None)
218    self.assertEqual(error.message, "There are currently no devices connected.")
219    self.assertEqual(error.suggestion, None)
220
221  @mock.patch.object(subprocess, "run", autospec=True)
222  def test_check_device_connection_no_devices_connected_adb_not_started_error(
223      self, mock_subprocess_run):
224    mock_subprocess_run.return_value = (
225        self.generate_adb_devices_result([], False))
226    adbDevice = AdbDevice(None)
227
228    error = adbDevice.check_device_connection()
229
230    self.assertNotEqual(error, None)
231    self.assertEqual(error.message, "There are currently no devices connected.")
232    self.assertEqual(error.suggestion, None)
233
234  @mock.patch.dict(os.environ, {}, clear=True)
235  @mock.patch.object(subprocess, "run", autospec=True)
236  def test_check_device_connection_only_one_device(self, mock_subprocess_run):
237    mock_subprocess_run.return_value = (
238        self.generate_adb_devices_result([TEST_DEVICE_SERIAL]))
239    adbDevice = AdbDevice(None)
240
241    error = adbDevice.check_device_connection()
242
243    self.assertEqual(error, None)
244    self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL)
245
246  @mock.patch.dict(os.environ, {}, clear=True)
247  @mock.patch.object(subprocess, "run", autospec=True)
248  @mock.patch.object(builtins, "input")
249  def test_check_device_connection_multiple_devices_select_first(self, mock_input,
250      mock_subprocess_run):
251    mock_input.return_value = "0"
252    mock_subprocess_run.return_value = (
253        self.generate_adb_devices_result([TEST_DEVICE_SERIAL,
254                                          TEST_DEVICE_SERIAL2]))
255    adbDevice = AdbDevice(None)
256
257    error = adbDevice.check_device_connection()
258
259    self.assertEqual(error, None)
260    self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL)
261
262  @mock.patch.dict(os.environ, {}, clear=True)
263  @mock.patch.object(subprocess, "run", autospec=True)
264  @mock.patch.object(builtins, "input")
265  def test_check_device_connection_multiple_devices_select_second(self, mock_input,
266      mock_subprocess_run):
267    mock_input.return_value = "1"
268    mock_subprocess_run.return_value = (
269        self.generate_adb_devices_result([TEST_DEVICE_SERIAL,
270                                          TEST_DEVICE_SERIAL2]))
271    adbDevice = AdbDevice(None)
272
273    error = adbDevice.check_device_connection()
274
275    self.assertEqual(error, None)
276    self.assertEqual(adbDevice.serial, TEST_DEVICE_SERIAL2)
277
278  @mock.patch.object(subprocess, "run", autospec=True)
279  def test_root_device_success(self, mock_subprocess_run):
280    mock_subprocess_run.side_effect = [
281        self.generate_mock_completed_process(),
282        self.generate_adb_devices_result([TEST_DEVICE_SERIAL])]
283    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
284
285    # No exception is expected to be thrown
286    adbDevice.root_device()
287
288  @mock.patch.object(subprocess, "run", autospec=True)
289  def test_root_device_failure(self, mock_subprocess_run):
290    mock_subprocess_run.side_effect = TEST_EXCEPTION
291    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
292
293    with self.assertRaises(Exception) as e:
294      adbDevice.root_device()
295
296    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
297
298  @mock.patch.object(subprocess, "run", autospec=True)
299  def test_root_device_times_out_error(self, mock_subprocess_run):
300    mock_subprocess_run.side_effect = lambda args, capture_output=True: (
301        next(self.subprocess_output(self.generate_adb_devices_result([]),
302                                    self.generate_mock_completed_process())))
303    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
304
305    with self.assertRaises(Exception) as e:
306      adbDevice.root_device()
307
308    self.assertEqual(str(e.exception), ("Device with serial %s took too long to"
309                                        " reconnect after being rooted."
310                                        % TEST_DEVICE_SERIAL))
311
312  @mock.patch.object(subprocess, "run", autospec=True)
313  def test_root_device_and_adb_devices_fails_error(self, mock_subprocess_run):
314    mock_subprocess_run.side_effect = [self.generate_mock_completed_process(),
315                                       TEST_EXCEPTION]
316    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
317
318    with self.assertRaises(Exception) as e:
319      adbDevice.root_device()
320
321    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
322
323  @mock.patch.object(subprocess, "run", autospec=True)
324  def test_remove_file_success(self, mock_subprocess_run):
325    mock_subprocess_run.return_value = self.generate_mock_completed_process()
326    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
327
328    # No exception is expected to be thrown
329    adbDevice.remove_file(TEST_FILE_PATH)
330
331  @mock.patch.object(subprocess, "run", autospec=True)
332  def test_remove_file_failure(self, mock_subprocess_run):
333    mock_subprocess_run.side_effect = TEST_EXCEPTION
334    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
335
336    with self.assertRaises(Exception) as e:
337      adbDevice.remove_file(TEST_FILE_PATH)
338
339    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
340
341  @mock.patch.object(subprocess, "Popen", autospec=True)
342  def test_start_perfetto_trace_success(self, mock_subprocess_popen):
343    # Mocking the return value of subprocess.Popen to ensure it's
344    # not modified and returned by AdbDevice.start_perfetto_trace
345    mock_subprocess_popen.return_value = mock.Mock()
346    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
347
348    mock_process = adbDevice.start_perfetto_trace(None)
349
350    # No exception is expected to be thrown
351    self.assertEqual(mock_process, mock_subprocess_popen.return_value)
352
353  @mock.patch.object(subprocess, "Popen", autospec=True)
354  def test_start_perfetto_trace_failure(self, mock_subprocess_popen):
355    mock_subprocess_popen.side_effect = TEST_EXCEPTION
356    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
357
358    with self.assertRaises(Exception) as e:
359      adbDevice.start_perfetto_trace(None)
360
361    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
362
363  @mock.patch.object(subprocess, "Popen", autospec=True)
364  def test_start_simpleperf_trace_success(self, mock_subprocess_popen):
365    # Mocking the return value of subprocess.Popen to ensure it's
366    # not modified and returned by AdbDevice.start_simpleperf_trace
367    mock_subprocess_popen.return_value = mock.Mock()
368    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
369    command = ProfilerCommand("profiler", "custom", None, None,
370                              10000, None, None, ["cpu-cycles"], None, None,
371                              None, None, None, None, None, None, None)
372    mock_process = adbDevice.start_simpleperf_trace(command)
373
374    # No exception is expected to be thrown
375    self.assertEqual(mock_process, mock_subprocess_popen.return_value)
376
377  @mock.patch.object(subprocess, "Popen", autospec=True)
378  def test_start_simpleperf_trace_failure(self, mock_subprocess_popen):
379    mock_subprocess_popen.side_effect = TEST_EXCEPTION
380    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
381
382    command = ProfilerCommand("profiler", "custom", None, None,
383                              10000, None, None, ["cpu-cycles"], None, None,
384                              None, None, None, None, None, None, None)
385    with self.assertRaises(Exception) as e:
386      adbDevice.start_simpleperf_trace(command)
387
388    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
389
390
391  @mock.patch.object(subprocess, "run", autospec=True)
392  def test_pull_file_success(self, mock_subprocess_run):
393    mock_subprocess_run.return_value = self.generate_mock_completed_process()
394    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
395
396    # No exception is expected to be thrown
397    adbDevice.pull_file(TEST_FILE_PATH, TEST_FILE_PATH)
398
399  @mock.patch.object(subprocess, "run", autospec=True)
400  def test_pull_file_failure(self, mock_subprocess_run):
401    mock_subprocess_run.side_effect = TEST_EXCEPTION
402    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
403
404    with self.assertRaises(Exception) as e:
405      adbDevice.pull_file(TEST_FILE_PATH, TEST_FILE_PATH)
406
407    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
408
409  @mock.patch.object(subprocess, "run", autospec=True)
410  def test_get_all_users_success(self, mock_subprocess_run):
411    mock_subprocess_run.return_value = self.mock_users()
412
413    users = AdbDevice(TEST_DEVICE_SERIAL).get_all_users()
414
415    self.assertEqual(users, [TEST_USER_ID_1, TEST_USER_ID_2])
416
417  @mock.patch.object(subprocess, "run", autospec=True)
418  def test_get_all_users_failure(self, mock_subprocess_run):
419    mock_subprocess_run.side_effect = TEST_EXCEPTION
420    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
421
422    with self.assertRaises(Exception) as e:
423      adbDevice.get_all_users()
424
425    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
426
427  @mock.patch.object(subprocess, "run", autospec=True)
428  def test_user_exists_success(self, mock_subprocess_run):
429    mock_subprocess_run.return_value = self.mock_users()
430    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
431
432    error = adbDevice.user_exists(TEST_USER_ID_1)
433
434    self.assertEqual(error, None)
435
436  @mock.patch.object(subprocess, "run", autospec=True)
437  def test_user_exists_and_user_does_not_exist_failure(self,
438      mock_subprocess_run):
439    mock_subprocess_run.return_value = self.mock_users()
440    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
441
442    error = adbDevice.user_exists(TEST_USER_ID_3)
443
444    self.assertNotEqual(error, None)
445    self.assertEqual(error.message, ("User ID %s does not exist on device with"
446                                     " serial %s." % (TEST_USER_ID_3,
447                                                      TEST_DEVICE_SERIAL)))
448    self.assertEqual(error.suggestion,
449                     ("Select from one of the following user IDs on device with"
450                      " serial %s: %s, %s"
451                      % (TEST_DEVICE_SERIAL, TEST_USER_ID_1, TEST_USER_ID_2)))
452
453  @mock.patch.object(subprocess, "run", autospec=True)
454  def test_user_exists_and_get_all_users_fails_error(self, mock_subprocess_run):
455    mock_subprocess_run.side_effect = TEST_EXCEPTION
456    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
457
458    with self.assertRaises(Exception) as e:
459      adbDevice.user_exists(TEST_USER_ID_1)
460
461    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
462
463  @mock.patch.object(subprocess, "run", autospec=True)
464  def test_get_current_user_success(self, mock_subprocess_run):
465    mock_subprocess_run.return_value = (
466        mock.create_autospec(subprocess.CompletedProcess, instance=True,
467                             stdout=b'%d\n' % TEST_USER_ID_1))
468    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
469
470    user = adbDevice.get_current_user()
471
472    self.assertEqual(user, TEST_USER_ID_1)
473
474  @mock.patch.object(subprocess, "run", autospec=True)
475  def test_get_current_user_failure(self, mock_subprocess_run):
476    mock_subprocess_run.side_effect = TEST_EXCEPTION
477    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
478
479    with self.assertRaises(Exception) as e:
480      adbDevice.get_current_user()
481
482    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
483
484  @mock.patch.object(subprocess, "run", autospec=True)
485  def test_perform_user_switch_success(self, mock_subprocess_run):
486    mock_subprocess_run.return_value = self.generate_mock_completed_process()
487    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
488
489    # No exception is expected to be thrown
490    adbDevice.perform_user_switch(TEST_USER_ID_1)
491
492  @mock.patch.object(subprocess, "run", autospec=True)
493  def test_perform_user_switch_failure(self, mock_subprocess_run):
494    mock_subprocess_run.side_effect = TEST_EXCEPTION
495    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
496
497    with self.assertRaises(Exception) as e:
498      adbDevice.perform_user_switch(TEST_USER_ID_1)
499
500    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
501
502  @mock.patch.object(subprocess, "run", autospec=True)
503  def test_write_to_file_success(self, mock_subprocess_run):
504    mock_subprocess_run.return_value = self.generate_mock_completed_process()
505    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
506
507    # No exception is expected to be thrown
508    adbDevice.write_to_file(TEST_FILE_PATH, TEST_STRING_FILE)
509
510  @mock.patch.object(subprocess, "run", autospec=True)
511  def test_write_to_file_failure(self, mock_subprocess_run):
512    mock_subprocess_run.side_effect = TEST_EXCEPTION
513    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
514
515    with self.assertRaises(Exception) as e:
516      adbDevice.write_to_file(TEST_FILE_PATH, TEST_STRING_FILE)
517
518    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
519
520  @mock.patch.object(subprocess, "run", autospec=True)
521  def test_set_prop_success(self, mock_subprocess_run):
522    mock_subprocess_run.return_value = self.generate_mock_completed_process()
523    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
524
525    # No exception is expected to be thrown
526    adbDevice.set_prop(TEST_PROP, TEST_PROP_VALUE)
527
528  @mock.patch.object(subprocess, "run", autospec=True)
529  def test_set_prop_failure(self, mock_subprocess_run):
530    mock_subprocess_run.side_effect = TEST_EXCEPTION
531    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
532
533    with self.assertRaises(Exception) as e:
534      adbDevice.set_prop(TEST_PROP, TEST_PROP_VALUE)
535
536    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
537
538  @mock.patch.object(subprocess, "run", autospec=True)
539  def test_reboot_success(self, mock_subprocess_run):
540    mock_subprocess_run.return_value = self.generate_mock_completed_process()
541    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
542
543    # No exception is expected to be thrown
544    adbDevice.reboot()
545
546  @mock.patch.object(subprocess, "run", autospec=True)
547  def test_reboot_failure(self, mock_subprocess_run):
548    mock_subprocess_run.side_effect = TEST_EXCEPTION
549    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
550
551    with self.assertRaises(Exception) as e:
552      adbDevice.reboot()
553
554    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
555
556  @mock.patch.object(subprocess, "run", autospec=True)
557  def test_wait_for_device_success(self, mock_subprocess_run):
558    mock_subprocess_run.return_value = self.generate_mock_completed_process()
559    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
560
561    # No exception is expected to be thrown
562    adbDevice.wait_for_device()
563
564  @mock.patch.object(subprocess, "run", autospec=True)
565  def test_wait_for_device_failure(self, mock_subprocess_run):
566    mock_subprocess_run.side_effect = TEST_EXCEPTION
567    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
568
569    with self.assertRaises(Exception) as e:
570      adbDevice.wait_for_device()
571
572    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
573
574  @mock.patch.object(subprocess, "run", autospec=True)
575  def test_is_boot_completed_and_is_completed(self, mock_subprocess_run):
576    mock_subprocess_run.return_value = (
577        self.generate_mock_completed_process(BOOT_COMPLETE_OUTPUT))
578    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
579
580    is_completed = adbDevice.is_boot_completed()
581
582    self.assertEqual(is_completed, True)
583
584  @mock.patch.object(subprocess, "run", autospec=True)
585  def test_is_boot_completed_and_is_not_completed(self, mock_subprocess_run):
586    mock_subprocess_run.return_value = self.generate_mock_completed_process()
587    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
588
589    is_completed = adbDevice.is_boot_completed()
590
591    self.assertEqual(is_completed, False)
592
593  @mock.patch.object(subprocess, "run", autospec=True)
594  def test_is_boot_completed_failure(self, mock_subprocess_run):
595    mock_subprocess_run.side_effect = TEST_EXCEPTION
596    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
597
598    with self.assertRaises(Exception) as e:
599      adbDevice.is_boot_completed()
600
601    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
602
603  @mock.patch.object(subprocess, "run", autospec=True)
604  def test_wait_for_boot_to_complete_success(self, mock_subprocess_run):
605    mock_subprocess_run.return_value = (
606        self.generate_mock_completed_process(BOOT_COMPLETE_OUTPUT))
607    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
608
609    # No exception is expected to be thrown
610    adbDevice.wait_for_boot_to_complete()
611
612  @mock.patch.object(subprocess, "run", autospec=True)
613  def test_wait_for_boot_to_complete_and_is_boot_completed_fails_error(self,
614      mock_subprocess_run):
615    mock_subprocess_run.side_effect = TEST_EXCEPTION
616    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
617
618    with self.assertRaises(Exception) as e:
619      adbDevice.wait_for_boot_to_complete()
620
621    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
622
623  @mock.patch.object(subprocess, "run", autospec=True)
624  def test_wait_for_boot_to_complete_times_out_error(self, mock_subprocess_run):
625    mock_subprocess_run.return_value = self.generate_mock_completed_process()
626    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
627
628    with self.assertRaises(Exception) as e:
629      adbDevice.wait_for_boot_to_complete()
630
631    self.assertEqual(str(e.exception), ("Device with serial %s took too long to"
632                                        " finish rebooting."
633                                        % adbDevice.serial))
634
635  @mock.patch.object(subprocess, "run", autospec=True)
636  def test_get_packages_success(self, mock_subprocess_run):
637    mock_subprocess_run.return_value = self.mock_packages()
638    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
639
640    packages = adbDevice.get_packages()
641
642    self.assertEqual(packages, [TEST_PACKAGE_1, TEST_PACKAGE_2])
643
644  @mock.patch.object(subprocess, "run", autospec=True)
645  def test_get_packages_failure(self, mock_subprocess_run):
646    mock_subprocess_run.side_effect = TEST_EXCEPTION
647    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
648
649    with self.assertRaises(Exception) as e:
650      adbDevice.get_packages()
651
652    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
653
654  @mock.patch.object(subprocess, "run", autospec=True)
655  def test_get_pid_success(self, mock_subprocess_run):
656    mock_subprocess_run.return_value = self.generate_mock_completed_process(
657        TEST_PID_OUTPUT)
658    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
659
660    process_id = adbDevice.get_pid(TEST_PACKAGE_1)
661
662    self.assertEqual(process_id, "8241")
663
664  @mock.patch.object(subprocess, "run", autospec=True)
665  def test_get_pid_failure(self, mock_subprocess_run):
666    mock_subprocess_run.side_effect = TEST_EXCEPTION
667    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
668
669    with self.assertRaises(Exception) as e:
670      adbDevice.get_pid(TEST_PACKAGE_1)
671
672    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
673
674  @mock.patch.object(subprocess, "run", autospec=True)
675  def test_package_running(self, mock_subprocess_run):
676    mock_subprocess_run.return_value = self.generate_mock_completed_process(
677        TEST_PID_OUTPUT)
678    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
679
680    is_running = adbDevice.is_package_running(TEST_PACKAGE_1)
681
682    self.assertEqual(is_running, True)
683
684  @mock.patch.object(subprocess, "run", autospec=True)
685  def test_package_not_running(self, mock_subprocess_run):
686    mock_subprocess_run.return_value = self.generate_mock_completed_process()
687    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
688
689    is_running = adbDevice.is_package_running(TEST_PACKAGE_1)
690
691    self.assertEqual(is_running, False)
692
693  @mock.patch.object(subprocess, "run", autospec=True)
694  def test_package_running_and_get_pid_failure(self, mock_subprocess_run):
695    mock_subprocess_run.side_effect = TEST_EXCEPTION
696    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
697
698    with self.assertRaises(Exception) as e:
699      adbDevice.is_package_running(TEST_PACKAGE_1)
700
701    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
702
703  @mock.patch.object(subprocess, "run", autospec=True)
704  def test_start_package_success(self, mock_subprocess_run):
705    mock_subprocess_run.return_value = self.generate_mock_completed_process()
706    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
707
708    error = adbDevice.start_package(TEST_PACKAGE_1)
709
710    self.assertEqual(error, None)
711
712  @mock.patch.object(subprocess, "run", autospec=True)
713  def test_start_package_fails_with_service_app(self, mock_subprocess_run):
714    mock_subprocess_run.return_value = self.generate_mock_completed_process(
715        stderr_string=b'%s\n' % TEST_FAILURE_MSG.encode("utf-8"))
716    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
717
718    error = adbDevice.start_package(TEST_PACKAGE_1)
719
720    self.assertNotEqual(error, None)
721    self.assertEqual(error.message, ("Cannot start package %s on device with"
722                                     " serial %s because %s is a service"
723                                     " package, which doesn't implement a MAIN"
724                                     " activity." % (TEST_PACKAGE_1,
725                                                     TEST_DEVICE_SERIAL,
726                                                     TEST_PACKAGE_1)))
727    self.assertEqual(error.suggestion, None)
728
729  @mock.patch.object(subprocess, "run", autospec=True)
730  def test_start_package_failure(self, mock_subprocess_run):
731    mock_subprocess_run.side_effect = TEST_EXCEPTION
732    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
733
734    with self.assertRaises(Exception) as e:
735      adbDevice.start_package(TEST_PACKAGE_1)
736
737    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
738
739  @mock.patch.object(subprocess, "run", autospec=True)
740  def test_kill_pid_success(self, mock_subprocess_run):
741    mock_subprocess_run.side_effect = [
742        self.generate_mock_completed_process(TEST_PID_OUTPUT), None]
743    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
744
745    # No exception is expected to be thrown
746    adbDevice.kill_pid(TEST_PACKAGE_1)
747
748  @mock.patch.object(subprocess, "run", autospec=True)
749  def test_kill_pid_and_get_pid_failure(self, mock_subprocess_run):
750    mock_subprocess_run.side_effect = TEST_EXCEPTION
751    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
752
753    with self.assertRaises(Exception) as e:
754      adbDevice.kill_pid(TEST_PACKAGE_1)
755
756    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
757
758  @mock.patch.object(subprocess, "run", autospec=True)
759  def test_kill_pid_failure(self, mock_subprocess_run):
760    mock_subprocess_run.side_effect = [
761        self.generate_mock_completed_process(TEST_PID_OUTPUT), TEST_EXCEPTION]
762    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
763
764    with self.assertRaises(Exception) as e:
765      adbDevice.kill_pid(TEST_PACKAGE_1)
766
767    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
768
769  @mock.patch.object(subprocess, "run", autospec=True)
770  def test_force_stop_package_success(self, mock_subprocess_run):
771    mock_subprocess_run.return_value = None
772    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
773
774    # No exception is expected to be thrown
775    adbDevice.force_stop_package(TEST_PACKAGE_1)
776
777  @mock.patch.object(subprocess, "run", autospec=True)
778  def test_force_stop_package_failure(self, mock_subprocess_run):
779    mock_subprocess_run.side_effect = TEST_EXCEPTION
780    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
781
782    with self.assertRaises(Exception) as e:
783      adbDevice.force_stop_package(TEST_PACKAGE_1)
784
785    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
786
787  @mock.patch.object(subprocess, "run", autospec=True)
788  def test_get_prop_success(self, mock_subprocess_run):
789    test_prop_value = ANDROID_SDK_VERSION_T
790    mock_subprocess_run.return_value = self.generate_mock_completed_process(
791        stdout_string=b'%d\n' % test_prop_value)
792    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
793
794    prop_value = int(adbDevice.get_prop(TEST_PROP))
795
796    self.assertEqual(prop_value, test_prop_value)
797
798  @mock.patch.object(subprocess, "run", autospec=True)
799  def test_get_prop_package_failure(self, mock_subprocess_run):
800    mock_subprocess_run.side_effect = TEST_EXCEPTION
801    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
802
803    with self.assertRaises(Exception) as e:
804      adbDevice.get_prop(TEST_PROP)
805
806    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
807
808  @mock.patch.object(subprocess, "run", autospec=True)
809  def test_get_android_sdk_version_success(self, mock_subprocess_run):
810    mock_subprocess_run.return_value = self.generate_mock_completed_process(
811        stdout_string=b'%d\n' % ANDROID_SDK_VERSION_T)
812    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
813
814    prop_value = adbDevice.get_android_sdk_version()
815
816    self.assertEqual(prop_value, ANDROID_SDK_VERSION_T)
817
818  @mock.patch.object(subprocess, "run", autospec=True)
819  def test_get_android_sdk_version_failure(self, mock_subprocess_run):
820    mock_subprocess_run.side_effect = TEST_EXCEPTION
821    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
822
823    with self.assertRaises(Exception) as e:
824      adbDevice.get_android_sdk_version()
825
826    self.assertEqual(str(e.exception), TEST_FAILURE_MSG)
827
828  @mock.patch.object(subprocess, "run", autospec=True)
829  def test_simpleperf_event_exists_success(self, mock_subprocess_run):
830    mock_subprocess_run.return_value = (
831        self.generate_mock_completed_process(b'List of software events:\n  '
832                                             b'alignment-faults\n  '
833                                             b'context-switches\n  '
834                                             b'cpu-clock\n  '
835                                             b'cpu-migrations\n  '
836                                             b'emulation-faults\n  '
837                                             b'major-faults\n  '
838                                             b'minor-faults\n  page-faults\n  '
839                                             b'task-clock'))
840    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
841
842    events = ["cpu-clock", "minor-faults"]
843    # No exception is expected to be thrown
844    error = adbDevice.simpleperf_event_exists(events)
845
846    self.assertEqual(error, None)
847    # Check that the list passed to the function is unchanged
848    self.assertEqual(events, ["cpu-clock", "minor-faults"])
849
850  @mock.patch.object(subprocess, "run", autospec=True)
851  def test_simpleperf_event_exists_failure(self, mock_subprocess_run):
852    mock_subprocess_run.return_value = (
853        self.generate_mock_completed_process(b'List of software events:\n  '
854                                             b'alignment-faults\n  '
855                                             b'context-switches\n  '
856                                             b'cpu-clock\n  '
857                                             b'cpu-migrations\n  '
858                                             b'emulation-faults\n  '
859                                             b'major-faults\n  '
860                                             b'minor-faults\n  page-faults\n  '
861                                             b'task-clock'))
862    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
863
864    error = adbDevice.simpleperf_event_exists(["cpu-clock", "minor-faults",
865                                               "List"])
866
867    self.assertEqual(error.message, "The following simpleperf event(s) are "
868                                    "invalid: ['List'].")
869    self.assertEqual(error.suggestion, "Run adb shell simpleperf list to"
870                                       " see valid simpleperf events.")
871
872  @mock.patch.object(subprocess, "run", autospec=True)
873  def test_simpleperf_not_installed(self, mock_subprocess_run):
874    mock_subprocess_run.return_value = (
875        self.generate_mock_completed_process(
876            b'',
877            b'/system/bin/sh: simpleperf: inaccessible or not found\n')
878    )
879    adbDevice = AdbDevice(TEST_DEVICE_SERIAL)
880
881    error = adbDevice.simpleperf_event_exists(["cpu-clock", "minor-faults",
882                                               "List"])
883
884    self.assertEqual(error.message, "Simpleperf was not found in the device")
885    self.assertEqual(error.suggestion, "Push the simpleperf binary to the device")
886
887if __name__ == '__main__':
888  unittest.main()
889