faft: Separate the run_shell_command method that returns a result.
In CL:1863838, the behavior for block=True changed, breaking tests.
Before, it waited for process to exit; after, it waited for stdout
to be read as well.
This commit changes the method back to its old behavior, and adds a
separate method to give a result with stdout, stderr, and returncode.
BUG=b:147227865
TEST=Run firmware_FAFTRPC.system
Change-Id: Ie516a8baed2b5d1a19ca764e62f037e224da16e3
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/1988732
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Tested-by: Dana Goyette <dgoyette@chromium.org>
Commit-Queue: Dana Goyette <dgoyette@chromium.org>
diff --git a/client/cros/faft/rpc_functions.py b/client/cros/faft/rpc_functions.py
index a14d5a4..8f75386 100644
--- a/client/cros/faft/rpc_functions.py
+++ b/client/cros/faft/rpc_functions.py
@@ -766,8 +766,8 @@
@return: A string of the model name.
"""
- model = cros_config.call_cros_config_get_output('/ name',
- self._os_if.run_shell_command)
+ model = cros_config.call_cros_config_get_output(
+ '/ name', self._os_if.run_shell_command_get_result)
if not model:
raise Exception('Failed getting model name from cros_config')
return model
diff --git a/client/cros/faft/utils/firmware_updater.py b/client/cros/faft/utils/firmware_updater.py
index 6a06efd..9c54649 100644
--- a/client/cros/faft/utils/firmware_updater.py
+++ b/client/cros/faft/utils/firmware_updater.py
@@ -405,7 +405,7 @@
@type shellball: str | None
"""
model_result = cros_config.call_cros_config_get_output(
- '/ name', self.os_if.run_shell_command)
+ '/ name', self.os_if.run_shell_command_get_result)
if not model_result:
return
diff --git a/client/cros/faft/utils/os_interface.py b/client/cros/faft/utils/os_interface.py
index a891bbb..739ca0e 100644
--- a/client/cros/faft/utils/os_interface.py
+++ b/client/cros/faft/utils/os_interface.py
@@ -93,19 +93,27 @@
This should be set for RPC commands that alter
the OS or firmware in some persistent way.
- @return: the result of the command, or None if skipped for test mode.
- @rtype: autotest_lib.client.common_lib.utils.CmdResult | None
@raise autotest_lib.client.common_lib.error.CmdError: if command fails
"""
if self.test_mode and modifies_device:
self.log('[SKIPPED] %s' % cmd)
else:
- return self.shell.run_command(cmd)
+ self.shell.run_command(cmd)
def run_shell_command_check_output(self, cmd, success_token):
"""Run shell command and check its stdout for a string."""
return self.shell.run_command_check_output(cmd, success_token)
+ def run_shell_command_get_result(self, cmd, ignore_status=False):
+ """Run shell command and get a CmdResult object as a result.
+
+ @param cmd: the command to run
+ @param ignore_status: if True, do not raise CmdError, even if rc != 0.
+ @rtype: autotest_lib.client.common_lib.utils.CmdResult
+ @raise autotest_lib.client.common_lib.error.CmdError: if command fails
+ """
+ return self.shell.run_command_get_result(cmd, ignore_status)
+
def run_shell_command_get_status(self, cmd):
"""Run shell command and return its return code."""
return self.shell.run_command_get_status(cmd)
diff --git a/client/cros/faft/utils/shell_wrapper.py b/client/cros/faft/utils/shell_wrapper.py
index fe7000d..3aec171 100644
--- a/client/cros/faft/utils/shell_wrapper.py
+++ b/client/cros/faft/utils/shell_wrapper.py
@@ -48,23 +48,42 @@
all output.
@raise error.CmdError: if block is True and command fails (rc!=0)
- @return: the result, if block is True
-
- @rtype: utils.CmdResult | None
"""
start_time = time.time()
- process = self._run_command(cmd)
- if block:
+ process = self._run_command(cmd, block)
+ if process.returncode:
returncode = process.returncode
stdout = process.stdout.read()
stderr = process.stderr.read()
duration = time.time() - start_time
result = utils.CmdResult(cmd, stdout, stderr, returncode, duration)
- if returncode:
- self._os_if.log('Command failed.\n%s' % result)
- raise error.CmdError(cmd, result)
- else:
- return result
+ self._os_if.log('Command failed.\n%s' % result)
+ raise error.CmdError(cmd, result)
+
+ def run_command_get_result(self, cmd, ignore_status=False):
+ """Run a shell command, and get the result (output and returncode).
+
+ @param ignore_status: if True, do not raise CmdError, even if rc != 0.
+ @raise error.CmdError: if command fails (rc!=0) and not ignore_result
+ @return the result of the command
+ @rtype: utils.CmdResult
+ """
+ start_time = time.time()
+
+ process = self._run_command(cmd, block=True)
+
+ returncode = process.returncode
+ stdout = process.stdout.read()
+ stderr = process.stderr.read()
+ duration = time.time() - start_time
+ result = utils.CmdResult(cmd, stdout, stderr, returncode, duration)
+
+ if returncode and not ignore_status:
+ self._os_if.log('Command failed:\n%s' % result)
+ raise error.CmdError(cmd, result)
+
+ self._os_if.log('Command result:\n%s' % result)
+ return result
def run_command_check_output(self, cmd, success_token):
"""Run a command and check whether standard output contains some string.