1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
from unittest.mock import patch
from django.core.cache.backends.base import BaseCache, CacheKeyWarning
from django.test import TestCase
from health_check.cache.backends import CacheBackend
# A Mock version of the cache to use for testing
class MockCache(BaseCache):
"""
A Mock Cache used for testing.
set_works - set to False to make the mocked set method fail, but not raise
set_raises - The Exception to be raised when set() is called, if any.
"""
key = None
value = None
set_works = None
set_raises = None
def __init__(self, set_works=True, set_raises=None):
super().__init__(params={})
self.set_works = set_works
self.set_raises = set_raises
def set(self, key, value, *args, **kwargs):
if self.set_raises is not None:
raise self.set_raises
elif self.set_works:
self.key = key
self.value = value
else:
self.key = key
self.value = None
def get(self, key, *args, **kwargs):
if key == self.key:
return self.value
else:
return None
class HealthCheckCacheTests(TestCase):
"""
Tests health check behavior with a mocked cache backend.
Ensures check_status returns/raises the expected result when the cache works, fails, or raises exceptions.
"""
@patch("health_check.cache.backends.caches", dict(default=MockCache()))
def test_check_status_working(self):
cache_backend = CacheBackend()
cache_backend.run_check()
self.assertFalse(cache_backend.errors)
@patch(
"health_check.cache.backends.caches",
dict(default=MockCache(), broken=MockCache(set_works=False)),
)
def test_multiple_backends_check_default(self):
# default backend works while other is broken
cache_backend = CacheBackend("default")
cache_backend.run_check()
self.assertFalse(cache_backend.errors)
@patch(
"health_check.cache.backends.caches",
dict(default=MockCache(), broken=MockCache(set_works=False)),
)
def test_multiple_backends_check_broken(self):
cache_backend = CacheBackend("broken")
cache_backend.run_check()
self.assertTrue(cache_backend.errors)
self.assertIn("does not match", cache_backend.pretty_status())
# check_status should raise ServiceUnavailable when values at cache key do not match
@patch("health_check.cache.backends.caches", dict(default=MockCache(set_works=False)))
def test_set_fails(self):
cache_backend = CacheBackend()
cache_backend.run_check()
self.assertTrue(cache_backend.errors)
self.assertIn("does not match", cache_backend.pretty_status())
# check_status should catch generic exceptions raised by set and convert to ServiceUnavailable
@patch(
"health_check.cache.backends.caches",
dict(default=MockCache(set_raises=Exception)),
)
def test_set_raises_generic(self):
cache_backend = CacheBackend()
with self.assertRaises(Exception):
cache_backend.run_check()
# check_status should catch CacheKeyWarning and convert to ServiceReturnedUnexpectedResult
@patch(
"health_check.cache.backends.caches",
dict(default=MockCache(set_raises=CacheKeyWarning)),
)
def test_set_raises_cache_key_warning(self):
cache_backend = CacheBackend()
cache_backend.check_status()
cache_backend.run_check()
self.assertIn("unexpected result: Cache key warning", cache_backend.pretty_status())
|