Skip to content

Commit 0b971f6

Browse files
committed
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
1 parent 085e7d2 commit 0b971f6

7 files changed

Lines changed: 69 additions & 17 deletions

File tree

ietf/release/urls.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
from django.conf.urls import patterns
22

33
urlpatterns = patterns('',
4-
(r'^$', 'ietf.release.views.release'),
5-
(r'^(?P<version>.+)/$', 'ietf.release.views.release'),
6-
(r'^coverage/code/$', 'ietf.release.views.code_coverage')
4+
(r'^$', 'ietf.release.views.release'),
5+
(r'^(?P<version>[0-9.]+.*)/$', 'ietf.release.views.release'),
76
)
87

ietf/release/views.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import os
22
import re
3+
import json
4+
import datetime
35

46
from django.template import RequestContext
57
from django.shortcuts import render_to_response
@@ -30,7 +32,34 @@ def release(request, version=None):
3032
next = entry
3133
entries = dict((entry.version, entry) for entry in log_entries)
3234
if version == None or version not in entries:
33-
version = log_entries[0].version
34-
entries[version].logentry = trac_links(entries[version].logentry)
35-
return render_to_response('release/release.html', { 'releases': log_entries, 'version': version, 'entry': entries[version], }, context_instance=RequestContext(request))
35+
version = log_entries[0].version
36+
entries[version].logentry = trac_links(entries[version].logentry.strip('\n'))
3637

38+
code_coverage_url = None
39+
code_coverage_time = None
40+
if os.path.exists(settings.TEST_CODE_COVERAGE_REPORT_FILE) and version == log_entries[0].version:
41+
code_coverage_url = settings.TEST_CODE_COVERAGE_REPORT_URL
42+
code_coverage_time = datetime.datetime.fromtimestamp(os.path.getmtime(settings.TEST_CODE_COVERAGE_REPORT_FILE))
43+
44+
coverage = {}
45+
if os.path.exists(settings.TEST_COVERAGE_MASTER_FILE):
46+
with open(settings.TEST_COVERAGE_MASTER_FILE) as file:
47+
coverage_data = json.load(file)
48+
if version in coverage_data:
49+
coverage = coverage_data[version]
50+
for key in coverage:
51+
if "coverage" in coverage[key]:
52+
coverage[key]["percentage"] = coverage[key]["coverage"] * 100
53+
54+
return render_to_response('release/release.html',
55+
{
56+
'releases': log_entries,
57+
'version': version,
58+
'entry': entries[version],
59+
'coverage': coverage,
60+
'code_coverage_url': code_coverage_url,
61+
'code_coverage_time': code_coverage_time,
62+
},
63+
context_instance=RequestContext(request))
64+
65+

ietf/settings.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -289,18 +289,22 @@ def skip_unreadable_post(record):
289289
TEST_COVERAGE_MASTER_FILE = "release-coverage.json"
290290
TEST_COVERAGE_LATEST_FILE = "latest-coverage.json"
291291

292-
293292
if SERVER_MODE != 'production':
294293
import coverage
295-
COVERAGE_CHECKER = coverage.coverage(source=[ BASE_DIR ], cover_pylib=False, omit=TEST_CODE_COVERAGE_EXCLUDE)
296-
if len(COVERAGE_CHECKER.collector._collectors) == 0:
297-
COVERAGE_CHECKER.start()
294+
TEST_CODE_COVERAGE_CHECKER = coverage.coverage(source=[ BASE_DIR ], cover_pylib=False, omit=TEST_CODE_COVERAGE_EXCLUDE)
295+
if len(TEST_CODE_COVERAGE_CHECKER.collector._collectors) == 0:
296+
TEST_CODE_COVERAGE_CHECKER.start()
297+
298+
TEST_CODE_COVERAGE_REPORT_PATH = "static/coverage/"
299+
TEST_CODE_COVERAGE_REPORT_URL = os.path.join(STATIC_URL, TEST_CODE_COVERAGE_REPORT_PATH, "index.html")
300+
TEST_CODE_COVERAGE_REPORT_DIR = os.path.join(STATIC_ROOT, TEST_CODE_COVERAGE_REPORT_PATH)
301+
TEST_CODE_COVERAGE_REPORT_FILE = os.path.join(TEST_CODE_COVERAGE_REPORT_DIR, "index.html")
298302

299303
# WG Chair configuration
300304
MAX_WG_DELEGATES = 3
301305

302306
DATE_FORMAT = "Y-m-d"
303-
DATETIME_FORMAT = "Y-m-d H:i"
307+
DATETIME_FORMAT = "Y-m-d H:i T"
304308

305309
# Override this in settings_local.py if needed
306310
# *_PATH variables ends with a slash/ .

ietf/templates/release/release.html

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,30 @@ <h2><a href="https://trac.tools.ietf.org/tools/ietfdb/browser/tags/{{entry.versi
1010
|
1111
{% if entry.next %}<a href="/release/{{entry.next.version}}/">next release</a>&nbsp;&rarr;{% else %}<span style="color: grey">next release &rarr;</span>{% endif %}
1212
</p>
13+
1314
<p>
14-
<b>Release Notes:</b>
15+
{% if coverage %}
16+
Tested:
17+
<b>Code</b>: {{coverage.code.percentage|stringformat:".2f"}}%, &nbsp;
18+
<b>Templates</b>: {{coverage.template.percentage|stringformat:".2f"}}%, &nbsp;
19+
<b>URLs</b>: {{coverage.url.percentage|stringformat:".2f"}}% &nbsp;
20+
{% endif %}
21+
{% if code_coverage_url %}
22+
<br/>
23+
(A <a href="{{code_coverage_url}}">code test coverage report</a> dated {{code_coverage_time}} is available.)
24+
{% endif %}
25+
</p>
26+
27+
28+
29+
<p>
30+
<h2>Release Notes:</h2>
1531
<tt>
1632
<pre>
1733
{{entry.logentry|safe}}
1834
</pre>
1935
</tt>
2036
</p>
21-
22-
2337

2438
<h2>Release list:</h2>
2539
<table style="margin-left: 3em">

ietf/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474

7575
if settings.SERVER_MODE in ('development', 'test'):
7676
urlpatterns += patterns('',
77-
(r'^(?P<path>(?:images|css|js|test)/.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
77+
(r'^(?P<path>(?:images|css|js|test|static)/.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
7878
(r'^(?P<path>admin/(?:img|css|js)/.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
7979
(r'^(?P<path>secretariat/(img|css|js)/.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
8080
(r'^(?P<path>robots\.txt)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT+"dev/"}),

ietf/utils/test_runner.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,15 @@ def code_coverage_test(self):
283283
include = [ os.path.join(path, '*') for path in self.runner.test_paths ]
284284
checker = self.runner.code_coverage_checker
285285
checker.stop()
286+
# Save to the .coverage file
286287
checker.save()
287-
checker._harvest_data()
288+
# Apply the confirured and requested omit and include data
288289
checker.config.from_args(ignore_errors=None, omit=settings.TEST_CODE_COVERAGE_EXCLUDE,
289290
include=include, file=None)
291+
# Maybe output a html report
292+
if self.runner.run_full_test_suite:
293+
checker.html_report(directory=settings.TEST_CODE_COVERAGE_REPORT_DIR)
294+
# In any case, build a dictionary with per-file data for this run
290295
reporter = CoverageReporter(checker, checker.config)
291296
self.runner.coverage_data["code"] = reporter.report()
292297
self.report_test_result("code")
@@ -340,7 +345,7 @@ def setup_test_environment(self, **kwargs):
340345
settings.TEMPLATE_LOADERS = ('ietf.utils.test_runner.template_coverage_loader',) + settings.TEMPLATE_LOADERS
341346
settings.MIDDLEWARE_CLASSES = ('ietf.utils.test_runner.RecordUrlsMiddleware',) + settings.MIDDLEWARE_CLASSES
342347

343-
self.code_coverage_checker = settings.COVERAGE_CHECKER
348+
self.code_coverage_checker = settings.TEST_CODE_COVERAGE_CHECKER
344349

345350
if settings.SITE_ID != 1:
346351
print " Changing SITE_ID to '1' during testing."

static/static/coverage/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/*

0 commit comments

Comments
 (0)