make SpecialTasks recoverable.  this involves quite a few changes.
* run tasks in determined dirs instead of temp dirs.  the dir paths look like hosts//-, for example, hosts/myhost/4-verify.  the ID comes from the SpecialTask DB row.  this allows us to find the pidfile when we go looking for it during recovery, and it makes it simple to find the logs for any given special task, much like for HostQueueEntries. added SpecialTask.execution_path() for this purpose, and added models_test to test it.
* added execution_path() to HostQueueEntry to match the interface of SpecialTask, allowing for more polymorphism, and changed most call sites to use it.
* since we're running in these dirs, copy the full results back in these dirs, instead of just copying a single log file.
* move process recovery code up into AgentTask, so that all AgentTasks can share the same generic process recovery code.
* change SpecialTask recovery code to do process recovery.
* change VerifyTask handling of multiple pending verify requests for a machine.  instead of updating all the requests, just delete all other tasks.  they're not specially tracked in any way so it's simplest to just delete them.
* made special tasks get marked is_active=False when they complete, to be consistent with HQEs

other changes:
* added null=True to SpecialTask.time_started definition
* made EmailManager.enqueue_notify_email always log the message, and removed explicit logging calls from call sites
* added feature to DroneManager.execute_command() to automatically substitute the working directory into the command.  this avoids some duplicate information being passed around and simplifies the unit test.

Signed-off-by: Steve Howard <showard@google.com>


git-svn-id: http://test.kernel.org/svn/autotest/trunk@3380 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/frontend/afe/models_test.py b/frontend/afe/models_test.py
new file mode 100644
index 0000000..bb20103
--- /dev/null
+++ b/frontend/afe/models_test.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+import unittest
+import common
+from autotest_lib.frontend import setup_django_environment
+from autotest_lib.frontend.afe import frontend_test_utils
+from autotest_lib.frontend.afe import models
+
+class SpecialTaskUnittest(unittest.TestCase,
+                          frontend_test_utils.FrontendTestMixin):
+    def setUp(self):
+        self._frontend_common_setup()
+
+
+    def tearDown(self):
+        self._frontend_common_teardown()
+
+
+    def test_execution_path(self):
+        task = models.SpecialTask.objects.create(
+                host=self.hosts[0], task=models.SpecialTask.Task.VERIFY)
+
+        self.assertEquals(task.execution_path(), 'hosts/host1/1-verify')
+
+
+if __name__ == '__main__':
+    unittest.main()