test_views.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import sys
  2. import unittest
  3. from django.http import HttpResponse
  4. from django.test.client import Client
  5. from django.test.testcases import TestCase as DjangoTestCase
  6. from django.core.urlresolvers import reverse
  7. from django.template import TemplateDoesNotExist
  8. from anyjson import deserialize as JSON_load
  9. from billiard.utils.functional import curry
  10. from celery import conf
  11. from celery import states
  12. from celery.utils import gen_unique_id, get_full_cls_name
  13. from celery.backends import default_backend
  14. from celery.exceptions import RetryTaskError
  15. from celery.decorators import task
  16. from celery.datastructures import ExceptionInfo
  17. def reversestar(name, **kwargs):
  18. return reverse(name, kwargs=kwargs)
  19. task_is_successful = curry(reversestar, "celery-is_task_successful")
  20. task_status = curry(reversestar, "celery-task_status")
  21. task_apply = curry(reverse, "celery-apply")
  22. scratch = {}
  23. @task()
  24. def mytask(x, y):
  25. ret = scratch["result"] = int(x) * int(y)
  26. return ret
  27. def create_exception(name, base=Exception):
  28. return type(name, (base, ), {})
  29. def catch_exception(exception):
  30. try:
  31. raise exception
  32. except exception.__class__, exc:
  33. exc = default_backend.prepare_exception(exc)
  34. return exc, ExceptionInfo(sys.exc_info()).traceback
  35. class ViewTestCase(DjangoTestCase):
  36. def assertJSONEquals(self, json, py):
  37. json = isinstance(json, HttpResponse) and json.content or json
  38. try:
  39. self.assertEquals(JSON_load(json), py)
  40. except TypeError, exc:
  41. raise TypeError("%s: %s" % (exc, json))
  42. class TestTaskApply(ViewTestCase):
  43. def test_apply(self):
  44. conf.ALWAYS_EAGER = True
  45. try:
  46. ret = self.client.get(task_apply(kwargs={"task_name":
  47. mytask.name}) + "?x=4&y=4")
  48. self.assertEquals(scratch["result"], 16)
  49. finally:
  50. conf.ALWAYS_EAGER = False
  51. def test_apply_raises_404_on_unregistered_task(self):
  52. conf.ALWAYS_EAGER = True
  53. try:
  54. name = "xxx.does.not.exist"
  55. action = curry(self.client.get, task_apply(kwargs={
  56. "task_name": name}) + "?x=4&y=4")
  57. self.assertRaises(TemplateDoesNotExist, action)
  58. finally:
  59. conf.ALWAYS_EAGER = False
  60. class TestTaskStatus(ViewTestCase):
  61. def assertStatusForIs(self, status, res, traceback=None):
  62. uuid = gen_unique_id()
  63. default_backend.store_result(uuid, res, status,
  64. traceback=traceback)
  65. json = self.client.get(task_status(task_id=uuid))
  66. expect = dict(id=uuid, status=status, result=res)
  67. if status in default_backend.EXCEPTION_STATES:
  68. instore = default_backend.get_result(uuid)
  69. self.assertEquals(str(instore.args), str(res.args))
  70. expect["result"] = str(res.args[0])
  71. expect["exc"] = get_full_cls_name(res.__class__)
  72. expect["traceback"] = traceback
  73. self.assertJSONEquals(json, dict(task=expect))
  74. def test_task_status_success(self):
  75. self.assertStatusForIs(states.SUCCESS, "The quick brown fox")
  76. def test_task_status_failure(self):
  77. exc, tb = catch_exception(KeyError("foo"))
  78. self.assertStatusForIs(states.FAILURE, exc, tb)
  79. def test_task_status_retry(self):
  80. oexc, _ = catch_exception(KeyError("Resource not available"))
  81. exc, tb = catch_exception(RetryTaskError(str(oexc), oexc))
  82. self.assertStatusForIs(states.RETRY, exc, tb)
  83. class TestTaskIsSuccessful(ViewTestCase):
  84. def assertStatusForIs(self, status, outcome):
  85. uuid = gen_unique_id()
  86. result = gen_unique_id()
  87. default_backend.store_result(uuid, result, status)
  88. json = self.client.get(task_is_successful(task_id=uuid))
  89. self.assertJSONEquals(json, {"task": {"id": uuid,
  90. "executed": outcome}})
  91. def test_is_successful_success(self):
  92. self.assertStatusForIs(states.SUCCESS, True)
  93. def test_is_successful_pending(self):
  94. self.assertStatusForIs(states.PENDING, False)
  95. def test_is_successful_failure(self):
  96. self.assertStatusForIs(states.FAILURE, False)
  97. def test_is_successful_retry(self):
  98. self.assertStatusForIs(states.RETRY, False)