[autotest] De-prioritize hostless hqes in favor of tests.

Currently, hostless hqes get precedence over tests. In situations
when we're flooded with suites this is a problem, as it leads to
a deadlock situation where many hostless jobs are waiting on tests
that the drone doesn't have the capacity to run. Note that even
after this change such scenarios are possible, just a little less
likely.

TEST=Started suites, set a low limit, checked that we run tests before
     hostless jobs. Checked that we prioritize (host+no metahost) over
     (no host+metahost). Ran unittests.
BUG=chromium:312847
DEPLOY=scheduler

Change-Id: Ibe66e8a0b6319561cc24e491ec7b9b370a840bad
Reviewed-on: https://chromium-review.googlesource.com/175028
Tested-by: Prashanth B <beeps@chromium.org>
Reviewed-by: Alex Miller <milleral@chromium.org>
Commit-Queue: Prashanth B <beeps@chromium.org>
diff --git a/scheduler/monitor_db_unittest.py b/scheduler/monitor_db_unittest.py
index ba025b7..016f264 100755
--- a/scheduler/monitor_db_unittest.py
+++ b/scheduler/monitor_db_unittest.py
@@ -99,6 +99,9 @@
         self._database.debug = _DEBUG
 
         self.god.stub_with(monitor_db, '_db', self._database)
+        self.god.stub_with(monitor_db.BaseDispatcher,
+                           '_get_pending_queue_entries',
+                           self._get_pending_hqes)
         self.god.stub_with(scheduler_models, '_db', self._database)
         self.god.stub_with(drone_manager.instance(), '_results_dir',
                            '/test/path')
@@ -127,6 +130,17 @@
         self._do_query(query)
 
 
+    def _get_pending_hqes(self):
+        query_string=('afe_jobs.priority DESC, '
+                      'ifnull(nullif(host_id, NULL), host_id) DESC, '
+                      'ifnull(nullif(meta_host, NULL), meta_host) DESC, '
+                      'job_id')
+        return list(scheduler_models.HostQueueEntry.fetch(
+            joins='INNER JOIN afe_jobs ON (job_id=afe_jobs.id)',
+            where='NOT complete AND NOT active AND status="Queued"',
+            order_by=query_string))
+
+
 class DispatcherSchedulingTest(BaseSchedulerTest):
     _jobs_scheduled = []
 
@@ -440,7 +454,7 @@
 #                [self.label4.id, self.label8.id], queue_entry))
 #        self.assertTrue(mock_logging_error._num_calls > 0)
 #        self.god.unstub(logging, 'error')
-# 
+#
 #        # Two labels both in the same atomic group, this should not raise an
 #        # error, it will merely cause the job to schedule on the intersection.
 #        self.assertEquals(1, host_scheduler._get_host_atomic_group_id(