test_http.py 4.9 KB

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