Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(808)

Unified Diff: tools/code_coverage/coverage_posix.py

Issue 8598003: Changes to code coverage infrastructure to allow subset coverage analysis. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« build/downloads.croc ('K') | « build/downloads.croc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/code_coverage/coverage_posix.py
diff --git a/tools/code_coverage/coverage_posix.py b/tools/code_coverage/coverage_posix.py
index aaa400aa6293e21a3c4d780144daf31c3c6fbfee..9aef0de9ada0c627ad64146d717449740d39f9b8 100755
--- a/tools/code_coverage/coverage_posix.py
+++ b/tools/code_coverage/coverage_posix.py
@@ -94,6 +94,7 @@ import logging
import optparse
import os
import Queue
+import re
import shutil
import signal
import subprocess
@@ -146,6 +147,10 @@ class RunTooLongException(Exception):
"""Thrown when a command runs too long without output."""
pass
+class BadUserInput(Exception):
+ """Thrown when arguments from the user are incorrectly formatted."""
+ pass
+
class RunProgramThread(threading.Thread):
"""A thread to run a subprocess.
@@ -316,6 +321,8 @@ class Coverage(object):
self.ConfirmPlatformAndPaths()
self.tests = []
self.xvfb_pid = 0
+ self.test_files = [] # List of files with test specifications.
+ self.test_filters = {} # Mapping from testname->--gtest_filter arg.
logging.info('self.directory: ' + self.directory)
logging.info('self.directory_parent: ' + self.directory_parent)
@@ -437,8 +444,20 @@ class Coverage(object):
if self.options.all_unittests:
self.tests += glob.glob(os.path.join(self.directory, '*_unittests'))
- # Tests can come in as args or as a file of bundles.
+ # Tests can come in as args directly, indirectly (through a file
+ # of test lists) or as a file of bundles.
all_testnames = self.args[:] # Copy since we might modify
+
+ for test_file in self.options.test_files:
+ f = open(test_file)
+ for line in f:
+ line = re.sub(r"#.*$", "", line)
+ line = re.sub(r"\s*", "", line)
+ if re.match("\s*$"):
+ continue
+ all_testnames.append(line)
+ f.close()
+
tests_from_bundles = None
if self.options.bundles:
try:
@@ -459,10 +478,18 @@ class Coverage(object):
# If told explicit tests, run those (after stripping the name as
# appropriate)
for testname in all_testnames:
+ mo = re.search(r"(.*)\[(.*)\]$", testname)
+ gtest_filter = None
+ if mo:
+ gtest_filter = mo.group(2)
+ testname = mo.group(1)
+
if ':' in testname:
- self.tests += [os.path.join(self.directory, testname.split(':')[1])]
- else:
- self.tests += [os.path.join(self.directory, testname)]
+ testname = testname.split(':')[1]
+ self.tests += [os.path.join(self.directory, testname)]
+ if gtest_filter:
+ self.test_filters[testname] = gtest_filter
+
# Medium tests?
# Not sure all of these work yet (e.g. page_cycler_tests)
# self.tests += glob.glob(os.path.join(self.directory, '*_tests'))
@@ -600,17 +627,47 @@ class Coverage(object):
Returns:
String of the form '--gtest_filter=BLAH', or None.
"""
- if self.options.no_exclusions:
- return
- exclusions = excl or gTestExclusions
- excldict = exclusions.get(sys.platform)
- if excldict:
- for test in excldict.keys():
- # example: if base_unittests in ../blah/blah/base_unittests.exe
- if test in fulltest:
- gfilter = '--gtest_filter=-' + ':-'.join(excldict[test])
- return gfilter
- return None
+ positive_gfilter_list = []
+ negative_gfilter_list = []
+
+ # Exclude all flaky and failing tests; they don't count for code coverage.
+ negative_gfilter_list += ("*.FLAKY_*", "*.FAILS_*")
+
+ if not self.options.no_exclusions:
+ exclusions = excl or gTestExclusions
+ excldict = exclusions.get(sys.platform)
+ if excldict:
+ for test in excldict.keys():
+ # example: if base_unittests in ../blah/blah/base_unittests.exe
+ if test in fulltest:
+ negative_gfilter_list += excldict[test]
+
+ fulltest_basename = os.path.basename(fulltest)
+ if fulltest_basename in self.test_filters:
+ specific_test_filters = self.test_filters[fulltest_basename].split("-")
+ if len(specific_test_filters) > 2:
+ logging.error("Multiple '-' symbols in filter list: %s" %
+ self.test_filters[fulltest_basename])
+ raise BadUserInput()
+ if len(specific_test_filters) == 2:
+ # Remove trailing ":"
+ specific_test_filters[0] = specific_test_filters[0][:-1]
+
+ if specific_test_filters[0]: # Test for no positive filters.
+ positive_gfilter_list += specific_test_filters[0].split(":")
+ if len(specific_test_filters) > 1:
+ negative_gfilter_list += specific_test_filters[1].split(":")
+
+ if not positive_gfilter_list and not negative_gfilter_list:
+ return None
+
+ result = "--gtest_filter="
+ if positive_gfilter_list:
+ result += ":".join(positive_gfilter_list)
+ if negative_gfilter_list:
+ if positive_gfilter_list: result += ":"
+ result += "-" + ":".join(negative_gfilter_list)
+ return result
def RunTests(self):
"""Run all unit tests and generate appropriate lcov files."""
@@ -888,6 +945,13 @@ def CoverageOptionParser():
default=False,
action='store_true',
help=('Turn off clearing of cov data from a prev run'))
+ parser.add_option('-F',
+ '--test-file',
+ dest="test_files",
+ default=[],
+ action="append",
+ help=('Specify a file from which tests to be run will ' +
+ 'be extracted'))
return parser
« build/downloads.croc ('K') | « build/downloads.croc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698