1//
2// ExpireLRUCacheTest.cpp
3//
4// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "ExpireLRUCacheTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Exception.h"
15#include "Poco/ExpireLRUCache.h"
16#include "Poco/AccessExpireLRUCache.h"
17#include "Poco/Bugcheck.h"
18#include "Poco/Thread.h"
19
20
21using namespace Poco;
22
23
24#define DURSLEEP 250
25#define DURHALFSLEEP DURSLEEP / 2
26#define DURWAIT 300
27
28
29ExpireLRUCacheTest::ExpireLRUCacheTest(const std::string& rName): CppUnit::TestCase(rName)
30{
31}
32
33
34ExpireLRUCacheTest::~ExpireLRUCacheTest()
35{
36}
37
38
39void ExpireLRUCacheTest::testClear()
40{
41 ExpireLRUCache<int, int> aCache(DURSLEEP);
42 aCache.add(1, 2);
43 aCache.add(3, 4);
44 aCache.add(5, 6);
45 assertTrue (aCache.has(1));
46 assertTrue (aCache.has(3));
47 assertTrue (aCache.has(5));
48 assertTrue (*aCache.get(1) == 2);
49 assertTrue (*aCache.get(3) == 4);
50 assertTrue (*aCache.get(5) == 6);
51 aCache.clear();
52 assertTrue (!aCache.has(1));
53 assertTrue (!aCache.has(3));
54 assertTrue (!aCache.has(5));
55}
56
57
58void ExpireLRUCacheTest::testExpire0()
59{
60 try
61 {
62 ExpireLRUCache<int, int> aCache(1024, 24);
63 failmsg("cache expire lower than 25 is illegal, test should fail");
64 }
65 catch (Poco::InvalidArgumentException&)
66 {
67 }
68}
69
70
71void ExpireLRUCacheTest::testExpireN()
72{
73 // 3-1 represents the cache sorted by age, elements get replaced at the end of the list
74 // 3-1|5 -> 5 gets removed
75 ExpireLRUCache<int, int> aCache(3, DURSLEEP);
76 aCache.add(1, 2); // 1
77 assertTrue (aCache.has(1));
78 SharedPtr<int> tmp = aCache.get(1);
79 assertTrue (!tmp.isNull());
80 assertTrue (*tmp == 2);
81 Thread::sleep(DURWAIT);
82 assertTrue (!aCache.has(1));
83
84 // tmp must still be valid, access it
85 assertTrue (*tmp == 2);
86 tmp = aCache.get(1);
87 assertTrue (!tmp);
88
89 aCache.add(1, 2); // 1
90 Thread::sleep(DURHALFSLEEP);
91 aCache.add(3, 4); // 3-1
92 assertTrue (aCache.has(1));
93 assertTrue (aCache.has(3));
94 tmp = aCache.get(1);
95 SharedPtr<int> tmp2 = aCache.get(3);
96 assertTrue (*tmp == 2);
97 assertTrue (*tmp2 == 4);
98
99 Thread::sleep(DURHALFSLEEP+25); //3|1
100 assertTrue (!aCache.has(1));
101 assertTrue (aCache.has(3));
102 assertTrue (*tmp == 2); // 1-3
103 assertTrue (*tmp2 == 4); // 3-1
104 tmp2 = aCache.get(3);
105 assertTrue (*tmp2 == 4);
106 Thread::sleep(DURHALFSLEEP+25); //3|1
107 assertTrue (!aCache.has(3));
108 assertTrue (*tmp2 == 4);
109 tmp = aCache.get(1);
110 tmp2 = aCache.get(3);
111 assertTrue (!tmp);
112 assertTrue (!tmp2);
113
114 // removing illegal entries should work too
115 aCache.remove(666);
116
117 aCache.clear();
118 assertTrue (!aCache.has(5));
119 assertTrue (!aCache.has(3));
120}
121
122
123void ExpireLRUCacheTest::testAccessExpireN()
124{
125 // 3-1 represents the cache sorted by age, elements get replaced at the end of the list
126 // 3-1|5 -> 5 gets removed
127 AccessExpireLRUCache<int, int> aCache(3, DURSLEEP);
128 aCache.add(1, 2); // 1
129 assertTrue (aCache.has(1));
130 SharedPtr<int> tmp = aCache.get(1);
131 assertTrue (!tmp.isNull());
132 assertTrue (*tmp == 2);
133 assertTrue (aCache.size() == 1);
134 Thread::sleep(DURWAIT);
135 assertTrue (aCache.size() == 0);
136 assertTrue (!aCache.has(1));
137
138 // tmp must still be valid, access it
139 assertTrue (*tmp == 2);
140 tmp = aCache.get(1);
141 assertTrue (!tmp);
142
143 aCache.add(1, 2); // 1
144 Thread::sleep(DURHALFSLEEP);
145 aCache.add(3, 4); // 3-1
146 assertTrue (aCache.has(1));
147 assertTrue (aCache.has(3));
148
149 Thread::sleep(DURHALFSLEEP+50); //3|1
150 assertTrue (!aCache.has(1));
151 assertTrue (*aCache.get(3) == 4);
152 Thread::sleep(DURHALFSLEEP+25); //3|1
153 assertTrue (*aCache.get(3) == 4);
154 // removing illegal entries should work too
155 aCache.remove(666);
156
157 aCache.clear();
158 assertTrue (!aCache.has(5));
159 assertTrue (!aCache.has(3));
160}
161
162
163void ExpireLRUCacheTest::testCacheSize0()
164{
165 // cache size 0 is illegal
166 try
167 {
168 ExpireLRUCache<int, int> aCache(0);
169 failmsg ("cache size of 0 is illegal, test should fail");
170 }
171 catch (Poco::InvalidArgumentException&)
172 {
173 }
174}
175
176
177void ExpireLRUCacheTest::testCacheSize1()
178{
179 ExpireLRUCache<int, int> aCache(1);
180 aCache.add(1, 2);
181 assertTrue (aCache.has(1));
182 assertTrue (*aCache.get(1) == 2);
183
184 aCache.add(3, 4); // replaces 1
185 assertTrue (!aCache.has(1));
186 assertTrue (aCache.has(3));
187 assertTrue (*aCache.get(3) == 4);
188
189 aCache.add(5, 6);
190 assertTrue (!aCache.has(1));
191 assertTrue (!aCache.has(3));
192 assertTrue (aCache.has(5));
193 assertTrue (*aCache.get(5) == 6);
194
195 aCache.remove(5);
196 assertTrue (!aCache.has(5));
197
198 // removing illegal entries should work too
199 aCache.remove(666);
200}
201
202
203void ExpireLRUCacheTest::testCacheSize2()
204{
205 // 3-1 represents the cache sorted by pos, elements get replaced at the end of the list
206 // 3-1|5 -> 5 gets removed
207 ExpireLRUCache<int, int> aCache(2);
208 aCache.add(1, 2); // 1
209 assertTrue (aCache.has(1));
210 assertTrue (*aCache.get(1) == 2);
211
212 aCache.add(3, 4); // 3-1
213 assertTrue (aCache.has(1));
214 assertTrue (aCache.has(3));
215 assertTrue (*aCache.get(1) == 2); // 1-3
216 assertTrue (*aCache.get(3) == 4); // 3-1
217
218 aCache.add(5, 6); // 5-3|1
219 assertTrue (!aCache.has(1));
220 assertTrue (aCache.has(3));
221 assertTrue (aCache.has(5));
222 assertTrue (*aCache.get(5) == 6); // 5-3
223 assertTrue (*aCache.get(3) == 4); // 3-5
224
225 // test remove from the end and the beginning of the list
226 aCache.remove(5); // 3
227 assertTrue (!aCache.has(5));
228 assertTrue (*aCache.get(3) == 4); // 3
229 aCache.add(5, 6); // 5-3
230 assertTrue (*aCache.get(3) == 4); // 3-5
231 aCache.remove(3); // 5
232 assertTrue (!aCache.has(3));
233 assertTrue (*aCache.get(5) == 6); // 5
234
235 // removing illegal entries should work too
236 aCache.remove(666);
237
238 aCache.clear();
239 assertTrue (!aCache.has(5));
240}
241
242
243void ExpireLRUCacheTest::testCacheSizeN()
244{
245 // 3-1 represents the cache sorted by pos, elements get replaced at the end of the list
246 // 3-1|5 -> 5 gets removed
247 ExpireLRUCache<int, int> aCache(3);
248 aCache.add(1, 2); // 1
249 assertTrue (aCache.has(1));
250 assertTrue (*aCache.get(1) == 2);
251
252 aCache.add(3, 4); // 3-1
253 assertTrue (aCache.has(1));
254 assertTrue (aCache.has(3));
255 assertTrue (*aCache.get(1) == 2); // 1-3
256 assertTrue (*aCache.get(3) == 4); // 3-1
257
258 aCache.add(5, 6); // 5-3-1
259 assertTrue (aCache.has(1));
260 assertTrue (aCache.has(3));
261 assertTrue (aCache.has(5));
262 assertTrue (*aCache.get(5) == 6); // 5-3-1
263 assertTrue (*aCache.get(3) == 4); // 3-5-1
264
265 aCache.add(7, 8); // 7-5-3|1
266 assertTrue (!aCache.has(1));
267 assertTrue (aCache.has(7));
268 assertTrue (aCache.has(3));
269 assertTrue (aCache.has(5));
270 assertTrue (*aCache.get(5) == 6); // 5-7-3
271 assertTrue (*aCache.get(3) == 4); // 3-5-7
272 assertTrue (*aCache.get(7) == 8); // 7-3-5
273
274 // test remove from the end and the beginning of the list
275 aCache.remove(5); // 7-3
276 assertTrue (!aCache.has(5));
277 assertTrue (*aCache.get(3) == 4); // 3-7
278 aCache.add(5, 6); // 5-3-7
279 assertTrue (*aCache.get(7) == 8); // 7-5-3
280 aCache.remove(7); // 5-3
281 assertTrue (!aCache.has(7));
282 assertTrue (aCache.has(3));
283 assertTrue (*aCache.get(5) == 6); // 5-3
284
285 // removing illegal entries should work too
286 aCache.remove(666);
287
288 aCache.clear();
289 assertTrue (!aCache.has(5));
290 assertTrue (!aCache.has(3));
291}
292
293
294void ExpireLRUCacheTest::testDuplicateAdd()
295{
296 ExpireLRUCache<int, int> aCache(3);
297 aCache.add(1, 2); // 1
298 assertTrue (aCache.has(1));
299 assertTrue (*aCache.get(1) == 2);
300 aCache.add(1, 3);
301 assertTrue (aCache.has(1));
302 assertTrue (*aCache.get(1) == 3);
303}
304
305
306void ExpireLRUCacheTest::setUp()
307{
308}
309
310
311void ExpireLRUCacheTest::tearDown()
312{
313}
314
315
316CppUnit::Test* ExpireLRUCacheTest::suite()
317{
318 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ExpireLRUCacheTest");
319
320 CppUnit_addTest(pSuite, ExpireLRUCacheTest, testClear);
321 CppUnit_addTest(pSuite, ExpireLRUCacheTest, testExpire0);
322 CppUnit_addTest(pSuite, ExpireLRUCacheTest, testExpireN);
323 CppUnit_addTest(pSuite, ExpireLRUCacheTest, testAccessExpireN);
324 CppUnit_addTest(pSuite, ExpireLRUCacheTest, testCacheSize0);
325 CppUnit_addTest(pSuite, ExpireLRUCacheTest, testCacheSize1);
326 CppUnit_addTest(pSuite, ExpireLRUCacheTest, testCacheSize2);
327 CppUnit_addTest(pSuite, ExpireLRUCacheTest, testCacheSizeN);
328 CppUnit_addTest(pSuite, ExpireLRUCacheTest, testDuplicateAdd);
329
330 return pSuite;
331}
332