test_couchdb.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. from __future__ import absolute_import, unicode_literals
  2. import pytest
  3. from case import MagicMock, Mock, sentinel, skip
  4. from celery.app import backends
  5. from celery.backends import couchdb as module
  6. from celery.backends.couchdb import CouchBackend
  7. from celery.exceptions import ImproperlyConfigured
  8. try:
  9. import pycouchdb
  10. except ImportError:
  11. pycouchdb = None # noqa
  12. COUCHDB_CONTAINER = 'celery_container'
  13. @skip.unless_module('pycouchdb')
  14. class test_CouchBackend:
  15. def setup(self):
  16. self.Server = self.patching('pycouchdb.Server')
  17. self.backend = CouchBackend(app=self.app)
  18. def test_init_no_pycouchdb(self):
  19. """test init no pycouchdb raises"""
  20. prev, module.pycouchdb = module.pycouchdb, None
  21. try:
  22. with pytest.raises(ImproperlyConfigured):
  23. CouchBackend(app=self.app)
  24. finally:
  25. module.pycouchdb = prev
  26. def test_get_container_exists(self):
  27. self.backend._connection = sentinel._connection
  28. connection = self.backend.connection
  29. assert connection is sentinel._connection
  30. self.Server.assert_not_called()
  31. def test_get(self):
  32. """test_get
  33. CouchBackend.get should return and take two params
  34. db conn to couchdb is mocked.
  35. """
  36. x = CouchBackend(app=self.app)
  37. x._connection = Mock()
  38. get = x._connection.get = MagicMock()
  39. assert x.get('1f3fab') == get.return_value['value']
  40. x._connection.get.assert_called_once_with('1f3fab')
  41. def test_get_non_existent_key(self):
  42. x = CouchBackend(app=self.app)
  43. x._connection = Mock()
  44. get = x._connection.get = MagicMock()
  45. get.side_effect = pycouchdb.exceptions.NotFound
  46. assert x.get('1f3fab') is None
  47. x._connection.get.assert_called_once_with('1f3fab')
  48. @pytest.mark.parametrize("key", ['1f3fab', b'1f3fab'])
  49. def test_set(self, key):
  50. x = CouchBackend(app=self.app)
  51. x._connection = Mock()
  52. x.set(key, 'value')
  53. x._connection.save.assert_called_once_with({'_id': '1f3fab',
  54. 'value': 'value'})
  55. @pytest.mark.parametrize("key", ['1f3fab', b'1f3fab'])
  56. def test_set_with_conflict(self, key):
  57. x = CouchBackend(app=self.app)
  58. x._connection = Mock()
  59. x._connection.save.side_effect = (pycouchdb.exceptions.Conflict, None)
  60. get = x._connection.get = MagicMock()
  61. x.set(key, 'value')
  62. x._connection.get.assert_called_once_with('1f3fab')
  63. x._connection.get('1f3fab').__setitem__.assert_called_once_with(
  64. 'value', 'value')
  65. x._connection.save.assert_called_with(get('1f3fab'))
  66. assert x._connection.save.call_count == 2
  67. def test_delete(self):
  68. """test_delete
  69. CouchBackend.delete should return and take two params
  70. db conn to pycouchdb is mocked.
  71. TODO Should test on key not exists
  72. """
  73. x = CouchBackend(app=self.app)
  74. x._connection = Mock()
  75. mocked_delete = x._connection.delete = Mock()
  76. mocked_delete.return_value = None
  77. # should return None
  78. assert x.delete('1f3fab') is None
  79. x._connection.delete.assert_called_once_with('1f3fab')
  80. def test_backend_by_url(self, url='couchdb://myhost/mycoolcontainer'):
  81. from celery.backends.couchdb import CouchBackend
  82. backend, url_ = backends.by_url(url, self.app.loader)
  83. assert backend is CouchBackend
  84. assert url_ == url
  85. def test_backend_params_by_url(self):
  86. url = 'couchdb://johndoe:mysecret@myhost:123/mycoolcontainer'
  87. with self.Celery(backend=url) as app:
  88. x = app.backend
  89. assert x.container == 'mycoolcontainer'
  90. assert x.host == 'myhost'
  91. assert x.username == 'johndoe'
  92. assert x.password == 'mysecret'
  93. assert x.port == 123