From 97b24c4d65712aab0fa15f18eac316890a5d1a34 Mon Sep 17 00:00:00 2001 From: Nicolas Catania Date: Wed, 22 Apr 2009 11:08:32 -0700 Subject: [PATCH] Added a method in run_command.py to run a host test. The run can also happen under valgrind. runtest.py: Search for host test as well. Run these under valgrind. --- testrunner/run_command.py | 57 ++++++++++++++++++++++++++------------- testrunner/runtest.py | 19 +++++++++++-- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/testrunner/run_command.py b/testrunner/run_command.py index 6b72b77b3..5336f332d 100755 --- a/testrunner/run_command.py +++ b/testrunner/run_command.py @@ -3,37 +3,37 @@ # # 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 +# 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 +# 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 +# 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 time import threading +import time # local imports -import logger import errors +import logger _abort_on_error = False def SetAbortOnError(abort=True): - """Sets behavior of RunCommand to throw AbortError if command process returns + """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): """Spawns a subprocess to run the given shell command, and checks for timeout_time. If return_output is True, the output of the command is returned @@ -42,7 +42,7 @@ def RunCommand(cmd, timeout_time=None, retry_count=3, return_output=True): result = None while True: try: - result = RunOnce(cmd, timeout_time=timeout_time, + result = RunOnce(cmd, timeout_time=timeout_time, return_output=return_output) except errors.WaitForResponseTimedOutError: if retry_count == 0: @@ -59,13 +59,13 @@ def RunOnce(cmd, timeout_time=None, return_output=True): pid = [] global _abort_on_error error_occurred = False - + def Run(): if return_output: output_dest = subprocess.PIPE else: # None means direct to stdout - output_dest = None + output_dest = None pipe = subprocess.Popen( cmd, executable='/bin/bash', @@ -83,9 +83,9 @@ def RunOnce(cmd, timeout_time=None, return_output=True): so.append("ERROR") error_occurred = True if pipe.returncode < 0: - logger.SilentLog("Error: %s was terminated by signal %d" %(cmd, + logger.SilentLog("Error: %s was terminated by signal %d" %(cmd, pipe.returncode)) - error_occurred = True + error_occurred = True t = threading.Thread(target=Run) t.start() @@ -113,5 +113,26 @@ def RunOnce(cmd, timeout_time=None, return_output=True): if _abort_on_error and error_occurred: raise errors.AbortError - + return "".join(so) + + +def RunHostCommand(binary, valgrind=False): + """Run a command on the host (opt using valgrind). + + Runs the host binary. Does not capture any output but it + returns the exit code. The command can be run under valgrind. + + Args: + binary: basename of the file to be run. It is expected to be under + out/host/linux-x86/bin. + valgrind: If True the command will be run under valgrind. + + Returns: + The command exit code (int) + """ + full_path = os.path.join("out", "host", "linux-x86", "bin", binary) + if not valgrind: + return subprocess.call(full_path) + else: + return subprocess.call(["/usr/bin/valgrind", "-q", full_path]) diff --git a/testrunner/runtest.py b/testrunner/runtest.py index 6d6c6df41..f87d451b8 100755 --- a/testrunner/runtest.py +++ b/testrunner/runtest.py @@ -44,7 +44,7 @@ class TestRunner(object): # file path to android core platform tests, relative to android build root # TODO move these test data files to another directory - _CORE_TEST_PATH = os.path.join("development", "testrunner", + _CORE_TEST_PATH = os.path.join("development", "testrunner", _TEST_FILE_NAME) # vendor glob file path patterns to tests, relative to android @@ -60,7 +60,7 @@ class TestRunner(object): def __init__(self): # disable logging of timestamp self._root_path = android_build.GetTop() - logger.SetTimestampLogging(False) + logger.SetTimestampLogging(False) def _ProcessOptions(self): """Processes command-line options.""" @@ -290,12 +290,27 @@ class TestRunner(object): # find all test files, convert unicode names to ascii, take the basename # and drop the .cc/.cpp extension. file_pattern = os.path.join(test_suite.GetBuildPath(), "test_*") + logger.SilentLog("Scanning %s" % test_suite.GetBuildPath()) file_list = [] for f in map(str, glob.glob(file_pattern)): f = os.path.basename(f) f = re.split(".[cp]+$", f)[0] + logger.SilentLog("Found %s" % f) file_list.append(f) + # Run on the host + logger.Log("\nRunning on host") + for f in file_list: + if run_command.RunHostCommand(f) != 0: + logger.Log("%s... failed" % f) + else: + if run_command.RunHostCommand(f, valgrind=True) == 0: + logger.Log("%s... ok\t\t[valgrind: ok]" % f) + else: + logger.Log("%s... ok\t\t[valgrind: failed]" % f) + + # Run on the device + logger.Log("\nRunning on target") for f in file_list: full_path = "/system/bin/%s" % f