=== added file 'smokeng/migrations/0004_add_stdout_stderr.py'
--- smokeng/migrations/0004_add_stdout_stderr.py 1970-01-01 00:00:00 +0000
+++ smokeng/migrations/0004_add_stdout_stderr.py 2013-07-30 23:05:44 +0000
@@ -0,0 +1,127 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'SmokeTestResult.stderr'
+ db.add_column('smoke_tests', 'stderr',
+ self.gf('django.db.models.fields.TextField')(null=True),
+ keep_default=False)
+
+ # Adding field 'SmokeTestResult.stdout'
+ db.add_column('smoke_tests', 'stdout',
+ self.gf('django.db.models.fields.TextField')(null=True),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'SmokeTestResult.stderr'
+ db.delete_column('smoke_tests', 'stderr')
+
+ # Deleting field 'SmokeTestResult.stdout'
+ db.delete_column('smoke_tests', 'stdout')
+
+
+ models = {
+ 'common.bug': {
+ 'Meta': {'object_name': 'Bug', 'db_table': "'bugs'"},
+ 'assignee': ('django.db.models.fields.CharField', [], {'max_length': '4096', 'null': 'True'}),
+ 'bug_no': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importance': ('django.db.models.fields.CharField', [], {'default': "u'unknown'", 'max_length': '4096'}),
+ 'internal': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'project': ('django.db.models.fields.CharField', [], {'max_length': '4096', 'null': 'True'}),
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "u'unknown'", 'max_length': '4096'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '4096', 'null': 'True'}),
+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'common.jenkinsbuild': {
+ 'Meta': {'unique_together': "(('job', 'build_number'),)", 'object_name': 'JenkinsBuild', 'db_table': "'jenkins_builds'"},
+ 'bugs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'build_bugs'", 'symmetrical': 'False', 'to': "orm['common.Bug']"}),
+ 'build_description': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024'}),
+ 'build_number': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'failed': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'internal': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['common.JenkinsJob']"}),
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'ran_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'common.jenkinsjob': {
+ 'Meta': {'object_name': 'JenkinsJob', 'db_table': "'jenkins_jobs'"},
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'internal': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'}),
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'smokeng.smokeimage': {
+ 'Meta': {'object_name': 'SmokeImage', 'db_table': "'smoke_images'"},
+ 'arch': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'build_number': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'flavor': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'internal': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'release': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'variant': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'smokeng.smokeresult': {
+ 'Meta': {'object_name': 'SmokeResult', 'db_table': "'smoke_results'"},
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'error_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'fail_count': ('django.db.models.fields.IntegerField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'image': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['smokeng.SmokeImage']"}),
+ 'internal': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'jenkins_build': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['common.JenkinsBuild']"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'pass_count': ('django.db.models.fields.IntegerField', [], {}),
+ 'pass_rate': ('django.db.models.fields.FloatField', [], {'default': '0.0'}),
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'ran_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'total_count': ('django.db.models.fields.IntegerField', [], {}),
+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'smokeng.smokeresultbug': {
+ 'Meta': {'object_name': 'SmokeResultBug', 'db_table': "'smoke_result_bugs'"},
+ 'bug': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['common.Bug']"}),
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'internal': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'result': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['smokeng.SmokeResult']"}),
+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'smokeng.smoketestresult': {
+ 'Meta': {'object_name': 'SmokeTestResult', 'db_table': "'smoke_tests'"},
+ 'command': ('django.db.models.fields.CharField', [], {'max_length': '4096'}),
+ 'command_type': ('django.db.models.fields.CharField', [], {'max_length': '4096'}),
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'internal': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'result': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['smokeng.SmokeResult']"}),
+ 'returncode': ('django.db.models.fields.IntegerField', [], {}),
+ 'stderr': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'stdout': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'testcase': ('django.db.models.fields.CharField', [], {'max_length': '4096'}),
+ 'testsuite': ('django.db.models.fields.CharField', [], {'max_length': '4096'}),
+ 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ }
+ }
+
+ complete_apps = ['smokeng']
\ No newline at end of file
=== modified file 'smokeng/models.py'
--- smokeng/models.py 2013-07-10 16:56:19 +0000
+++ smokeng/models.py 2013-07-30 23:05:44 +0000
@@ -162,3 +162,5 @@
testcase = models.CharField(max_length=4096)
testsuite = models.CharField(max_length=4096)
returncode = models.IntegerField()
+ stderr = models.TextField(null=True)
+ stdout = models.TextField(null=True)
=== modified file 'smokeng/tables.py'
--- smokeng/tables.py 2013-07-19 15:47:56 +0000
+++ smokeng/tables.py 2013-07-30 23:05:44 +0000
@@ -115,11 +115,14 @@
class SmokeTestResultTable(tables.Table):
- command_type = tables.TemplateColumn(
- '
'
+ command_type = tables.LinkColumn(
+ "smokeng.views.test_result_detail",
+ kwargs={
+ "release": A('release'),
+ "image_id": A('image_id'),
+ "name": A('name'),
+ "id": A('id'),
+ },
)
testcase = tables.Column()
returncode = tables.TemplateColumn(
=== added file 'smokeng/templates/smokeng/test_result_detail.html'
--- smokeng/templates/smokeng/test_result_detail.html 1970-01-01 00:00:00 +0000
+++ smokeng/templates/smokeng/test_result_detail.html 2013-07-30 23:05:44 +0000
@@ -0,0 +1,49 @@
+{% extends "smokeng/smoke_layout.html" %}
+{% load dashboard_extras staticfiles %}
+{% load render_table from django_tables2 %}
+{% block page_name %}
+Testcase: {{ testcase }} - {{ image.release }} {{ image.arch|display_name }} {{build_number }}
+{% endblock %}
+{% block content %}
+
+
+
+ Testcase: {{ testcase }}
+
+
Build data
+
+
+ Build #: | {{ build_number }} |
+
+
+ Arch: | {{ image.arch|display_name }} |
+
+
+ Release: | {{ image.release }} |
+
+
+ Variant: | {{ image.variant }} |
+
+
+ Job data: |
+
+ Artifacts,
+ Console Log
+ |
+
+
+
Test case data
+
+ {% for entry in results %}
+ {% for key, value in entry.items %}
+
+ {% if value != '' and value != None %}
+ {{ key }} |
+ {{ value|wordwrap:150 }} |
+ {% endif %}
+
+ {% endfor %}
+ {% endfor %}
+
+
+{% endblock content %}
=== removed file 'smokeng/templates/smokeng/test_results_popup.html'
--- smokeng/templates/smokeng/test_results_popup.html 2013-07-13 18:13:42 +0000
+++ smokeng/templates/smokeng/test_results_popup.html 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-
- {% for key, value in popup_data.items %}
-
- {% if value != '' %}
- {{ key }} |
- {{ value }} |
- {% endif %}
-
- {% endfor %}
-
=== modified file 'smokeng/tests.py'
--- smokeng/tests.py 2013-07-10 18:33:06 +0000
+++ smokeng/tests.py 2013-07-30 23:05:44 +0000
@@ -165,6 +165,19 @@
response = self._test_url(url)
self.assertTemplateUsed(response, 'smokeng/test_results.html')
+ def test_test_result_detail_url(self):
+ url = reverse(
+ 'smokeng_test_result_detail',
+ args=(
+ self.image.release,
+ self.image.id,
+ self.result.name,
+ self.testcaseresult.pk,
+ ),
+ )
+ response = self._test_url(url)
+ self.assertTemplateUsed(response, 'smokeng/test_result_detail.html')
+
class TestSmoke(TestCase):
""" Tests for the smoke models. """
=== modified file 'smokeng/urls.py'
--- smokeng/urls.py 2013-07-10 16:56:19 +0000
+++ smokeng/urls.py 2013-07-30 23:05:44 +0000
@@ -23,16 +23,21 @@
url(
r'^(?:(?P\w+)/)?$',
'overview',
- name='smokeng_overview'
+ name='smokeng_overview',
),
url(
r'^(?P\w+)/image/(?P\d+)/$',
'image_overview',
- name='smokeng_image_overview'
+ name='smokeng_image_overview',
+ ),
+ url(
+ r'^(?P\w+)/image/(?P\d+)/(?P.*)/(?P\d+)/$',
+ 'test_result_detail',
+ name='smokeng_test_result_detail',
),
url(
r'^(?P\w+)/image/(?P\d+)/(?P.*)/$',
'image_test_results',
- name='smokeng_image_test_results'
+ name='smokeng_image_test_results',
),
)
=== modified file 'smokeng/utah_utils.py'
--- smokeng/utah_utils.py 2013-07-10 18:05:55 +0000
+++ smokeng/utah_utils.py 2013-07-30 23:05:44 +0000
@@ -58,6 +58,8 @@
for cmd in data['commands']:
command_type = cmd['cmd_type']
command = cmd['command']
+ stderr = cmd['stderr']
+ stdout = cmd['stdout']
"""
In the past, Utah would return 'null' as a returncode in certain
instances. The null return has now changed to return '15' when the
@@ -75,6 +77,8 @@
command_type=command_type,
command=command,
returncode=returncode,
+ stderr=stderr,
+ stdout=stdout,
)
else:
testcase = cmd['testcase']
@@ -86,6 +90,8 @@
testcase=testcase,
testsuite=testsuite,
returncode=returncode,
+ stderr=stderr,
+ stdout=stdout,
)
details.append(testresult)
=== modified file 'smokeng/views.py'
--- smokeng/views.py 2013-07-15 14:01:25 +0000
+++ smokeng/views.py 2013-07-30 23:05:44 +0000
@@ -23,7 +23,6 @@
from django_tables2 import RequestConfig
from django.template import RequestContext
from django.views.decorators.http import require_GET
-from django.template.loader import render_to_string
from common.bread_crumbs import (
BreadCrumb,
@@ -267,15 +266,15 @@
table_data = []
for test in tests:
test_data = dict(
+ release=release,
+ name=name,
testcase=test.testcase,
+ url_name=os.path.basename(test.testcase),
testsuite=os.path.basename(test.testsuite),
command_type=test.command_type,
returncode=test.returncode,
command=test.command,
- )
- test_data['popup_body'] = render_to_string(
- 'smokeng/test_results_popup.html',
- dict(popup_data=test_data),
+ image_id=image.id,
)
test_data['id'] = test.pk
table_data.append(test_data)
@@ -284,6 +283,7 @@
RequestConfig(request, paginate=None).configure(table)
data = {
+ 'name': name,
'image': image,
'build_number': image.build_number,
'release': release,
@@ -304,3 +304,57 @@
data,
RequestContext(request),
)
+
+
+@BreadCrumb(
+ "Testcase details",
+ parent=image_test_results,
+ needs=['release', 'image_id', 'name', 'id'],
+)
+@require_GET
+def test_result_detail(request, release, image_id, name, id):
+ test = get_object_or_404(
+ SmokeTestResult,
+ pk=id,
+ )
+
+ results = []
+ test_data = dict(
+ command_type=test.command_type,
+ testsuite=test.testsuite,
+ testcase=test.testcase,
+ command=test.command,
+ returncode=test.returncode,
+ stderr=test.stderr,
+ stdout=test.stdout,
+ )
+ results.append(test_data)
+
+ jenkins_url = (
+ test.result.jenkins_build.job.url +
+ test.result.jenkins_build.build_number
+ )
+
+ data = {
+ 'results': results,
+ 'name': name,
+ 'image': test.result.image,
+ 'build_number': test.result.image.build_number,
+ 'release': test.result.image.release,
+ 'jenkins_url': jenkins_url,
+ 'testcase': test.testcase,
+ 'bread_crumb_trail': BreadCrumbTrail.leading_to(
+ test_result_detail,
+ release=release,
+ image_id=image_id,
+ name=name,
+ id=id,
+ build_number=test.result.image.build_number,
+ ),
+ }
+
+ return render_to_response(
+ 'smokeng/test_result_detail.html',
+ data,
+ RequestContext(request),
+ )