From 0b971f635df881220a1c4f6adad11ce867a0004a Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Sat, 14 Mar 2015 19:08:37 +0000 Subject: [PATCH] Added test coverage data to the release pages if available for the release. Added saving of html pages for the code coverage to a directory in the static files area. If a code coverage report is available, a link to it will be shown on the release page of the current release. Renamed some setting variables related to test coverage to be more explicit and precise. - Legacy-Id: 9201 --- ietf/release/urls.py | 5 ++--- ietf/release/views.py | 35 ++++++++++++++++++++++++++--- ietf/settings.py | 14 +++++++----- ietf/templates/release/release.html | 20 ++++++++++++++--- ietf/urls.py | 2 +- ietf/utils/test_runner.py | 9 ++++++-- static/static/coverage/.gitignore | 1 + 7 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 static/static/coverage/.gitignore diff --git a/ietf/release/urls.py b/ietf/release/urls.py index 137deb616..5f6068d8e 100644 --- a/ietf/release/urls.py +++ b/ietf/release/urls.py @@ -1,8 +1,7 @@ from django.conf.urls import patterns urlpatterns = patterns('', - (r'^$', 'ietf.release.views.release'), - (r'^(?P.+)/$', 'ietf.release.views.release'), - (r'^coverage/code/$', 'ietf.release.views.code_coverage') + (r'^$', 'ietf.release.views.release'), + (r'^(?P[0-9.]+.*)/$', 'ietf.release.views.release'), ) diff --git a/ietf/release/views.py b/ietf/release/views.py index dc086b390..825d6e1d2 100644 --- a/ietf/release/views.py +++ b/ietf/release/views.py @@ -1,5 +1,7 @@ import os import re +import json +import datetime from django.template import RequestContext from django.shortcuts import render_to_response @@ -30,7 +32,34 @@ def release(request, version=None): next = entry entries = dict((entry.version, entry) for entry in log_entries) if version == None or version not in entries: - version = log_entries[0].version - entries[version].logentry = trac_links(entries[version].logentry) - return render_to_response('release/release.html', { 'releases': log_entries, 'version': version, 'entry': entries[version], }, context_instance=RequestContext(request)) + version = log_entries[0].version + entries[version].logentry = trac_links(entries[version].logentry.strip('\n')) + code_coverage_url = None + code_coverage_time = None + if os.path.exists(settings.TEST_CODE_COVERAGE_REPORT_FILE) and version == log_entries[0].version: + code_coverage_url = settings.TEST_CODE_COVERAGE_REPORT_URL + code_coverage_time = datetime.datetime.fromtimestamp(os.path.getmtime(settings.TEST_CODE_COVERAGE_REPORT_FILE)) + + coverage = {} + if os.path.exists(settings.TEST_COVERAGE_MASTER_FILE): + with open(settings.TEST_COVERAGE_MASTER_FILE) as file: + coverage_data = json.load(file) + if version in coverage_data: + coverage = coverage_data[version] + for key in coverage: + if "coverage" in coverage[key]: + coverage[key]["percentage"] = coverage[key]["coverage"] * 100 + + return render_to_response('release/release.html', + { + 'releases': log_entries, + 'version': version, + 'entry': entries[version], + 'coverage': coverage, + 'code_coverage_url': code_coverage_url, + 'code_coverage_time': code_coverage_time, + }, + context_instance=RequestContext(request)) + + diff --git a/ietf/settings.py b/ietf/settings.py index b22e6c6d8..39fa04abb 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -289,18 +289,22 @@ TEST_CODE_COVERAGE_EXCLUDE = [ TEST_COVERAGE_MASTER_FILE = "release-coverage.json" TEST_COVERAGE_LATEST_FILE = "latest-coverage.json" - if SERVER_MODE != 'production': import coverage - COVERAGE_CHECKER = coverage.coverage(source=[ BASE_DIR ], cover_pylib=False, omit=TEST_CODE_COVERAGE_EXCLUDE) - if len(COVERAGE_CHECKER.collector._collectors) == 0: - COVERAGE_CHECKER.start() + 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_REPORT_PATH = "static/coverage/" +TEST_CODE_COVERAGE_REPORT_URL = os.path.join(STATIC_URL, TEST_CODE_COVERAGE_REPORT_PATH, "index.html") +TEST_CODE_COVERAGE_REPORT_DIR = os.path.join(STATIC_ROOT, TEST_CODE_COVERAGE_REPORT_PATH) +TEST_CODE_COVERAGE_REPORT_FILE = os.path.join(TEST_CODE_COVERAGE_REPORT_DIR, "index.html") # WG Chair configuration MAX_WG_DELEGATES = 3 DATE_FORMAT = "Y-m-d" -DATETIME_FORMAT = "Y-m-d H:i" +DATETIME_FORMAT = "Y-m-d H:i T" # Override this in settings_local.py if needed # *_PATH variables ends with a slash/ . diff --git a/ietf/templates/release/release.html b/ietf/templates/release/release.html index eaf23b320..4d1d53a71 100644 --- a/ietf/templates/release/release.html +++ b/ietf/templates/release/release.html @@ -10,16 +10,30 @@ | {% if entry.next %}next release →{% else %}next release →{% endif %}

+

- Release Notes: + {% if coverage %} + Tested: + Code: {{coverage.code.percentage|stringformat:".2f"}}%,   + Templates: {{coverage.template.percentage|stringformat:".2f"}}%,   + URLs: {{coverage.url.percentage|stringformat:".2f"}}%   + {% endif %} + {% if code_coverage_url %} +
+ (A code test coverage report dated {{code_coverage_time}} is available.) + {% endif %} +

+ + + +

+

Release Notes:

 {{entry.logentry|safe}}
       

- -

Release list:

diff --git a/ietf/urls.py b/ietf/urls.py index 05e0cd5a7..34ccd3fc2 100644 --- a/ietf/urls.py +++ b/ietf/urls.py @@ -74,7 +74,7 @@ for n,a in api._api_list: if settings.SERVER_MODE in ('development', 'test'): urlpatterns += patterns('', - (r'^(?P(?:images|css|js|test)/.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), + (r'^(?P(?:images|css|js|test|static)/.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), (r'^(?Padmin/(?:img|css|js)/.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), (r'^(?Psecretariat/(img|css|js)/.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), (r'^(?Probots\.txt)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT+"dev/"}), diff --git a/ietf/utils/test_runner.py b/ietf/utils/test_runner.py index 414249dc2..7c991cffb 100644 --- a/ietf/utils/test_runner.py +++ b/ietf/utils/test_runner.py @@ -283,10 +283,15 @@ class CoverageTest(TestCase): include = [ os.path.join(path, '*') for path in self.runner.test_paths ] checker = self.runner.code_coverage_checker checker.stop() + # Save to the .coverage file checker.save() - checker._harvest_data() + # Apply the confirured and requested omit and include data checker.config.from_args(ignore_errors=None, omit=settings.TEST_CODE_COVERAGE_EXCLUDE, include=include, file=None) + # Maybe output a html report + if self.runner.run_full_test_suite: + checker.html_report(directory=settings.TEST_CODE_COVERAGE_REPORT_DIR) + # In any case, build a dictionary with per-file data for this run reporter = CoverageReporter(checker, checker.config) self.runner.coverage_data["code"] = reporter.report() self.report_test_result("code") @@ -340,7 +345,7 @@ class IetfTestRunner(DiscoverRunner): settings.TEMPLATE_LOADERS = ('ietf.utils.test_runner.template_coverage_loader',) + settings.TEMPLATE_LOADERS settings.MIDDLEWARE_CLASSES = ('ietf.utils.test_runner.RecordUrlsMiddleware',) + settings.MIDDLEWARE_CLASSES - self.code_coverage_checker = settings.COVERAGE_CHECKER + self.code_coverage_checker = settings.TEST_CODE_COVERAGE_CHECKER if settings.SITE_ID != 1: print " Changing SITE_ID to '1' during testing." diff --git a/static/static/coverage/.gitignore b/static/static/coverage/.gitignore new file mode 100644 index 000000000..33662f554 --- /dev/null +++ b/static/static/coverage/.gitignore @@ -0,0 +1 @@ +/*