def compile_large_format_files(): try: with current_app.test_request_context(): print "[+] Starting large format file cache reset..." cache = Cache(config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_DB': 0}) cache.init_app(current_app) data = _compile_large_format_files() if "error" not in data: cache.set('large_format', data, timeout=CACHE_TIMEOUT) print "[+] large format files updated." else: print "[-] Error in large file format update" except Exception as err: message = 'compile_large_format_files exception: %s' % err.message current_app.logger.warning(message)
def compile_cam_images(): try: with current_app.test_request_context(): print "[+] Starting cam images cache reset..." cache = Cache(config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_DB': 0}) cache.init_app(current_app) cam_images = _compile_cam_images() if "error" not in cam_images: cache.set('cam_images', cam_images, timeout=CACHE_TIMEOUT) print "[+] cam images cache reset." else: print "[-] Error in cache update" except Exception as err: message = 'compile_cam_images exception: %s' % err.message current_app.logger.warning(message)
def compile_glider_tracks(): try: with current_app.test_request_context(): print "[+] Starting glider tracks cache reset..." cache = Cache(config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_DB': 0}) cache.init_app(current_app) glider_tracks = _compile_glider_tracks(True) if "error" not in glider_tracks: cache.set('glider_tracks', glider_tracks, timeout=CACHE_TIMEOUT) print "[+] Glider tracks cache reset." else: print "[-] Error in cache update" except Exception as err: message = 'compile_glider_tracks exception: %s' % err.message current_app.logger.warning(message)
def compile_bad_assets(): try: with current_app.test_request_context(): print "[+] Starting bad asset cache reset..." cache = Cache(config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_DB': 0}) cache.init_app(current_app) url = current_app.config['UFRAME_ASSETS_URL'] + '/assets' payload = requests.get(url) if payload.status_code is 200: data = payload.json() bad_assets = _compile_bad_assets(data) if "error" not in bad_assets: cache.set('bad_asset_list', bad_assets, timeout=CACHE_TIMEOUT) print "[+] Bad asset cache reset" else: print "[-] Error in cache update" except Exception as err: message = 'compile_bad_assets exception: %s' % err.message current_app.logger.warning(message)
def compile_vocabulary(): try: with current_app.test_request_context(): print "[+] Starting vocabulary cache reset..." cache = Cache(config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_DB': 0}) cache.init_app(current_app) url = current_app.config['UFRAME_VOCAB_URL'] + '/vocab' payload = requests.get(url) if payload.status_code is 200: data = payload.json() vocab_dict, vocab_codes = compile_vocab(data) if "error" not in vocab_dict: cache.set('vocab_dict', vocab_dict, timeout=CACHE_TIMEOUT) cache.set('vocab_codes', codes, timeout=CACHE_TIMEOUT) print "[+] Vocabulary cache reset" else: print "[-] Error in cache update" except Exception as err: message = 'compile_vocabulary exception: %s' % err.message current_app.logger.warning(message)
def compile_c2_toc(): try: c2_toc = {} with current_app.test_request_context(): print "[+] Starting c2 toc cache reset..." cache = Cache(config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_DB': 0}) cache.init_app(current_app) try: c2_toc = _compile_c2_toc() except Exception as err: message = 'Error processing compile_c2_toc: ', err.message current_app.logger.warning(message) if c2_toc is not None: cache.set('c2_toc', c2_toc, timeout=CACHE_TIMEOUT) print "[+] C2 toc cache reset..." else: print "[-] Error in cache update" except Exception as err: message = 'compile_c2_toc exception: ', err.message current_app.logger.warning(message)
def compile_assets_rd(): try: asset_rds = {} with current_app.test_request_context(): print "[+] Starting asset reference designators cache reset..." cache = Cache(config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_DB': 0}) cache.init_app(current_app) try: asset_rds, _ = _compile_asset_rds() except Exception as err: message = 'Error processing _compile_asset_rds: ', err.message current_app.logger.warning(message) if asset_rds: cache.set('asset_rds', asset_rds, timeout=CACHE_TIMEOUT) print "[+] Asset reference designators cache reset..." else: print "[-] Error in cache update" except Exception as err: message = 'compile_asset_rds exception: %s' % err.message current_app.logger.warning(message) raise Exception(message)
def compile_assets(): try: print '\n debug - *** tasks - compile_assets()' with current_app.test_request_context(): print "[+] Starting asset cache reset..." cache = Cache(config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_DB': 0}) cache.init_app(current_app) url = current_app.config['UFRAME_ASSETS_URL'] + '/%s' % ('assets') payload = requests.get(url) if payload.status_code is 200: # Cache assets_list data = payload.json() assets, asset_rds = _compile_assets(data) if "error" not in assets: cache.set('asset_list', assets, timeout=CACHE_TIMEOUT) print "[+] Asset list cache reset" # Cache assets_dict (based on success of _compile_assets returning assets) assets_dict = get_assets_dict_from_list(assets) if not assets_dict: message = 'Warning: get_assets_dict_from_list returned empty assets_dict.' print '\n debug -- message: ', message current_app.logger.info(message) if isinstance(assets_dict, dict): cache.set('assets_dict', assets_dict, timeout=CACHE_TIMEOUT) print "[+] Assets dictionary cache reset" else: print "[-] Error in Assets dictionary cache update" else: print "[-] Error in asset_list and asset_dict cache update" # Cache assets_rd if asset_rds: cache.set('asset_rds', asset_rds, timeout=CACHE_TIMEOUT) print "[+] Asset reference designators cache reset..." else: print "[-] Error in asset_rds cache update" else: print "[-] Error in cache update" except Exception as err: message = 'compile_assets exception: %s' % err.message current_app.logger.warning(message) raise Exception(message)
class CacheStorage(Storage): """Implement storage engine for Flask-Cache useful for testing.""" def __init__(self, **kwargs): """See :meth:`~jsonalchemy.storage.Storage.__init__`.""" self._cache = kwargs.get('cache', None) if self._cache is None: from flask.ext.cache import Cache self._cache = Cache() self._prefix = kwargs.get('model', '') def _set(self, data): self._keys = self._keys | set([data['_id']]) self._cache.set(self._prefix + data['_id'], data, timeout=99999) def _get(self, id): value = self._cache.get(self._prefix + id) if value is None: raise KeyError() return value @property def _keys(self): return self._cache.get(self._prefix + '::keys') or set() @_keys.setter def _keys(self, value): self._cache.set(self._prefix + '::keys', value) def save_one(self, data, id=None): """See :meth:`~jsonalchemy.storage.Storage.save_one`.""" if id is not None: data['_id'] = id self._set(data) return data def save_many(self, jsons, ids=None): """See :meth:`~jsonalchemy.storage.Storage.save_many`.""" return map(lambda k: self.save_one(*k), zip(jsons, ids)) def update_one(self, data, id=None): """See :meth:`~jsonalchemy.storage.Storage.update_one`.""" if id is not None: data['_id'] = id id = data['_id'] old_data = self._get(id) old_data.update(data) self._set(old_data) return old_data def update_many(self, jsons, ids=None): """See :meth:`~jsonalchemy.storage.Storage.update_many`.""" return map(lambda k: self.update_one(*k), zip(jsons, ids)) def get_one(self, id): """See :meth:`~jsonalchemy.storage.Storage.get_one`.""" return self._get(id) def get_many(self, ids): """See :meth:`~jsonalchemy.storage.Storage.get_many`.""" return map(self.get_one, ids) def get_field_values(self, ids, field, repetitive_values=True, count=False, include_recid=False, split_by=0): """See :meth:`~jsonalchemy.storage.Storage.get_field_values`.""" raise NotImplementedError() def get_fields_values(self, ids, fields, repetitive_values=True, count=False, include_recid=False, split_by=0): """See :meth:`~jsonalchemy.storage.Storage.get_fields_values`.""" raise NotImplementedError() def search(self, query): """See :meth:`~jsonalchemy.storage.Storage.search`.""" def _find(item): for k, v in six.iteritems(query): if item is None: return False test_v = item.get(k) if test_v is None and v is not None: return False elif test_v != v: return False return True return filter(_find, map(self._get, self._keys)) def create(self): """See :meth:`~jsonalchemy.storage.Storage.create`.""" assert len(self._keys) == 0 def drop(self): """See :meth:`~jsonalchemy.storage.Storage.create`.""" while self._keys: self._cache.delete(self._prefix + self._keys.pop())
class CacheTestCase(unittest.TestCase): def setUp(self): app = Flask(__name__) app.debug = False app.config['CACHE_TYPE'] = 'simple' self.cache = Cache(app) self.app = app def tearDown(self): self.app = None self.cache = None self.tc = None def test_00_set(self): self.cache.set('hi', 'hello') assert self.cache.get('hi') == 'hello' def test_01_add(self): self.cache.add('hi', 'hello') assert self.cache.get('hi') == 'hello' self.cache.add('hi', 'foobar') assert self.cache.get('hi') == 'hello' def test_02_delete(self): self.cache.set('hi', 'hello') self.cache.delete('hi') assert self.cache.get('hi') is None def test_03_cached_view(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data time.sleep(2) rv = tc.get('/') assert the_time == rv.data time.sleep(5) rv = tc.get('/') assert the_time != rv.data def test_04_cached_view_unless(self): @self.app.route('/a') @self.cache.cached(5, unless=lambda: True) def non_cached_view(): return str(time.time()) @self.app.route('/b') @self.cache.cached(5, unless=lambda: False) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/a') the_time = rv.data time.sleep(1) rv = tc.get('/a') assert the_time != rv.data rv = tc.get('/b') the_time = rv.data time.sleep(1) rv = tc.get('/b') assert the_time == rv.data def test_05_cached_function(self): with self.app.test_request_context(): @self.cache.cached(2, key_prefix='MyBits') def get_random_bits(): return [random.randrange(0, 2) for i in range(50)] my_list = get_random_bits() his_list = get_random_bits() assert my_list == his_list time.sleep(4) his_list = get_random_bits() assert my_list != his_list def test_06_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a + b + random.randrange(0, 100000) result = big_foo(5, 2) time.sleep(1) assert big_foo(5, 2) == result result2 = big_foo(5, 3) assert result2 != result time.sleep(4) assert big_foo(5, 2) != result assert big_foo(5, 3) == result2 time.sleep(1) assert big_foo(5, 3) != result2 def test_07_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a + b + random.randrange(0, 100000) result = big_foo(5, 2) result2 = big_foo(5, 3) time.sleep(1) assert big_foo(5, 2) == result assert big_foo(5, 2) == result assert big_foo(5, 3) != result assert big_foo(5, 3) == result2 self.cache.delete_memoized(big_foo) assert big_foo(5, 2) != result assert big_foo(5, 3) != result2 def test_08_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return a + b + random.randrange(0, 100000) result_a = big_foo(5, 1) result_b = big_foo(5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) == result_b self.cache.delete_memoized(big_foo, 5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) != result_b def test_09_args_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return sum(a) + sum(b) + random.randrange(0, 100000) result_a = big_foo([5, 3, 2], [1]) result_b = big_foo([3, 3], [3, 1]) assert big_foo([5, 3, 2], [1]) == result_a assert big_foo([3, 3], [3, 1]) == result_b self.cache.delete_memoized(big_foo, [5, 3, 2], [1]) assert big_foo([5, 3, 2], [1]) != result_a assert big_foo([3, 3], [3, 1]) == result_b def test_10_kwargs_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b=None): return a + sum(b.values()) + random.randrange(0, 100000) result_a = big_foo(1, dict(one=1, two=2)) result_b = big_foo(5, dict(three=3, four=4)) assert big_foo(1, dict(one=1, two=2)) == result_a assert big_foo(5, dict(three=3, four=4)) == result_b self.cache.delete_memoized(big_foo, 1, dict(one=1, two=2)) assert big_foo(1, dict(one=1, two=2)) != result_a assert big_foo(5, dict(three=3, four=4)) == result_b def test_10a_kwargonly_memoize(self): @self.cache.memoize() def big_foo(a=None): if a is None: a = 0 return a + random.random() result_a = big_foo() result_b = big_foo(5) assert big_foo() == result_a assert big_foo() < 1 assert big_foo(5) == result_b assert big_foo(5) >= 5 and big_foo(5) < 6 def test_10a_arg_kwarg_memoize(self): @self.cache.memoize() def f(a, b=0): pass f(1) f(1) def test_10b_classarg_memoize(self): @self.cache.memoize() def bar(a): return a.value + random.random() class Adder(object): def __init__(self, value): self.value = value adder = Adder(15) adder2 = Adder(20) y = bar(adder) z = bar(adder2) assert y != z assert bar(adder) == y assert bar(adder) != z adder.value = 14 assert bar(adder) == y assert bar(adder) != z assert bar(adder) != bar(adder2) assert bar(adder2) == z def test_10c_classfunc_memoize(self): class Adder(object): def __init__(self, initial): self.initial = initial @self.cache.memoize() def add(self, b): return self.initial + b adder1 = Adder(1) adder2 = Adder(2) x = adder1.add(3) assert adder1.add(3) == x assert adder1.add(4) != x assert adder1.add(3) != adder2.add(3) def test_11_cache_key_property(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data with self.app.test_request_context(): cache_data = self.cache.get(cached_view.make_cache_key()) assert the_time == cache_data def test_12_make_cache_key_function_property(self): @self.app.route('/<foo>/<bar>') @self.cache.memoize(5) def cached_view(foo, bar): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/a/b') the_time = rv.data cache_key = cached_view.make_cache_key(cached_view.uncached, foo=u"a", bar=u"b") cache_data = self.cache.get(cache_key) assert the_time == cache_data different_key = cached_view.make_cache_key(cached_view.uncached, foo=u"b", bar=u"a") different_data = self.cache.get(different_key) assert the_time != different_data def test_13_cache_timeout_property(self): @self.app.route('/') @self.cache.memoize(5) def cached_view1(): return str(time.time()) @self.app.route('/<foo>/<bar>') @self.cache.memoize(10) def cached_view2(foo, bar): return str(time.time()) assert hasattr(cached_view1, "cache_timeout") assert hasattr(cached_view2, "cache_timeout") assert cached_view1.cache_timeout == 5 assert cached_view2.cache_timeout == 10 # test that this is a read-write property cached_view1.cache_timeout = 2 cached_view2.cache_timeout = 3 assert cached_view1.cache_timeout == 2 assert cached_view2.cache_timeout == 3 tc = self.app.test_client() rv1 = tc.get('/') time1 = rv1.data time.sleep(1) rv2 = tc.get('/a/b') time2 = rv2.data # VIEW1 # it's been 1 second, cache is still active assert time1 == tc.get('/').data time.sleep(2) # it's been 3 seconds, cache is not still active assert time1 != tc.get('/').data # VIEW2 # it's been 2 seconds, cache is still active assert time2 == tc.get('/a/b').data time.sleep(2) # it's been 4 seconds, cache is not still active assert time2 != tc.get('/a/b').data def test_14_memoized_multiple_arg_kwarg_calls(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b, c=[1, 1], d=[1, 1]): return sum(a) + sum(b) + sum(c) + sum(d) + random.randrange( 0, 100000) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert big_foo([5, 3, 2], [1], d=[3, 3], c=[3, 3]) == result_a assert big_foo(b=[1], a=[5, 3, 2], c=[3, 3], d=[3, 3]) == result_a assert big_foo([5, 3, 2], [1], [3, 3], [3, 3]) == result_a def test_15_memoize_multiple_arg_kwarg_delete(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b, c=[1, 1], d=[1, 1]): return sum(a) + sum(b) + sum(c) + sum(d) + random.randrange( 0, 100000) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) self.cache.delete_memoized(big_foo, [5, 3, 2], [1], [3, 3], [3, 3]) result_b = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], b=[1], c=[3, 3], d=[3, 3]) result_b = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], [1], c=[3, 3], d=[3, 3]) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], b=[1], c=[3, 3], d=[3, 3]) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], [1], c=[3, 3], d=[3, 3]) result_b = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], [1], [3, 3], [3, 3]) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b def test_16_memoize_kwargs_to_args(self): with self.app.test_request_context(): def big_foo(a, b, c=None, d=None): return sum(a) + sum(b) + random.randrange(0, 100000) expected = (1, 2, 'foo', 'bar') args, kwargs = self.cache.memoize_kwargs_to_args( big_foo, 1, 2, 'foo', 'bar') assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, 2, 'foo', 'bar', a=1) assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, a=1, b=2, c='foo', d='bar') assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, d='bar', b=2, a=1, c='foo') assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, 1, 2, d='bar', c='foo') assert (args == expected) def test_17_dict_config(self): cache = Cache(config={'CACHE_TYPE': 'simple'}) cache.init_app(self.app) assert cache.config['CACHE_TYPE'] == 'simple' def test_18_dict_config_initapp(self): cache = Cache() cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) from werkzeug.contrib.cache import SimpleCache assert isinstance(self.app.extensions['cache'], SimpleCache) def test_19_dict_config_both(self): cache = Cache(config={'CACHE_TYPE': 'null'}) cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) from werkzeug.contrib.cache import SimpleCache assert isinstance(self.app.extensions['cache'], SimpleCache)
class CacheTestCase(unittest.TestCase): def _set_app_config(self, app): app.config['CACHE_TYPE'] = 'simple' def setUp(self): app = Flask(__name__) app.debug = True self._set_app_config(app) self.cache = Cache(app) self.app = app def tearDown(self): self.app = None self.cache = None self.tc = None def test_00_set(self): self.cache.set('hi', 'hello') assert self.cache.get('hi') == 'hello' def test_01_add(self): self.cache.add('hi', 'hello') assert self.cache.get('hi') == 'hello' self.cache.add('hi', 'foobar') assert self.cache.get('hi') == 'hello' def test_02_delete(self): self.cache.set('hi', 'hello') self.cache.delete('hi') assert self.cache.get('hi') is None def test_03_cached_view(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data time.sleep(2) rv = tc.get('/') assert the_time == rv.data time.sleep(5) rv = tc.get('/') assert the_time != rv.data def test_04_cached_view_unless(self): @self.app.route('/a') @self.cache.cached(5, unless=lambda: True) def non_cached_view(): return str(time.time()) @self.app.route('/b') @self.cache.cached(5, unless=lambda: False) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/a') the_time = rv.data time.sleep(1) rv = tc.get('/a') assert the_time != rv.data rv = tc.get('/b') the_time = rv.data time.sleep(1) rv = tc.get('/b') assert the_time == rv.data def test_05_cached_function(self): with self.app.test_request_context(): @self.cache.cached(2, key_prefix='MyBits') def get_random_bits(): return [random.randrange(0, 2) for i in range(50)] my_list = get_random_bits() his_list = get_random_bits() assert my_list == his_list time.sleep(4) his_list = get_random_bits() assert my_list != his_list def test_06_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a+b+random.randrange(0, 100000) result = big_foo(5, 2) time.sleep(1) assert big_foo(5, 2) == result result2 = big_foo(5, 3) assert result2 != result time.sleep(4) assert big_foo(5, 2) != result assert big_foo(5, 3) == result2 time.sleep(1) assert big_foo(5, 3) != result2 def test_07_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a+b+random.randrange(0, 100000) result = big_foo(5, 2) result2 = big_foo(5, 3) time.sleep(1) assert big_foo(5, 2) == result assert big_foo(5, 2) == result assert big_foo(5, 3) != result assert big_foo(5, 3) == result2 self.cache.delete_memoized(big_foo) assert big_foo(5, 2) != result assert big_foo(5, 3) != result2 def test_08_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return a+b+random.randrange(0, 100000) result_a = big_foo(5, 1) result_b = big_foo(5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) == result_b self.cache.delete_memoized(big_foo, 5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) != result_b def test_09_args_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return sum(a)+sum(b)+random.randrange(0, 100000) result_a = big_foo([5,3,2], [1]) result_b = big_foo([3,3], [3,1]) assert big_foo([5,3,2], [1]) == result_a assert big_foo([3,3], [3,1]) == result_b self.cache.delete_memoized(big_foo, [5,3,2], [1]) assert big_foo([5,3,2], [1]) != result_a assert big_foo([3,3], [3,1]) == result_b def test_10_kwargs_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b=None): return a+sum(b.values())+random.randrange(0, 100000) result_a = big_foo(1, dict(one=1,two=2)) result_b = big_foo(5, dict(three=3,four=4)) assert big_foo(1, dict(one=1,two=2)) == result_a assert big_foo(5, dict(three=3,four=4)) == result_b self.cache.delete_memoized(big_foo, 1, dict(one=1,two=2)) assert big_foo(1, dict(one=1,two=2)) != result_a assert big_foo(5, dict(three=3,four=4)) == result_b def test_10a_kwargonly_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a=None): if a is None: a = 0 return a+random.random() result_a = big_foo() result_b = big_foo(5) assert big_foo() == result_a assert big_foo() < 1 assert big_foo(5) == result_b assert big_foo(5) >= 5 and big_foo(5) < 6 def test_10a_arg_kwarg_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def f(a, b, c=1): return a+b+c+random.randrange(0, 100000) assert f(1,2) == f(1,2,c=1) assert f(1,2) == f(1,2,1) assert f(1,2) == f(1,2) assert f(1,2,3) != f(1,2) with self.assertRaises(TypeError): f(1) def test_10b_classarg_memoize(self): @self.cache.memoize() def bar(a): return a.value + random.random() class Adder(object): def __init__(self, value): self.value = value adder = Adder(15) adder2 = Adder(20) y = bar(adder) z = bar(adder2) assert y != z assert bar(adder) == y assert bar(adder) != z adder.value = 14 assert bar(adder) == y assert bar(adder) != z assert bar(adder) != bar(adder2) assert bar(adder2) == z def test_10c_classfunc_memoize(self): class Adder(object): def __init__(self, initial): self.initial = initial @self.cache.memoize() def add(self, b): return self.initial + b adder1 = Adder(1) adder2 = Adder(2) x = adder1.add(3) assert adder1.add(3) == x assert adder1.add(4) != x assert adder1.add(3) != adder2.add(3) def test_11_cache_key_property(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data with self.app.test_request_context(): cache_data = self.cache.get(cached_view.make_cache_key()) assert the_time == cache_data def test_12_make_cache_key_function_property(self): @self.app.route('/<foo>/<bar>') @self.cache.memoize(5) def cached_view(foo, bar): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/a/b') the_time = rv.data cache_key = cached_view.make_cache_key(cached_view.uncached, foo=u"a", bar=u"b") cache_data = self.cache.get(cache_key) assert the_time == cache_data different_key = cached_view.make_cache_key(cached_view.uncached, foo=u"b", bar=u"a") different_data = self.cache.get(different_key) assert the_time != different_data def test_13_cache_timeout_property(self): @self.app.route('/') @self.cache.memoize(5) def cached_view1(): return str(time.time()) @self.app.route('/<foo>/<bar>') @self.cache.memoize(10) def cached_view2(foo, bar): return str(time.time()) assert hasattr(cached_view1, "cache_timeout") assert hasattr(cached_view2, "cache_timeout") assert cached_view1.cache_timeout == 5 assert cached_view2.cache_timeout == 10 # test that this is a read-write property cached_view1.cache_timeout = 2 cached_view2.cache_timeout = 3 assert cached_view1.cache_timeout == 2 assert cached_view2.cache_timeout == 3 tc = self.app.test_client() rv1 = tc.get('/') time1 = rv1.data time.sleep(1) rv2 = tc.get('/a/b') time2 = rv2.data # VIEW1 # it's been 1 second, cache is still active assert time1 == tc.get('/').data time.sleep(2) # it's been 3 seconds, cache is not still active assert time1 != tc.get('/').data # VIEW2 # it's been 2 seconds, cache is still active assert time2 == tc.get('/a/b').data time.sleep(2) # it's been 4 seconds, cache is not still active assert time2 != tc.get('/a/b').data def test_14_memoized_multiple_arg_kwarg_calls(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b,c=[1,1],d=[1,1]): return sum(a)+sum(b)+sum(c)+sum(d)+random.randrange(0, 100000) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert big_foo([5,3,2], [1], d=[3,3], c=[3,3]) == result_a assert big_foo(b=[1],a=[5,3,2],c=[3,3],d=[3,3]) == result_a assert big_foo([5,3,2], [1], [3,3], [3,3]) == result_a def test_15_memoize_multiple_arg_kwarg_delete(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b,c=[1,1],d=[1,1]): return sum(a)+sum(b)+sum(c)+sum(d)+random.randrange(0, 100000) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) self.cache.delete_memoized(big_foo, [5,3,2],[1],[3,3],[3,3]) result_b = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],b=[1],c=[3,3],d=[3,3]) result_b = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],[1],c=[3,3],d=[3,3]) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],b=[1],c=[3,3],d=[3,3]) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],[1],c=[3,3],d=[3,3]) result_b = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],[1],[3,3],[3,3]) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b def test_16_memoize_kwargs_to_args(self): with self.app.test_request_context(): def big_foo(a, b, c=None, d=None): return sum(a)+sum(b)+random.randrange(0, 100000) expected = (1,2,'foo','bar') args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, 1,2,'foo','bar') assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, 2,'foo','bar',a=1) assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, a=1,b=2,c='foo',d='bar') assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, d='bar',b=2,a=1,c='foo') assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, 1,2,d='bar',c='foo') assert (args == expected) def test_17_dict_config(self): cache = Cache(config={'CACHE_TYPE': 'simple'}) cache.init_app(self.app) assert cache.config['CACHE_TYPE'] == 'simple' def test_18_dict_config_initapp(self): cache = Cache() cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) from werkzeug.contrib.cache import SimpleCache assert isinstance(self.app.extensions['cache'], SimpleCache) def test_19_dict_config_both(self): cache = Cache(config={'CACHE_TYPE': 'null'}) cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) from werkzeug.contrib.cache import SimpleCache assert isinstance(self.app.extensions['cache'], SimpleCache)
class CacheTestCase(unittest.TestCase): def setUp(self): app = Flask(__name__) app.debug = False app.config['CACHE_TYPE'] = 'simple' self.cache = Cache() self.cache.init_app(app) self.app = app def tearDown(self): self.app = None self.cache = None self.tc = None def test_00_set(self): self.cache.set('hi', 'hello') assert self.cache.get('hi') == 'hello' def test_01_add(self): self.cache.add('hi', 'hello') assert self.cache.get('hi') == 'hello' self.cache.add('hi', 'foobar') assert self.cache.get('hi') == 'hello' def test_02_delete(self): self.cache.set('hi', 'hello') self.cache.delete('hi') assert self.cache.get('hi') is None def test_03_cached_view(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data time.sleep(2) rv = tc.get('/') assert the_time == rv.data time.sleep(5) rv = tc.get('/') assert the_time != rv.data def test_04_cached_view_unless(self): @self.app.route('/a') @self.cache.cached(5, unless=lambda: True) def non_cached_view(): return str(time.time()) @self.app.route('/b') @self.cache.cached(5, unless=lambda: False) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/a') the_time = rv.data time.sleep(1) rv = tc.get('/a') assert the_time != rv.data rv = tc.get('/b') the_time = rv.data time.sleep(1) rv = tc.get('/b') assert the_time == rv.data def test_05_cached_function(self): with self.app.test_request_context(): @self.cache.cached(2, key_prefix='MyBits') def get_random_bits(): return [random.randrange(0, 2) for i in range(50)] my_list = get_random_bits() his_list = get_random_bits() assert my_list == his_list time.sleep(4) his_list = get_random_bits() assert my_list != his_list def test_06_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a+b+random.randrange(0, 100000) result = big_foo(5, 2) time.sleep(1) assert big_foo(5, 2) == result result2 = big_foo(5, 3) assert result2 != result time.sleep(4) assert big_foo(5, 2) != result assert big_foo(5, 3) == result2 time.sleep(1) assert big_foo(5, 3) != result2 def test_07_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a+b+random.randrange(0, 100000) result = big_foo(5, 2) result2 = big_foo(5, 3) time.sleep(1) assert big_foo(5, 2) == result assert big_foo(5, 2) == result assert big_foo(5, 3) != result assert big_foo(5, 3) == result2 self.cache.delete_memoized(big_foo) assert big_foo(5, 2) != result assert big_foo(5, 3) != result2 def test_08_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return a+b+random.randrange(0, 100000) result_a = big_foo(5, 1) result_b = big_foo(5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) == result_b self.cache.delete_memoized(big_foo, 5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) != result_b def test_09_args_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return sum(a)+sum(b)+random.randrange(0, 100000) result_a = big_foo([5,3,2], [1]) result_b = big_foo([3,3], [3,1]) assert big_foo([5,3,2], [1]) == result_a assert big_foo([3,3], [3,1]) == result_b self.cache.delete_memoized(big_foo, [5,3,2], [1]) assert big_foo([5,3,2], [1]) != result_a assert big_foo([3,3], [3,1]) == result_b def test_10_kwargs_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b=None): return a+sum(b.values())+random.randrange(0, 100000) result_a = big_foo(1, dict(one=1,two=2)) result_b = big_foo(5, dict(three=3,four=4)) assert big_foo(1, dict(one=1,two=2)) == result_a assert big_foo(5, dict(three=3,four=4)) == result_b self.cache.delete_memoized(big_foo, 1, dict(one=1,two=2)) assert big_foo(1, dict(one=1,two=2)) != result_a assert big_foo(5, dict(three=3,four=4)) == result_b def test_11_cache_key_property(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data with self.app.test_request_context(): cache_data = self.cache.get(cached_view.make_cache_key()) assert the_time == cache_data def test_12_make_cache_key_function_property(self): @self.app.route('/<foo>/<bar>') @self.cache.memoize(5) def cached_view(foo, bar): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/a/b') the_time = rv.data cache_key = cached_view.make_cache_key(cached_view.uncached, foo=u"a", bar=u"b") cache_data = self.cache.get(cache_key) assert the_time == cache_data different_key = cached_view.make_cache_key(cached_view.uncached, foo=u"b", bar=u"a") different_data = self.cache.get(different_key) assert the_time != different_data def test_13_cache_timeout_property(self): @self.app.route('/') @self.cache.memoize(5) def cached_view1(): return str(time.time()) @self.app.route('/<foo>/<bar>') @self.cache.memoize(10) def cached_view2(foo, bar): return str(time.time()) assert hasattr(cached_view1, "cache_timeout") assert hasattr(cached_view2, "cache_timeout") assert cached_view1.cache_timeout == 5 assert cached_view2.cache_timeout == 10 # test that this is a read-write property cached_view1.cache_timeout = 2 cached_view2.cache_timeout = 3 assert cached_view1.cache_timeout == 2 assert cached_view2.cache_timeout == 3 tc = self.app.test_client() rv1 = tc.get('/') time1 = rv1.data time.sleep(1) rv2 = tc.get('/a/b') time2 = rv2.data # VIEW1 # it's been 1 second, cache is still active assert time1 == tc.get('/').data time.sleep(2) # it's been 3 seconds, cache is not still active assert time1 != tc.get('/').data # VIEW2 # it's been 2 seconds, cache is still active assert time2 == tc.get('/a/b').data time.sleep(2) # it's been 4 seconds, cache is not still active assert time2 != tc.get('/a/b').data def test_14_memoized_multiple_arg_kwarg_calls(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b,c=[1,1],d=[1,1]): return sum(a)+sum(b)+sum(c)+sum(d)+random.randrange(0, 100000) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert big_foo([5,3,2], [1], d=[3,3], c=[3,3]) == result_a assert big_foo(b=[1],a=[5,3,2],c=[3,3],d=[3,3]) == result_a assert big_foo([5,3,2], [1], [3,3], [3,3]) == result_a def test_15_memoize_multiple_arg_kwarg_delete(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b,c=[1,1],d=[1,1]): return sum(a)+sum(b)+sum(c)+sum(d)+random.randrange(0, 100000) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) self.cache.delete_memoized(big_foo, [5,3,2],[1],[3,3],[3,3]) result_b = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],b=[1],c=[3,3],d=[3,3]) result_b = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],[1],c=[3,3],d=[3,3]) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],b=[1],c=[3,3],d=[3,3]) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],[1],c=[3,3],d=[3,3]) result_b = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],[1],[3,3],[3,3]) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b def test_16_memoize_kwargs_to_args(self): with self.app.test_request_context(): def big_foo(a, b, c=None, d=None): return sum(a)+sum(b)+random.randrange(0, 100000) expected = (1,2,'foo','bar') args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, 1,2,'foo','bar') assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, 2,'foo','bar',a=1) assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, a=1,b=2,c='foo',d='bar') assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, d='bar',b=2,a=1,c='foo') assert (args == expected) args, kwargs = self.cache.memoize_kwargs_to_args(big_foo, 1,2,d='bar',c='foo') assert (args == expected) def test_17_dict_config(self): cache = Cache(config={'CACHE_TYPE': 'simple'}) cache.init_app(self.app) assert cache.config['CACHE_TYPE'] == 'simple' def test_18_dict_config_initapp(self): cache = Cache() cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) assert cache.config['CACHE_TYPE'] == 'simple' def test_19_dict_config_both(self): cache = Cache(config={'CACHE_TYPE': 'null'}) cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) assert cache.config['CACHE_TYPE'] == 'simple'
class DataStore: def __init__(self, app): self.app = app # configuration config={'CACHE_TYPE':settings.DS_TYPE} if settings.DS_TYPE == 'filesystem': config['CACHE_DIR'] = settings.DS_FILESYSTEM_DIR elif settings.DS_TYPE == 'redis': config['CACHE_REDIS_HOST'] = settings.DS_REDIS_HOST config['CACHE_REDIS_PORT'] = settings.DS_REDIS_PORT config['CACHE_REDIS_PASSWORD'] = settings.DS_REDIS_PASSWORD config['CACHE_REDIS_DB'] = settings.DS_REDIS_DB self.cache = Cache(app, config=config) # generic methods def clear(self): ''' Clears all the information in the datastore ''' self.cache.clear() def set(self, key, value): ''' Sets value to a key ''' self.cache.set(key, value) def add(self, listKey, value): ''' Adds a item to a list ''' aux = self.cache.get(listKey) if aux == None: aux = [] aux.append(value) self.cache.set(listKey, aux) def get(self, key): ''' Gets a value from it key ''' return self.cache.get(key) def delete(self, key, element=None): ''' Deletes a key-value pair or an element in a list (if element argument is given) ''' if element==None: self.cache.delete(key) else: aux = self.cache.get(key) aux.remove(element) self.cache.set(key, aux) def checkIfExists(self, key, element=None): ''' Checks if a key is defined or if an element exists in a list (if element is given) ''' if element==None: if self.cache.get(key) == None: return False return True else: aux = self.cache.get(key) return element in aux def raiseIfDifferent(self, a, b): if a != b: raise DataStoreError('Error: \'' + a + '\' and \'' + b + '\' are different.') def raiseIfNotExists(self, key): if self.checkIfExists(key) == False: raise DataStoreError('Error: \'' + key + '\' does not exists.') # base images methods def addBase(self, name, base): ''' Adds a base ''' # check if the name provided is the same that in the base entity. self.raiseIfDifferent(name, base['name']) # add name to the list of bases self.add('bases', name) # add the base entity self.set(name, base) def getBases(self): ''' Gets the list with all the bases. ''' return self.get('bases') def getBase(self, name): ''' Gets a base ''' return self.get(name) def delBase(self, name): ''' Deletes a base ''' # delete from list of tokens self.delete('bases', name) # delete entity self.delete(name) def updateBase(self, name, base): ''' Updates a base with a new value ''' # check if the name provided is the same that in the context entity. self.raiseIfDifferent(name, base['name']) if self.getBase(name) is None: raise DataStoreError("Element do not exist") # set base entity self.set(name, base) # contexts methods def addContext(self, contextToken, context): ''' Adds a context ''' # check if the token provided is the same that in the context entity. self.raiseIfDifferent(contextToken, context['token']) # add token to the list of contexts self.add('contexts', contextToken) # add the context entity self.set(contextToken, context) def delContext(self, contextToken): ''' Deletes a context ''' # delete from list of tokens self.delete('contexts', contextToken) # delete entity self.delete(contextToken) def updateContext(self, contextToken, context): ''' Updates a context with a new value ''' # check if the token provided is the same that in the context entity. self.raiseIfDifferent(contextToken, context['token']) # set context entity self.set(contextToken, context) def getContext(self, contextToken): ''' Gets the context entity ''' return self.get(contextToken) def getContexts(self): ''' Gets the list with all the context tokens. ''' return self.get('contexts') # images methods def addImage(self, contextToken, imageToken, image): ''' Adds an image to a context. Raises DataStoreError if image is already associated with the context. ''' # check if the token provided is the same that in the image entity. self.raiseIfDifferent(imageToken, image['token']) # get context context = self.getContext(contextToken) # add to the list of images in the context if imageToken in context['images']: raise DataStoreError('\'' + imageToken + '\' already exists.') context['images'].append(imageToken) self.updateContext(context['token'], context) # add token to the list of images self.add('images', imageToken) # add the image entity self.set(imageToken, image) def delImage(self, imageToken): ''' Deletes an image ''' # get image image = self.getImage(imageToken) # get context context = self.getContext(image['context']) # remove reference to image in context context['images'].remove(imageToken) # delete from list of tokens self.delete('images', imageToken) # remove image entity self.delete(imageToken) def updateImage(self, imageToken, image): ''' Updates an image with a new value ''' # check if the token provided is the same that in the image entity. self.raiseIfDifferent(imageToken, image['token']) # set entity self.raiseIfNotExists(imageToken) self.set(imageToken, image) def getImage(self, imageToken): ''' Gets the image entity ''' return self.get(imageToken) def getImages(self): ''' Gets all the images ''' return self.get('images') # cluster methods def addCluster(self, clusterToken, cluster): ''' Adds a cluster ''' # check if the token provided is the same that in the cluster entity. self.raiseIfDifferent(clusterToken, cluster['token']) # add to the list of clusters self.add('clusters', clusterToken) # add the cluster entity self.set(clusterToken, cluster) def delCluster(self, clusterToken): ''' Deletes a cluster ''' # delete from list of clusters self.delete('clusters', clusterToken) # delete entity self.delete(clusterToken) def updateCluster(self, clusterToken, cluster): ''' Updates a cluster with a new value ''' # check if the token provided is the same that in the cluster entity. self.raiseIfDifferent(clusterToken, cluster['token']) # set cluster entity self.set(clusterToken, cluster) def getCluster(self, clusterToken): ''' Gets the cluster entity ''' return self.get(clusterToken) def getClusters(self): ''' Gets the list of clusters ''' return self.get('clusters') # compositions methods def addComposition(self, compositionToken, composition): ''' Adds a composition ''' # check if the token provided is the same that in the composition entity. self.raiseIfDifferent(compositionToken, composition['token']) # add to the list of compositions self.add('compositions', compositionToken) # add the composition entity self.set(compositionToken, composition) def delComposition(self, compositionToken): ''' Deletes a composition ''' # delete from list of compositions self.delete('compositions', compositionToken) # delete entity self.delete(compositionToken) def updateComposition(self, compositionToken, composition): ''' Updates a composition with a new value ''' # check if the token provided is the same that in the composition entity. self.raiseIfDifferent(compositionToken, composition['token']) # set composition entity self.set(compositionToken, composition) def getComposition(self, compositionToken): ''' Gets the composition entity ''' return self.get(compositionToken) def getCompositions(self): ''' Gets all the compositions entity ''' return self.get('compositions') # Other methods def getTokens(self): ''' Retrieve all the tokens ''' response = {} # add contexts list = self.getContexts() response['contexts'] = list if list!=None else [] # add images list = self.getImages() response['images'] = list if list!=None else [] # add clusters list = self.getClusters() response['clusters'] = list if list!=None else [] # add compositions list = self.getCompositions() response['compositions'] = list if list!=None else [] return response
class CacheTestCase(unittest.TestCase): def _set_app_config(self, app): app.config['CACHE_TYPE'] = 'simple' def setUp(self): app = Flask(__name__, template_folder=os.path.dirname(__file__)) app.debug = True self._set_app_config(app) self.cache = Cache(app) self.app = app def tearDown(self): self.app = None self.cache = None self.tc = None def test_00_set(self): self.cache.set('hi', 'hello') assert self.cache.get('hi') == 'hello' def test_01_add(self): self.cache.add('hi', 'hello') assert self.cache.get('hi') == 'hello' self.cache.add('hi', 'foobar') assert self.cache.get('hi') == 'hello' def test_02_delete(self): self.cache.set('hi', 'hello') self.cache.delete('hi') assert self.cache.get('hi') is None def test_03_cached_view(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data.decode('utf-8') time.sleep(2) rv = tc.get('/') assert the_time == rv.data.decode('utf-8') time.sleep(5) rv = tc.get('/') assert the_time != rv.data.decode('utf-8') def test_04_cached_view_unless(self): @self.app.route('/a') @self.cache.cached(5, unless=lambda: True) def non_cached_view(): return str(time.time()) @self.app.route('/b') @self.cache.cached(5, unless=lambda: False) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/a') the_time = rv.data.decode('utf-8') time.sleep(1) rv = tc.get('/a') assert the_time != rv.data.decode('utf-8') rv = tc.get('/b') the_time = rv.data.decode('utf-8') time.sleep(1) rv = tc.get('/b') assert the_time == rv.data.decode('utf-8') def test_05_cached_function(self): with self.app.test_request_context(): @self.cache.cached(2, key_prefix='MyBits') def get_random_bits(): return [random.randrange(0, 2) for i in range(50)] my_list = get_random_bits() his_list = get_random_bits() assert my_list == his_list time.sleep(4) his_list = get_random_bits() assert my_list != his_list def test_06_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a+b+random.randrange(0, 100000) result = big_foo(5, 2) time.sleep(1) assert big_foo(5, 2) == result result2 = big_foo(5, 3) assert result2 != result time.sleep(6) assert big_foo(5, 2) != result time.sleep(1) assert big_foo(5, 3) != result2 def test_06a_memoize(self): self.app.config['CACHE_DEFAULT_TIMEOUT'] = 1 self.cache = Cache(self.app) with self.app.test_request_context(): @self.cache.memoize(50) def big_foo(a, b): return a+b+random.randrange(0, 100000) result = big_foo(5, 2) time.sleep(2) assert big_foo(5, 2) == result def test_07_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a+b+random.randrange(0, 100000) result = big_foo(5, 2) result2 = big_foo(5, 3) time.sleep(1) assert big_foo(5, 2) == result assert big_foo(5, 2) == result assert big_foo(5, 3) != result assert big_foo(5, 3) == result2 self.cache.delete_memoized(big_foo) assert big_foo(5, 2) != result assert big_foo(5, 3) != result2 def test_07b_delete_memoized_verhash(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a+b+random.randrange(0, 100000) result = big_foo(5, 2) result2 = big_foo(5, 3) time.sleep(1) assert big_foo(5, 2) == result assert big_foo(5, 2) == result assert big_foo(5, 3) != result assert big_foo(5, 3) == result2 self.cache.delete_memoized_verhash(big_foo) _fname, _fname_instance = function_namespace(big_foo) version_key = self.cache._memvname(_fname) assert self.cache.get(version_key) is None assert big_foo(5, 2) != result assert big_foo(5, 3) != result2 assert self.cache.get(version_key) is not None def test_08_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return a+b+random.randrange(0, 100000) result_a = big_foo(5, 1) result_b = big_foo(5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) == result_b self.cache.delete_memoized(big_foo, 5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) != result_b ## Cleanup bigfoo 5,1 5,2 or it might conflict with ## following run if it also uses memecache self.cache.delete_memoized(big_foo, 5, 2) self.cache.delete_memoized(big_foo, 5, 1) def test_09_args_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return sum(a)+sum(b)+random.randrange(0, 100000) result_a = big_foo([5,3,2], [1]) result_b = big_foo([3,3], [3,1]) assert big_foo([5,3,2], [1]) == result_a assert big_foo([3,3], [3,1]) == result_b self.cache.delete_memoized(big_foo, [5,3,2], [1]) assert big_foo([5,3,2], [1]) != result_a assert big_foo([3,3], [3,1]) == result_b ## Cleanup bigfoo 5,1 5,2 or it might conflict with ## following run if it also uses memecache self.cache.delete_memoized(big_foo, [5,3,2], [1]) self.cache.delete_memoized(big_foo, [3,3], [1]) def test_10_kwargs_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b=None): return a+sum(b.values())+random.randrange(0, 100000) result_a = big_foo(1, dict(one=1,two=2)) result_b = big_foo(5, dict(three=3,four=4)) assert big_foo(1, dict(one=1,two=2)) == result_a assert big_foo(5, dict(three=3,four=4)) == result_b self.cache.delete_memoized(big_foo, 1, dict(one=1,two=2)) assert big_foo(1, dict(one=1,two=2)) != result_a assert big_foo(5, dict(three=3,four=4)) == result_b def test_10a_kwargonly_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a=None): if a is None: a = 0 return a+random.random() result_a = big_foo() result_b = big_foo(5) assert big_foo() == result_a assert big_foo() < 1 assert big_foo(5) == result_b assert big_foo(5) >= 5 and big_foo(5) < 6 def test_10a_arg_kwarg_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def f(a, b, c=1): return a+b+c+random.randrange(0, 100000) assert f(1,2) == f(1,2,c=1) assert f(1,2) == f(1,2,1) assert f(1,2) == f(1,2) assert f(1,2,3) != f(1,2) with self.assertRaises(TypeError): f(1) def test_10b_classarg_memoize(self): @self.cache.memoize() def bar(a): return a.value + random.random() class Adder(object): def __init__(self, value): self.value = value adder = Adder(15) adder2 = Adder(20) y = bar(adder) z = bar(adder2) assert y != z assert bar(adder) == y assert bar(adder) != z adder.value = 14 assert bar(adder) == y assert bar(adder) != z assert bar(adder) != bar(adder2) assert bar(adder2) == z def test_10c_classfunc_memoize(self): class Adder(object): def __init__(self, initial): self.initial = initial @self.cache.memoize() def add(self, b): return self.initial + b adder1 = Adder(1) adder2 = Adder(2) x = adder1.add(3) assert adder1.add(3) == x assert adder1.add(4) != x assert adder1.add(3) != adder2.add(3) def test_10d_classfunc_memoize_delete(self): with self.app.test_request_context(): class Adder(object): def __init__(self, initial): self.initial = initial @self.cache.memoize() def add(self, b): return self.initial + b + random.random() adder1 = Adder(1) adder2 = Adder(2) a1 = adder1.add(3) a2 = adder2.add(3) assert a1 != a2 assert adder1.add(3) == a1 assert adder2.add(3) == a2 self.cache.delete_memoized(adder1.add) a3 = adder1.add(3) a4 = adder2.add(3) self.assertNotEqual(a1, a3) assert a1 != a3 self.assertEqual(a2, a4) self.cache.delete_memoized(Adder.add) a5 = adder1.add(3) a6 = adder2.add(3) self.assertNotEqual(a5, a6) self.assertNotEqual(a3, a5) self.assertNotEqual(a4, a6) def test_10e_delete_memoize_classmethod(self): with self.app.test_request_context(): class Mock(object): @classmethod @self.cache.memoize(5) def big_foo(cls, a, b): return a+b+random.randrange(0, 100000) result = Mock.big_foo(5, 2) result2 = Mock.big_foo(5, 3) time.sleep(1) assert Mock.big_foo(5, 2) == result assert Mock.big_foo(5, 2) == result assert Mock.big_foo(5, 3) != result assert Mock.big_foo(5, 3) == result2 self.cache.delete_memoized(Mock.big_foo) assert Mock.big_foo(5, 2) != result assert Mock.big_foo(5, 3) != result2 def test_11_cache_key_property(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data.decode('utf-8') with self.app.test_request_context(): cache_data = self.cache.get(cached_view.make_cache_key()) assert the_time == cache_data def test_12_make_cache_key_function_property(self): @self.app.route('/<foo>/<bar>') @self.cache.memoize(5) def cached_view(foo, bar): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/a/b') the_time = rv.data.decode('utf-8') cache_key = cached_view.make_cache_key(cached_view.uncached, foo=u"a", bar=u"b") cache_data = self.cache.get(cache_key) assert the_time == cache_data different_key = cached_view.make_cache_key(cached_view.uncached, foo=u"b", bar=u"a") different_data = self.cache.get(different_key) assert the_time != different_data def test_13_cache_timeout_property(self): @self.app.route('/') @self.cache.memoize(5) def cached_view1(): return str(time.time()) @self.app.route('/<foo>/<bar>') @self.cache.memoize(10) def cached_view2(foo, bar): return str(time.time()) assert hasattr(cached_view1, "cache_timeout") assert hasattr(cached_view2, "cache_timeout") assert cached_view1.cache_timeout == 5 assert cached_view2.cache_timeout == 10 # test that this is a read-write property cached_view1.cache_timeout = 15 cached_view2.cache_timeout = 30 assert cached_view1.cache_timeout == 15 assert cached_view2.cache_timeout == 30 tc = self.app.test_client() rv1 = tc.get('/') time1 = rv1.data.decode('utf-8') time.sleep(1) rv2 = tc.get('/a/b') time2 = rv2.data.decode('utf-8') # VIEW1 # it's been 1 second, cache is still active assert time1 == tc.get('/').data.decode('utf-8') time.sleep(16) # it's been >15 seconds, cache is not still active assert time1 != tc.get('/').data.decode('utf-8') # VIEW2 # it's been >17 seconds, cache is still active self.assertEqual(time2, tc.get('/a/b').data.decode('utf-8')) time.sleep(30) # it's been >30 seconds, cache is not still active assert time2 != tc.get('/a/b').data.decode('utf-8') def test_14_memoized_multiple_arg_kwarg_calls(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b,c=[1,1],d=[1,1]): return sum(a)+sum(b)+sum(c)+sum(d)+random.randrange(0, 100000) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert big_foo([5,3,2], [1], d=[3,3], c=[3,3]) == result_a assert big_foo(b=[1],a=[5,3,2],c=[3,3],d=[3,3]) == result_a assert big_foo([5,3,2], [1], [3,3], [3,3]) == result_a def test_15_memoize_multiple_arg_kwarg_delete(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b,c=[1,1],d=[1,1]): return sum(a)+sum(b)+sum(c)+sum(d)+random.randrange(0, 100000) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) self.cache.delete_memoized(big_foo, [5,3,2],[1],[3,3],[3,3]) result_b = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],b=[1],c=[3,3],d=[3,3]) result_b = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],[1],c=[3,3],d=[3,3]) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],b=[1],c=[3,3],d=[3,3]) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],[1],c=[3,3],d=[3,3]) result_b = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5,3,2],[1],[3,3],[3,3]) result_a = big_foo([5,3,2], [1], c=[3,3], d=[3,3]) assert result_a != result_b def test_16_memoize_kwargs_to_args(self): with self.app.test_request_context(): def big_foo(a, b, c=None, d=None): return sum(a)+sum(b)+random.randrange(0, 100000) expected = (1,2,'foo','bar') args, kwargs = self.cache._memoize_kwargs_to_args(big_foo, 1,2,'foo','bar') assert (args == expected) args, kwargs = self.cache._memoize_kwargs_to_args(big_foo, 2,'foo','bar',a=1) assert (args == expected) args, kwargs = self.cache._memoize_kwargs_to_args(big_foo, a=1,b=2,c='foo',d='bar') assert (args == expected) args, kwargs = self.cache._memoize_kwargs_to_args(big_foo, d='bar',b=2,a=1,c='foo') assert (args == expected) args, kwargs = self.cache._memoize_kwargs_to_args(big_foo, 1,2,d='bar',c='foo') assert (args == expected) def test_17_dict_config(self): cache = Cache(config={'CACHE_TYPE': 'simple'}) cache.init_app(self.app) assert cache.config['CACHE_TYPE'] == 'simple' def test_18_dict_config_initapp(self): cache = Cache() cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) from werkzeug.contrib.cache import SimpleCache assert isinstance(self.app.extensions['cache'][cache], SimpleCache) def test_19_dict_config_both(self): cache = Cache(config={'CACHE_TYPE': 'null'}) cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) from werkzeug.contrib.cache import SimpleCache assert isinstance(self.app.extensions['cache'][cache], SimpleCache) def test_20_jinja2ext_cache(self): somevar = ''.join([random.choice(string.ascii_letters) for x in range(6)]) testkeys = [ make_template_fragment_key("fragment1"), make_template_fragment_key("fragment1", vary_on=["key1"]), make_template_fragment_key("fragment1", vary_on=["key1", somevar]), ] delkey = make_template_fragment_key("fragment2") with self.app.test_request_context(): #: Test if elements are cached render_template("test_template.html", somevar=somevar, timeout=60) for k in testkeys: assert self.cache.get(k) == somevar assert self.cache.get(delkey) == somevar #: Test timeout=del to delete key render_template("test_template.html", somevar=somevar, timeout="del") for k in testkeys: assert self.cache.get(k) == somevar assert self.cache.get(delkey) is None #: Test rendering templates from strings output = render_template_string( """{% cache 60, "fragment3" %}{{somevar}}{% endcache %}""", somevar=somevar ) assert self.cache.get(make_template_fragment_key("fragment3")) == somevar assert output == somevar #: Test backwards compatibility output = render_template_string( """{% cache 30 %}{{somevar}}{% endcache %}""", somevar=somevar) assert self.cache.get(make_template_fragment_key("None1")) == somevar assert output == somevar output = render_template_string( """{% cache 30, "fragment4", "fragment5"%}{{somevar}}{% endcache %}""", somevar=somevar) k = make_template_fragment_key("fragment4", vary_on=["fragment5"]) assert self.cache.get(k) == somevar assert output == somevar def test_21_cached_view_forced_update(self): forced_update = False def forced_update_fn(): return forced_update @self.app.route('/a') @self.cache.cached(5, forced_update=lambda: forced_update) def view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/a') the_time = rv.data.decode('utf-8') time.sleep(1) rv = tc.get('/a') assert the_time == rv.data.decode('utf-8') forced_update = True rv = tc.get('/a') new_time = rv.data.decode('utf-8') assert new_time != the_time forced_update = False time.sleep(1) rv = tc.get('/a') assert new_time == rv.data.decode('utf-8') def test_22_memoize_forced_update(self): with self.app.test_request_context(): forced_update = False @self.cache.memoize(5, forced_update=lambda: forced_update) def big_foo(a, b): return a+b+random.randrange(0, 100000) result = big_foo(5, 2) time.sleep(1) assert big_foo(5, 2) == result forced_update = True new_result = big_foo(5, 2) assert new_result != result forced_update = False time.sleep(1) assert big_foo(5, 2) == new_result def test_23_init_app_sets_app_attribute(self): cache = Cache() cache.init_app(self.app) assert cache.app == self.app def test_24_generate_cache_key_from_different_view(self): @self.app.route('/cake/<flavor>') @self.cache.cached() def view_cake(flavor): # What's the cache key for apple cake? view_cake.cake_cache_key = view_cake.make_cache_key('apple') # print view_cake.cake_cache_key return str(time.time()) view_cake.cake_cache_key = '' @self.app.route('/pie/<flavor>') @self.cache.cached() def view_pie(flavor): # What's the cache key for apple cake? view_pie.cake_cache_key = view_cake.make_cache_key('apple') # print view_pie.cake_cache_key return str(time.time()) view_pie.cake_cache_key = '' tc = self.app.test_client() rv1 = tc.get('/cake/chocolate') rv2 = tc.get('/pie/chocolate') # print view_cake.cake_cache_key # print view_pie.cake_cache_key assert view_cake.cake_cache_key == view_pie.cake_cache_key
class CacheTestCase(unittest.TestCase): def _set_app_config(self, app): app.config['CACHE_TYPE'] = 'simple' def setUp(self): app = Flask(__name__, template_folder=os.path.dirname(__file__)) app.debug = True self._set_app_config(app) self.cache = Cache(app) self.app = app def tearDown(self): self.app = None self.cache = None self.tc = None def test_00_set(self): self.cache.set('hi', 'hello') assert self.cache.get('hi') == 'hello' def test_01_add(self): self.cache.add('hi', 'hello') assert self.cache.get('hi') == 'hello' self.cache.add('hi', 'foobar') assert self.cache.get('hi') == 'hello' def test_02_delete(self): self.cache.set('hi', 'hello') self.cache.delete('hi') assert self.cache.get('hi') is None def test_03_cached_view(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data.decode('utf-8') time.sleep(2) rv = tc.get('/') assert the_time == rv.data.decode('utf-8') time.sleep(5) rv = tc.get('/') assert the_time != rv.data.decode('utf-8') def test_04_cached_view_unless(self): @self.app.route('/a') @self.cache.cached(5, unless=lambda: True) def non_cached_view(): return str(time.time()) @self.app.route('/b') @self.cache.cached(5, unless=lambda: False) def cached_view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/a') the_time = rv.data.decode('utf-8') time.sleep(1) rv = tc.get('/a') assert the_time != rv.data.decode('utf-8') rv = tc.get('/b') the_time = rv.data.decode('utf-8') time.sleep(1) rv = tc.get('/b') assert the_time == rv.data.decode('utf-8') def test_05_cached_function(self): with self.app.test_request_context(): @self.cache.cached(2, key_prefix='MyBits') def get_random_bits(): return [random.randrange(0, 2) for i in range(50)] my_list = get_random_bits() his_list = get_random_bits() assert my_list == his_list time.sleep(4) his_list = get_random_bits() assert my_list != his_list def test_06_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a + b + random.randrange(0, 100000) result = big_foo(5, 2) time.sleep(1) assert big_foo(5, 2) == result result2 = big_foo(5, 3) assert result2 != result time.sleep(6) assert big_foo(5, 2) != result time.sleep(1) assert big_foo(5, 3) != result2 def test_06a_memoize(self): self.app.config['CACHE_DEFAULT_TIMEOUT'] = 1 self.cache = Cache(self.app) with self.app.test_request_context(): @self.cache.memoize(50) def big_foo(a, b): return a + b + random.randrange(0, 100000) result = big_foo(5, 2) time.sleep(2) assert big_foo(5, 2) == result def test_07_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a + b + random.randrange(0, 100000) result = big_foo(5, 2) result2 = big_foo(5, 3) time.sleep(1) assert big_foo(5, 2) == result assert big_foo(5, 2) == result assert big_foo(5, 3) != result assert big_foo(5, 3) == result2 self.cache.delete_memoized(big_foo) assert big_foo(5, 2) != result assert big_foo(5, 3) != result2 def test_07b_delete_memoized_verhash(self): with self.app.test_request_context(): @self.cache.memoize(5) def big_foo(a, b): return a + b + random.randrange(0, 100000) result = big_foo(5, 2) result2 = big_foo(5, 3) time.sleep(1) assert big_foo(5, 2) == result assert big_foo(5, 2) == result assert big_foo(5, 3) != result assert big_foo(5, 3) == result2 self.cache.delete_memoized_verhash(big_foo) _fname, _fname_instance = function_namespace(big_foo) version_key = self.cache._memvname(_fname) assert self.cache.get(version_key) is None assert big_foo(5, 2) != result assert big_foo(5, 3) != result2 assert self.cache.get(version_key) is not None def test_08_delete_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return a + b + random.randrange(0, 100000) result_a = big_foo(5, 1) result_b = big_foo(5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) == result_b self.cache.delete_memoized(big_foo, 5, 2) assert big_foo(5, 1) == result_a assert big_foo(5, 2) != result_b ## Cleanup bigfoo 5,1 5,2 or it might conflict with ## following run if it also uses memecache self.cache.delete_memoized(big_foo, 5, 2) self.cache.delete_memoized(big_foo, 5, 1) def test_09_args_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b): return sum(a) + sum(b) + random.randrange(0, 100000) result_a = big_foo([5, 3, 2], [1]) result_b = big_foo([3, 3], [3, 1]) assert big_foo([5, 3, 2], [1]) == result_a assert big_foo([3, 3], [3, 1]) == result_b self.cache.delete_memoized(big_foo, [5, 3, 2], [1]) assert big_foo([5, 3, 2], [1]) != result_a assert big_foo([3, 3], [3, 1]) == result_b ## Cleanup bigfoo 5,1 5,2 or it might conflict with ## following run if it also uses memecache self.cache.delete_memoized(big_foo, [5, 3, 2], [1]) self.cache.delete_memoized(big_foo, [3, 3], [1]) def test_10_kwargs_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b=None): return a + sum(b.values()) + random.randrange(0, 100000) result_a = big_foo(1, dict(one=1, two=2)) result_b = big_foo(5, dict(three=3, four=4)) assert big_foo(1, dict(one=1, two=2)) == result_a assert big_foo(5, dict(three=3, four=4)) == result_b self.cache.delete_memoized(big_foo, 1, dict(one=1, two=2)) assert big_foo(1, dict(one=1, two=2)) != result_a assert big_foo(5, dict(three=3, four=4)) == result_b def test_10a_kwargonly_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a=None): if a is None: a = 0 return a + random.random() result_a = big_foo() result_b = big_foo(5) assert big_foo() == result_a assert big_foo() < 1 assert big_foo(5) == result_b assert big_foo(5) >= 5 and big_foo(5) < 6 def test_10a_arg_kwarg_memoize(self): with self.app.test_request_context(): @self.cache.memoize() def f(a, b, c=1): return a + b + c + random.randrange(0, 100000) assert f(1, 2) == f(1, 2, c=1) assert f(1, 2) == f(1, 2, 1) assert f(1, 2) == f(1, 2) assert f(1, 2, 3) != f(1, 2) with self.assertRaises(TypeError): f(1) def test_10b_classarg_memoize(self): @self.cache.memoize() def bar(a): return a.value + random.random() class Adder(object): def __init__(self, value): self.value = value adder = Adder(15) adder2 = Adder(20) y = bar(adder) z = bar(adder2) assert y != z assert bar(adder) == y assert bar(adder) != z adder.value = 14 assert bar(adder) == y assert bar(adder) != z assert bar(adder) != bar(adder2) assert bar(adder2) == z def test_10c_classfunc_memoize(self): class Adder(object): def __init__(self, initial): self.initial = initial @self.cache.memoize() def add(self, b): return self.initial + b adder1 = Adder(1) adder2 = Adder(2) x = adder1.add(3) assert adder1.add(3) == x assert adder1.add(4) != x assert adder1.add(3) != adder2.add(3) def test_10d_classfunc_memoize_delete(self): with self.app.test_request_context(): class Adder(object): def __init__(self, initial): self.initial = initial @self.cache.memoize() def add(self, b): return self.initial + b + random.random() adder1 = Adder(1) adder2 = Adder(2) a1 = adder1.add(3) a2 = adder2.add(3) assert a1 != a2 assert adder1.add(3) == a1 assert adder2.add(3) == a2 self.cache.delete_memoized(adder1.add) a3 = adder1.add(3) a4 = adder2.add(3) self.assertNotEqual(a1, a3) assert a1 != a3 self.assertEqual(a2, a4) self.cache.delete_memoized(Adder.add) a5 = adder1.add(3) a6 = adder2.add(3) self.assertNotEqual(a5, a6) self.assertNotEqual(a3, a5) self.assertNotEqual(a4, a6) def test_10e_delete_memoize_classmethod(self): with self.app.test_request_context(): class Mock(object): @classmethod @self.cache.memoize(5) def big_foo(cls, a, b): return a + b + random.randrange(0, 100000) result = Mock.big_foo(5, 2) result2 = Mock.big_foo(5, 3) time.sleep(1) assert Mock.big_foo(5, 2) == result assert Mock.big_foo(5, 2) == result assert Mock.big_foo(5, 3) != result assert Mock.big_foo(5, 3) == result2 self.cache.delete_memoized(Mock.big_foo) assert Mock.big_foo(5, 2) != result assert Mock.big_foo(5, 3) != result2 def test_11_cache_key_property(self): @self.app.route('/') @self.cache.cached(5) def cached_view(): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/') the_time = rv.data.decode('utf-8') with self.app.test_request_context(): cache_data = self.cache.get(cached_view.make_cache_key()) assert the_time == cache_data def test_12_make_cache_key_function_property(self): @self.app.route('/<foo>/<bar>') @self.cache.memoize(5) def cached_view(foo, bar): return str(time.time()) assert hasattr(cached_view, "make_cache_key") assert callable(cached_view.make_cache_key) tc = self.app.test_client() rv = tc.get('/a/b') the_time = rv.data.decode('utf-8') cache_key = cached_view.make_cache_key(cached_view.uncached, foo=u"a", bar=u"b") cache_data = self.cache.get(cache_key) assert the_time == cache_data different_key = cached_view.make_cache_key(cached_view.uncached, foo=u"b", bar=u"a") different_data = self.cache.get(different_key) assert the_time != different_data def test_13_cache_timeout_property(self): @self.app.route('/') @self.cache.memoize(5) def cached_view1(): return str(time.time()) @self.app.route('/<foo>/<bar>') @self.cache.memoize(10) def cached_view2(foo, bar): return str(time.time()) assert hasattr(cached_view1, "cache_timeout") assert hasattr(cached_view2, "cache_timeout") assert cached_view1.cache_timeout == 5 assert cached_view2.cache_timeout == 10 # test that this is a read-write property cached_view1.cache_timeout = 15 cached_view2.cache_timeout = 30 assert cached_view1.cache_timeout == 15 assert cached_view2.cache_timeout == 30 tc = self.app.test_client() rv1 = tc.get('/') time1 = rv1.data.decode('utf-8') time.sleep(1) rv2 = tc.get('/a/b') time2 = rv2.data.decode('utf-8') # VIEW1 # it's been 1 second, cache is still active assert time1 == tc.get('/').data.decode('utf-8') time.sleep(16) # it's been >15 seconds, cache is not still active assert time1 != tc.get('/').data.decode('utf-8') # VIEW2 # it's been >17 seconds, cache is still active self.assertEqual(time2, tc.get('/a/b').data.decode('utf-8')) time.sleep(30) # it's been >30 seconds, cache is not still active assert time2 != tc.get('/a/b').data.decode('utf-8') def test_14_memoized_multiple_arg_kwarg_calls(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b, c=[1, 1], d=[1, 1]): return sum(a) + sum(b) + sum(c) + sum(d) + random.randrange( 0, 100000) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert big_foo([5, 3, 2], [1], d=[3, 3], c=[3, 3]) == result_a assert big_foo(b=[1], a=[5, 3, 2], c=[3, 3], d=[3, 3]) == result_a assert big_foo([5, 3, 2], [1], [3, 3], [3, 3]) == result_a def test_15_memoize_multiple_arg_kwarg_delete(self): with self.app.test_request_context(): @self.cache.memoize() def big_foo(a, b, c=[1, 1], d=[1, 1]): return sum(a) + sum(b) + sum(c) + sum(d) + random.randrange( 0, 100000) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) self.cache.delete_memoized(big_foo, [5, 3, 2], [1], [3, 3], [3, 3]) result_b = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], b=[1], c=[3, 3], d=[3, 3]) result_b = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], [1], c=[3, 3], d=[3, 3]) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], b=[1], c=[3, 3], d=[3, 3]) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], [1], c=[3, 3], d=[3, 3]) result_b = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b self.cache.delete_memoized(big_foo, [5, 3, 2], [1], [3, 3], [3, 3]) result_a = big_foo([5, 3, 2], [1], c=[3, 3], d=[3, 3]) assert result_a != result_b def test_16_memoize_kwargs_to_args(self): with self.app.test_request_context(): def big_foo(a, b, c=None, d=None): return sum(a) + sum(b) + random.randrange(0, 100000) expected = (1, 2, 'foo', 'bar') args, kwargs = self.cache._memoize_kwargs_to_args( big_foo, 1, 2, 'foo', 'bar') assert (args == expected) args, kwargs = self.cache._memoize_kwargs_to_args(big_foo, 2, 'foo', 'bar', a=1) assert (args == expected) args, kwargs = self.cache._memoize_kwargs_to_args(big_foo, a=1, b=2, c='foo', d='bar') assert (args == expected) args, kwargs = self.cache._memoize_kwargs_to_args(big_foo, d='bar', b=2, a=1, c='foo') assert (args == expected) args, kwargs = self.cache._memoize_kwargs_to_args(big_foo, 1, 2, d='bar', c='foo') assert (args == expected) def test_17_dict_config(self): cache = Cache(config={'CACHE_TYPE': 'simple'}) cache.init_app(self.app) assert cache.config['CACHE_TYPE'] == 'simple' def test_18_dict_config_initapp(self): cache = Cache() cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) from werkzeug.contrib.cache import SimpleCache assert isinstance(self.app.extensions['cache'][cache], SimpleCache) def test_19_dict_config_both(self): cache = Cache(config={'CACHE_TYPE': 'null'}) cache.init_app(self.app, config={'CACHE_TYPE': 'simple'}) from werkzeug.contrib.cache import SimpleCache assert isinstance(self.app.extensions['cache'][cache], SimpleCache) def test_20_jinja2ext_cache(self): somevar = ''.join( [random.choice(string.ascii_letters) for x in range(6)]) testkeys = [ make_template_fragment_key("fragment1"), make_template_fragment_key("fragment1", vary_on=["key1"]), make_template_fragment_key("fragment1", vary_on=["key1", somevar]), ] delkey = make_template_fragment_key("fragment2") with self.app.test_request_context(): #: Test if elements are cached render_template("test_template.html", somevar=somevar, timeout=60) for k in testkeys: assert self.cache.get(k) == somevar assert self.cache.get(delkey) == somevar #: Test timeout=del to delete key render_template("test_template.html", somevar=somevar, timeout="del") for k in testkeys: assert self.cache.get(k) == somevar assert self.cache.get(delkey) is None #: Test rendering templates from strings output = render_template_string( """{% cache 60, "fragment3" %}{{somevar}}{% endcache %}""", somevar=somevar) assert self.cache.get( make_template_fragment_key("fragment3")) == somevar assert output == somevar #: Test backwards compatibility output = render_template_string( """{% cache 30 %}{{somevar}}{% endcache %}""", somevar=somevar) assert self.cache.get( make_template_fragment_key("None1")) == somevar assert output == somevar output = render_template_string( """{% cache 30, "fragment4", "fragment5"%}{{somevar}}{% endcache %}""", somevar=somevar) k = make_template_fragment_key("fragment4", vary_on=["fragment5"]) assert self.cache.get(k) == somevar assert output == somevar def test_21_cached_view_forced_update(self): forced_update = False def forced_update_fn(): return forced_update @self.app.route('/a') @self.cache.cached(5, forced_update=lambda: forced_update) def view(): return str(time.time()) tc = self.app.test_client() rv = tc.get('/a') the_time = rv.data.decode('utf-8') time.sleep(1) rv = tc.get('/a') assert the_time == rv.data.decode('utf-8') forced_update = True rv = tc.get('/a') new_time = rv.data.decode('utf-8') assert new_time != the_time forced_update = False time.sleep(1) rv = tc.get('/a') assert new_time == rv.data.decode('utf-8') def test_22_memoize_forced_update(self): with self.app.test_request_context(): forced_update = False @self.cache.memoize(5, forced_update=lambda: forced_update) def big_foo(a, b): return a + b + random.randrange(0, 100000) result = big_foo(5, 2) time.sleep(1) assert big_foo(5, 2) == result forced_update = True new_result = big_foo(5, 2) assert new_result != result forced_update = False time.sleep(1) assert big_foo(5, 2) == new_result def test_23_init_app_sets_app_attribute(self): cache = Cache() cache.init_app(self.app) assert cache.app == self.app def test_24_generate_cache_key_from_different_view(self): @self.app.route('/cake/<flavor>') @self.cache.cached() def view_cake(flavor): # What's the cache key for apple cake? view_cake.cake_cache_key = view_cake.make_cache_key('apple') # print view_cake.cake_cache_key return str(time.time()) view_cake.cake_cache_key = '' @self.app.route('/pie/<flavor>') @self.cache.cached() def view_pie(flavor): # What's the cache key for apple cake? view_pie.cake_cache_key = view_cake.make_cache_key('apple') # print view_pie.cake_cache_key return str(time.time()) view_pie.cake_cache_key = '' tc = self.app.test_client() rv1 = tc.get('/cake/chocolate') rv2 = tc.get('/pie/chocolate') # print view_cake.cake_cache_key # print view_pie.cake_cache_key assert view_cake.cake_cache_key == view_pie.cake_cache_key
class DataStore: def __init__(self, app): self.app = app # configuration config={'CACHE_TYPE':settings.DS_TYPE} if settings.DS_TYPE == 'filesystem': config['CACHE_DIR'] = settings.DS_FILESYSTEM_DIR elif settings.DS_TYPE == 'redis': config['CACHE_REDIS_HOST'] = settings.DS_REDIS_HOST config['CACHE_REDIS_PORT'] = settings.DS_REDIS_PORT config['CACHE_REDIS_PASSWORD'] = settings.DS_REDIS_PASSWORD config['CACHE_REDIS_DB'] = settings.DS_REDIS_DB self.cache = Cache(app, config=config) # generic methods def clear(self): ''' Clears all the information in the datastore ''' self.cache.clear() def set(self, key, value): ''' Sets value to a key ''' self.cache.set(key, value) def add(self, listKey, value): ''' Adds a item to a list ''' aux = self.cache.get(listKey) if aux == None: aux = [] aux.append(value) self.cache.set(listKey, aux) def get(self, key): ''' Gets a value from it key ''' return self.cache.get(key) def delete(self, key, element=None): ''' Deletes a key-value pair or an element in a list (if element argument is given) ''' if element==None: self.cache.delete(key) else: aux = self.cache.get(key) aux.remove(element) self.cache.set(key, aux) def checkIfExists(self, key, element=None): ''' Checks if a key is defined or if an element exists in a list (if element is given) ''' if element==None: if self.cache.get(key) == None: return False return True else: aux = self.cache.get(key) return element in aux def raiseIfDifferent(self, a, b): if a != b: raise DataStoreError('Error: \'' + a + '\' and \'' + b + '\' are different.') def raiseIfNotExists(self, key): if self.checkIfExists(key) == False: raise DataStoreError('Error: \'' + key + '\' does not exists.') # base images methods def addBase(self, name, base): ''' Adds a base ''' # check if the name provided is the same that in the base entity. self.raiseIfDifferent(name, base['name']) # add name to the list of bases self.add('bases', name) # add the base entity self.set(name, base) def getBases(self): ''' Gets the list with all the bases. ''' return self.get('bases') def getBase(self, name): ''' Gets a base ''' return self.get(name) def delBase(self, name): ''' Deletes a base ''' # delete from list of tokens self.delete('bases', name) # delete entity self.delete(name) def updateBase(self, name, base): ''' Updates a base with a new value ''' # check if the name provided is the same that in the context entity. self.raiseIfDifferent(name, base['name']) if self.getBase(name) is None: raise DataStoreError("Element do not exist") # set base entity self.set(name, base) # contexts methods def addContext(self, contextToken, context): ''' Adds a context ''' # check if the token provided is the same that in the context entity. self.raiseIfDifferent(contextToken, context['token']) # add token to the list of contexts self.add('contexts', contextToken) # add the context entity self.set(contextToken, context) def delContext(self, contextToken): ''' Deletes a context ''' # delete from list of tokens self.delete('contexts', contextToken) # delete entity self.delete(contextToken) def updateContext(self, contextToken, context): ''' Updates a context with a new value ''' # check if the token provided is the same that in the context entity. self.raiseIfDifferent(contextToken, context['token']) # set context entity self.set(contextToken, context) def getContext(self, contextToken): ''' Gets the context entity ''' return self.get(contextToken) def getContexts(self): ''' Gets the list with all the context tokens. ''' return self.get('contexts') # images methods def addImage(self, contextToken, imageToken, image): ''' Adds an image to a context. Raises DataStoreError if image is already associated with the context. ''' # check if the token provided is the same that in the image entity. self.raiseIfDifferent(imageToken, image['token']) # get context context = self.getContext(contextToken) # add to the list of images in the context if imageToken in context['images']: raise DataStoreError('\'' + imageToken + '\' already exists.') context['images'].append(imageToken) self.updateContext(context['token'], context) # add the image entity self.set(imageToken, image) def delImage(self, imageToken): ''' Deletes an image ''' # get image image = self.getImage(imageToken) # get context context = self.getContext(image['context']) # remove reference to image in context context['images'].remove(imageToken) # remove image entity self.delete(imageToken) def updateImage(self, imageToken, image): ''' Updates an image with a new value ''' # check if the token provided is the same that in the image entity. self.raiseIfDifferent(imageToken, image['token']) # set entity self.raiseIfNotExists(imageToken) self.set(imageToken, image) def getImage(self, imageToken): ''' Gets the image entity ''' return self.get(imageToken) def getImages(self): ''' Gets all the images ''' return self.get('images') # cluster methods def addCluster(self, clusterToken, cluster): ''' Adds a cluster ''' # check if the token provided is the same that in the cluster entity. self.raiseIfDifferent(clusterToken, cluster['token']) # add to the list of clusters self.add('clusters', clusterToken) # add the cluster entity self.set(clusterToken, cluster) def delCluster(self, clusterToken): ''' Deletes a cluster ''' # delete from list of clusters self.delete('clusters', clusterToken) # delete entity self.delete(clusterToken) def updateCluster(self, clusterToken, cluster): ''' Updates a cluster with a new value ''' # check if the token provided is the same that in the cluster entity. self.raiseIfDifferent(clusterToken, cluster['token']) # set cluster entity self.set(clusterToken, cluster) def getCluster(self, clusterToken): ''' Gets the cluster entity ''' return self.get(clusterToken) def getClusters(self): ''' Gets the list of clusters ''' return self.get('clusters') # compositions methods def addComposition(self, compositionToken, composition): ''' Adds a composition ''' # check if the token provided is the same that in the composition entity. self.raiseIfDifferent(compositionToken, composition['token']) # add to the list of compositions self.add('compositions', compositionToken) # add the composition entity self.set(compositionToken, composition) def delComposition(self, compositionToken): ''' Deletes a composition ''' # delete from list of compositions self.delete('compositions', compositionToken) # delete entity self.delete(compositionToken) def updateComposition(self, compositionToken, composition): ''' Updates a composition with a new value ''' # check if the token provided is the same that in the composition entity. self.raiseIfDifferent(compositionToken, composition['token']) # set composition entity self.set(compositionToken, composition) def getComposition(self, compositionToken): ''' Gets the composition entity ''' return self.get(compositionToken) def getCompositions(self): ''' Gets all the compositions entity ''' return self.get('compositions') # Other methods def getTokens(self): ''' Retrieve all the tokens ''' response = {} # add contexts list = self.getContexts() response['contexts'] = list if list!=None else [] # add images list = self.getImages() response['images'] = list if list!=None else [] # add clusters list = self.getClusters() response['clusters'] = list if list!=None else [] # add compositions list = self.getCompositions() response['compositions'] = list if list!=None else [] return response