Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: third_party/android_testrunner/run_command.py

Issue 1288993002: Revert of [Android] Remove android_commands and android_testrunner. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/android_testrunner/patch.diff ('k') | tools/android/appstats.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/android_testrunner/run_command.py
diff --git a/third_party/android_testrunner/run_command.py b/third_party/android_testrunner/run_command.py
new file mode 100644
index 0000000000000000000000000000000000000000..6b84156fe0e549b50a8a0c996e754b67e41cd799
--- /dev/null
+++ b/third_party/android_testrunner/run_command.py
@@ -0,0 +1,192 @@
+#!/usr/bin/python2.4
+#
+#
+# Copyright 2007, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# System imports
+import os
+import signal
+import subprocess
+import tempfile
+import threading
+import time
+
+# local imports
+import errors
+import logger
+
+_abort_on_error = False
+
+def SetAbortOnError(abort=True):
+ """Sets behavior of RunCommand to throw AbortError if command process returns
+ a negative error code"""
+ global _abort_on_error
+ _abort_on_error = abort
+
+def RunCommand(cmd, timeout_time=None, retry_count=3, return_output=True,
+ stdin_input=None):
+ """Spawn and retry a subprocess to run the given shell command.
+
+ Args:
+ cmd: shell command to run
+ timeout_time: time in seconds to wait for command to run before aborting.
+ retry_count: number of times to retry command
+ return_output: if True return output of command as string. Otherwise,
+ direct output of command to stdout.
+ stdin_input: data to feed to stdin
+ Returns:
+ output of command
+ """
+ result = None
+ while True:
+ try:
+ result = RunOnce(cmd, timeout_time=timeout_time,
+ return_output=return_output, stdin_input=stdin_input)
+ except errors.WaitForResponseTimedOutError:
+ if retry_count == 0:
+ raise
+ retry_count -= 1
+ logger.Log("No response for %s, retrying" % cmd)
+ else:
+ # Success
+ return result
+
+def RunOnce(cmd, timeout_time=None, return_output=True, stdin_input=None):
+ """Spawns a subprocess to run the given shell command.
+
+ Args:
+ cmd: shell command to run
+ timeout_time: time in seconds to wait for command to run before aborting.
+ return_output: if True return output of command as string. Otherwise,
+ direct output of command to stdout.
+ stdin_input: data to feed to stdin
+ Returns:
+ output of command
+ Raises:
+ errors.WaitForResponseTimedOutError if command did not complete within
+ timeout_time seconds.
+ errors.AbortError is command returned error code and SetAbortOnError is on.
+ """
+ start_time = time.time()
+ so = []
+ global _abort_on_error, error_occurred
+ error_occurred = False
+
+ if return_output:
+ output_dest = tempfile.TemporaryFile(bufsize=0)
+ else:
+ # None means direct to stdout
+ output_dest = None
+ if stdin_input:
+ stdin_dest = subprocess.PIPE
+ else:
+ stdin_dest = None
+ pipe = subprocess.Popen(
+ cmd,
+ executable='/bin/bash',
+ stdin=stdin_dest,
+ stdout=output_dest,
+ stderr=subprocess.STDOUT,
+ shell=True, close_fds=True,
+ preexec_fn=lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL))
+
+ def Run():
+ global error_occurred
+ try:
+ pipe.communicate(input=stdin_input)
+ output = None
+ if return_output:
+ output_dest.seek(0)
+ output = output_dest.read()
+ output_dest.close()
+ if output is not None and len(output) > 0:
+ so.append(output)
+ except OSError, e:
+ logger.SilentLog("failed to retrieve stdout from: %s" % cmd)
+ logger.Log(e)
+ so.append("ERROR")
+ error_occurred = True
+ if pipe.returncode:
+ logger.SilentLog("Error: %s returned %d error code" %(cmd,
+ pipe.returncode))
+ error_occurred = True
+
+ t = threading.Thread(target=Run)
+ t.start()
+ t.join(timeout_time)
+ if t.isAlive():
+ try:
+ pipe.kill()
+ except OSError:
+ # Can't kill a dead process.
+ pass
+ finally:
+ logger.SilentLog("about to raise a timeout for: %s" % cmd)
+ raise errors.WaitForResponseTimedOutError
+
+ output = "".join(so)
+ if _abort_on_error and error_occurred:
+ raise errors.AbortError(msg=output)
+
+ return "".join(so)
+
+
+def RunHostCommand(binary, valgrind=False):
+ """Run a command on the host (opt using valgrind).
+
+ Runs the host binary and returns the exit code.
+ If successfull, the output (stdout and stderr) are discarded,
+ but printed in case of error.
+ The command can be run under valgrind in which case all the
+ output are always discarded.
+
+ Args:
+ binary: full path of the file to be run.
+ valgrind: If True the command will be run under valgrind.
+
+ Returns:
+ The command exit code (int)
+ """
+ if not valgrind:
+ subproc = subprocess.Popen(binary, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ subproc.wait()
+ if subproc.returncode != 0: # In case of error print the output
+ print subproc.communicate()[0]
+ return subproc.returncode
+ else:
+ # Need the full path to valgrind to avoid other versions on the system.
+ subproc = subprocess.Popen(["/usr/bin/valgrind", "--tool=memcheck",
+ "--leak-check=yes", "-q", binary],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ # Cannot rely on the retcode of valgrind. Instead look for an empty output.
+ valgrind_out = subproc.communicate()[0].strip()
+ if valgrind_out:
+ print valgrind_out
+ return 1
+ else:
+ return 0
+
+
+def HasValgrind():
+ """Check that /usr/bin/valgrind exists.
+
+ We look for the fullpath to avoid picking up 'alternative' valgrind
+ on the system.
+
+ Returns:
+ True if a system valgrind was found.
+ """
+ return os.path.exists("/usr/bin/valgrind")
« no previous file with comments | « third_party/android_testrunner/patch.diff ('k') | tools/android/appstats.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698