def test_store_upstream(self): l1 = LocalFIFOCache(1) l2 = LocalFIFOCache(1) @CallCache([l1, l2]) def _get_time(): return time.time() _get_time() self.assertEqual(len(l1), 1) self.assertEqual(len(l2), 1)
def test_complex_arguments(self): @CallCache([LocalFIFOCache(1)]) def _complex_arguments(*args, **kwargs): return json.dumps((time.time(), args, kwargs)) results = [_complex_arguments(1, 2, 3, a='1', b=None) for _ in range(10)] self.assertEqual(len(set(results)), 1)
def test_time_10_times(self): @CallCache([LocalFIFOCache(1)]) def _get_time(): return time.time() results = [_get_time() for _ in range(10)] self.assertEqual(len(set(results)), 1)
class LocationService(BaseService): """ Location service with geo-coding """ VERSION = 1 NAME = 'location' def __init__(self): super().__init__(add_auth_header=config.getboolean( "service-location", "auth_header", fallback=False)) self.BASE_URL = f'{config.get("service-location", "url", fallback="http://*****:*****@prometheus_latency('service-location.forward_lookup') @CallCache([LocalFIFOCache(max_size=100)]) def forward_lookup(self, location_params): url = f'{self.url}/geo' with self.session as session: try: with partner_call(session.get, LocationService.NAME) as get: result = get(url, params=location_params, headers=self._headers()) return result.json() except (json.decoder.JSONDecodeError, requests.exceptions.RequestException) as ex: logger.error( f"{self.url}/geo?{location_params} responded with error: {ex}" ) if isinstance(ex, requests.exceptions.RequestException): raise @prometheus_latency('service-location.reverse_lookup') @CallCache([LocalFIFOCache(max_size=100)]) def reverse_lookup(self, latitude, longitude): url = f'{self.url}/reversegeo' params = {'lat': latitude, 'lng': longitude} with self.session as session: try: with partner_call(session.get, LocationService.NAME) as get: result = get(url, params=params, headers=self._headers()) return result.json() except (json.decoder.JSONDecodeError, requests.exceptions.RequestException) as ex: logger.error( f"{self.url}/reversegeo?{params} responded with error: {ex}" ) if isinstance(ex, requests.exceptions.RequestException): raise
def test_no_store_upstream_or_cached_value(self): l1 = LocalFIFOCache(1) l2 = LocalFIFOCache(1) @CallCache([l1, l2]) def _get_time(): return time.time() a = _get_time() self.assertEqual(len(l1), 1) self.assertEqual(len(l2), 1) l2.purge() self.assertEqual(len(l2), 0) b = _get_time() self.assertEqual(a, b) self.assertEqual(len(l1), 1) self.assertEqual(len(l2), 0)
def test_store_downstream(self): l1 = LocalFIFOCache(1) l2 = LocalFIFOCache(1) @CallCache([l1, l2]) def _get_time(): return time.time() a = _get_time() self.assertEqual(len(l1), 1) self.assertEqual(len(l2), 1) l1.purge() self.assertEqual(len(l1), 0) self.assertEqual(len(l2), 1) b = _get_time() self.assertEqual(a, b) self.assertEqual(len(l1), 1) self.assertEqual(len(l2), 1)
def test_ignore_first_argument_off(self): c = CallCache([LocalFIFOCache(1)], ignore_first_argument=False) c.key_generator = MagicMock(return_value=b'test_key') @c def _test_method(a, b, c): return None _test_method(1, 2, 3) self.assertEqual(c.key_generator.call_args[0][1], (1, 2, 3))
def test_fifo_push_out(self): @CallCache([LocalFIFOCache(1)]) def _complex_arguments(*args, **kwargs): return json.dumps((time.time(), args, kwargs)) result1 = _complex_arguments(1, 2, 3, a='1', b=None) result2 = _complex_arguments(1, 2, 3, a='2', b=None) result3 = _complex_arguments(1, 2, 3, a='1', b=None) self.assertNotEqual(result1, result2) self.assertNotEqual(result1, result3)
def test_complex_arguments_different(self): @CallCache([LocalFIFOCache(2)]) def _complex_arguments(*args, **kwargs): return json.dumps((time.time(), args, kwargs)) results1 = [_complex_arguments(1, 2, 3, a='1', b=None) for _ in range(10)] results2 = [_complex_arguments(1, 2, 3, a='2', b=None) for _ in range(10)] self.assertEqual(len(set(results1)), 1) self.assertEqual(len(set(results2)), 1) self.assertNotEqual(results1.pop(), results2.pop())
def test_raise_on_exception_do_not_cache(self): l1 = LocalFIFOCache(1) @CallCache([l1]) def _get_time(): raise ValueError(time.time()) with self.assertRaises(ValueError): _get_time() with self.assertRaises(ValueError): _get_time() self.assertEqual(len(l1), 0)
def test_call_cache_lazy_call(self): """ Make sure decorated wrapper is evaluated at runtime """ from skill_sdk.tracing import initialize_tracer initialize_tracer() @CallCache([LocalFIFOCache(1)]) def _get_time(): return time.perf_counter() decorators.CACHES_ACTIVE = False results = [_get_time() for _ in range(10)] self.assertEqual(len(set(results)), 10) decorators.CACHES_ACTIVE = True results = [_get_time() for _ in range(10)] self.assertEqual(len(set(results)), 1)
class TestLocalFIFOCache(TestBaseLocalCache): def setUp(self): self.cache = LocalFIFOCache(10) def test_set_overflow(self): for index, value in enumerate('1234567890'): self.cache.set(value, index) self.assertEqual(len(self.cache), 10) self.cache.set('a', 'a') self.assertEqual(len(self.cache), 10) self.assertEqual(list(self.cache.data.keys()), list('234567890a')) def test_validate_too_long(self): for index, value in enumerate('1234567890'): self.cache.set(value, index) self.cache.data['a'] = LocalCacheItem('a') self.assertEqual(len(self.cache), 11) self.cache.validate() self.assertEqual(len(self.cache), 10)
def setUp(self): self.cache = LocalFIFOCache(10)
def test_init(self): zcbs = CircuitBreakerSession(cache=LocalFIFOCache()) self.assertEqual(zcbs.internal, False) self.assertEqual(zcbs.circuit_breaker, DEFAULT_CIRCUIT_BREAKER) self.assertTrue(isinstance(zcbs, Session))