diff --git a/ietf/settings.py b/ietf/settings.py index 33f4f1511..1f10b97e6 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -352,9 +352,7 @@ TEST_COVERAGE_LATEST_FILE = os.path.join(BASE_DIR, "../latest-coverage.json") TEST_CODE_COVERAGE_CHECKER = None if SERVER_MODE != 'production': import coverage - TEST_CODE_COVERAGE_CHECKER = coverage.coverage(source=[ BASE_DIR ], cover_pylib=False, omit=TEST_CODE_COVERAGE_EXCLUDE) - if len(TEST_CODE_COVERAGE_CHECKER.collector._collectors) == 0: - TEST_CODE_COVERAGE_CHECKER.start() + TEST_CODE_COVERAGE_CHECKER = coverage.Coverage(source=[ BASE_DIR ], cover_pylib=False, omit=TEST_CODE_COVERAGE_EXCLUDE) TEST_CODE_COVERAGE_REPORT_PATH = "coverage/" TEST_CODE_COVERAGE_REPORT_URL = os.path.join(STATIC_URL, TEST_CODE_COVERAGE_REPORT_PATH, "index.html") diff --git a/ietf/settings_sqlitetest.py b/ietf/settings_sqlitetest.py index 9fdeb95ce..82aa8b2be 100644 --- a/ietf/settings_sqlitetest.py +++ b/ietf/settings_sqlitetest.py @@ -36,3 +36,6 @@ DATABASES = { }, } +if TEST_CODE_COVERAGE_CHECKER and not TEST_CODE_COVERAGE_CHECKER._started: + TEST_CODE_COVERAGE_CHECKER.start() + diff --git a/ietf/utils/management/commands/coverage_changes.py b/ietf/utils/management/commands/coverage_changes.py index 85afcdac2..aac5dbfd2 100644 --- a/ietf/utils/management/commands/coverage_changes.py +++ b/ietf/utils/management/commands/coverage_changes.py @@ -67,13 +67,19 @@ class Command(BaseCommand): header_written = False for key in keys: - if not key in mcoverage: + mkey = key + if not mkey in mcoverage: + if mkey.endswith(".py"): + mkey = mkey[:-3] + else: + mkey = mkey + ".py" + if not mkey in mcoverage: mlines, mcov = None, None else: if mformat == 1: - mlines, mcov = None, mcoverage[key] + mlines, mcov = None, mcoverage[mkey] elif mformat == 2: - mlines, mcov = mcoverage[key] + mlines, mcov = mcoverage[mkey] else: raise CommandError("The release coverage data has an unknown format ('%s'), quitting." % mformat) if lformat == 1: diff --git a/ietf/utils/test_runner.py b/ietf/utils/test_runner.py index 436e2be49..4ca615041 100644 --- a/ietf/utils/test_runner.py +++ b/ietf/utils/test_runner.py @@ -177,15 +177,15 @@ def save_test_results(failures, test_labels): class CoverageReporter(Reporter): def report(self): - self.find_code_units(None) + self.find_file_reporters(None) total = Numbers() result = {"coverage": 0.0, "covered": {}, "format": 2, } - for cu in self.code_units: + for fr in self.file_reporters: try: - analysis = self.coverage._analyze(cu) + analysis = self.coverage._analyze(fr) nums = analysis.numbers - result["covered"][cu.name] = (nums.n_statements, nums.pc_covered/100.0) + result["covered"][fr.relative_filename()] = (nums.n_statements, nums.pc_covered/100.0) total += nums except KeyboardInterrupt: # pragma: not covered raise @@ -193,7 +193,7 @@ class CoverageReporter(Reporter): report_it = not self.config.ignore_errors if report_it: typ, msg = sys.exc_info()[:2] - if typ is NotPython and not cu.should_be_python(): + if typ is NotPython and not fr.should_be_python(): report_it = False if report_it: raise @@ -355,6 +355,11 @@ class IetfTestRunner(DiscoverRunner): settings.MIDDLEWARE_CLASSES = ('ietf.utils.test_runner.RecordUrlsMiddleware',) + settings.MIDDLEWARE_CLASSES self.code_coverage_checker = settings.TEST_CODE_COVERAGE_CHECKER + if not self.code_coverage_checker._started: + sys.stderr.write(" ** Warning: In %s: Expected the coverage checker to have\n" + " been started already, but it wasn't. Doing so now. Coverage numbers\n" + " will be off, though.\n" % __name__) + self.code_coverage_checker.start() if settings.SITE_ID != 1: print " Changing SITE_ID to '1' during testing." @@ -397,7 +402,7 @@ class IetfTestRunner(DiscoverRunner): self.coverage_master[self.save_version_coverage] = self.coverage_data if self.coverage_file.endswith('.gz'): with gzip.open(self.coverage_file, "wb") as file: - json.dump(self.coverage_master, file, indent=2, sort_keys=True) + json.dump(self.coverage_master, file, sort_keys=True) else: with codecs.open(self.coverage_file, "w", encoding="utf-8") as file: json.dump(self.coverage_master, file, indent=2, sort_keys=True) @@ -436,7 +441,7 @@ class IetfTestRunner(DiscoverRunner): test_paths = [ os.path.join(*app.split('.')) for app in test_apps ] return test_apps, test_paths - def run_tests(self, test_labels, extra_tests=None, **kwargs): + def run_tests(self, test_labels, extra_tests=[], **kwargs): # Tests that involve switching back and forth between the real # database and the test database are way too dangerous to run # against the production database @@ -457,13 +462,14 @@ class IetfTestRunner(DiscoverRunner): self.test_apps, self.test_paths = self.get_test_paths(test_labels) - extra_tests = [ - CoverageTest(test_runner=self, methodName='url_coverage_test'), - CoverageTest(test_runner=self, methodName='template_coverage_test'), - CoverageTest(test_runner=self, methodName='code_coverage_test'), - ] + if self.check_coverage: + extra_tests += [ + CoverageTest(test_runner=self, methodName='url_coverage_test'), + CoverageTest(test_runner=self, methodName='template_coverage_test'), + CoverageTest(test_runner=self, methodName='code_coverage_test'), + ] - self.reorder_by += (CoverageTest, ) # see to it that the coverage tests come last + self.reorder_by += (CoverageTest, ) # see to it that the coverage tests come last failures = super(IetfTestRunner, self).run_tests(test_labels, extra_tests=extra_tests, **kwargs) diff --git a/ietf/utils/test_utils.py b/ietf/utils/test_utils.py index 9f296df8c..fc671bc97 100644 --- a/ietf/utils/test_utils.py +++ b/ietf/utils/test_utils.py @@ -284,3 +284,5 @@ class TestCase(django.test.TestCase): self.assertHttpOK(resp) self.assertTrue(resp['Content-Type'].startswith('text/html')) self.assertValidHTML(resp.content) + + diff --git a/release-coverage.json.gz b/release-coverage.json.gz index 1e8563b7d..e330aeb21 100644 Binary files a/release-coverage.json.gz and b/release-coverage.json.gz differ diff --git a/requirements.txt b/requirements.txt index 15996ac2c..190b7f381 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ # -*- conf-mode -*- setuptools>=1.2 # Require this first, to prevent later errors # -coverage>=3.7.1,<4.0 +coverage>=4.0.1 #cssselect>=0.6.1 # for PyQuery decorator>=3.4.0 defusedxml>=0.4.1 # for TastyPie when ussing xml; not a declared dependency