|
@@ -5,6 +5,7 @@ from celery.tests.utils import skip_if_quick
|
|
|
from celery.result import AsyncResult, TaskSetResult
|
|
|
from celery.backends import default_backend
|
|
|
from celery.exceptions import TimeoutError
|
|
|
+from celery.task.base import Task
|
|
|
|
|
|
|
|
|
def mock_task(name, status, result):
|
|
@@ -12,12 +13,15 @@ def mock_task(name, status, result):
|
|
|
|
|
|
|
|
|
def save_result(task):
|
|
|
+ traceback = "Some traceback"
|
|
|
if task["status"] == "SUCCESS":
|
|
|
default_backend.mark_as_done(task["id"], task["result"])
|
|
|
elif task["status"] == "RETRY":
|
|
|
- default_backend.mark_as_retry(task["id"], task["result"])
|
|
|
+ default_backend.mark_as_retry(task["id"], task["result"],
|
|
|
+ traceback=traceback)
|
|
|
else:
|
|
|
- default_backend.mark_as_failure(task["id"], task["result"])
|
|
|
+ default_backend.mark_as_failure(task["id"], task["result"],
|
|
|
+ traceback=traceback)
|
|
|
|
|
|
|
|
|
def make_mock_taskset(size=10):
|
|
@@ -65,6 +69,15 @@ class TestAsyncResult(unittest.TestCase):
|
|
|
self.assertEquals(repr(nok_res), "<AsyncResult: %s>" % (
|
|
|
self.task3["id"]))
|
|
|
|
|
|
+ def test_get_traceback(self):
|
|
|
+ ok_res = AsyncResult(self.task1["id"])
|
|
|
+ nok_res = AsyncResult(self.task3["id"])
|
|
|
+ nok_res2 = AsyncResult(self.task4["id"])
|
|
|
+ self.assertFalse(ok_res.traceback)
|
|
|
+ self.assertTrue(nok_res.traceback)
|
|
|
+ self.assertTrue(nok_res2.traceback)
|
|
|
+
|
|
|
+
|
|
|
def test_get(self):
|
|
|
ok_res = AsyncResult(self.task1["id"])
|
|
|
ok2_res = AsyncResult(self.task2["id"])
|
|
@@ -93,6 +106,28 @@ class TestAsyncResult(unittest.TestCase):
|
|
|
self.assertFalse(AsyncResult(self.task4["id"]).ready())
|
|
|
|
|
|
|
|
|
+class MockAsyncResultFailure(AsyncResult):
|
|
|
+
|
|
|
+ @property
|
|
|
+ def result(self):
|
|
|
+ return KeyError("baz")
|
|
|
+
|
|
|
+ @property
|
|
|
+ def status(self):
|
|
|
+ return "FAILURE"
|
|
|
+
|
|
|
+
|
|
|
+class MockAsyncResultSuccess(AsyncResult):
|
|
|
+
|
|
|
+ @property
|
|
|
+ def result(self):
|
|
|
+ return 42
|
|
|
+
|
|
|
+ @property
|
|
|
+ def status(self):
|
|
|
+ return "SUCCESS"
|
|
|
+
|
|
|
+
|
|
|
class TestTaskSetResult(unittest.TestCase):
|
|
|
|
|
|
def setUp(self):
|
|
@@ -102,6 +137,27 @@ class TestTaskSetResult(unittest.TestCase):
|
|
|
def test_total(self):
|
|
|
self.assertEquals(self.ts.total, self.size)
|
|
|
|
|
|
+ def test_iterate_raises(self):
|
|
|
+ ar = MockAsyncResultFailure(gen_unique_id())
|
|
|
+ ts = TaskSetResult(gen_unique_id(), [ar])
|
|
|
+ it = iter(ts)
|
|
|
+ self.assertRaises(KeyError, it.next)
|
|
|
+
|
|
|
+ def test_iterate_yields(self):
|
|
|
+ ar = MockAsyncResultSuccess(gen_unique_id())
|
|
|
+ ar2 = MockAsyncResultSuccess(gen_unique_id())
|
|
|
+ ts = TaskSetResult(gen_unique_id(), [ar, ar2])
|
|
|
+ it = iter(ts)
|
|
|
+ self.assertEquals(it.next(), 42)
|
|
|
+ self.assertEquals(it.next(), 42)
|
|
|
+
|
|
|
+ def test_join_timeout(self):
|
|
|
+ ar = MockAsyncResultSuccess(gen_unique_id())
|
|
|
+ ar2 = MockAsyncResultSuccess(gen_unique_id())
|
|
|
+ ar3 = AsyncResult(gen_unique_id())
|
|
|
+ ts = TaskSetResult(gen_unique_id(), [ar, ar2, ar3])
|
|
|
+ self.assertRaises(TimeoutError, ts.join, timeout=0.0000001)
|
|
|
+
|
|
|
def test_itersubtasks(self):
|
|
|
|
|
|
it = self.ts.itersubtasks()
|
|
@@ -207,3 +263,20 @@ class TestTaskSetPending(unittest.TestCase):
|
|
|
@skip_if_quick
|
|
|
def x_join_longer(self):
|
|
|
self.assertRaises(TimeoutError, self.ts.join, timeout=1)
|
|
|
+
|
|
|
+
|
|
|
+class RaisingTask(Task):
|
|
|
+
|
|
|
+ def run(self, x, y):
|
|
|
+ raise KeyError("xy")
|
|
|
+
|
|
|
+
|
|
|
+class TestEagerResult(unittest.TestCase):
|
|
|
+
|
|
|
+ def test_wait_raises(self):
|
|
|
+ res = RaisingTask.apply(args=[3, 3])
|
|
|
+ self.assertRaises(KeyError, res.wait)
|
|
|
+
|
|
|
+ def test_revoke(self):
|
|
|
+ res = RaisingTask.apply(args=[3, 3])
|
|
|
+ self.assertFalse(res.revoke())
|