From patchwork Mon Jun 13 04:34:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael-Doyle Hudson X-Patchwork-Id: 1828 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.47.109) by localhost6.localdomain6 with IMAP4-SSL; 14 Jun 2011 16:45:48 -0000 Delivered-To: patches@linaro.org Received: by 10.52.181.10 with SMTP id ds10cs431436vdc; Sun, 12 Jun 2011 21:34:17 -0700 (PDT) Received: by 10.227.19.130 with SMTP id a2mr4643058wbb.8.1307939656583; Sun, 12 Jun 2011 21:34:16 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id e5si12000010wbh.39.2011.06.12.21.34.15; Sun, 12 Jun 2011 21:34:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) client-ip=91.189.90.139; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) smtp.mail=bounces@canonical.com Received: from loganberry.canonical.com ([91.189.90.37]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QVyqs-0005fV-U9 for ; Mon, 13 Jun 2011 04:34:14 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id E08AE2E8950 for ; Mon, 13 Jun 2011 04:34:14 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: lava-scheduler X-Launchpad-Branch: ~linaro-validation/lava-scheduler/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 3 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-validation/lava-scheduler/trunk] Rev 3: Add a method for creating TestJobs, and enough of the model required to do Message-Id: <20110613043414.8377.73841.launchpad@loganberry.canonical.com> Date: Mon, 13 Jun 2011 04:34:14 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13175"; Instance="initZopeless config overlay" X-Launchpad-Hash: 92eaa44691f93550e5e7a6fca0dbe1287c90fdca Merge authors: Michael Hudson-Doyle (mwhudson) Related merge proposals: https://code.launchpad.net/~mwhudson/lava-scheduler/create-TestJob/+merge/64350 proposed by: Michael Hudson-Doyle (mwhudson) review: Approve - Zygmunt Krynicki (zkrynicki) ------------------------------------------------------------ revno: 3 [merge] committer: Michael-Doyle Hudson branch nick: trunk timestamp: Mon 2011-06-13 16:31:39 +1200 message: Add a method for creating TestJobs, and enough of the model required to do that. added: .bzrignore modified: lava_scheduler_app/models.py lava_scheduler_app/tests.py --- lp:lava-scheduler https://code.launchpad.net/~linaro-validation/lava-scheduler/trunk You are subscribed to branch lp:lava-scheduler. To unsubscribe from this branch go to https://code.launchpad.net/~linaro-validation/lava-scheduler/trunk/+edit-subscription === added file '.bzrignore' --- .bzrignore 1970-01-01 00:00:00 +0000 +++ .bzrignore 2011-06-07 06:10:56 +0000 @@ -0,0 +1,1 @@ +*.egg-info === modified file 'lava_scheduler_app/models.py' --- lava_scheduler_app/models.py 2011-05-25 03:50:34 +0000 +++ lava_scheduler_app/models.py 2011-06-13 04:25:04 +0000 @@ -1,3 +1,142 @@ +import json + +from django.contrib.auth.models import User from django.db import models - -# Create your models here. +from django.utils.translation import ugettext as _ + + +class DeviceType(models.Model): + """ + A class of device, for example a pandaboard or a snowball. + """ + + name = models.SlugField(primary_key=True) + + def __unicode__(self): + return self.name + + # We will probably hang uboot command and such off here... + + +class Device(models.Model): + """ + A device that we can run tests on. + """ + + #OFFLINE = 0 + #IDLE = 1 + #RUNNING = 2 + # + #STATUS_CHOICES = ( + # (OFFLINE, 'Offline'), + # (IDLE, 'Idle'), + # (RUNNING, 'Running'), + #) + + hostname = models.CharField( + verbose_name = _(u"Hostname"), + max_length = 200, + primary_key = True, + ) + + device_type = models.ForeignKey( + DeviceType, verbose_name=_(u"Device type")) + + #status = models.IntegerField( + # choices = STATUS_CHOICES, + # default = IDLE, + # verbose_name = _(u"Device status"), + # editable = False + #) + + def __unicode__(self): + return self.hostname + + #@classmethod + #def find_devices_by_type(cls, device_type): + # return device_type.device_set.all() + + +class TestJob(models.Model): + """ + A test job is a test process that will be run on a Device. + """ + + SUBMITTED = 0 + RUNNING = 1 + COMPLETE = 2 + INCOMPLETE = 3 + CANCELED = 4 + + STATUS_CHOICES = ( + (SUBMITTED, 'Submitted'), + (RUNNING, 'Running'), + (COMPLETE, 'Complete'), + (INCOMPLETE, 'Incomplete'), + (CANCELED, 'Canceled'), + ) + + submitter = models.ForeignKey( + User, + verbose_name = _(u"Submitter"), + ) + + #description = models.CharField( + # verbose_name = _(u"Description"), + # max_length = 200 + #) + + target = models.ForeignKey(Device, null=True) + device_type = models.ForeignKey(DeviceType) + + #priority = models.IntegerField( + # verbose_name = _(u"Priority"), + # default=0) + submit_time = models.DateTimeField( + verbose_name = _(u"Submit time"), + auto_now = False, + auto_now_add = True + ) + #start_time = models.DateTimeField( + # verbose_name = _(u"Start time"), + # auto_now = False, + # auto_now_add = False, + # null = True, + # blank = True, + # editable = False + #) + #end_time = models.DateTimeField( + # verbose_name = _(u"End time"), + # auto_now = False, + # auto_now_add = False, + # null = True, + # blank = True, + # editable = False + #) + status = models.IntegerField( + choices = STATUS_CHOICES, + default = SUBMITTED, + verbose_name = _(u"Status"), + editable = False + ) + definition = models.TextField( + editable = False, + ) + + #def __unicode__(self): + # return self.description + + @classmethod + def from_json_and_user(cls, json_data, user): + job_data = json.loads(json_data) + if 'target' in job_data: + target = Device.objects.get(hostname=job_data['target']) + device_type = target.device_type + else: + target = None + device_type = DeviceType.objects.get(name=job_data['device_type']) + job = TestJob( + definition=json_data, submitter=user, device_type=device_type, + target=target) + job.save() + return job === modified file 'lava_scheduler_app/tests.py' --- lava_scheduler_app/tests.py 2011-05-25 03:50:34 +0000 +++ lava_scheduler_app/tests.py 2011-06-13 04:25:04 +0000 @@ -1,23 +1,62 @@ -""" -This file demonstrates two different styles of tests (one doctest and one -unittest). These will both pass when you run "manage.py test". - -Replace these with more appropriate tests for your application. -""" - +import datetime +import json + +from django.contrib.auth.models import User from django.test import TestCase -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.failUnlessEqual(1 + 1, 2) - -__test__ = {"doctest": """ -Another way to test that 1 + 1 is equal to 2. - ->>> 1 + 1 == 2 -True -"""} - +from lava_scheduler_app.models import Device, DeviceType, TestJob + + +class TestTestJob(TestCase): + + def make_user(self): + return User.objects.create_user( + 'username', 'e@mail.invalid', 'password') + + def test_from_json_and_user_sets_definition(self): + DeviceType.objects.get_or_create(name='panda') + definition = json.dumps({'device_type':'panda'}) + job = TestJob.from_json_and_user(definition, self.make_user()) + self.assertEqual(definition, job.definition) + + def test_from_json_and_user_sets_submitter(self): + DeviceType.objects.get_or_create(name='panda') + user = self.make_user() + job = TestJob.from_json_and_user( + json.dumps({'device_type':'panda'}), user) + self.assertEqual(user, job.submitter) + + def test_from_json_and_user_sets_device_type(self): + panda_type = DeviceType.objects.get_or_create(name='panda')[0] + job = TestJob.from_json_and_user( + json.dumps({'device_type':'panda'}), self.make_user()) + self.assertEqual(panda_type, job.device_type) + + def test_from_json_and_user_sets_target(self): + panda_type = DeviceType.objects.get_or_create(name='panda')[0] + panda_board = Device(device_type=panda_type, hostname='panda01') + panda_board.save() + job = TestJob.from_json_and_user( + json.dumps({'target':'panda01'}), self.make_user()) + self.assertEqual(panda_board, job.target) + + def test_from_json_and_user_sets_device_type_from_target(self): + panda_type = DeviceType.objects.get_or_create(name='panda')[0] + Device(device_type=panda_type, hostname='panda').save() + job = TestJob.from_json_and_user( + json.dumps({'target':'panda'}), self.make_user()) + self.assertEqual(panda_type, job.device_type) + + def test_from_json_and_user_sets_date_submitted(self): + DeviceType.objects.get_or_create(name='panda') + before = datetime.datetime.now() + job = TestJob.from_json_and_user( + json.dumps({'device_type':'panda'}), self.make_user()) + after = datetime.datetime.now() + self.assertTrue(before < job.submit_time < after) + + def test_from_json_and_user_sets_status_to_SUBMITTED(self): + DeviceType.objects.get_or_create(name='panda') + job = TestJob.from_json_and_user( + json.dumps({'device_type':'panda'}), self.make_user()) + self.assertEqual(job.status, TestJob.SUBMITTED)