test_http.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import
  3. from __future__ import with_statement
  4. from contextlib import contextmanager
  5. from functools import wraps
  6. try:
  7. from urllib import addinfourl
  8. except ImportError: # py3k
  9. from urllib.request import addinfourl # noqa
  10. from anyjson import dumps
  11. from kombu.utils.encoding import from_utf8
  12. from celery.task import http
  13. from celery.tests.utils import Case, eager_tasks
  14. from celery.utils.compat import StringIO
  15. @contextmanager
  16. def mock_urlopen(response_method):
  17. import urllib2
  18. urlopen = urllib2.urlopen
  19. @wraps(urlopen)
  20. def _mocked(url, *args, **kwargs):
  21. response_data, headers = response_method(url)
  22. return addinfourl(StringIO(response_data), headers, url)
  23. urllib2.urlopen = _mocked
  24. try:
  25. yield True
  26. finally:
  27. urllib2.urlopen = urlopen
  28. def _response(res):
  29. return lambda r: (res, [])
  30. def success_response(value):
  31. return _response(dumps({'status': 'success', 'retval': value}))
  32. def fail_response(reason):
  33. return _response(dumps({'status': 'failure', 'reason': reason}))
  34. def unknown_response():
  35. return _response(dumps({'status': 'u.u.u.u', 'retval': True}))
  36. class test_encodings(Case):
  37. def test_utf8dict(self):
  38. uk = 'foobar'
  39. d = {u'følelser ær langé': u'ærbadægzaå寨Å',
  40. from_utf8(uk): from_utf8('xuzzybaz')}
  41. for key, value in http.utf8dict(d.items()).items():
  42. self.assertIsInstance(key, str)
  43. self.assertIsInstance(value, str)
  44. class test_MutableURL(Case):
  45. def test_url_query(self):
  46. url = http.MutableURL('http://example.com?x=10&y=20&z=Foo')
  47. self.assertDictContainsSubset({'x': '10',
  48. 'y': '20',
  49. 'z': 'Foo'}, url.query)
  50. url.query['name'] = 'George'
  51. url = http.MutableURL(str(url))
  52. self.assertDictContainsSubset({'x': '10',
  53. 'y': '20',
  54. 'z': 'Foo',
  55. 'name': 'George'}, url.query)
  56. def test_url_keeps_everything(self):
  57. url = 'https://e.com:808/foo/bar#zeta?x=10&y=20'
  58. url = http.MutableURL(url)
  59. self.assertEqual(
  60. str(url).split('?')[0],
  61. 'https://e.com:808/foo/bar#zeta',
  62. )
  63. def test___repr__(self):
  64. url = http.MutableURL('http://e.com/foo/bar')
  65. self.assertTrue(repr(url).startswith('<MutableURL: http://e.com'))
  66. def test_set_query(self):
  67. url = http.MutableURL('http://e.com/foo/bar/?x=10')
  68. url.query = {'zzz': 'xxx'}
  69. url = http.MutableURL(str(url))
  70. self.assertEqual(url.query, {'zzz': 'xxx'})
  71. class test_HttpDispatch(Case):
  72. def test_dispatch_success(self):
  73. with mock_urlopen(success_response(100)):
  74. d = http.HttpDispatch('http://example.com/mul', 'GET', {
  75. 'x': 10, 'y': 10})
  76. self.assertEqual(d.dispatch(), 100)
  77. def test_dispatch_failure(self):
  78. with mock_urlopen(fail_response('Invalid moon alignment')):
  79. d = http.HttpDispatch('http://example.com/mul', 'GET', {
  80. 'x': 10, 'y': 10})
  81. with self.assertRaises(http.RemoteExecuteError):
  82. d.dispatch()
  83. def test_dispatch_empty_response(self):
  84. with mock_urlopen(_response('')):
  85. d = http.HttpDispatch('http://example.com/mul', 'GET', {
  86. 'x': 10, 'y': 10})
  87. with self.assertRaises(http.InvalidResponseError):
  88. d.dispatch()
  89. def test_dispatch_non_json(self):
  90. with mock_urlopen(_response("{'#{:'''")):
  91. d = http.HttpDispatch('http://example.com/mul', 'GET', {
  92. 'x': 10, 'y': 10})
  93. with self.assertRaises(http.InvalidResponseError):
  94. d.dispatch()
  95. def test_dispatch_unknown_status(self):
  96. with mock_urlopen(unknown_response()):
  97. d = http.HttpDispatch('http://example.com/mul', 'GET', {
  98. 'x': 10, 'y': 10})
  99. with self.assertRaises(http.UnknownStatusError):
  100. d.dispatch()
  101. def test_dispatch_POST(self):
  102. with mock_urlopen(success_response(100)):
  103. d = http.HttpDispatch('http://example.com/mul', 'POST', {
  104. 'x': 10, 'y': 10})
  105. self.assertEqual(d.dispatch(), 100)
  106. class test_URL(Case):
  107. def test_URL_get_async(self):
  108. with eager_tasks():
  109. with mock_urlopen(success_response(100)):
  110. d = http.URL('http://example.com/mul').get_async(x=10, y=10)
  111. self.assertEqual(d.get(), 100)
  112. def test_URL_post_async(self):
  113. with eager_tasks():
  114. with mock_urlopen(success_response(100)):
  115. d = http.URL('http://example.com/mul').post_async(x=10, y=10)
  116. self.assertEqual(d.get(), 100)