# -*- coding: utf-8 -*- """ tests.unit.utils.cache_test ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Test the salt cache objects """ # Import python libs from __future__ import absolute_import, print_function, unicode_literals import os import shutil import tempfile import time # Import salt libs import salt.config import salt.loader import salt.payload import salt.utils.cache as cache import salt.utils.data import salt.utils.files # Import Salt Testing libs from tests.support.unit import TestCase class CacheDictTestCase(TestCase): def test_sanity(self): """ Make sure you can instantiate etc. """ cd = cache.CacheDict(5) self.assertIsInstance(cd, cache.CacheDict) # do some tests to make sure it looks like a dict self.assertNotIn("foo", cd) cd["foo"] = "bar" self.assertEqual(cd["foo"], "bar") del cd["foo"] self.assertNotIn("foo", cd) def test_ttl(self): cd = cache.CacheDict(0.1) cd["foo"] = "bar" self.assertIn("foo", cd) self.assertEqual(cd["foo"], "bar") time.sleep(0.2) self.assertNotIn("foo", cd) # make sure that a get would get a regular old key error self.assertRaises(KeyError, cd.__getitem__, "foo") class CacheContextTestCase(TestCase): def setUp(self): context_dir = os.path.join(tempfile.gettempdir(), "context") if os.path.exists(context_dir): shutil.rmtree(os.path.join(tempfile.gettempdir(), "context")) def test_smoke_context(self): """ Smoke test the context cache """ if os.path.exists(os.path.join(tempfile.gettempdir(), "context")): self.skipTest("Context dir already exists") else: opts = salt.config.DEFAULT_MINION_OPTS.copy() opts["cachedir"] = tempfile.gettempdir() context_cache = cache.ContextCache(opts, "cache_test") context_cache.cache_context({"a": "b"}) ret = context_cache.get_cache_context() self.assertDictEqual({"a": "b"}, ret) def test_context_wrapper(self): """ Test to ensure that a module which decorates itself with a context cache can store and retrieve its contextual data """ opts = salt.config.DEFAULT_MINION_OPTS.copy() opts["cachedir"] = tempfile.gettempdir() ll_ = salt.loader.LazyLoader( [os.path.join(os.path.dirname(os.path.realpath(__file__)), "cache_mods")], tag="rawmodule", virtual_enable=False, opts=opts, ) cache_test_func = ll_["cache_mod.test_context_module"] self.assertEqual(cache_test_func()["called"], 0) self.assertEqual(cache_test_func()["called"], 1) __context__ = {"a": "b"} __opts__ = {"cachedir": "/tmp"} class ContextCacheTest(TestCase): """ Test case for salt.utils.cache.ContextCache """ def setUp(self): """ Clear the cache before every test """ context_dir = os.path.join(__opts__["cachedir"], "context") if os.path.isdir(context_dir): shutil.rmtree(context_dir) def test_set_cache(self): """ Tests to ensure the cache is written correctly """ @cache.context_cache def _test_set_cache(): """ This will inherit globals from the test module itself. Normally these are injected by the salt loader [salt.loader] """ _test_set_cache() target_cache_file = os.path.join( __opts__["cachedir"], "context", "{0}.p".format(__name__) ) self.assertTrue( os.path.isfile(target_cache_file), "Context cache did not write cache file" ) # Test manual de-serialize with salt.utils.files.fopen(target_cache_file, "rb") as fp_: target_cache_data = salt.utils.data.decode( salt.payload.Serial(__opts__).load(fp_) ) self.assertDictEqual(__context__, target_cache_data) # Test cache de-serialize cc = cache.ContextCache(__opts__, __name__) retrieved_cache = cc.get_cache_context() self.assertDictEqual(retrieved_cache, __context__) def test_refill_cache(self): """ Tests to ensure that the context cache can rehydrate a wrapped function """ # First populate the cache @cache.context_cache def _test_set_cache(): pass _test_set_cache() # Then try to rehydate a func @cache.context_cache def _test_refill_cache(comparison_context): self.assertEqual(__context__, comparison_context) global __context__ __context__ = {} _test_refill_cache({"a": "b"}) # Compare to the context before it was emptied class CacheDiskTestCase(TestCase): def test_everything(self): """ Make sure you can instantiate, add, update, remove, expire """ try: tmpdir = tempfile.mkdtemp() path = os.path.join(tmpdir, "CacheDisk_test") # test instantiation cd = cache.CacheDisk(0.1, path) self.assertIsInstance(cd, cache.CacheDisk) # test to make sure it looks like a dict self.assertNotIn("foo", cd) cd["foo"] = "bar" self.assertIn("foo", cd) self.assertEqual(cd["foo"], "bar") del cd["foo"] self.assertNotIn("foo", cd) # test persistence cd["foo"] = "bar" cd2 = cache.CacheDisk(0.1, path) self.assertIn("foo", cd2) self.assertEqual(cd2["foo"], "bar") # test ttl time.sleep(0.2) self.assertNotIn("foo", cd) self.assertNotIn("foo", cd2) finally: shutil.rmtree(tmpdir, ignore_errors=True)