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