summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/common.gypi11
-rw-r--r--chrome/chrome.gyp15
-rwxr-xr-xtools/code_coverage/coverage_posix.py71
3 files changed, 76 insertions, 21 deletions
diff --git a/build/common.gypi b/build/common.gypi
index 93e9df9..5ab5edc 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -72,16 +72,13 @@
}],
],
}],
- # TODO(jrg): complete this work once Linux transitions to gyp.
- # This is untested (--> likely doesn't work).
+ # Linux gyp (into scons) doesn't like target_conditions?
+ # TODO(???): track down why 'target_conditions' doesn't work
+ # on Linux gyp into scons like it does on Mac gyp into xcodeproj.
['OS=="linux"', {
'cflags': [ '-ftest-coverage',
'-fprofile-arcs' ],
- 'target_conditions': [
- ['_type=="executable"', {
- 'link_settings': { 'libraries': [ '-lgcov' ] },
- }],
- ],
+ 'link_settings': { 'libraries': [ '-lgcov' ] },
}],
]},
# TODO(jrg): options for code coverage on Windows
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index a22dcf2..ffce28c 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -3000,8 +3000,7 @@
]}, # 'targets'
], # OS=="win"
# TODO(jrg): add in Windows code coverage targets.
- # Also test on Linux.
- ['coverage!=0 and OS=="mac"',
+ ['coverage!=0 and OS!="win"',
{ 'targets': [
{
'target_name': 'coverage',
@@ -3011,16 +3010,26 @@
'type': 'none',
'dependencies': [
'../base/base.gyp:base_unittests',
+ '../media/media.gyp:media_unittests',
+ '../net/net.gyp:net_unittests',
+ '../printing/printing.gyp:printing_unittests',
],
'actions': [
{
+ # 'message' for Linux/scons in particular
+ 'message': 'Running coverage_posix.py to generate coverage numbers',
'inputs': [],
'outputs': [],
'action_name': 'coverage',
'action': [ 'python',
'../tools/code_coverage/coverage_posix.py',
'--directory',
- '<(PRODUCT_DIR)' ],
+ '<(PRODUCT_DIR)',
+ '--',
+ '<@(_dependencies)'],
+ # Use outputs of this action as inputs for the main target build.
+ # Seems as a misnomer but makes this happy on Linux (scons).
+ 'process_outputs_as_sources': 1,
},
], # 'actions'
},
diff --git a/tools/code_coverage/coverage_posix.py b/tools/code_coverage/coverage_posix.py
index 876a117..0f5d60b 100755
--- a/tools/code_coverage/coverage_posix.py
+++ b/tools/code_coverage/coverage_posix.py
@@ -5,30 +5,45 @@
"""Generate and process code coverage on POSIX systems.
-Written for and tested on Mac.
-Not tested on Linux yet.
+Written for and tested on Mac and Linux. To use this script to
+generate coverage numbers, please run from within a gyp-generated
+project.
+
+All platforms, to set up coverage:
+ cd ...../chromium ; src/tools/gyp/gyp_dogfood -Dcoverage=1 src/build/all.gyp
+
+Run coverage on...
+Mac:
+ ( cd src/chrome ; xcodebuild -configuration Debug -target coverage )
+Linux:
+ ( cd src/chrome ; hammer coverage )
+ # In particular, don't try and run 'coverage' from src/build
+
--directory=DIR: specify directory that contains gcda files, and where
a "coverage" directory will be created containing the output html.
+ Example name: ..../chromium/src/xcodebuild/Debug
-TODO(jrg): make list of unit tests an arg to this script
+--all_unittests: is present, run all files named *_unittests that we
+ can find.
+
+Strings after all options are considered tests to run. Test names
+have all text before a ':' stripped to help with gyp compatibility.
+For example, ../base/base.gyp:base_unittests is interpreted as a test
+named "base_unittests".
"""
+import glob
import logging
import optparse
import os
+import shutil
import subprocess
import sys
class Coverage(object):
"""Doitall class for code coverage."""
- # Unit test files to run.
- UNIT_TESTS = [
- 'base_unittests',
- # 'unit_tests,
- ]
-
def __init__(self, directory):
super(Coverage, self).__init__()
self.directory = directory
@@ -43,6 +58,34 @@ class Coverage(object):
self.genhtml = os.path.join(self.lcov_directory, 'genhtml')
self.coverage_info_file = os.path.join(self.directory, 'coverage.info')
self.ConfirmPlatformAndPaths()
+ self.tests = []
+
+ def FindTests(self, options, args):
+ """Find unit tests to run; set self.tests to this list.
+
+ Obtain instructions from the command line seen in the provided
+ parsed options and post-option args.
+ """
+ # Small tests: can be run in the "chromium" directory.
+ # If asked, run all we can find.
+ if options.all_unittests:
+ self.tests += glob.glob(os.path.join(self.directory, '*_unittests'))
+
+ # If told explicit tests, run those (after stripping the name as
+ # appropriate)
+ for testname in args:
+ if ':' in testname:
+ self.tests += [os.path.join(self.directory, testname.split(':')[1])]
+ else:
+ self.tests += [os.path.join(self.directory, testname)]
+
+ # Needs to be run in the "chrome" directory?
+ # ut = os.path.join(self.directory, 'unit_tests')
+ # if os.path.exists(ut):
+ # self.tests.append(ut)
+ # Medium tests?
+ # Not sure all of these work yet (e.g. page_cycler_tests)
+ # self.tests += glob.glob(os.path.join(self.directory, '*_tests'))
def ConfirmPlatformAndPaths(self):
"""Confirm OS and paths (e.g. lcov)."""
@@ -70,11 +113,11 @@ class Coverage(object):
subprocess.call([self.lcov,
'--directory', self.directory_parent,
'--zerocounters'])
+ shutil.rmtree(os.path.join(self.directory, 'coverage'))
def RunTests(self):
"""Run all unit tests."""
- for test in self.UNIT_TESTS:
- fulltest = os.path.join(self.directory, test)
+ for fulltest in self.tests:
if not os.path.exists(fulltest):
logging.fatal(fulltest + ' does not exist')
# TODO(jrg): add timeout?
@@ -113,12 +156,18 @@ def main():
dest='directory',
default=None,
help='Directory of unit test files')
+ parser.add_option('-a',
+ '--all_unittests',
+ dest='all_unittests',
+ default=False,
+ help='Run all tests we can find (*_unittests)')
(options, args) = parser.parse_args()
if not options.directory:
parser.error('Directory not specified')
coverage = Coverage(options.directory)
coverage.ClearData()
+ coverage.FindTests(options, args)
coverage.RunTests()
coverage.GenerateOutput()
return 0