am 08e5a8ae: Merge "Coverage and unbundling changes for runtest." into jb-mr1-dev

* commit '08e5a8ae69a8d6f9d50cc84768c85a73ddfa748f':
  Coverage and unbundling changes for runtest.
This commit is contained in:
Brett Chabot
2012-09-10 07:59:59 -07:00
committed by Android Git Automerger
5 changed files with 56 additions and 54 deletions

View File

@@ -1 +1,2 @@
*.pyc
.*

View File

@@ -131,6 +131,17 @@ class AdbInterface:
logger.Log("ADB Pull Failed: Source file %s does not exist." % src)
return False
def Install(self, apk_path):
"""Installs apk on device.
Args:
apk_path: file path to apk file on host
Returns:
output of install command
"""
return self.SendCommand("install -r %s" % apk_path)
def DoesFileExist(self, src):
"""Checks if the given path exists on device target.

View File

@@ -289,25 +289,6 @@ def EnableCoverageBuild():
os.environ["EMMA_INSTRUMENT"] = "true"
def TestDeviceCoverageSupport(adb):
"""Check if device has support for generating code coverage metrics.
This tries to dump emma help information on device, a response containing
help information will indicate that emma is already on system class path.
Returns:
True if device can support code coverage. False otherwise.
"""
try:
output = adb.SendShellCommand("exec app_process / emma -h")
if output.find('emma usage:') == 0:
return True
except errors.AbortError:
pass
return False
def Run():
"""Does coverage operations based on command line args."""
# TODO: do we want to support combining coverage for a single target

View File

@@ -33,6 +33,7 @@ Do runtest --help to see full list of options.
import glob
import optparse
import os
import re
from sets import Set
import sys
import time
@@ -73,6 +74,13 @@ class TestRunner(object):
_DALVIK_VERIFIER_OFF_PROP = "dalvik.vm.dexopt-flags = v=n"
# regular expression to match install: statements in make output
_RE_MAKE_INSTALL = re.compile(r'Install:\s(.+)')
# regular expression to find remote device path from a file path relative
# to build root
_RE_MAKE_INSTALL_PATH = re.compile(r'out\/target\/product\/\w+\/(.+)$')
def __init__(self):
# disable logging of timestamp
self._root_path = android_build.GetTop()
@@ -243,23 +251,11 @@ class TestRunner(object):
self._adb.EnableAdbRoot()
else:
logger.Log("adb root")
rebuild_libcore = False
if target_set:
if self._options.coverage:
coverage.EnableCoverageBuild()
# hack to remove core library intermediates
# hack is needed because:
# 1. EMMA_INSTRUMENT changes what source files to include in libcore
# but it does not trigger a rebuild
# 2. there's no target (like "clear-intermediates") to remove the files
# decently
rebuild_libcore = not coverage.TestDeviceCoverageSupport(self._adb)
if rebuild_libcore:
cmd = "rm -rf %s" % os.path.join(
self._root_path,
"out/target/common/obj/JAVA_LIBRARIES/core_intermediates/")
logger.Log(cmd)
run_command.RunCommand(cmd, return_output=False)
target_set.append("external/emma/Android.mk")
# TODO: detect if external/emma exists
target_build_string = " ".join(target_set)
extra_args_string = " ".join(extra_args_set)
@@ -270,17 +266,38 @@ class TestRunner(object):
target_build_string, self._options.make_jobs, self._root_path,
extra_args_string)
logger.Log(cmd)
if not self._options.preview:
output = run_command.RunCommand(cmd, return_output=True, timeout_time=600)
self._DoInstall(output)
if self._options.preview:
# in preview mode, just display to the user what command would have been
# run
logger.Log("adb sync")
def _DoInstall(self, make_output):
"""Install artifacts from build onto device.
Looks for 'install:' text from make output to find artifacts to install.
Args:
make_output: stdout from make command
"""
for line in make_output.split("\n"):
m = self._RE_MAKE_INSTALL.match(line)
if m:
install_path = m.group(1)
if install_path.endswith(".apk"):
abs_install_path = os.path.join(self._root_path, install_path)
logger.Log("adb install -r %s" % abs_install_path)
logger.Log(self._adb.Install(abs_install_path))
else:
# set timeout for build to 10 minutes, since libcore may need to
# be rebuilt
run_command.RunCommand(cmd, return_output=False, timeout_time=600)
logger.Log("Syncing to device...")
self._adb.Sync(runtime_restart=rebuild_libcore)
self._PushInstallFileToDevice(install_path)
def _PushInstallFileToDevice(self, install_path):
m = self._RE_MAKE_INSTALL_PATH.match(install_path)
if m:
remote_path = m.group(1)
abs_install_path = os.path.join(self._root_path, install_path)
logger.Log("adb push %s %s", abs_install_path, remote_path)
self._adb.Push(abs_install_path, remote_path)
else:
logger.Log("Error: Failed to recognize path of file to install %s" % install_path)
def _DoFullBuild(self, tests):
"""If necessary, run a full 'make' command for the tests that need it."""
@@ -309,8 +326,9 @@ class TestRunner(object):
if not self._options.preview:
old_dir = os.getcwd()
os.chdir(self._root_path)
run_command.RunCommand(cmd, return_output=False)
output = run_command.RunCommand(cmd, return_output=False)
os.chdir(old_dir)
self._DoInstall(output)
def _AddBuildTarget(self, test_suite, target_set, extra_args_set):
if not test_suite.IsFullMake():
@@ -369,7 +387,7 @@ class TestRunner(object):
If one or more tests needs dalvik verifier off, and it is not already off,
turns off verifier and reboots device to allow change to take effect.
"""
# hack to check if these are framework/base tests. If so, turn off verifier
# hack to check if these are frameworks/base tests. If so, turn off verifier
# to allow framework tests to access package-private framework api
framework_test = False
for test in test_list:

View File

@@ -33,9 +33,6 @@ class InstrumentationTestSuite(test_suite.AbstractTestSuite):
DEFAULT_RUNNER = "android.test.InstrumentationTestRunner"
# dependency on libcore (used for Emma)
_LIBCORE_BUILD_PATH = "libcore"
def __init__(self):
test_suite.AbstractTestSuite.__init__(self)
self._package_name = None
@@ -87,8 +84,6 @@ class InstrumentationTestSuite(test_suite.AbstractTestSuite):
return self
def GetBuildDependencies(self, options):
if options.coverage:
return [self._LIBCORE_BUILD_PATH]
return []
def Run(self, options, adb):
@@ -145,8 +140,6 @@ class InstrumentationTestSuite(test_suite.AbstractTestSuite):
logger.Log(adb_cmd)
elif options.coverage:
coverage_gen = coverage.CoverageGenerator(adb)
adb.WaitForInstrumentation(self.GetPackageName(),
self.GetRunnerName())
# need to parse test output to determine path to coverage file
logger.Log("Running in coverage mode, suppressing test output")
try:
@@ -168,8 +161,6 @@ class InstrumentationTestSuite(test_suite.AbstractTestSuite):
if coverage_file is not None:
logger.Log("Coverage report generated at %s" % coverage_file)
else:
adb.WaitForInstrumentation(self.GetPackageName(),
self.GetRunnerName())
adb.StartInstrumentationNoResults(
package_name=self.GetPackageName(),
runner_name=self.GetRunnerName(),