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:
@@ -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])
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user