=== modified file 'dashboard_app/helpers.py'
@@ -700,6 +700,48 @@
return s_test_run
+class BundleFormatImporter_1_4(BundleFormatImporter_1_3):
+ """
+ IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.4"
+ """
+
+ def _import_test_run(self, c_test_run, s_bundle):
+ s_test_run = super(BundleFormatImporter_1_4, self)._import_test_run(c_test_run, s_bundle)
+ test_duration = c_test_run.get('test_duration')
+ if test_duration is not None:
+ test_duration = timedelta_extension.from_json(test_duration)
+ s_test_run.test_duration = test_duration
+ s_test_run.save()
+ return s_test_run
+
+
+class BundleFormatImporter_1_5(BundleFormatImporter_1_4):
+ """
+ IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.5"
+ """
+
+ def _import_test_result_attachments(self, c_test_result, s_test_result):
+ for c_attachment in c_test_result.get("attachments", []):
+ s_attachment = s_test_result.attachments.create(
+ content_filename = c_attachment["pathname"],
+ mime_type = c_attachment["mime_type"])
+ # Save to get pk
+ s_attachment.save()
+ content = base64.standard_b64decode(c_attachment["content"])
+ s_attachment.content.save(
+ "attachment-{0}.txt".format(s_attachment.pk),
+ ContentFile(content))
+
+ def _import_test_results(self, c_test_run, s_test_run):
+ from dashboard_app.models import TestResult
+ super(BundleFormatImporter_1_5, self)._import_test_results(c_test_run, s_test_run)
+ for index, c_test_result in enumerate(c_test_run.get("test_results", []), 1):
+ if c_test_result.get("attributes", {}):
+ s_test_result = TestResult.objects.get(
+ relative_index=index, test_run=s_test_run)
+ self._import_test_result_attachments(c_test_result, s_test_result)
+
+
class BundleDeserializer(object):
"""
Helper class for de-serializing JSON bundle content into database models
@@ -711,6 +753,8 @@
"Dashboard Bundle Format 1.1": BundleFormatImporter_1_1,
"Dashboard Bundle Format 1.2": BundleFormatImporter_1_2,
"Dashboard Bundle Format 1.3": BundleFormatImporter_1_3,
+ "Dashboard Bundle Format 1.4": BundleFormatImporter_1_4,
+ "Dashboard Bundle Format 1.5": BundleFormatImporter_1_5,
}
def deserialize(self, s_bundle, prefer_evolution):
=== added file 'dashboard_app/migrations/0025_auto__add_field_testrun_microseconds.py'
@@ -0,0 +1,270 @@
+# -*- 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 'TestRun.microseconds'
+ db.add_column('dashboard_app_testrun', 'microseconds',
+ self.gf('django.db.models.fields.BigIntegerField')(null=True, blank=True),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'TestRun.microseconds'
+ db.delete_column('dashboard_app_testrun', 'microseconds')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'dashboard_app.attachment': {
+ 'Meta': {'object_name': 'Attachment'},
+ 'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
+ 'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
+ },
+ 'dashboard_app.bundle': {
+ 'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
+ '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
+ '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
+ 'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
+ 'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
+ 'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
+ },
+ 'dashboard_app.bundledeserializationerror': {
+ 'Meta': {'object_name': 'BundleDeserializationError'},
+ 'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
+ 'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+ 'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
+ },
+ 'dashboard_app.bundlestream': {
+ 'Meta': {'object_name': 'BundleStream'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
+ 'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
+ },
+ 'dashboard_app.hardwaredevice': {
+ 'Meta': {'object_name': 'HardwareDevice'},
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
+ 'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+ 'dashboard_app.image': {
+ 'Meta': {'object_name': 'Image'},
+ 'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
+ },
+ 'dashboard_app.imageset': {
+ 'Meta': {'object_name': 'ImageSet'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
+ },
+ 'dashboard_app.launchpadbug': {
+ 'Meta': {'object_name': 'LaunchpadBug'},
+ 'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
+ },
+ 'dashboard_app.namedattribute': {
+ 'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.TextField', [], {}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'value': ('django.db.models.fields.TextField', [], {})
+ },
+ 'dashboard_app.softwarepackage': {
+ 'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'dashboard_app.softwarepackagescratch': {
+ 'Meta': {'object_name': 'SoftwarePackageScratch'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'dashboard_app.softwaresource': {
+ 'Meta': {'object_name': 'SoftwareSource'},
+ 'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
+ 'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+ 'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
+ },
+ 'dashboard_app.tag': {
+ 'Meta': {'object_name': 'Tag'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
+ },
+ 'dashboard_app.test': {
+ 'Meta': {'object_name': 'Test'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
+ 'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
+ },
+ 'dashboard_app.testcase': {
+ 'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
+ 'test_case_id': ('django.db.models.fields.TextField', [], {}),
+ 'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
+ },
+ 'dashboard_app.testingeffort': {
+ 'Meta': {'object_name': 'TestingEffort'},
+ 'description': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
+ },
+ 'dashboard_app.testresult': {
+ 'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
+ '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
+ 'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+ 'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
+ 'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
+ 'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
+ 'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'dashboard_app.testrun': {
+ 'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
+ 'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
+ 'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
+ 'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
+ 'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
+ 'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
+ 'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
+ 'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
+ 'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'dashboard_app.testrundenormalization': {
+ 'Meta': {'object_name': 'TestRunDenormalization'},
+ 'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
+ },
+ 'dashboard_app.testrunfilter': {
+ 'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
+ 'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+ 'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
+ 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
+ },
+ 'dashboard_app.testrunfilterattribute': {
+ 'Meta': {'object_name': 'TestRunFilterAttribute'},
+ 'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+ 'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
+ },
+ 'dashboard_app.testrunfiltersubscription': {
+ 'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
+ 'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'dashboard_app.testrunfiltertest': {
+ 'Meta': {'object_name': 'TestRunFilterTest'},
+ 'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
+ },
+ 'dashboard_app.testrunfiltertestcase': {
+ 'Meta': {'object_name': 'TestRunFilterTestCase'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
+ 'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
+ },
+ 'lava_projects.project': {
+ 'Meta': {'object_name': 'Project'},
+ 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
+ 'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
+ 'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
+ }
+ }
+
+ complete_apps = ['dashboard_app']
\ No newline at end of file
=== modified file 'dashboard_app/models.py'
@@ -824,6 +824,11 @@
"with lots of tests results from 1972")
)
+ microseconds = models.BigIntegerField(
+ blank = True,
+ null = True
+ )
+
# Software Context
sw_image_desc = models.CharField(
@@ -927,6 +932,27 @@
self._cached_summary_results = self._get_summary_results()
return self._cached_summary_results
+ # test_duration property
+
+ def _get_test_duration(self):
+ if self.microseconds is None:
+ return None
+ else:
+ return datetime.timedelta(microseconds = self.microseconds)
+
+ def _set_test_duration(self, duration):
+ if duration is None:
+ self.microseconds = None
+ else:
+ if not isinstance(duration, datetime.timedelta):
+ raise TypeError("duration must be a datetime.timedelta() instance")
+ self.microseconds = (
+ duration.microseconds +
+ (duration.seconds * 10 ** 6) +
+ (duration.days * 24 * 60 * 60 * 10 ** 6))
+
+ test_duration = property(_get_test_duration, _set_test_duration)
+
class Meta:
ordering = ['-import_assigned_date']
@@ -1168,6 +1194,10 @@
attributes = generic.GenericRelation(NamedAttribute)
+ # Attachments
+
+ attachments = generic.GenericRelation(Attachment)
+
# Duration property
def _get_duration(self):
=== modified file 'setup.py'
@@ -52,7 +52,7 @@
'django-staticfiles == 0.3.4',
'docutils >= 0.6',
'lava-server >= 0.8',
- 'linaro-dashboard-bundle >= 1.5.2',
+ 'linaro-dashboard-bundle >= 1.8',
'linaro-django-pagination >= 2.0.2',
'linaro-django-xmlrpc >= 0.4',
'pygments >= 1.2',