Merge change 434 into donut

* changes:
  Added a method in run_command.py to run a host test. The run can also happen under valgrind.
This commit is contained in:
Android (Google) Code Review
2009-04-23 14:49:30 -07:00
2 changed files with 56 additions and 20 deletions

View File

@@ -3,37 +3,37 @@
# #
# Copyright 2007, The Android Open Source Project # Copyright 2007, The Android Open Source Project
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # 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 # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# System imports # System imports
import os import os
import signal import signal
import subprocess import subprocess
import time
import threading import threading
import time
# local imports # local imports
import logger
import errors import errors
import logger
_abort_on_error = False _abort_on_error = False
def SetAbortOnError(abort=True): 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""" a negative error code"""
global _abort_on_error global _abort_on_error
_abort_on_error = abort _abort_on_error = abort
def RunCommand(cmd, timeout_time=None, retry_count=3, return_output=True): def RunCommand(cmd, timeout_time=None, retry_count=3, return_output=True):
"""Spawns a subprocess to run the given shell command, and checks for """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 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 result = None
while True: while True:
try: try:
result = RunOnce(cmd, timeout_time=timeout_time, result = RunOnce(cmd, timeout_time=timeout_time,
return_output=return_output) return_output=return_output)
except errors.WaitForResponseTimedOutError: except errors.WaitForResponseTimedOutError:
if retry_count == 0: if retry_count == 0:
@@ -59,13 +59,13 @@ def RunOnce(cmd, timeout_time=None, return_output=True):
pid = [] pid = []
global _abort_on_error global _abort_on_error
error_occurred = False error_occurred = False
def Run(): def Run():
if return_output: if return_output:
output_dest = subprocess.PIPE output_dest = subprocess.PIPE
else: else:
# None means direct to stdout # None means direct to stdout
output_dest = None output_dest = None
pipe = subprocess.Popen( pipe = subprocess.Popen(
cmd, cmd,
executable='/bin/bash', executable='/bin/bash',
@@ -83,9 +83,9 @@ def RunOnce(cmd, timeout_time=None, return_output=True):
so.append("ERROR") so.append("ERROR")
error_occurred = True error_occurred = True
if pipe.returncode < 0: 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)) pipe.returncode))
error_occurred = True error_occurred = True
t = threading.Thread(target=Run) t = threading.Thread(target=Run)
t.start() t.start()
@@ -113,5 +113,26 @@ def RunOnce(cmd, timeout_time=None, return_output=True):
if _abort_on_error and error_occurred: if _abort_on_error and error_occurred:
raise errors.AbortError raise errors.AbortError
return "".join(so) 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])

View File

@@ -44,7 +44,7 @@ class TestRunner(object):
# file path to android core platform tests, relative to android build root # file path to android core platform tests, relative to android build root
# TODO move these test data files to another directory # 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) _TEST_FILE_NAME)
# vendor glob file path patterns to tests, relative to android # vendor glob file path patterns to tests, relative to android
@@ -60,7 +60,7 @@ class TestRunner(object):
def __init__(self): def __init__(self):
# disable logging of timestamp # disable logging of timestamp
self._root_path = android_build.GetTop() self._root_path = android_build.GetTop()
logger.SetTimestampLogging(False) logger.SetTimestampLogging(False)
def _ProcessOptions(self): def _ProcessOptions(self):
"""Processes command-line options.""" """Processes command-line options."""
@@ -290,12 +290,27 @@ class TestRunner(object):
# find all test files, convert unicode names to ascii, take the basename # find all test files, convert unicode names to ascii, take the basename
# and drop the .cc/.cpp extension. # and drop the .cc/.cpp extension.
file_pattern = os.path.join(test_suite.GetBuildPath(), "test_*") file_pattern = os.path.join(test_suite.GetBuildPath(), "test_*")
logger.SilentLog("Scanning %s" % test_suite.GetBuildPath())
file_list = [] file_list = []
for f in map(str, glob.glob(file_pattern)): for f in map(str, glob.glob(file_pattern)):
f = os.path.basename(f) f = os.path.basename(f)
f = re.split(".[cp]+$", f)[0] f = re.split(".[cp]+$", f)[0]
logger.SilentLog("Found %s" % f)
file_list.append(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: for f in file_list:
full_path = "/system/bin/%s" % f full_path = "/system/bin/%s" % f