blob: bd66be4bf83568fdf4347aa05e1d978d2e38bf46 [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001# Copyright 2016 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Copybara854996b2021-09-07 19:36:02 +00004
5"""Tests for the cachemanager service."""
6from __future__ import print_function
7from __future__ import division
8from __future__ import absolute_import
9
10import unittest
11
Adrià Vilanova Martínez9f9ade52022-10-10 23:20:11 +020012try:
13 from mox3 import mox
14except ImportError:
15 import mox
Copybara854996b2021-09-07 19:36:02 +000016
17from framework import sql
18from services import cachemanager_svc
19from services import caches
20from services import service_manager
21from testing import fake
22from testing import testing_helpers
23
24
25class CacheManagerServiceTest(unittest.TestCase):
26
27 def setUp(self):
28 self.mox = mox.Mox()
29 self.cnxn = fake.MonorailConnection()
30 self.cache_manager = cachemanager_svc.CacheManager()
31 self.cache_manager.invalidate_tbl = self.mox.CreateMock(
32 sql.SQLTableManager)
33
34 def tearDown(self):
35 self.mox.UnsetStubs()
36 self.mox.ResetAll()
37
38 def testRegisterCache(self):
39 ram_cache = 'fake ramcache'
40 self.cache_manager.RegisterCache(ram_cache, 'issue')
41 self.assertTrue(ram_cache in self.cache_manager.cache_registry['issue'])
42
43 def testRegisterCache_UnknownKind(self):
44 ram_cache = 'fake ramcache'
45 self.assertRaises(
46 AssertionError,
47 self.cache_manager.RegisterCache, ram_cache, 'foo')
48
49 def testProcessInvalidateRows_Empty(self):
50 rows = []
51 self.cache_manager._ProcessInvalidationRows(rows)
52 self.assertEqual(0, self.cache_manager.processed_invalidations_up_to)
53
54 def testProcessInvalidateRows_Some(self):
55 ram_cache = caches.RamCache(self.cache_manager, 'issue')
56 ram_cache.CacheAll({
57 33: 'issue 33',
58 34: 'issue 34',
59 })
60 rows = [(1, 'issue', 34),
61 (2, 'project', 789),
62 (3, 'issue', 39)]
63 self.cache_manager._ProcessInvalidationRows(rows)
64 self.assertEqual(3, self.cache_manager.processed_invalidations_up_to)
65 self.assertTrue(ram_cache.HasItem(33))
66 self.assertFalse(ram_cache.HasItem(34))
67
68 def testProcessInvalidateRows_All(self):
69 ram_cache = caches.RamCache(self.cache_manager, 'issue')
70 ram_cache.CacheAll({
71 33: 'issue 33',
72 34: 'issue 34',
73 })
74 rows = [(991, 'issue', 34),
75 (992, 'project', 789),
76 (993, 'issue', cachemanager_svc.INVALIDATE_ALL_KEYS)]
77 self.cache_manager._ProcessInvalidationRows(rows)
78 self.assertEqual(993, self.cache_manager.processed_invalidations_up_to)
79 self.assertEqual({}, ram_cache.cache)
80
81 def SetUpDoDistributedInvalidation(self, rows):
82 self.cache_manager.invalidate_tbl.Select(
83 self.cnxn, cols=['timestep', 'kind', 'cache_key'],
84 where=[('timestep > %s', [0])],
85 order_by=[('timestep DESC', [])],
86 limit=cachemanager_svc.MAX_INVALIDATE_ROWS_TO_CONSIDER
87 ).AndReturn(rows)
88
89 def testDoDistributedInvalidation_Empty(self):
90 rows = []
91 self.SetUpDoDistributedInvalidation(rows)
92 self.mox.ReplayAll()
93 self.cache_manager.DoDistributedInvalidation(self.cnxn)
94 self.mox.VerifyAll()
95 self.assertEqual(0, self.cache_manager.processed_invalidations_up_to)
96
97 def testDoDistributedInvalidation_Some(self):
98 ram_cache = caches.RamCache(self.cache_manager, 'issue')
99 ram_cache.CacheAll({
100 33: 'issue 33',
101 34: 'issue 34',
102 })
103 rows = [(1, 'issue', 34),
104 (2, 'project', 789),
105 (3, 'issue', 39)]
106 self.SetUpDoDistributedInvalidation(rows)
107 self.mox.ReplayAll()
108 self.cache_manager.DoDistributedInvalidation(self.cnxn)
109 self.mox.VerifyAll()
110 self.assertEqual(3, self.cache_manager.processed_invalidations_up_to)
111 self.assertTrue(ram_cache.HasItem(33))
112 self.assertFalse(ram_cache.HasItem(34))
113
114 def testDoDistributedInvalidation_Redundant(self):
115 ram_cache = caches.RamCache(self.cache_manager, 'issue')
116 ram_cache.CacheAll({
117 33: 'issue 33',
118 34: 'issue 34',
119 })
120 rows = [(1, 'issue', 34),
121 (2, 'project', 789),
122 (3, 'issue', 39),
123 (4, 'project', 789),
124 (5, 'issue', 39)]
125 self.SetUpDoDistributedInvalidation(rows)
126 self.mox.ReplayAll()
127 self.cache_manager.DoDistributedInvalidation(self.cnxn)
128 self.mox.VerifyAll()
129 self.assertEqual(5, self.cache_manager.processed_invalidations_up_to)
130 self.assertTrue(ram_cache.HasItem(33))
131 self.assertFalse(ram_cache.HasItem(34))
132
133 def testStoreInvalidateRows_UnknownKind(self):
134 self.assertRaises(
135 AssertionError,
136 self.cache_manager.StoreInvalidateRows, self.cnxn, 'foo', [1, 2])
137
138 def SetUpStoreInvalidateRows(self, rows):
139 self.cache_manager.invalidate_tbl.InsertRows(
140 self.cnxn, ['kind', 'cache_key'], rows)
141
142 def testStoreInvalidateRows(self):
143 rows = [('issue', 1), ('issue', 2)]
144 self.SetUpStoreInvalidateRows(rows)
145 self.mox.ReplayAll()
146 self.cache_manager.StoreInvalidateRows(self.cnxn, 'issue', [1, 2])
147 self.mox.VerifyAll()
148
149 def SetUpStoreInvalidateAll(self, kind):
150 self.cache_manager.invalidate_tbl.InsertRow(
151 self.cnxn, kind=kind, cache_key=cachemanager_svc.INVALIDATE_ALL_KEYS,
152 ).AndReturn(44)
153 self.cache_manager.invalidate_tbl.Delete(
154 self.cnxn, kind=kind, where=[('timestep < %s', [44])])
155
156 def testStoreInvalidateAll(self):
157 self.SetUpStoreInvalidateAll('issue')
158 self.mox.ReplayAll()
159 self.cache_manager.StoreInvalidateAll(self.cnxn, 'issue')
160 self.mox.VerifyAll()
161
162
163class RamCacheConsolidateTest(unittest.TestCase):
164
165 def setUp(self):
166 self.mox = mox.Mox()
167 self.cnxn = 'fake connection'
168 self.cache_manager = cachemanager_svc.CacheManager()
169 self.cache_manager.invalidate_tbl = self.mox.CreateMock(
170 sql.SQLTableManager)
171 self.services = service_manager.Services(
172 cache_manager=self.cache_manager)
Adrià Vilanova Martínez9f9ade52022-10-10 23:20:11 +0200173 self.servlet = cachemanager_svc.RamCacheConsolidate(services=self.services)
Copybara854996b2021-09-07 19:36:02 +0000174
175 def testHandleRequest_NothingToDo(self):
176 mr = testing_helpers.MakeMonorailRequest()
177 self.cache_manager.invalidate_tbl.SelectValue(
178 mr.cnxn, 'COUNT(*)').AndReturn(112)
179 self.cache_manager.invalidate_tbl.SelectValue(
180 mr.cnxn, 'COUNT(*)').AndReturn(112)
181 self.mox.ReplayAll()
182
183 json_data = self.servlet.HandleRequest(mr)
184 self.mox.VerifyAll()
185 self.assertEqual(json_data['old_count'], 112)
186 self.assertEqual(json_data['new_count'], 112)
187
188 def testHandleRequest_Truncate(self):
189 mr = testing_helpers.MakeMonorailRequest()
190 self.cache_manager.invalidate_tbl.SelectValue(
191 mr.cnxn, 'COUNT(*)').AndReturn(4012)
192 self.cache_manager.invalidate_tbl.Select(
193 mr.cnxn, ['timestep'],
194 order_by=[('timestep DESC', [])],
195 limit=cachemanager_svc.MAX_INVALIDATE_ROWS_TO_CONSIDER
196 ).AndReturn([[3012]]) # Actual would be 1000 rows ending with 3012.
197 self.cache_manager.invalidate_tbl.Delete(
198 mr.cnxn, where=[('timestep < %s', [3012])])
199 self.cache_manager.invalidate_tbl.SelectValue(
200 mr.cnxn, 'COUNT(*)').AndReturn(1000)
201 self.mox.ReplayAll()
202
203 json_data = self.servlet.HandleRequest(mr)
204 self.mox.VerifyAll()
205 self.assertEqual(json_data['old_count'], 4012)
206 self.assertEqual(json_data['new_count'], 1000)