Make the scheduler robust to finding a HostQueueEntry with more than one
atomic group label.  Log a detailed error message and continue rather than
bailing out with a SchedulerError.

Signed-off-by: Gregory Smith <gps@google.com>


git-svn-id: http://test.kernel.org/svn/autotest/trunk@3373 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/scheduler/monitor_db_unittest.py b/scheduler/monitor_db_unittest.py
index bf5014c..7b4761c 100644
--- a/scheduler/monitor_db_unittest.py
+++ b/scheduler/monitor_db_unittest.py
@@ -1,6 +1,7 @@
 #!/usr/bin/python
 
 import unittest, time, subprocess, os, StringIO, tempfile, datetime, shutil
+import logging
 import common
 import MySQLdb
 from autotest_lib.frontend import setup_django_environment
@@ -455,8 +456,10 @@
         # Indirectly initialize the internal state of the host scheduler.
         self._dispatcher._refresh_pending_queue_entries()
 
-        atomic_hqe = monitor_db.HostQueueEntry(id=atomic_job.id)
-        normal_hqe = monitor_db.HostQueueEntry(id=normal_job.id)
+        atomic_hqe = monitor_db.HostQueueEntry.fetch(where='job_id=%d' %
+                                                     atomic_job.id).next()
+        normal_hqe = monitor_db.HostQueueEntry.fetch(where='job_id=%d' %
+                                                     normal_job.id).next()
 
         host_scheduler = self._dispatcher._host_scheduler
         self.assertTrue(host_scheduler._check_atomic_group_labels(
@@ -467,28 +470,46 @@
                 [self.label5.id, self.label6.id, self.label7.id], normal_hqe))
         self.assertTrue(host_scheduler._check_atomic_group_labels(
                 [self.label4.id, self.label6.id], atomic_hqe))
-        self.assertRaises(monitor_db.SchedulerError,
-                          host_scheduler._check_atomic_group_labels,
-                          [self.label4.id, self.label5.id],
-                          atomic_hqe)
+        self.assertTrue(host_scheduler._check_atomic_group_labels(
+                        [self.label4.id, self.label5.id],
+                        atomic_hqe))
 
 
     def test_HostScheduler_get_host_atomic_group_id(self):
-        self._create_job(metahosts=[self.label6.id])
+        job = self._create_job(metahosts=[self.label6.id])
+        queue_entry = monitor_db.HostQueueEntry.fetch(
+                where='job_id=%d' % job.id).next()
         # Indirectly initialize the internal state of the host scheduler.
         self._dispatcher._refresh_pending_queue_entries()
 
         # Test the host scheduler
         host_scheduler = self._dispatcher._host_scheduler
-        self.assertRaises(monitor_db.SchedulerError,
-                          host_scheduler._get_host_atomic_group_id,
-                          [self.label4.id, self.label5.id])
-        self.assertEqual(None, host_scheduler._get_host_atomic_group_id([]))
-        self.assertEqual(None, host_scheduler._get_host_atomic_group_id(
+
+        # Two labels each in a different atomic group.  This should log an
+        # error and continue.
+        orig_logging_error = logging.error
+        def mock_logging_error(message, *args):
+            mock_logging_error._num_calls += 1
+            # Test the logging call itself, we just wrapped it to count it.
+            orig_logging_error(message, *args)
+        mock_logging_error._num_calls = 0
+        self.god.stub_with(logging, 'error', mock_logging_error)
+        self.assertNotEquals(None, host_scheduler._get_host_atomic_group_id(
+                [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(
+                [self.label4.id, self.label5.id]))
+
+        self.assertEquals(None, host_scheduler._get_host_atomic_group_id([]))
+        self.assertEquals(None, host_scheduler._get_host_atomic_group_id(
                 [self.label3.id, self.label7.id, self.label6.id]))
-        self.assertEqual(1, host_scheduler._get_host_atomic_group_id(
+        self.assertEquals(1, host_scheduler._get_host_atomic_group_id(
                 [self.label4.id, self.label7.id, self.label6.id]))
-        self.assertEqual(1, host_scheduler._get_host_atomic_group_id(
+        self.assertEquals(1, host_scheduler._get_host_atomic_group_id(
                 [self.label7.id, self.label5.id]))