1. Removed the system() and system_output() implementations from client/bin/autotest_utils.py so that the ones in common_lib/utils.py are used throughout.
2. Add an optional parameter to system_output() in client/common_lib/utils.py to retain stdout and not throw it away.
3. Renamed ignorestatus to ignore_status to make it consistent with the rest of the code.
4. Modified the tests to use the renamed ignore_status option
5. Modifed the CmdError() implementation in client/common_lib/error.py and made sure all the places on the server side, that expect a AutoservRunError exception are changed to expect and handle a CmdError exception instead.
Signed-off-by: Ashwin Ganti <aganti@google.com>
git-svn-id: http://test.kernel.org/svn/autotest/trunk@1499 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/client/common_lib/utils.py b/client/common_lib/utils.py
index f3805dc..2a9db31 100644
--- a/client/common_lib/utils.py
+++ b/client/common_lib/utils.py
@@ -136,7 +136,7 @@
a CmdResult object
Raises:
- AutoservRunError: the exit code of the command
+ CmdError: the exit code of the command
execution was not 0
"""
return join_bg_job(run_bg(command), timeout, ignore_status,
@@ -158,15 +158,16 @@
sp, result = bg_job
stdout_file = StringIO.StringIO()
stderr_file = StringIO.StringIO()
+ (ret, timeouterr) = (0, False)
try:
# We are holding ends to stdin, stdout pipes
# hence we need to be sure to close those fds no mater what
start_time = time.time()
- ret = _wait_for_command(sp, start_time, timeout, stdout_file,
- stderr_file, stdout_tee, stderr_tee)
+ (ret, timeouterr) = _wait_for_command(sp, start_time,
+ timeout, stdout_file, stderr_file,
+ stdout_tee, stderr_tee)
result.exit_status = ret
-
result.duration = time.time() - start_time
# don't use os.read now, so we get all the rest of the output
_process_output(sp.stdout, stdout_file, stdout_tee,
@@ -181,12 +182,17 @@
result.stdout = stdout_file.getvalue()
result.stderr = stderr_file.getvalue()
- if not ignore_status and result.exit_status > 0:
- raise error.AutoservRunError("command execution error", result)
+ if result.exit_status != 0:
+ if timeouterr:
+ raise error.CmdError('Command not complete within'
+ ' %s seconds' % timeout, result)
+ elif not ignore_status:
+ raise error.CmdError("command execution error", result)
return result
-
+# this returns a tuple with the return code and a flag to specify if the error
+# is due to the process not terminating within timeout
def _wait_for_command(subproc, start_time, timeout, stdout_file, stderr_file,
stdout_tee, stderr_tee):
if timeout:
@@ -211,16 +217,17 @@
exit_status_indication = subproc.poll()
if exit_status_indication is not None:
- return exit_status_indication
+ return (exit_status_indication, False)
+
if timeout:
time_left = stop_time - time.time()
# the process has not terminated within timeout,
# kill it via an escalating series of signals.
if exit_status_indication is None:
- nuke_subprocess(subproc)
- raise error.AutoservRunError('Command not complete within %s seconds'
- % timeout, None)
+ exit_status_indication = nuke_subprocess(subproc)
+
+ return (exit_status_indication, True)
def _process_output(pipe, fbuffer, teefile=None, use_os_read=True):
@@ -248,7 +255,7 @@
for i in range(5):
rc = subproc.poll()
if rc != None:
- return
+ return rc
time.sleep(1)
@@ -296,8 +303,13 @@
stdout_tee=sys.stdout, stderr_tee=sys.stderr).exit_status
-def system_output(command, timeout=None, ignore_status=False):
- out = run(command, timeout, ignore_status).stdout
+def system_output(command, timeout=None, ignore_status=False,
+ retain_output=False):
+ if retain_output:
+ out = run(command, timeout, ignore_status,
+ stdout_tee=sys.stdout, stderr_tee=sys.stderr).stdout
+ else:
+ out = run(command, timeout, ignore_status).stdout
if out[-1:] == '\n': out = out[:-1]
return out