diff options
author | Stevan Radakovic <stevan.radakovic@linaro.org> | 2017-11-29 10:57:22 +0100 |
---|---|---|
committer | Neil Williams <neil.williams@linaro.org> | 2017-11-30 10:43:32 +0000 |
commit | 3587c07e5d17ab9c0da4c430c817b3c07366702f (patch) | |
tree | 5547077a65bad9f1faae850fe82a07cd3451e4d2 /lava_results_app | |
parent | 41c636935765dfcad8b6771e1ff23346be4fa4e8 (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.py | 5 | ||||
-rw-r--r-- | lava_results_app/models.py | 64 | ||||
-rw-r--r-- | lava_results_app/templates/lava_results_app/case.html | 77 | ||||
-rw-r--r-- | lava_results_app/templates/lava_results_app/suite.html | 2 | ||||
-rw-r--r-- | lava_results_app/urls.py | 3 | ||||
-rw-r--r-- | lava_results_app/views/__init__.py | 11 |
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&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> fail</h3> + <h3>{{ testcase.name }} <span class="glyphicon glyphicon-remove"></span> 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> skipped</h3> + <h3>{{ testcase.name }} <span class="glyphicon glyphicon-minus"></span> 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> unknown</h3> + <h3>{{ testcase.name }} <span class="glyphicon glyphicon-minus"></span> 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> pass</h3> + <h3>{{ testcase.name }} <span class="glyphicon glyphicon-ok"></span> 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&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&token=tokenstring">?</button> + ?user=user.name&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): |