Make recovered tasks correctly handle being aborted before being started. Unlike other tasks, recovered tasks are effectively "started" as soon as they're created, since they're recovering a previously started task. So implement that properly so that when they're aborted, they do all the necessary killing and cleanup stuff.
This should fix a bug where jobs aborted while the scheduler is down won't get properly aborted when the scheduler starts up.
Signed-off-by: Steve Howard <showard@google.com>
git-svn-id: http://test.kernel.org/svn/autotest/trunk@3171 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/scheduler/monitor_db_unittest.py b/scheduler/monitor_db_unittest.py
index 240eb5a..773af7b 100644
--- a/scheduler/monitor_db_unittest.py
+++ b/scheduler/monitor_db_unittest.py
@@ -1563,7 +1563,7 @@
self.test_verify_task_with_queue_entry()
- def _setup_post_job_task_expects(self, autoserv_success, hqe_status,
+ def _setup_post_job_task_expects(self, autoserv_success, hqe_status=None,
hqe_aborted=False):
self.queue_entry.execution_tag.expect_call().and_return('tag')
self.pidfile_monitor = monitor_db.PidfileRunMonitor.expect_new()
@@ -1578,7 +1578,8 @@
if not hqe_aborted:
self.pidfile_monitor.exit_code.expect_call().and_return(code)
- self.queue_entry.set_status.expect_call(hqe_status)
+ if hqe_status:
+ self.queue_entry.set_status.expect_call(hqe_status)
def _setup_pre_parse_expects(self, autoserv_success):
@@ -1593,6 +1594,12 @@
self.queue_entry.set_status.expect_call(status)
+ def _expect_execute_run_monitor(self):
+ self.monitor.exit_code.expect_call()
+ self.monitor.exit_code.expect_call().and_return(0)
+ self._expect_copy_results()
+
+
def _setup_post_job_run_monitor(self, pidfile_name):
self.pidfile_monitor.has_process.expect_call().and_return(True)
autoserv_pidfile_id = object()
@@ -1604,9 +1611,7 @@
log_file=mock.anything_comparator(),
pidfile_name=pidfile_name,
paired_with_pidfile=self.PIDFILE_ID)
- self.monitor.exit_code.expect_call()
- self.monitor.exit_code.expect_call().and_return(0)
- self._expect_copy_results()
+ self._expect_execute_run_monitor()
def _expect_copy_results(self, monitor=None, queue_entry=None):
@@ -1658,6 +1663,20 @@
self.god.check_playback()
+ def test_final_reparse_recovery(self):
+ self.god.stub_class(monitor_db, 'PidfileRunMonitor')
+ self.monitor = self.god.create_mock_class(monitor_db.PidfileRunMonitor,
+ 'run_monitor')
+ self._setup_post_job_task_expects(True)
+ self._expect_execute_run_monitor()
+ self._setup_post_parse_expects(True)
+
+ task = monitor_db.FinalReparseTask([self.queue_entry],
+ run_monitor=self.monitor)
+ self.run_task(task, True)
+ self.god.check_playback()
+
+
def _setup_gather_logs_expects(self, autoserv_killed=True,
hqe_aborted=False):
self.god.stub_class(monitor_db, 'PidfileRunMonitor')
@@ -1773,6 +1792,26 @@
self._test_cleanup_task_helper(False, True)
+ def test_recovery_queue_task_aborted_early(self):
+ # abort a RecoveryQueueTask right after it's created
+ self.god.stub_class_method(monitor_db.QueueTask, '_log_abort')
+ self.god.stub_class_method(monitor_db.QueueTask, '_finish_task')
+ run_monitor = self.god.create_mock_class(monitor_db.PidfileRunMonitor,
+ 'run_monitor')
+
+ self.queue_entry.execution_tag.expect_call().and_return('tag')
+ run_monitor.kill.expect_call()
+ run_monitor.has_process.expect_call().and_return(True)
+ monitor_db.QueueTask._log_abort.expect_call()
+ monitor_db.QueueTask._finish_task.expect_call()
+
+ task = monitor_db.RecoveryQueueTask(self.job, [self.queue_entry],
+ run_monitor)
+ task.abort()
+ self.assert_(task.aborted)
+ self.god.check_playback()
+
+
class HostTest(BaseSchedulerTest):
def test_cmp_for_sort(self):
expected_order = [