Simplify local_host.run
+ Also preserves the original stack trace from utils.run for better
error reporting.
BUG=chromium:684311
TEST=unittests
Change-Id: If8b386fe261e03a55e7419921a9368506c25173c
Reviewed-on: https://chromium-review.googlesource.com/567758
Commit-Ready: Prathmesh Prabhu <[email protected]>
Tested-by: Prathmesh Prabhu <[email protected]>
Reviewed-by: Prathmesh Prabhu <[email protected]>
Reviewed-by: Xixuan Wu <[email protected]>
diff --git a/client/bin/local_host.py b/client/bin/local_host.py
index 7d8db26..2f0a91b 100644
--- a/client/bin/local_host.py
+++ b/client/bin/local_host.py
@@ -3,11 +3,18 @@
"""
This file contains the implementation of a host object for the local machine.
"""
+import distutils.core
+import glob
+import os
+import platform
+import shutil
+import sys
-import distutils.core, glob, os, platform, shutil
+import common
from autotest_lib.client.common_lib import hosts, error
from autotest_lib.client.bin import utils
+
class LocalHost(hosts.Host):
"""This class represents a host running locally on the host."""
@@ -44,23 +51,20 @@
@see common_lib.hosts.Host.run()
"""
try:
- result = utils.run(
- command, timeout=timeout, ignore_status=True,
- ignore_timeout=ignore_timeout,
- stdout_tee=stdout_tee, stderr_tee=stderr_tee, stdin=stdin,
- args=args)
- except error.CmdError, e:
- # this indicates a timeout exception
- raise error.AutotestHostRunError('command timed out', e.result_obj)
-
- if ignore_timeout and result is None:
- # We have timed out, there is no result to report.
- return None
-
- if not ignore_status and result.exit_status > 0:
- raise error.AutotestHostRunError('command execution error', result)
-
- return result
+ return utils.run(
+ command, timeout=timeout, ignore_status=ignore_status,
+ ignore_timeout=ignore_timeout, stdout_tee=stdout_tee,
+ stderr_tee=stderr_tee, stdin=stdin, args=args)
+ except error.CmdTimeoutError as e:
+ # CmdTimeoutError is a subclass of CmdError, so must be caught first
+ new_error = error.AutotestHostRunTimeoutError(
+ e.command, e.result_obj, additional_text=e.additional_text)
+ raise error.AutotestHostRunTimeoutError, new_error, \
+ sys.exc_info()[2]
+ except error.CmdError as e:
+ new_error = error.AutotestHostRunCmdError(
+ e.command, e.result_obj, additional_text=e.additional_text)
+ raise error.AutotestHostRunCmdError, new_error, sys.exc_info()[2]
def list_files_glob(self, path_glob):
diff --git a/client/bin/local_host_unittest.py b/client/bin/local_host_unittest.py
index 51ca71d..f5bc5f5 100755
--- a/client/bin/local_host_unittest.py
+++ b/client/bin/local_host_unittest.py
@@ -71,24 +71,41 @@
@mock.patch('autotest_lib.client.bin.local_host.utils.run')
- def test_run_failure_raised(self, mock_run):
- result = local_host.utils.CmdResult(
- command='yes',
- stdout='',
- stderr='err',
- exit_status=1,
- duration=1,
- )
- mock_run.return_value = result
+ def test_run_cmd_failure_raised(self, mock_run):
+ mock_result = mock.MagicMock()
+ mock_run.side_effect = error.CmdError('yes', mock_result)
host = local_host.LocalHost()
- with self.assertRaises(error.AutotestHostRunError):
+ with self.assertRaises(error.AutotestHostRunCmdError) as exc_cm:
host.run('yes', timeout=123)
+ self.assertEqual(exc_cm.exception.result_obj, mock_result)
mock_run.assert_called_once_with(
- result.command,
+ 'yes',
timeout=123,
- ignore_status=True,
+ ignore_status=False,
+ stdout_tee=local_host.utils.TEE_TO_LOGS,
+ stderr_tee=local_host.utils.TEE_TO_LOGS,
+ stdin=None,
+ ignore_timeout=False,
+ args=(),
+ )
+
+
+ @mock.patch('autotest_lib.client.bin.local_host.utils.run')
+ def test_run_cmd_timeout_raised(self, mock_run):
+ mock_result = mock.MagicMock()
+ mock_run.side_effect = error.CmdTimeoutError('yes', mock_result)
+
+ host = local_host.LocalHost()
+ with self.assertRaises(error.AutotestHostRunTimeoutError) as exc_cm:
+ host.run('yes', timeout=123)
+
+ self.assertEqual(exc_cm.exception.result_obj, mock_result)
+ mock_run.assert_called_once_with(
+ 'yes',
+ timeout=123,
+ ignore_status=False,
stdout_tee=local_host.utils.TEE_TO_LOGS,
stderr_tee=local_host.utils.TEE_TO_LOGS,
stdin=None,
diff --git a/client/common_lib/error.py b/client/common_lib/error.py
index 4268870..f9babce 100644
--- a/client/common_lib/error.py
+++ b/client/common_lib/error.py
@@ -210,6 +210,30 @@
pass
+class AutotestHostRunCmdError(AutotestHostRunError):
+ """Indicates that the command run via Host.run failed.
+
+ This is equivalent to CmdError when raised from a Host object instead of
+ directly on the DUT using utils.run
+ """
+
+ def __init__(self, command, result_obj, additional_text=''):
+ description = command
+ if additional_text:
+ description += ' (%s)' % additional_text
+ super(AutotestHostRunCmdError, self).__init__(description, result_obj)
+ self.command = command
+ self.additional_text = additional_text
+
+
+class AutotestHostRunTimeoutError(AutotestHostRunCmdError):
+ """Indicates that a command run via Host.run timed out.
+
+ This is equivalent to CmdTimeoutError when raised from a Host object instead
+ of directly on the DUT using utils.run
+ """
+
+
# server-specific errors
class AutoservError(Exception):