From patchwork Thu Jul 21 00:49:18 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: 2898 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 3AADF23F42 for ; Thu, 21 Jul 2011 00:49:21 +0000 (UTC) Received: from mail-qy0-f180.google.com (mail-qy0-f180.google.com [209.85.216.180]) by fiordland.canonical.com (Postfix) with ESMTP id DB48BA18048 for ; Thu, 21 Jul 2011 00:49:20 +0000 (UTC) Received: by qyk30 with SMTP id 30so553210qyk.11 for ; Wed, 20 Jul 2011 17:49:20 -0700 (PDT) Received: by 10.229.25.212 with SMTP id a20mr7704651qcc.148.1311209360279; Wed, 20 Jul 2011 17:49:20 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.217.78 with SMTP id hl14cs127222qcb; Wed, 20 Jul 2011 17:49:19 -0700 (PDT) Received: by 10.227.11.134 with SMTP id t6mr2401018wbt.21.1311209358748; Wed, 20 Jul 2011 17:49:18 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id ei15si1459792wbb.98.2011.07.20.17.49.18; Wed, 20 Jul 2011 17:49:18 -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 1QjhS2-0003ht-4z for ; Thu, 21 Jul 2011 00:49:18 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id 248E02E814B for ; Thu, 21 Jul 2011 00:49:18 +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: 38 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-validation/lava-scheduler/trunk] Rev 38: Dispatch jobs that are targeted at a device type not just a device. (Jobs that Message-Id: <20110721004918.18269.61908.launchpad@loganberry.canonical.com> Date: Thu, 21 Jul 2011 00:49:18 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13475"; Instance="initZopeless config overlay" X-Launchpad-Hash: c2a42f75ce6055133a0edb18fc1cec90dc8af97a Merge authors: Michael Hudson-Doyle (mwhudson) ------------------------------------------------------------ revno: 38 [merge] committer: Michael-Doyle Hudson branch nick: trunk timestamp: Thu 2011-07-21 12:45:54 +1200 message: Dispatch jobs that are targeted at a device type not just a device. (Jobs that are targeted directly at a board will be processed before jobs that are targeted at a device type). Also, fix the attempt to process older jobs first to actually work. modified: lava_scheduler_app/tests.py lava_scheduler_daemon/dbjobsource.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 === modified file 'lava_scheduler_app/tests.py' --- lava_scheduler_app/tests.py 2011-07-20 04:58:48 +0000 +++ lava_scheduler_app/tests.py 2011-07-21 00:45:08 +0000 @@ -66,15 +66,15 @@ device.save() return device - def make_testjob(self, target=None, device_type=None, definition=None): + def make_testjob(self, device_type=None, definition=None, **kwargs): if device_type is None: device_type = self.ensure_device_type() if definition is None: definition = json.dumps({}) submitter = self.make_user() testjob = TestJob( - device_type=device_type, target=target, definition=definition, - submitter=submitter) + device_type=device_type, definition=definition, + submitter=submitter, **kwargs) testjob.save() return testjob @@ -206,6 +206,49 @@ self.assertEqual( None, DatabaseJobSource().getJobForBoard_impl('panda01')) + def test_getJobForBoard_considers_device_type(self): + panda_type = self.factory.ensure_device_type(name='panda') + self.factory.make_device(hostname='panda01', device_type=panda_type) + definition = {'foo': 'bar'} + self.factory.make_testjob( + device_type=panda_type, definition=json.dumps(definition)) + transaction.commit() + self.assertEqual( + definition, DatabaseJobSource().getJobForBoard_impl('panda01')) + + def test_getJobForBoard_prefers_older(self): + panda_type = self.factory.ensure_device_type(name='panda') + panda01 = self.factory.make_device( + hostname='panda01', device_type=panda_type) + first_definition = {'foo': 'bar'} + second_definition = {'foo': 'baz'} + self.factory.make_testjob( + target=panda01, definition=json.dumps(first_definition), + submit_time=datetime.datetime.now() - datetime.timedelta(days=1)) + self.factory.make_testjob( + target=panda01, definition=json.dumps(second_definition), + submit_time=datetime.datetime.now()) + transaction.commit() + self.assertEqual( + first_definition, + DatabaseJobSource().getJobForBoard_impl('panda01')) + + def test_getJobForBoard_prefers_directly_targeted(self): + panda_type = self.factory.ensure_device_type(name='panda') + panda01 = self.factory.make_device( + hostname='panda01', device_type=panda_type) + type_definition = {'foo': 'bar'} + device_definition = {'foo': 'baz'} + self.factory.make_testjob( + device_type=panda_type, definition=json.dumps(type_definition), + submit_time=datetime.datetime.now() - datetime.timedelta(days=1)) + self.factory.make_testjob( + target=panda01, definition=json.dumps(device_definition)) + transaction.commit() + self.assertEqual( + device_definition, + DatabaseJobSource().getJobForBoard_impl('panda01')) + def test_getJobForBoard_sets_start_time(self): device = self.factory.make_device(hostname='panda01') job = self.factory.make_testjob(target=device) === modified file 'lava_scheduler_daemon/dbjobsource.py' --- lava_scheduler_daemon/dbjobsource.py 2011-07-20 05:08:59 +0000 +++ lava_scheduler_daemon/dbjobsource.py 2011-07-21 00:40:39 +0000 @@ -3,6 +3,7 @@ import logging from django.db import IntegrityError, transaction +from django.db.models import Q from twisted.internet.threads import deferToThread @@ -32,8 +33,11 @@ if device.status != Device.IDLE: return None jobs_for_device = TestJob.objects.all().filter( - target=device, status=TestJob.SUBMITTED) - jobs_for_device.order_by('submit_time') + Q(target=device) | Q(device_type=device.device_type), + status=TestJob.SUBMITTED) + jobs_for_device = jobs_for_device.extra( + select={'is_targeted': 'target_id is not NULL'}, + order_by=['-is_targeted', 'submit_time']) jobs = jobs_for_device[:1] if jobs: job = jobs[0]