test_dict_cache.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. # Copyright 2015, 2016 OpenMarket Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from synapse.util.caches.dictionary_cache import DictionaryCache
  15. from tests import unittest
  16. class DictCacheTestCase(unittest.TestCase):
  17. def setUp(self) -> None:
  18. self.cache: DictionaryCache[str, str, str] = DictionaryCache(
  19. "foobar", max_entries=10
  20. )
  21. def test_simple_cache_hit_full(self) -> None:
  22. key = "test_simple_cache_hit_full"
  23. v = self.cache.get(key)
  24. self.assertIs(v.full, False)
  25. self.assertEqual(v.known_absent, set())
  26. self.assertEqual({}, v.value)
  27. seq = self.cache.sequence
  28. test_value = {"test": "test_simple_cache_hit_full"}
  29. self.cache.update(seq, key, test_value)
  30. c = self.cache.get(key)
  31. self.assertEqual(test_value, c.value)
  32. def test_simple_cache_hit_partial(self) -> None:
  33. key = "test_simple_cache_hit_partial"
  34. seq = self.cache.sequence
  35. test_value = {"test": "test_simple_cache_hit_partial"}
  36. self.cache.update(seq, key, test_value)
  37. c = self.cache.get(key, ["test"])
  38. self.assertEqual(test_value, c.value)
  39. def test_simple_cache_miss_partial(self) -> None:
  40. key = "test_simple_cache_miss_partial"
  41. seq = self.cache.sequence
  42. test_value = {"test": "test_simple_cache_miss_partial"}
  43. self.cache.update(seq, key, test_value)
  44. c = self.cache.get(key, ["test2"])
  45. self.assertEqual({}, c.value)
  46. def test_simple_cache_hit_miss_partial(self) -> None:
  47. key = "test_simple_cache_hit_miss_partial"
  48. seq = self.cache.sequence
  49. test_value = {
  50. "test": "test_simple_cache_hit_miss_partial",
  51. "test2": "test_simple_cache_hit_miss_partial2",
  52. "test3": "test_simple_cache_hit_miss_partial3",
  53. }
  54. self.cache.update(seq, key, test_value)
  55. c = self.cache.get(key, ["test2"])
  56. self.assertEqual({"test2": "test_simple_cache_hit_miss_partial2"}, c.value)
  57. def test_multi_insert(self) -> None:
  58. key = "test_simple_cache_hit_miss_partial"
  59. seq = self.cache.sequence
  60. test_value_1 = {"test": "test_simple_cache_hit_miss_partial"}
  61. self.cache.update(seq, key, test_value_1, fetched_keys={"test"})
  62. seq = self.cache.sequence
  63. test_value_2 = {"test2": "test_simple_cache_hit_miss_partial2"}
  64. self.cache.update(seq, key, test_value_2, fetched_keys={"test2"})
  65. c = self.cache.get(key, dict_keys=["test", "test2"])
  66. self.assertEqual(
  67. {
  68. "test": "test_simple_cache_hit_miss_partial",
  69. "test2": "test_simple_cache_hit_miss_partial2",
  70. },
  71. c.value,
  72. )
  73. self.assertEqual(c.full, False)
  74. def test_invalidation(self) -> None:
  75. """Test that the partial dict and full dicts get invalidated
  76. separately.
  77. """
  78. key = "some_key"
  79. seq = self.cache.sequence
  80. # start by populating a "full dict" entry
  81. self.cache.update(seq, key, {"a": "b", "c": "d"})
  82. # add a bunch of individual entries, also keeping the individual
  83. # entry for "a" warm.
  84. for i in range(20):
  85. self.cache.get(key, ["a"])
  86. self.cache.update(seq, f"key{i}", {"1": "2"})
  87. # We should have evicted the full dict...
  88. r = self.cache.get(key)
  89. self.assertFalse(r.full)
  90. self.assertTrue("c" not in r.value)
  91. # ... but kept the "a" entry that we kept querying.
  92. r = self.cache.get(key, dict_keys=["a"])
  93. self.assertFalse(r.full)
  94. self.assertEqual(r.value, {"a": "b"})