Special tasks show "Failed" as their status instead of "Completed" if
they failed

Signed-off-by: James Ren <jamesren@google.com>


git-svn-id: http://test.kernel.org/svn/autotest/trunk@3946 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/frontend/afe/models.py b/frontend/afe/models.py
index e2909f8..5a42742 100644
--- a/frontend/afe/models.py
+++ b/frontend/afe/models.py
@@ -938,6 +938,7 @@
     is_complete = dbmodels.BooleanField(default=False, blank=False, null=False)
     time_started = dbmodels.DateTimeField(null=True, blank=True)
     queue_entry = dbmodels.ForeignKey(HostQueueEntry, blank=True, null=True)
+    success = dbmodels.BooleanField(default=False, blank=False, null=False)
 
     objects = model_logic.ExtendedManager()
 
@@ -957,7 +958,9 @@
         present similar statuses.
         """
         if self.is_complete:
-            return HostQueueEntry.Status.COMPLETED
+            if self.success:
+                return HostQueueEntry.Status.COMPLETED
+            return HostQueueEntry.Status.FAILED
         if self.is_active:
             return HostQueueEntry.Status.RUNNING
         return HostQueueEntry.Status.QUEUED
@@ -992,13 +995,14 @@
         self.save()
 
 
-    def finish(self):
+    def finish(self, success):
         """
         Sets a task as completed
         """
         logging.info('Finished: %s', self)
         self.is_active = False
         self.is_complete = True
+        self.success = success
         self.save()
 
 
diff --git a/frontend/afe/models_test.py b/frontend/afe/models_test.py
index 47932e0..734be2a 100755
--- a/frontend/afe/models_test.py
+++ b/frontend/afe/models_test.py
@@ -92,9 +92,12 @@
         task.update_object(is_active=True)
         self.assertEquals(task.status, 'Running')
 
-        task.update_object(is_active=False, is_complete=True)
+        task.update_object(is_active=False, is_complete=True, success=True)
         self.assertEquals(task.status, 'Completed')
 
+        task.update_object(success=False)
+        self.assertEquals(task.status, 'Failed')
+
 
     def test_activate(self):
         task = self._create_task()
@@ -106,9 +109,10 @@
     def test_finish(self):
         task = self._create_task()
         task.activate()
-        task.finish()
+        task.finish(True)
         self.assertFalse(task.is_active)
         self.assertTrue(task.is_complete)
+        self.assertTrue(task.success)
 
 
 if __name__ == '__main__':
diff --git a/frontend/migrations/041_add_special_task_success.py b/frontend/migrations/041_add_special_task_success.py
new file mode 100644
index 0000000..2000088
--- /dev/null
+++ b/frontend/migrations/041_add_special_task_success.py
@@ -0,0 +1,14 @@
+UP_SQL = """
+ALTER TABLE special_tasks
+ADD COLUMN success TINYINT(1)
+NOT NULL DEFAULT 0;
+
+UPDATE special_tasks
+SET success = 1
+WHERE is_complete = 1;
+"""
+
+DOWN_SQL = """
+ALTER TABLE special_tasks
+DROP COLUMN success;
+"""
diff --git a/scheduler/monitor_db.py b/scheduler/monitor_db.py
index 064c9c7..cf0ec2e 100755
--- a/scheduler/monitor_db.py
+++ b/scheduler/monitor_db.py
@@ -1725,7 +1725,10 @@
 
     def cleanup(self):
         super(SpecialAgentTask, self).cleanup()
-        self.task.finish()
+
+        # We will consider an aborted task to be "Failed"
+        self.task.finish(bool(self.success))
+
         if self.monitor:
             if self.monitor.has_process():
                 self._copy_results([self.task])
diff --git a/scheduler/monitor_db_unittest.py b/scheduler/monitor_db_unittest.py
index 5130e93..4cb3642 100755
--- a/scheduler/monitor_db_unittest.py
+++ b/scheduler/monitor_db_unittest.py
@@ -1322,7 +1322,7 @@
 
 
     def setup_run_monitor(self, exit_status, task_tag, copy_log_file=True,
-                          aborted=False):
+                          aborted=False, special_task_success=True):
         monitor_db.PidfileRunMonitor.run.expect_call(
             mock.is_instance_comparator(list),
             self.BASE_TASK_DIR + task_tag,
@@ -1337,7 +1337,7 @@
             monitor_db.PidfileRunMonitor.exit_code.expect_call().and_return(
                     exit_status)
 
-        self.task.finish.expect_call()
+        self.task.finish.expect_call(special_task_success)
 
         if copy_log_file:
             self._setup_move_logfile()
@@ -1393,10 +1393,10 @@
 
         self.host.set_status.expect_call('Repairing')
         if success:
-            self.setup_run_monitor(0, task_tag)
+            self.setup_run_monitor(0, task_tag, special_task_success=True)
             self.host.set_status.expect_call('Ready')
         else:
-            self.setup_run_monitor(1, task_tag)
+            self.setup_run_monitor(1, task_tag, special_task_success=False)
             self.host.set_status.expect_call('Repair Failed')
 
         task = monitor_db.RepairTask(task=self.task)
@@ -1454,7 +1454,8 @@
         self._setup_write_host_keyvals_expects(task_tag)
 
         self.host.set_status.expect_call('Repairing')
-        self.setup_run_monitor(0, task_tag, aborted=True)
+        self.setup_run_monitor(0, task_tag, aborted=True,
+                               special_task_success=False)
 
         task = monitor_db.RepairTask(task=self.task)
         task.host = self.host
@@ -1484,7 +1485,7 @@
         self._setup_write_host_keyvals_expects(task_tag)
 
         self.host.set_status.expect_call('Repairing')
-        self.setup_run_monitor(1, task_tag)
+        self.setup_run_monitor(1, task_tag, special_task_success=False)
         self.host.set_status.expect_call('Repair Failed')
         self.queue_entry.update_from_database.expect_call()
         self.queue_entry.status = 'Queued'
@@ -1523,7 +1524,7 @@
 
 
     def _setup_prejob_task_failure(self, task_tag, use_queue_entry):
-        self.setup_run_monitor(1, task_tag)
+        self.setup_run_monitor(1, task_tag, special_task_success=False)
         if use_queue_entry:
             if not self.queue_entry.meta_host:
                 self.queue_entry.set_execution_subdir.expect_call()
@@ -1596,7 +1597,7 @@
     def test_specialtask_abort_before_prolog(self):
         self._setup_special_task(1, models.SpecialTask.Task.REPAIR, False)
         task = monitor_db.RepairTask(task=self.task)
-        self.task.finish.expect_call()
+        self.task.finish.expect_call(False)
         task.abort()
         self.assertTrue(task.aborted)