summaryrefslogtreecommitdiffstats
path: root/tools/code_coverage
diff options
context:
space:
mode:
authorjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-03 04:35:18 +0000
committerjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-03 04:35:18 +0000
commitf5ecbba1f92417edf8759d93904e12cfe9a2d0b4 (patch)
tree88eb8f6e89012dd41189a478fa6e263569a23ffa /tools/code_coverage
parenta6cf87ec511a64fc29c0bda5cf83ec282d34be59 (diff)
downloadchromium_src-f5ecbba1f92417edf8759d93904e12cfe9a2d0b4.zip
chromium_src-f5ecbba1f92417edf8759d93904e12cfe9a2d0b4.tar.gz
chromium_src-f5ecbba1f92417edf8759d93904e12cfe9a2d0b4.tar.bz2
Start of code coverage for Mac.
Only base_unittests included for now. Linux changes added as well but untested until Linux switches to gyp. Enable coverage with the following command: src/tools/gyp/gyp_dogfood -Dcoverage=1 src/build/all.gyp Review URL: http://codereview.chromium.org/56136 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13068 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/code_coverage')
-rwxr-xr-xtools/code_coverage/coverage_posix.py120
1 files changed, 120 insertions, 0 deletions
diff --git a/tools/code_coverage/coverage_posix.py b/tools/code_coverage/coverage_posix.py
new file mode 100755
index 0000000..88eb23c
--- /dev/null
+++ b/tools/code_coverage/coverage_posix.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+# Copyright (c) 2009 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Generate and process code coverage on POSIX systems.
+
+Written for and tested on Mac.
+Not tested on Linux yet.
+
+--directory=DIR: specify directory that contains gcda files, and where
+ a "coverage" directory will be created containing the output html.
+
+TODO(jrg): make list of unit tests an arg to this script
+"""
+
+import logging
+import optparse
+import os
+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
+ self.output_directory = os.path.join(self.directory, 'coverage')
+ if not os.path.exists(self.output_directory):
+ os.mkdir(self.output_directory)
+ self.lcov_directory = os.path.join(sys.path[0],
+ '../../third_party/lcov/bin')
+ self.lcov = os.path.join(self.lcov_directory, 'lcov')
+ self.mcov = os.path.join(self.lcov_directory, 'mcov')
+ self.genhtml = os.path.join(self.lcov_directory, 'genhtml')
+ self.coverage_info_file = self.directory + 'coverage.info'
+ self.ConfirmPlatformAndPaths()
+
+ def ConfirmPlatformAndPaths(self):
+ """Confirm OS and paths (e.g. lcov)."""
+ if not self.IsPosix():
+ logging.fatal('Not posix.')
+ programs = [self.lcov, self.genhtml]
+ if self.IsMac():
+ programs.append(self.mcov)
+ for program in programs:
+ if not os.path.exists(program):
+ logging.fatal('lcov program missing: ' + program)
+
+ def IsPosix(self):
+ """Return True if we are POSIX."""
+ return self.IsMac() or self.IsLinux()
+
+ def IsMac(self):
+ return sys.platform == 'darwin'
+
+ def IsLinux(self):
+ return sys.platform == 'linux2'
+
+ def ClearData(self):
+ """Clear old gcda files"""
+ subprocess.call([self.lcov,
+ '--directory', self.directory,
+ '--zerocounters'])
+
+ def RunTests(self):
+ """Run all unit tests."""
+ for test in self.UNIT_TESTS:
+ fulltest = os.path.join(self.directory, test)
+ if not os.path.exists(fulltest):
+ logging.fatal(fulltest + ' does not exist')
+ # TODO(jrg): add timeout?
+ # TODO(jrg): check return value and choke if it failed?
+ # TODO(jrg): add --gtest_print_time like as run from XCode?
+ subprocess.call([fulltest])
+
+ def GenerateOutput(self):
+ """Convert profile data to html."""
+ if self.IsLinux():
+ subprocess.call([self.lcov,
+ '--directory', self.directory,
+ '--capture',
+ '--output-file',
+ self.coverage_info_file])
+ else:
+ subprocess.call([self.mcov,
+ '--directory', self.directory,
+ '--output', self.coverage_info_file])
+ subprocess.call([self.genhtml,
+ self.coverage_info_file,
+ '--output-directory',
+ self.output_directory])
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('-d',
+ '--directory',
+ dest='directory',
+ default=None,
+ help='Directory of unit test files')
+ (options, args) = parser.parse_args()
+ if not options.directory:
+ parser.error('Directory not specified')
+
+ coverage = Coverage(options.directory)
+ coverage.ClearData()
+ coverage.RunTests()
+ coverage.GenerateOutput()
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())