test_cache.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. # -*- coding: utf-8 -*-
  2. """
  3. tests.unit.utils.cache_test
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5. Test the salt cache objects
  6. """
  7. # Import python libs
  8. from __future__ import absolute_import, print_function, unicode_literals
  9. import os
  10. import shutil
  11. import tempfile
  12. import time
  13. # Import salt libs
  14. import salt.config
  15. import salt.loader
  16. import salt.payload
  17. import salt.utils.cache as cache
  18. import salt.utils.data
  19. import salt.utils.files
  20. # Import Salt Testing libs
  21. from tests.support.unit import TestCase
  22. class CacheDictTestCase(TestCase):
  23. def test_sanity(self):
  24. """
  25. Make sure you can instantiate etc.
  26. """
  27. cd = cache.CacheDict(5)
  28. self.assertIsInstance(cd, cache.CacheDict)
  29. # do some tests to make sure it looks like a dict
  30. self.assertNotIn("foo", cd)
  31. cd["foo"] = "bar"
  32. self.assertEqual(cd["foo"], "bar")
  33. del cd["foo"]
  34. self.assertNotIn("foo", cd)
  35. def test_ttl(self):
  36. cd = cache.CacheDict(0.1)
  37. cd["foo"] = "bar"
  38. self.assertIn("foo", cd)
  39. self.assertEqual(cd["foo"], "bar")
  40. time.sleep(0.2)
  41. self.assertNotIn("foo", cd)
  42. # make sure that a get would get a regular old key error
  43. self.assertRaises(KeyError, cd.__getitem__, "foo")
  44. class CacheContextTestCase(TestCase):
  45. def setUp(self):
  46. context_dir = os.path.join(tempfile.gettempdir(), "context")
  47. if os.path.exists(context_dir):
  48. shutil.rmtree(os.path.join(tempfile.gettempdir(), "context"))
  49. def test_smoke_context(self):
  50. """
  51. Smoke test the context cache
  52. """
  53. if os.path.exists(os.path.join(tempfile.gettempdir(), "context")):
  54. self.skipTest("Context dir already exists")
  55. else:
  56. opts = salt.config.DEFAULT_MINION_OPTS.copy()
  57. opts["cachedir"] = tempfile.gettempdir()
  58. context_cache = cache.ContextCache(opts, "cache_test")
  59. context_cache.cache_context({"a": "b"})
  60. ret = context_cache.get_cache_context()
  61. self.assertDictEqual({"a": "b"}, ret)
  62. def test_context_wrapper(self):
  63. """
  64. Test to ensure that a module which decorates itself
  65. with a context cache can store and retrieve its contextual
  66. data
  67. """
  68. opts = salt.config.DEFAULT_MINION_OPTS.copy()
  69. opts["cachedir"] = tempfile.gettempdir()
  70. ll_ = salt.loader.LazyLoader(
  71. [os.path.join(os.path.dirname(os.path.realpath(__file__)), "cache_mods")],
  72. tag="rawmodule",
  73. virtual_enable=False,
  74. opts=opts,
  75. )
  76. cache_test_func = ll_["cache_mod.test_context_module"]
  77. self.assertEqual(cache_test_func()["called"], 0)
  78. self.assertEqual(cache_test_func()["called"], 1)
  79. __context__ = {"a": "b"}
  80. __opts__ = {"cachedir": "/tmp"}
  81. class ContextCacheTest(TestCase):
  82. """
  83. Test case for salt.utils.cache.ContextCache
  84. """
  85. def setUp(self):
  86. """
  87. Clear the cache before every test
  88. """
  89. context_dir = os.path.join(__opts__["cachedir"], "context")
  90. if os.path.isdir(context_dir):
  91. shutil.rmtree(context_dir)
  92. def test_set_cache(self):
  93. """
  94. Tests to ensure the cache is written correctly
  95. """
  96. @cache.context_cache
  97. def _test_set_cache():
  98. """
  99. This will inherit globals from the test module itself.
  100. Normally these are injected by the salt loader [salt.loader]
  101. """
  102. _test_set_cache()
  103. target_cache_file = os.path.join(
  104. __opts__["cachedir"], "context", "{0}.p".format(__name__)
  105. )
  106. self.assertTrue(
  107. os.path.isfile(target_cache_file), "Context cache did not write cache file"
  108. )
  109. # Test manual de-serialize
  110. with salt.utils.files.fopen(target_cache_file, "rb") as fp_:
  111. target_cache_data = salt.utils.data.decode(
  112. salt.payload.Serial(__opts__).load(fp_)
  113. )
  114. self.assertDictEqual(__context__, target_cache_data)
  115. # Test cache de-serialize
  116. cc = cache.ContextCache(__opts__, __name__)
  117. retrieved_cache = cc.get_cache_context()
  118. self.assertDictEqual(retrieved_cache, __context__)
  119. def test_refill_cache(self):
  120. """
  121. Tests to ensure that the context cache can rehydrate a wrapped function
  122. """
  123. # First populate the cache
  124. @cache.context_cache
  125. def _test_set_cache():
  126. pass
  127. _test_set_cache()
  128. # Then try to rehydate a func
  129. @cache.context_cache
  130. def _test_refill_cache(comparison_context):
  131. self.assertEqual(__context__, comparison_context)
  132. global __context__
  133. __context__ = {}
  134. _test_refill_cache({"a": "b"}) # Compare to the context before it was emptied
  135. class CacheDiskTestCase(TestCase):
  136. def test_everything(self):
  137. """
  138. Make sure you can instantiate, add, update, remove, expire
  139. """
  140. try:
  141. tmpdir = tempfile.mkdtemp()
  142. path = os.path.join(tmpdir, "CacheDisk_test")
  143. # test instantiation
  144. cd = cache.CacheDisk(0.1, path)
  145. self.assertIsInstance(cd, cache.CacheDisk)
  146. # test to make sure it looks like a dict
  147. self.assertNotIn("foo", cd)
  148. cd["foo"] = "bar"
  149. self.assertIn("foo", cd)
  150. self.assertEqual(cd["foo"], "bar")
  151. del cd["foo"]
  152. self.assertNotIn("foo", cd)
  153. # test persistence
  154. cd["foo"] = "bar"
  155. cd2 = cache.CacheDisk(0.1, path)
  156. self.assertIn("foo", cd2)
  157. self.assertEqual(cd2["foo"], "bar")
  158. # test ttl
  159. time.sleep(0.2)
  160. self.assertNotIn("foo", cd)
  161. self.assertNotIn("foo", cd2)
  162. finally:
  163. shutil.rmtree(tmpdir, ignore_errors=True)