aboutsummaryrefslogtreecommitdiff
path: root/lava_results_app
diff options
context:
space:
mode:
authorStevan Radakovic <stevan.radakovic@linaro.org>2017-11-29 10:57:22 +0100
committerNeil Williams <neil.williams@linaro.org>2017-11-30 10:43:32 +0000
commit3587c07e5d17ab9c0da4c430c817b3c07366702f (patch)
tree5547077a65bad9f1faae850fe82a07cd3451e4d2 /lava_results_app
parent41c636935765dfcad8b6771e1ff23346be4fa4e8 (diff)
LAVA-1151 - REST API for individual test case results
Add a testcase yaml download support with buglinks. Reformat testcase template a bit. Add a generic relation from buglinks to testcase for convenience' sake. Change-Id: I3522118e48504d102dd0acdcacdb2af04eb2b35c
Diffstat (limited to 'lava_results_app')
-rw-r--r--lava_results_app/dbutils.py5
-rw-r--r--lava_results_app/models.py64
-rw-r--r--lava_results_app/templates/lava_results_app/case.html77
-rw-r--r--lava_results_app/templates/lava_results_app/suite.html2
-rw-r--r--lava_results_app/urls.py3
-rw-r--r--lava_results_app/views/__init__.py11
6 files changed, 96 insertions, 66 deletions
diff --git a/lava_results_app/dbutils.py b/lava_results_app/dbutils.py
index 60a48ad2c..3e46c8d97 100644
--- a/lava_results_app/dbutils.py
+++ b/lava_results_app/dbutils.py
@@ -409,7 +409,7 @@ def testcase_export_fields():
]
-def export_testcase(testcase):
+def export_testcase(testcase, with_buglinks=False):
"""
Returns string versions of selected elements of a TestCase
Unicode causes issues with CSV and can complicate YAML parsing
@@ -440,6 +440,9 @@ def export_testcase(testcase):
'logged': str(testcase.logged),
'metadata': metadata,
}
+ if with_buglinks:
+ casedict['buglinks'] = [str(url) for url in testcase.buglinks.values_list('url', flat=True)]
+
return casedict
diff --git a/lava_results_app/models.py b/lava_results_app/models.py
index eab78c509..d23524d77 100644
--- a/lava_results_app/models.py
+++ b/lava_results_app/models.py
@@ -162,6 +162,37 @@ class QueryMaterializedView(MaterializedView):
return QueryMaterializedView.objects.all()
+class BugLink(models.Model):
+
+ class Meta:
+ unique_together = (('object_id', 'url', 'content_type'))
+
+ url = models.URLField(
+ max_length=1024,
+ blank=False,
+ null=False,
+ verbose_name=_(u"Bug Link URL"),
+ )
+
+ content_type = models.ForeignKey(ContentType)
+ object_id = models.PositiveIntegerField()
+ content_object = fields.GenericForeignKey('content_type', 'object_id')
+
+ def log_admin_entry(self, user, reason):
+ buglink_ct = ContentType.objects.get_for_model(BugLink)
+ LogEntry.objects.log_action(
+ user_id=user.id,
+ content_type_id=buglink_ct.pk,
+ object_id=self.pk,
+ object_repr=unicode(self),
+ action_flag=ADDITION,
+ change_message=reason
+ )
+
+ def __unicode__(self):
+ return unicode(self.url)
+
+
class TestSuite(models.Model, Queryable):
"""
Result suite of a pipeline job.
@@ -378,6 +409,8 @@ class TestCase(models.Model, Queryable):
auto_now=True
)
+ buglinks = fields.GenericRelation(BugLink)
+
@property
def action_metadata(self):
if not self.metadata:
@@ -1718,34 +1751,3 @@ class ChartQueryUser(models.Model):
is_delta = models.BooleanField(
default=False,
verbose_name='Delta reporting')
-
-
-class BugLink(models.Model):
-
- class Meta:
- unique_together = (('object_id', 'url', 'content_type'))
-
- url = models.URLField(
- max_length=1024,
- blank=False,
- null=False,
- verbose_name=_(u"Bug Link URL"),
- )
-
- content_type = models.ForeignKey(ContentType)
- object_id = models.PositiveIntegerField()
- content_object = fields.GenericForeignKey('content_type', 'object_id')
-
- def log_admin_entry(self, user, reason):
- buglink_ct = ContentType.objects.get_for_model(BugLink)
- LogEntry.objects.log_action(
- user_id=user.id,
- content_type_id=buglink_ct.pk,
- object_id=self.pk,
- object_repr=unicode(self),
- action_flag=ADDITION,
- change_message=reason
- )
-
- def __unicode__(self):
- return unicode(self.url)
diff --git a/lava_results_app/templates/lava_results_app/case.html b/lava_results_app/templates/lava_results_app/case.html
index eebe711ff..ed112abf6 100644
--- a/lava_results_app/templates/lava_results_app/case.html
+++ b/lava_results_app/templates/lava_results_app/case.html
@@ -16,12 +16,18 @@
</style>
{% endblock %}
{% block content %}
-<h1>Test suite <a href="{{ suite.get_absolute_url }}">{{ suite.name }}</a> for job {{ job_link }}</h1>
+ <h1>Test suite <a href="{{ suite.get_absolute_url }}">{{ suite.name }}</a> for job {{ job_link }}</h1>
+
{% if not test_cases %}
{% for testset in sets %}
<h2>Test Set: {{ testset.name }}</h2>
{% for testcase in testset.test_cases.all %}
<dl class="dl-horizontal">
+ <dt>Test case export : <button class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="right" title="Download link can be used with tokens:?user=user.name&amp;token=tokenstring">?</button>
+ </dt>
+ <dd><a class="btn btn-xs btn-info" href="{% url 'lava.results.testcase_yaml' testcase.id %}" title="Download as YAML"><span class="glyphicon glyphicon-download"></span> YAML</a></dd>
+ </dl>
+ <dl class="dl-horizontal">
<dt>Test Case:</dt>
<dd><a href="{{ testcase.get_absolute_url }}">{{ testcase.name }}</a></dd>
<dt>Result:</dt>
@@ -36,28 +42,28 @@
{% endif %}
{% for testcase in test_cases %}
{% if testcase.test_set %}
- <h2>Test Set: <a href="{{ testcase.test_set.get_absolute_url }}">{{ testcase.test_set.name }}</a></h2>
+ <h2>Test Set: <a href="{{ testcase.test_set.get_absolute_url }}">{{ testcase.test_set.name }}</a></h2>
{% endif %}
{% if testcase.result == 1%}
- <h3>{{ testcase.name }} <span class="glyphicon glyphicon-remove"></span>&nbsp;fail</h3>
+ <h3>{{ testcase.name }} <span class="glyphicon glyphicon-remove"></span>&nbsp;fail</h3>
<h4><a
title="view test job output for this failed test"
href="{{ job.get_absolute_url }}#results_{{ testcase.id }}">
Log entry in job {{ job.id }} for test case {{ testcase.id }}</a></h4>
{% elif testcase.result == 2 %}
- <h3>{{ testcase.name }} <span class="glyphicon glyphicon-minus"></span>&nbsp;skipped</h3>
+ <h3>{{ testcase.name }} <span class="glyphicon glyphicon-minus"></span>&nbsp;skipped</h3>
<h4><a
title="view test job output for this test which was skipped"
href="{{ job.get_absolute_url }}#results_{{ testcase.id }}">
Log entry in job {{ job.id }} for test case {{ testcase.id }}</a></h4>
{% elif testcase.result == 3 %}
- <h3>{{ testcase.name }} <span class="glyphicon glyphicon-minus"></span>&nbsp;unknown</h3>
+ <h3>{{ testcase.name }} <span class="glyphicon glyphicon-minus"></span>&nbsp;unknown</h3>
<h4><a
title="view test job output for this test which gave an unknown result"
href="{{ job.get_absolute_url }}#results_{{ testcase.id }}">
Log entry in job {{ job.id }} for test case {{ testcase.id }}</a></h4>
{% else %}
- <h3>{{ testcase.name }} <span class="glyphicon glyphicon-ok"></span>&nbsp;pass</h3>
+ <h3>{{ testcase.name }} <span class="glyphicon glyphicon-ok"></span>&nbsp;pass</h3>
<h4><a
title="view test job output for this passed test"
href="{{ job.get_absolute_url }}#results_{{ testcase.id }}">
@@ -70,37 +76,42 @@
{% endif %}
{% if testcase.action_metadata %}
<ul class="list-unstyled">
- {% for key, value in testcase.action_metadata.items|sort_items %}
- {% get_extra_source testcase extra_source as testcase_extra %}
- {% if key == 'extra' and extra_source %}
- <li><strong>{{ key }}:</strong><pre style="white-space: pre-wrap; word-wrap: break-word;">{{ testcase_extra }}</pre></li>
- {% elif key == 'level' %}
- <li><strong>Pipeline description</strong>: <a
- href="{% url 'lava.scheduler.job.definition' job.pk %}#pipeline:{{ value }}">{{ value }}</a></li>
- {% elif key == 'duration' %}
- <li><strong>{{ key }}</strong>: {{ value|floatformat:2 }} secs</li>
- {% elif key == 'case' or key == 'result' or key == 'definition' %}
- {% elif value.items %}
- <li><strong>{{ key }}</strong><ul>
- {% for k, v in value.items %}
- <li><strong>{{ k }}</strong>: {{ v }}</li>
+ {% for key, value in testcase.action_metadata.items|sort_items %}
+ {% get_extra_source testcase extra_source as testcase_extra %}
+ {% if key == 'extra' and extra_source %}
+ <li><strong>{{ key }}:</strong><pre style="white-space: pre-wrap; word-wrap: break-word;">{{ testcase_extra }}</pre></li>
+ {% elif key == 'level' %}
+ <li><strong>Pipeline description</strong>: <a
+ href="{% url 'lava.scheduler.job.definition' job.pk %}#pipeline:{{ value }}">{{ value }}</a></li>
+ {% elif key == 'duration' %}
+ <li><strong>{{ key }}</strong>: {{ value|floatformat:2 }} secs</li>
+ {% elif key == 'case' or key == 'result' or key == 'definition' %}
+ {% elif value.items %}
+ <li><strong>{{ key }}</strong><ul>
+ {% for k, v in value.items %}
+ <li><strong>{{ k }}</strong>: {{ v }}</li>
+ {% endfor %}
+ </ul></li>
+ {% else %}
+ <li><strong>{{ key }}</strong>: {{ value }}</li>
+ {% endif %}
{% endfor %}
- </ul></li>
- {% else %}
- <li><strong>{{ key }}</strong>: {{ value }}</li>
- {% endif %}
- {% endfor %}
</ul>
{% else %}
- <dl class='dl-horizontal'>
- <dt>Result</dt>
- <dd>{{ testcase.result_code }}</dd>
- {% if testcase.measurement >= 0.0 %}
- <dt>Measurement</dt>
- <dd>{{ testcase.measurement|floatformat:2 }} {{ testcase.units }}</dd>
- {% endif %}
- </dl>
+ <dl class='dl-horizontal'>
+ <dt>Result</dt>
+ <dd>{{ testcase.result_code }}</dd>
+ {% if testcase.measurement >= 0.0 %}
+ <dt>Measurement</dt>
+ <dd>{{ testcase.measurement|floatformat:2 }} {{ testcase.units }}</dd>
+ {% endif %}
+ </dl>
{% endif %}
+
+ <ul class="list-unstyled">
+ <li>Test case export <button class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="right" title="Download link can be used with tokens:?user=user.name&amp;token=tokenstring">?</button> :
+ <a class="btn btn-xs btn-info" href="{% url 'lava.results.testcase_yaml' testcase.id %}" title="Download as YAML"><span class="glyphicon glyphicon-download"></span> YAML</a></li>
+ </ul>
{% endfor %}
<div class="panel-group" id="buglinks_accordion">
diff --git a/lava_results_app/templates/lava_results_app/suite.html b/lava_results_app/templates/lava_results_app/suite.html
index 7a68f93c1..67846ee90 100644
--- a/lava_results_app/templates/lava_results_app/suite.html
+++ b/lava_results_app/templates/lava_results_app/suite.html
@@ -20,7 +20,7 @@
<h4 class="modal-header">Exports
<button class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="right"
title="Download links can be used with tokens:
- ?name=user.name&amp;token=tokenstring">?</button>
+ ?user=user.name&amp;token=tokenstring">?</button>
</h4>
<dl class="dl-horizontal">
<dt>Test suite export :</dt>
diff --git a/lava_results_app/urls.py b/lava_results_app/urls.py
index bb8b01ada..42330b478 100644
--- a/lava_results_app/urls.py
+++ b/lava_results_app/urls.py
@@ -31,6 +31,7 @@ from lava_results_app.views import (
suite_csv,
suite_yaml,
testcase,
+ testcase_yaml,
testjob,
testjob_csv,
testjob_yaml,
@@ -166,6 +167,8 @@ urlpatterns = [
testcase, name='lava.results.testcase'),
url(r'^(?P<job>[0-9]+|[0-9]+.[0-9]+)/(?P<pk>[-_a-zA-Z0-9.]+)/(?P<case_id>[-_a-zA-Z0-9.\(\)+]+)$',
testcase, name='lava.results.testcase'),
+ url(r'^testcase/(?P<pk>[0-9]+)/yaml$',
+ testcase_yaml, name='lava.results.testcase_yaml'),
url(r'^get-bug-links-json$', get_bug_links_json,
name='lava.results.get_bug_links_json'),
url(r'^add-bug-link$', add_bug_link,
diff --git a/lava_results_app/views/__init__.py b/lava_results_app/views/__init__.py
index d0898b56f..4894637c2 100644
--- a/lava_results_app/views/__init__.py
+++ b/lava_results_app/views/__init__.py
@@ -425,6 +425,17 @@ def testcase(request, case_id, job=None, pk=None):
}, request=request))
+def testcase_yaml(request, pk):
+ testcase = get_object_or_404(TestCase, pk=pk)
+ check_request_auth(request, testcase.suite.job)
+ response = HttpResponse(content_type='text/yaml')
+ filename = "lava_%s.yaml" % testcase.name
+ response['Content-Disposition'] = 'attachment; filename="%s"' % filename
+ yaml.dump(export_testcase(testcase, with_buglinks=True), response,
+ Dumper=yaml.CDumper)
+ return response
+
+
@login_required
@post_only
def get_bug_links_json(request):