Switch to side-by-side view

--- a/Allura/allura/tests/test_commands.py
+++ b/Allura/allura/tests/test_commands.py
@@ -5,7 +5,7 @@
 
 from alluratest.controller import setup_basic_test, setup_global_objects
 from allura.command import script, set_neighborhood_features, \
-                           create_neighborhood, show_models
+                           create_neighborhood, show_models, taskd_cleanup
 from allura import model as M
 from forgeblog import model as BM
 from allura.lib.exceptions import InvalidNBFeatureValueError
@@ -186,3 +186,83 @@
             call.ensure_index([('foo', 1), ('baz', 1)], unique=True),
             call.ensure_index([('foo', 1), ('bar', 1)], background=True)
         ])
+
+
+class TestTaskdCleanupCommand(object):
+
+    def setUp(self):
+        self.cmd_class = taskd_cleanup.TaskdCleanupCommand
+        self.cmd_class._check_taskd_status = lambda x, p: 'OK'
+        self.cmd_class._check_task = lambda x, p, t: 'OK'
+        self.cmd_class._busy_tasks = lambda x: []
+        self.cmd_class._taskd_pids = lambda x: ['1111']
+        self.cmd_class._kill_stuck_taskd = Mock()
+        self.cmd_class._complete_suspicious_tasks = lambda x: []
+
+    def test_forsaken_tasks(self):
+        # forsaken task
+        task = Mock(state='busy', process='host pid 1111', result='')
+        self.cmd_class._busy_tasks = lambda x: [task]
+        self.cmd_class._taskd_pids = lambda x: ['2222']
+
+        cmd = self.cmd_class('taskd_command')
+        cmd.run([test_config, 'fake.log'])
+        assert task.state == 'error', task.state
+        assert task.result == 'Can\'t find taskd with given pid', task.result
+        assert cmd.error_tasks == [task]
+
+        # task actually running taskd pid == task.process pid == 2222
+        task = Mock(state='busy', process='host pid 2222', result='')
+        self.cmd_class._busy_tasks = lambda x: [task]
+        self.cmd_class._taskd_pids = lambda x: ['2222']
+
+        cmd = self.cmd_class('taskd_command')
+        cmd.run([test_config, 'fake.log'])
+        # nothing should change
+        assert task.state == 'busy', task.state
+        assert task.result == '', task.result
+        assert cmd.error_tasks == []
+
+    def test_stuck_taskd(self):
+        # does not stuck
+        cmd = self.cmd_class('taskd_command')
+        cmd.run([test_config, 'fake.log'])
+        assert cmd.stuck_pids == [], cmd.stuck_pids
+
+        # stuck
+        self.cmd_class._check_taskd_status = lambda x, p: 'STUCK'
+        cmd = self.cmd_class('taskd_command')
+        cmd.run([test_config, 'fake.log'])
+        assert cmd.stuck_pids == ['1111'], cmd.stuck_pids
+
+        # stuck with -k option
+        self.cmd_class._check_taskd_status = lambda x, p: 'STUCK'
+        cmd = self.cmd_class('taskd_command')
+        cmd.run([test_config, '-k', 'fake.log'])
+        cmd._kill_stuck_taskd.assert_called_with('1111')
+        assert cmd.stuck_pids == ['1111'], cmd.stuck_pids
+
+    def test_suspicious_tasks(self):
+        # task1 is lost
+        task1 = Mock(state='busy', process='host pid 1111', result='', _id=1)
+        task2 = Mock(state='busy', process='host pid 1111', result='', _id=2)
+        self.cmd_class._busy_tasks = lambda x: [task1, task2]
+        self.cmd_class._check_task = lambda x, p, t: 'FAIL' if t._id == 1 else 'OK'
+        cmd = self.cmd_class('taskd_command')
+        cmd.run([test_config, 'fake.log'])
+        assert cmd.suspicious_tasks == [task1], cmd.suspicious_tasks
+        assert cmd.error_tasks == [task1], cmd.error_tasks
+        assert task1.state == 'error'
+        assert task1.result == 'Forsaken task'
+
+        # task1 seems lost, but it just moved quickly
+        task1 = Mock(state='complete', process='host pid 1111', result='', _id=1)
+        task2 = Mock(state='busy', process='host pid 1111', result='', _id=2)
+        self.cmd_class._complete_suspicious_tasks = lambda x: [1]
+        self.cmd_class._busy_tasks = lambda x: [task1, task2]
+        self.cmd_class._check_task = lambda x, p, t: 'FAIL' if t._id == 1 else 'OK'
+        cmd = self.cmd_class('taskd_command')
+        cmd.run([test_config, 'fake.log'])
+        assert cmd.suspicious_tasks == [task1], cmd.suspicious_tasks
+        assert cmd.error_tasks == [], cmd.error_tasks
+        assert task1.state == 'complete'