=== 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]

