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