OLD | NEW |
(Empty) | |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 from cStringIO import StringIO |
| 6 |
| 7 try: |
| 8 import coverage |
| 9 coverage_version = coverage.__version__ |
| 10 except ImportError: |
| 11 coverage = None |
| 12 coverage_version = None |
| 13 |
| 14 from distutils.version import StrictVersion |
| 15 |
| 16 if (not coverage or |
| 17 not hasattr(coverage.collector, 'CTracer') or |
| 18 not coverage.collector.CTracer or |
| 19 StrictVersion(coverage_version) < StrictVersion('3.7')): |
| 20 raise ImportError( |
| 21 'This test requires natively-installed python-coverage (>=3.7). ' |
| 22 'Current is %s.' % coverage_version) |
| 23 |
| 24 |
| 25 # This is instead of a contextmanager because it causes old pylints to crash :( |
| 26 class _Cover(object): |
| 27 def __init__(self, enabled, maybe_kwargs): |
| 28 self.enabled = enabled |
| 29 self.kwargs = maybe_kwargs or {} |
| 30 self.c = None |
| 31 |
| 32 def __enter__(self): |
| 33 if self.enabled: |
| 34 self.c = coverage.coverage(**self.kwargs) |
| 35 self.c._warn_no_data = False |
| 36 self.c.start() |
| 37 |
| 38 def __exit__(self, *_): |
| 39 if self.enabled: |
| 40 self.c.stop() |
| 41 self.c.save() |
| 42 |
| 43 |
| 44 class CoverageContext(object): |
| 45 def __init__(self, name, includes, omits, enabled=True): |
| 46 self.opts = None |
| 47 self.cov = None |
| 48 self.enabled = enabled |
| 49 |
| 50 if enabled: |
| 51 self.opts = { |
| 52 'include': includes, |
| 53 'omit': omits, |
| 54 'data_file': '.%s_coverage' % name, |
| 55 'data_suffix': True |
| 56 } |
| 57 self.cov = coverage.coverage(**self.opts) |
| 58 self.cov.erase() |
| 59 |
| 60 def cleanup(self): |
| 61 if self.enabled: |
| 62 self.cov.combine() |
| 63 |
| 64 def report(self, verbose): |
| 65 fail = False |
| 66 |
| 67 if self.enabled: |
| 68 outf = StringIO() |
| 69 fail = self.cov.report(file=outf) != 100.0 |
| 70 summary = outf.getvalue().replace('%- 15s' % 'Name', 'Coverage Report', 1) |
| 71 if verbose: |
| 72 print |
| 73 print summary |
| 74 elif fail: |
| 75 print |
| 76 lines = summary.splitlines() |
| 77 lines[2:-2] = [l for l in lines[2:-2] |
| 78 if not l.strip().endswith('100%')] |
| 79 print '\n'.join(lines) |
| 80 print |
| 81 print 'FATAL: Test coverage is not at 100%.' |
| 82 |
| 83 return not fail |
| 84 |
| 85 def create_subprocess_context(self): |
| 86 # Can't have this method be the contextmanager because otherwise |
| 87 # self (and self.cov) will get pickled to the subprocess, and we don't want |
| 88 # that :( |
| 89 return _Cover(self.enabled, self.opts) |
OLD | NEW |