Add serial attr in `AdbError`. (#532)
diff --git a/mobly/controllers/android_device_lib/adb.py b/mobly/controllers/android_device_lib/adb.py
index 41af20c..5e0c36f 100644
--- a/mobly/controllers/android_device_lib/adb.py
+++ b/mobly/controllers/android_device_lib/adb.py
@@ -44,13 +44,17 @@
stdout: byte string, the raw stdout of the command.
stderr: byte string, the raw stderr of the command.
ret_code: int, the return code of the command.
+ serial: string, the serial of the device the command is executed on.
+ This is an empty string if the adb command is not specific to a
+ device.
"""
- def __init__(self, cmd, stdout, stderr, ret_code):
+ def __init__(self, cmd, stdout, stderr, ret_code, serial=None):
self.cmd = cmd
self.stdout = stdout
self.stderr = stderr
self.ret_code = ret_code
+ self.serial = serial
def __str__(self):
return ('Error executing adb cmd "%s". ret: %d, stdout: %s, stderr: %s'
@@ -179,7 +183,12 @@
if ret == 0:
return out
else:
- raise AdbError(cmd=args, stdout=out, stderr=err, ret_code=ret)
+ raise AdbError(
+ cmd=args,
+ stdout=out,
+ stderr=err,
+ ret_code=ret,
+ serial=self.serial)
def _execute_and_process_stdout(self, args, shell, handler):
"""Executes adb commands and processes the stdout with a handler.
diff --git a/tests/mobly/controllers/android_device_lib/adb_test.py b/tests/mobly/controllers/android_device_lib/adb_test.py
index 71fab9c..63ae285 100755
--- a/tests/mobly/controllers/android_device_lib/adb_test.py
+++ b/tests/mobly/controllers/android_device_lib/adb_test.py
@@ -91,15 +91,29 @@
@mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
@mock.patch('mobly.controllers.android_device_lib.adb.psutil.Process')
- def test_exec_cmd_error_no_timeout(self, mock_psutil_process, mock_popen):
+ def test_exec_cmd_error_with_serial(self, mock_psutil_process, mock_popen):
self._mock_process(mock_psutil_process, mock_popen)
# update return code to indicate command execution error
mock_popen.return_value.returncode = 1
-
+ mock_serial = 'ABCD1234'
with self.assertRaisesRegex(adb.AdbError,
- 'Error executing adb cmd .*'):
+ 'Error executing adb cmd .*') as context:
+ adb.AdbProxy(mock_serial)._exec_cmd(
+ ['fake_cmd'], shell=False, timeout=None, stderr=None)
+ self.assertEqual(context.exception.serial, mock_serial)
+
+ @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
+ @mock.patch('mobly.controllers.android_device_lib.adb.psutil.Process')
+ def test_exec_cmd_error_without_serial(self, mock_psutil_process,
+ mock_popen):
+ self._mock_process(mock_psutil_process, mock_popen)
+ # update return code to indicate command execution error
+ mock_popen.return_value.returncode = 1
+ with self.assertRaisesRegex(adb.AdbError,
+ 'Error executing adb cmd .*') as context:
adb.AdbProxy()._exec_cmd(
['fake_cmd'], shell=False, timeout=None, stderr=None)
+ self.assertFalse(context.exception.serial)
@mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
@mock.patch('mobly.controllers.android_device_lib.adb.psutil.Process')
@@ -156,8 +170,8 @@
self._mock_execute_and_process_stdout_process(mock_popen)
mock_handler = mock.MagicMock()
mock_popen.return_value.communicate = mock.Mock(
- return_value=(unexpected_stdout, MOCK_DEFAULT_STDERR.encode(
- 'utf-8')))
+ return_value=(unexpected_stdout,
+ MOCK_DEFAULT_STDERR.encode('utf-8')))
err = adb.AdbProxy()._execute_and_process_stdout(
['fake_cmd'], shell=False, handler=mock_handler)