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

Unified Diff: tools/telemetry/third_party/coverage/igor.py

Issue 1366913004: Add coverage Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months 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
Index: tools/telemetry/third_party/coverage/igor.py
diff --git a/third_party/pycoverage/igor.py b/tools/telemetry/third_party/coverage/igor.py
similarity index 51%
copy from third_party/pycoverage/igor.py
copy to tools/telemetry/third_party/coverage/igor.py
index 12ec6c8fec4afe1fe482cbcbcda18759135ff60e..8e172db0211477b0ae9e16d8108b431e1236e44d 100644
--- a/third_party/pycoverage/igor.py
+++ b/tools/telemetry/third_party/coverage/igor.py
@@ -1,3 +1,7 @@
+# coding: utf-8
+# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
+# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
+
"""Helper for building, testing, and linting coverage.py.
To get portability, all these operations are written in Python here instead
@@ -5,20 +9,42 @@ of in shell scripts, batch files, or Makefiles.
"""
+import contextlib
import fnmatch
import glob
import inspect
import os
import platform
-import socket
import sys
+import textwrap
+import warnings
import zipfile
+# We want to see all warnings while we are running tests. But we also need to
+# disable warnings for some of the more complex setting up of tests.
+warnings.simplefilter("default")
+
+
+@contextlib.contextmanager
+def ignore_warnings():
+ """Context manager to ignore warning within the with statement."""
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore")
+ yield
+
+
# Functions named do_* are executable from the command line: do_blah is run
# by "python igor.py blah".
+def do_show_env():
+ """Show the environment variables."""
+ print("Environment:")
+ for env in sorted(os.environ):
+ print(" %s = %r" % (env, os.environ[env]))
+
+
def do_remove_extension():
"""Remove the compiled C extension, no matter what its name."""
@@ -26,6 +52,7 @@ def do_remove_extension():
tracer.so
tracer.*.so
tracer.pyd
+ tracer.*.pyd
""".split()
for pattern in so_patterns:
@@ -36,47 +63,82 @@ def do_remove_extension():
except OSError:
pass
-def run_tests(tracer, *nose_args):
- """The actual running of tests."""
- import nose.core
+
+def label_for_tracer(tracer):
+ """Get the label for these tests."""
if tracer == "py":
label = "with Python tracer"
else:
label = "with C tracer"
- if os.environ.get("COVERAGE_NO_EXTENSION"):
- print("Skipping tests, no C extension in this environment")
- return
- print_banner(label)
- os.environ["COVERAGE_TEST_TRACER"] = tracer
+
+ return label
+
+
+def should_skip(tracer):
+ """Is there a reason to skip these tests?"""
+ if tracer == "py":
+ skipper = os.environ.get("COVERAGE_NO_PYTRACER")
+ else:
+ skipper = (
+ os.environ.get("COVERAGE_NO_EXTENSION") or
+ os.environ.get("COVERAGE_NO_CTRACER")
+ )
+
+ if skipper:
+ msg = "Skipping tests " + label_for_tracer(tracer)
+ if len(skipper) > 1:
+ msg += ": " + skipper
+ else:
+ msg = ""
+
+ return msg
+
+
+def run_tests(tracer, *nose_args):
+ """The actual running of tests."""
+ with ignore_warnings():
+ import nose.core
+
+ if 'COVERAGE_TESTING' not in os.environ:
+ os.environ['COVERAGE_TESTING'] = "True"
+ print_banner(label_for_tracer(tracer))
nose_args = ["nosetests"] + list(nose_args)
nose.core.main(argv=nose_args)
+
def run_tests_with_coverage(tracer, *nose_args):
"""Run tests, but with coverage."""
- import coverage
+ # Need to define this early enough that the first import of env.py sees it.
+ os.environ['COVERAGE_TESTING'] = "True"
os.environ['COVERAGE_PROCESS_START'] = os.path.abspath('metacov.ini')
os.environ['COVERAGE_HOME'] = os.getcwd()
# Create the .pth file that will let us measure coverage in sub-processes.
+ # The .pth file seems to have to be alphabetically after easy-install.pth
+ # or the sys.path entries aren't created right?
import nose
pth_dir = os.path.dirname(os.path.dirname(nose.__file__))
- pth_path = os.path.join(pth_dir, "covcov.pth")
- pth_file = open(pth_path, "w")
- try:
+ pth_path = os.path.join(pth_dir, "zzz_metacov.pth")
+ with open(pth_path, "w") as pth_file:
pth_file.write("import coverage; coverage.process_startup()\n")
- finally:
- pth_file.close()
+ # Make names for the data files that keep all the test runs distinct.
+ impl = platform.python_implementation().lower()
version = "%s%s" % sys.version_info[:2]
- suffix = "%s_%s_%s" % (version, tracer, socket.gethostname())
+ if '__pypy__' in sys.builtin_module_names:
+ version += "_%s%s" % sys.pypy_version_info[:2]
+ suffix = "%s%s_%s_%s" % (impl, version, tracer, platform.platform())
+
+ os.environ['COVERAGE_METAFILE'] = os.path.abspath(".metacov."+suffix)
- cov = coverage.coverage(config_file="metacov.ini", data_suffix=suffix)
- # Cheap trick: the coverage code itself is excluded from measurement, but
- # if we clobber the cover_prefix in the coverage object, we can defeat the
- # self-detection.
+ import coverage
+ cov = coverage.Coverage(config_file="metacov.ini", data_suffix=False)
+ # Cheap trick: the coverage.py code itself is excluded from measurement,
+ # but if we clobber the cover_prefix in the coverage object, we can defeat
+ # the self-detection.
cov.cover_prefix = "Please measure coverage.py!"
- cov.erase()
+ cov._warn_unimported_source = False
cov.start()
try:
@@ -92,7 +154,7 @@ def run_tests_with_coverage(tracer, *nose_args):
if getattr(mod, '__file__', "??").startswith(covdir):
covmods[name] = mod
del sys.modules[name]
- import coverage # don't warn about re-import: pylint: disable=W0404
+ import coverage # pylint: disable=reimported
sys.modules.update(covmods)
# Run nosetests, with the arguments from our command line.
@@ -105,53 +167,94 @@ def run_tests_with_coverage(tracer, *nose_args):
cov.stop()
os.remove(pth_path)
+ cov.combine()
cov.save()
+
def do_combine_html():
- """Combine data from a meta-coverage run, and make the HTML report."""
+ """Combine data from a meta-coverage run, and make the HTML and XML reports."""
import coverage
os.environ['COVERAGE_HOME'] = os.getcwd()
- cov = coverage.coverage(config_file="metacov.ini")
+ os.environ['COVERAGE_METAFILE'] = os.path.abspath(".metacov")
+ cov = coverage.Coverage(config_file="metacov.ini")
cov.load()
cov.combine()
cov.save()
cov.html_report()
+ cov.xml_report()
+
def do_test_with_tracer(tracer, *noseargs):
"""Run nosetests with a particular tracer."""
+ # If we should skip these tests, skip them.
+ skip_msg = should_skip(tracer)
+ if skip_msg:
+ print(skip_msg)
+ return
+
+ os.environ["COVERAGE_TEST_TRACER"] = tracer
if os.environ.get("COVERAGE_COVERAGE", ""):
return run_tests_with_coverage(tracer, *noseargs)
else:
return run_tests(tracer, *noseargs)
+
def do_zip_mods():
"""Build the zipmods.zip file."""
zf = zipfile.ZipFile("tests/zipmods.zip", "w")
+
+ # Take one file from disk.
zf.write("tests/covmodzip1.py", "covmodzip1.py")
+
+ # The others will be various encodings.
+ source = textwrap.dedent(u"""\
+ # coding: {encoding}
+ text = u"{text}"
+ ords = {ords}
+ assert [ord(c) for c in text] == ords
+ print(u"All OK with {encoding}")
+ """)
+ details = [
+ (u'utf8', u'ⓗⓔⓛⓛⓞ, ⓦⓞⓡⓛⓓ'),
+ (u'gb2312', u'你好,世界'),
+ (u'hebrew', u'שלום, עולם'),
+ (u'shift_jis', u'こんにちは世界'),
+ ]
+ for encoding, text in details:
+ filename = 'encoded_{0}.py'.format(encoding)
+ ords = [ord(c) for c in text]
+ source_text = source.format(encoding=encoding, text=text, ords=ords)
+ zf.writestr(filename, source_text.encode(encoding))
+
zf.close()
+
def do_install_egg():
"""Install the egg1 egg for tests."""
# I am pretty certain there are easier ways to install eggs...
- # pylint: disable=F0401,E0611,E1101
- import distutils.core
+ # pylint: disable=import-error,no-name-in-module
cur_dir = os.getcwd()
os.chdir("tests/eggsrc")
- distutils.core.run_setup("setup.py", ["--quiet", "bdist_egg"])
- egg = glob.glob("dist/*.egg")[0]
- distutils.core.run_setup(
- "setup.py", ["--quiet", "easy_install", "--no-deps", "--zip-ok", egg]
- )
+ with ignore_warnings():
+ import distutils.core
+ distutils.core.run_setup("setup.py", ["--quiet", "bdist_egg"])
+ egg = glob.glob("dist/*.egg")[0]
+ distutils.core.run_setup(
+ "setup.py", ["--quiet", "easy_install", "--no-deps", "--zip-ok", egg]
+ )
os.chdir(cur_dir)
+
def do_check_eol():
"""Check files for incorrect newlines and trailing whitespace."""
ignore_dirs = [
- '.svn', '.hg', '.tox', '.tox_kits', 'coverage.egg-info',
- '_build', 'covtestegg1.egg-info',
+ '.svn', '.hg', '.git',
+ '.tox*',
+ '*.egg-info',
+ '_build',
]
- checked = set([])
+ checked = set()
def check_file(fname, crlf=True, trail_white=True):
"""Check a single file for whitespace abuse."""
@@ -161,18 +264,19 @@ def do_check_eol():
checked.add(fname)
line = None
- for n, line in enumerate(open(fname, "rb")):
- if crlf:
- if "\r" in line:
- print("%s@%d: CR found" % (fname, n+1))
- return
- if trail_white:
- line = line[:-1]
- if not crlf:
- line = line.rstrip('\r')
- if line.rstrip() != line:
- print("%s@%d: trailing whitespace found" % (fname, n+1))
- return
+ with open(fname, "rb") as f:
+ for n, line in enumerate(f, start=1):
+ if crlf:
+ if "\r" in line:
+ print("%s@%d: CR found" % (fname, n))
+ return
+ if trail_white:
+ line = line[:-1]
+ if not crlf:
+ line = line.rstrip('\r')
+ if line.rstrip() != line:
+ print("%s@%d: trailing whitespace found" % (fname, n))
+ return
if line is not None and not line.strip():
print("%s: final blank line" % (fname,))
@@ -186,11 +290,16 @@ def do_check_eol():
if fnmatch.fnmatch(fname, p):
check_file(fname, **kwargs)
break
- for dir_name in ignore_dirs:
- if dir_name in dirs:
+ for ignore_dir in ignore_dirs:
+ ignored = []
+ for dir_name in dirs:
+ if fnmatch.fnmatch(dir_name, ignore_dir):
+ ignored.append(dir_name)
+ for dir_name in ignored:
dirs.remove(dir_name)
- check_files("coverage", ["*.py", "*.c"])
+ check_files("coverage", ["*.py"])
+ check_files("coverage/ctracer", ["*.c", "*.h"])
check_files("coverage/htmlfiles", ["*.html", "*.css", "*.js"])
check_file("tests/farm/html/src/bom.py", crlf=False)
check_files("tests", ["*.py"])
@@ -201,8 +310,8 @@ def do_check_eol():
check_file("Makefile")
check_file(".hgignore")
check_file(".travis.yml")
- check_files("doc", ["*.rst"])
- check_files(".", ["*.txt"])
+ check_files(".", ["*.rst", "*.txt"])
+ check_files(".", ["*.pip"])
def print_banner(label):
@@ -215,10 +324,11 @@ def print_banner(label):
version = platform.python_version()
if '__pypy__' in sys.builtin_module_names:
- pypy_version = sys.pypy_version_info # pylint: disable=E1101
- version += " (pypy %s)" % ".".join([str(v) for v in pypy_version])
+ version += " (pypy %s)" % ".".join(str(v) for v in sys.pypy_version_info)
- print('=== %s %s %s (%s) ===' % (impl, version, label, sys.executable))
+ which_python = os.path.relpath(sys.executable)
+ print('=== %s %s %s (%s) ===' % (impl, version, label, which_python))
+ sys.stdout.flush()
def do_help():
@@ -230,6 +340,22 @@ def do_help():
print("%-20s%s" % (name[3:], value.__doc__))
+def analyze_args(function):
+ """What kind of args does `function` expect?
+
+ Returns:
+ star, num_pos:
+ star(boolean): Does `function` accept *args?
+ num_args(int): How many positional arguments does `function` have?
+ """
+ try:
+ getargspec = inspect.getfullargspec
+ except AttributeError:
+ getargspec = inspect.getargspec
+ argspec = getargspec(function)
+ return bool(argspec[1]), len(argspec[0])
+
+
def main(args):
"""Main command-line execution for igor.
@@ -243,14 +369,13 @@ def main(args):
if handler is None:
print("*** No handler for %r" % verb)
return 1
- argspec = inspect.getargspec(handler)
- if argspec[1]:
+ star, num_args = analyze_args(handler)
+ if star:
# Handler has *args, give it all the rest of the command line.
handler_args = args
args = []
else:
# Handler has specific arguments, give it only what it needs.
- num_args = len(argspec[0])
handler_args = args[:num_args]
args = args[num_args:]
ret = handler(*handler_args)
@@ -258,5 +383,6 @@ def main(args):
if ret:
return ret
+
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
« no previous file with comments | « tools/telemetry/third_party/coverage/howto.txt ('k') | tools/telemetry/third_party/coverage/lab/branches.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698