Merge change 2687 into donut
* changes: Add support for parsing code coverage file path to runtest and related cleanup.
This commit is contained in:
@@ -157,8 +157,9 @@ class AdbInterface:
|
|||||||
separated into its package and runner components.
|
separated into its package and runner components.
|
||||||
"""
|
"""
|
||||||
instrumentation_path = "%s/%s" % (package_name, runner_name)
|
instrumentation_path = "%s/%s" % (package_name, runner_name)
|
||||||
return self.StartInstrumentation(self, instrumentation_path, timeout_time,
|
return self.StartInstrumentation(instrumentation_path, timeout_time=timeout_time,
|
||||||
no_window_animation, instrumentation_args)
|
no_window_animation=no_window_animation,
|
||||||
|
instrumentation_args=instrumentation_args)
|
||||||
|
|
||||||
def StartInstrumentation(
|
def StartInstrumentation(
|
||||||
self, instrumentation_path, timeout_time=60*10, no_window_animation=False,
|
self, instrumentation_path, timeout_time=60*10, no_window_animation=False,
|
||||||
@@ -203,7 +204,7 @@ class AdbInterface:
|
|||||||
instrumentation_path, no_window_animation=no_window_animation,
|
instrumentation_path, no_window_animation=no_window_animation,
|
||||||
profile=profile, raw_mode=True,
|
profile=profile, raw_mode=True,
|
||||||
instrumentation_args=instrumentation_args)
|
instrumentation_args=instrumentation_args)
|
||||||
|
logger.Log(command_string)
|
||||||
(test_results, inst_finished_bundle) = (
|
(test_results, inst_finished_bundle) = (
|
||||||
am_instrument_parser.ParseAmInstrumentOutput(
|
am_instrument_parser.ParseAmInstrumentOutput(
|
||||||
self.SendShellCommand(command_string, timeout_time=timeout_time,
|
self.SendShellCommand(command_string, timeout_time=timeout_time,
|
||||||
@@ -217,7 +218,7 @@ class AdbInterface:
|
|||||||
short_msg_result = "no error message"
|
short_msg_result = "no error message"
|
||||||
if "shortMsg" in inst_finished_bundle:
|
if "shortMsg" in inst_finished_bundle:
|
||||||
short_msg_result = inst_finished_bundle["shortMsg"]
|
short_msg_result = inst_finished_bundle["shortMsg"]
|
||||||
logger.Log(short_msg_result)
|
logger.Log("Error! Test run failed: %s" % short_msg_result)
|
||||||
raise errors.InstrumentationError(short_msg_result)
|
raise errors.InstrumentationError(short_msg_result)
|
||||||
|
|
||||||
if "INSTRUMENTATION_ABORTED" in inst_finished_bundle:
|
if "INSTRUMENTATION_ABORTED" in inst_finished_bundle:
|
||||||
|
|||||||
@@ -44,16 +44,15 @@ class CoverageGenerator(object):
|
|||||||
# path to EMMA host jar, relative to Android build root
|
# path to EMMA host jar, relative to Android build root
|
||||||
_EMMA_JAR = os.path.join(_EMMA_BUILD_PATH, "lib", "emma.jar")
|
_EMMA_JAR = os.path.join(_EMMA_BUILD_PATH, "lib", "emma.jar")
|
||||||
_TEST_COVERAGE_EXT = "ec"
|
_TEST_COVERAGE_EXT = "ec"
|
||||||
# default device-side path to code coverage results file
|
|
||||||
_DEVICE_COVERAGE_PATH = "/sdcard/coverage.ec"
|
|
||||||
# root path of generated coverage report files, relative to Android build root
|
# root path of generated coverage report files, relative to Android build root
|
||||||
_COVERAGE_REPORT_PATH = os.path.join("out", "emma")
|
_COVERAGE_REPORT_PATH = os.path.join("out", "emma")
|
||||||
|
_TARGET_DEF_FILE = "coverage_targets.xml"
|
||||||
_CORE_TARGET_PATH = os.path.join("development", "testrunner",
|
_CORE_TARGET_PATH = os.path.join("development", "testrunner",
|
||||||
"coverage_targets.xml")
|
_TARGET_DEF_FILE)
|
||||||
# vendor glob file path patterns to tests, relative to android
|
# vendor glob file path patterns to tests, relative to android
|
||||||
# build root
|
# build root
|
||||||
_VENDOR_TARGET_PATH = os.path.join("vendor", "*", "tests", "testinfo",
|
_VENDOR_TARGET_PATH = os.path.join("vendor", "*", "tests", "testinfo",
|
||||||
"coverage_targets.xml")
|
_TARGET_DEF_FILE)
|
||||||
|
|
||||||
# path to root of target build intermediates
|
# path to root of target build intermediates
|
||||||
_TARGET_INTERMEDIATES_BASE_PATH = os.path.join("out", "target", "common",
|
_TARGET_INTERMEDIATES_BASE_PATH = os.path.join("out", "target", "common",
|
||||||
@@ -93,7 +92,7 @@ class CoverageGenerator(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def ExtractReport(self, test_suite,
|
def ExtractReport(self, test_suite,
|
||||||
device_coverage_path=_DEVICE_COVERAGE_PATH,
|
device_coverage_path,
|
||||||
output_path=None):
|
output_path=None):
|
||||||
"""Extract runtime coverage data and generate code coverage report.
|
"""Extract runtime coverage data and generate code coverage report.
|
||||||
|
|
||||||
@@ -122,8 +121,14 @@ class CoverageGenerator(object):
|
|||||||
report_path = os.path.join(output_path,
|
report_path = os.path.join(output_path,
|
||||||
test_suite.GetName())
|
test_suite.GetName())
|
||||||
target = self._targets_manifest.GetTarget(test_suite.GetTargetName())
|
target = self._targets_manifest.GetTarget(test_suite.GetTargetName())
|
||||||
return self._GenerateReport(report_path, coverage_local_path, [target],
|
if target is None:
|
||||||
do_src=True)
|
msg = ["Error: test %s references undefined target %s."
|
||||||
|
% (test_suite.GetName(), test_suite.GetTargetName())]
|
||||||
|
msg.append(" Ensure target is defined in %s" % self._TARGET_DEF_FILE)
|
||||||
|
logger.Log("".join(msg))
|
||||||
|
else:
|
||||||
|
return self._GenerateReport(report_path, coverage_local_path, [target],
|
||||||
|
do_src=True)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _GenerateReport(self, report_path, coverage_file_path, targets,
|
def _GenerateReport(self, report_path, coverage_file_path, targets,
|
||||||
|
|||||||
@@ -278,16 +278,53 @@ class TestRunner(object):
|
|||||||
raw_mode=self._options.raw_mode,
|
raw_mode=self._options.raw_mode,
|
||||||
instrumentation_args=instrumentation_args)
|
instrumentation_args=instrumentation_args)
|
||||||
logger.Log(adb_cmd)
|
logger.Log(adb_cmd)
|
||||||
|
elif self._options.coverage:
|
||||||
|
# need to parse test output to determine path to coverage file
|
||||||
|
logger.Log("Running in coverage mode, suppressing test output")
|
||||||
|
try:
|
||||||
|
(test_results, status_map) = self._adb.StartInstrumentationForPackage(
|
||||||
|
package_name=test_suite.GetPackageName(),
|
||||||
|
runner_name=test_suite.GetRunnerName(),
|
||||||
|
timeout_time=60*60,
|
||||||
|
instrumentation_args=instrumentation_args)
|
||||||
|
except errors.InstrumentationError, errors.DeviceUnresponsiveError:
|
||||||
|
return
|
||||||
|
self._PrintTestResults(test_results)
|
||||||
|
device_coverage_path = status_map.get("coverageFilePath", None)
|
||||||
|
if device_coverage_path is None:
|
||||||
|
logger.Log("Error: could not find coverage data on device")
|
||||||
|
return
|
||||||
|
coverage_file = self._coverage_gen.ExtractReport(test_suite, device_coverage_path)
|
||||||
|
if coverage_file is not None:
|
||||||
|
logger.Log("Coverage report generated at %s" % coverage_file)
|
||||||
else:
|
else:
|
||||||
self._adb.StartInstrumentationNoResults(
|
self._adb.StartInstrumentationNoResults(
|
||||||
package_name=test_suite.GetPackageName(),
|
package_name=test_suite.GetPackageName(),
|
||||||
runner_name=test_suite.GetRunnerName(),
|
runner_name=test_suite.GetRunnerName(),
|
||||||
raw_mode=self._options.raw_mode,
|
raw_mode=self._options.raw_mode,
|
||||||
instrumentation_args=instrumentation_args)
|
instrumentation_args=instrumentation_args)
|
||||||
if self._options.coverage and test_suite.GetTargetName() is not None:
|
|
||||||
coverage_file = self._coverage_gen.ExtractReport(test_suite)
|
def _PrintTestResults(self, test_results):
|
||||||
if coverage_file is not None:
|
"""Prints a summary of test result data to stdout.
|
||||||
logger.Log("Coverage report generated at %s" % coverage_file)
|
|
||||||
|
Args:
|
||||||
|
test_results: a list of am_instrument_parser.TestResult
|
||||||
|
"""
|
||||||
|
total_count = 0
|
||||||
|
error_count = 0
|
||||||
|
fail_count = 0
|
||||||
|
for test_result in test_results:
|
||||||
|
if test_result.GetStatusCode() == -1: # error
|
||||||
|
logger.Log("Error in %s: %s" % (test_result.GetTestName(),
|
||||||
|
test_result.GetFailureReason()))
|
||||||
|
error_count+=1
|
||||||
|
elif test_result.GetStatusCode() == -2: # failure
|
||||||
|
logger.Log("Failure in %s: %s" % (test_result.GetTestName(),
|
||||||
|
test_result.GetFailureReason()))
|
||||||
|
fail_count+=1
|
||||||
|
total_count+=1
|
||||||
|
logger.Log("Tests run: %d, Failures: %d, Errors: %d" %
|
||||||
|
(total_count, fail_count, error_count))
|
||||||
|
|
||||||
def _CollectTestSources(self, test_list, dirname, files):
|
def _CollectTestSources(self, test_list, dirname, files):
|
||||||
"""For each directory, find tests source file and add them to the list.
|
"""For each directory, find tests source file and add them to the list.
|
||||||
|
|||||||
Reference in New Issue
Block a user