1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
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 */
15 #undef private
16 #undef protected
17 #define private public
18 #define protected public
19 #include "gtest/gtest.h"
20 #include "expire_lru_cache.h"
21 #include "message_parcel.h"
22 #include "test_log.h"
23
24 using namespace ::testing;
25 using namespace std;
26 using namespace testing::ext;
27
28 namespace OHOS {
29 namespace {
30 vector<char> g_Key1{'k', 'e', 'y', '1'};
31 vector<char> g_Key2{'k', 'e', 'y', '2'};
32 vector<char> g_Key3{'k', 'e', 'y', '3'};
33 vector<char> g_Key4{'k', 'e', 'y', '4'};
34 vector<char> g_Key5{'k', 'e', 'y', '5'};
35
36 vector<char> g_Val1{'v', 'a', 'l', '1'};
37 vector<char> g_Val2{'v', 'a', 'l', '2'};
38 vector<char> g_Val3{'v', 'a', 'l', '3'};
39 vector<char> g_Val4{'v', 'a', 'l', '4'};
40 vector<char> g_Val5{'v', 'a', 'l', '5'};
41 }
42
43 class ExpireLruCacheTest : public testing::Test {
44 public:
45 static void SetUpTestCase();
46 static void TearDownTestCase();
47 void SetUp();
48 void TearDown();
49 };
50
SetUpTestCase()51 void ExpireLruCacheTest::SetUpTestCase()
52 {
53 DTEST_LOG << "SetUpTestCase" << std::endl;
54 }
55
TearDownTestCase()56 void ExpireLruCacheTest::TearDownTestCase()
57 {
58 DTEST_LOG << "TearDownTestCase" << std::endl;
59 }
60
SetUp()61 void ExpireLruCacheTest::SetUp()
62 {
63 DTEST_LOG << "SetUp" << std::endl;
64 }
65
TearDown()66 void ExpireLruCacheTest::TearDown()
67 {
68 DTEST_LOG << "TearDown" << std::endl;
69 }
70
71 /**
72 * @tc.name: ConstructorTest001
73 * @tc.desc: test constructor input parameter
74 * @tc.type: FUNC
75 * @tc.require:
76 */
77 HWTEST_F(ExpireLruCacheTest, ConstructorTest001, TestSize.Level2)
78 {
79 DTEST_LOG << "ConstructorTest001 start" << std::endl;
80 {
81 ExpireLruCache<std::vector<char>, std::vector<char>> cache;
82 EXPECT_EQ(cache.size_, 8);
83 EXPECT_EQ(cache.expireTimeMilliSec_, 1000);
84 }
85
86 {
87 ExpireLruCache<std::vector<char>, std::vector<char>> cache(0, 0);
88 EXPECT_EQ(cache.size_, 1);
89 EXPECT_EQ(cache.expireTimeMilliSec_, 0);
90 }
91
92 {
93 ExpireLruCache<std::vector<char>, std::vector<char>> cache(0, -1);
94 EXPECT_EQ(cache.size_, 1);
95 EXPECT_EQ(cache.expireTimeMilliSec_, 1000);
96 }
97
98 {
99 ExpireLruCache<std::vector<char>, std::vector<char>> cache(100, 2000);
100 EXPECT_EQ(cache.size_, 100);
101 EXPECT_EQ(cache.expireTimeMilliSec_, 2000);
102 }
103 DTEST_LOG << "ConstructorTest001 end" << std::endl;
104 }
105
ExpirelruCacheTestCheckNums(ExpireLruCache<std::vector<char>,std::vector<char>> & cache,size_t expectNums)106 bool ExpirelruCacheTestCheckNums(ExpireLruCache<std::vector<char>, std::vector<char>>& cache, size_t expectNums)
107 {
108 size_t dataSize = cache.data_.size();
109 size_t timeStampSize = cache.timestamp_.size();
110 size_t keysSize = cache.keys_.size();
111
112 if (dataSize != expectNums) {
113 EXPECT_EQ(dataSize, expectNums);
114 return false;
115 }
116 if (timeStampSize != expectNums) {
117 EXPECT_EQ(timeStampSize, expectNums);
118 return false;
119 }
120 if (keysSize != expectNums) {
121 EXPECT_EQ(keysSize, expectNums);
122 return false;
123 }
124 return true;
125 }
126
ExpirelruCacheTestCheckSequence(ExpireLruCache<std::vector<char>,std::vector<char>> & cache,std::list<vector<char>> & expectSequence)127 bool ExpirelruCacheTestCheckSequence(ExpireLruCache<std::vector<char>, std::vector<char>>& cache,
128 std::list<vector<char>>& expectSequence)
129 {
130 auto iterA = cache.keys_.begin();
131 auto iterB = expectSequence.begin();
132 for (size_t i = 0; i < cache.keys_.size(); i++) {
133 if (*iterA != *iterB) {
134 EXPECT_EQ(*iterA, *iterB);
135 return false;
136 }
137 iterA++;
138 iterB++;
139 }
140 return true;
141 }
142
ExpirelruCacheTestCheckGetRet(ExpireLruCache<std::vector<char>,std::vector<char>> & cache,vector<char> & key,vector<char> & val)143 bool ExpirelruCacheTestCheckGetRet(ExpireLruCache<std::vector<char>, std::vector<char>>& cache,
144 vector<char>& key, vector<char>& val)
145 {
146 std::shared_ptr<vector<char>> retVal = cache.Get(key);
147 if (*retVal != val) {
148 EXPECT_EQ(*retVal == val, 0);
149 return false;
150 }
151 return true;
152 }
153 /**
154 * @tc.name: ADD_GET_CLEAR_Test001
155 * @tc.desc: test add、get、clear api
156 * @tc.type: FUNC
157 * @tc.require:
158 */
159 HWTEST_F(ExpireLruCacheTest, ADD_GET_CLEAR_Test001, TestSize.Level2)
160 {
161 DTEST_LOG << "ADD_GET_CLEAR_Test001 start" << std::endl;
162 ExpireLruCache<std::vector<char>, std::vector<char>> cache;
163
164 cache.Add(g_Key1, g_Val1);
165 cache.Add(g_Key2, g_Val2);
166 cache.Add(g_Key3, g_Val3);
167 cache.Add(g_Key4, g_Val4);
168 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 4), true);
169
170 std::list<vector<char>> expectSequence1 = {g_Key4, g_Key3, g_Key2, g_Key1};
171 EXPECT_EQ(ExpirelruCacheTestCheckSequence(cache, expectSequence1), true);
172
173 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key4, g_Val4), true);
174 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key3, g_Val3), true);
175 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key2, g_Val2), true);
176 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key1, g_Val1), true);
177
178 std::list<vector<char>> expectSequence2 = {g_Key1, g_Key2, g_Key3, g_Key4};
179 EXPECT_EQ(ExpirelruCacheTestCheckSequence(cache, expectSequence2), true);
180
181 cache.Add(g_Key1, g_Val1);
182 EXPECT_EQ(cache.data_.size(), 4);
183
184 cache.Add(g_Key2, g_Val3);
185 EXPECT_EQ(cache.data_.size(), 4);
186 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key2, g_Val3), true);
187
188 std::list<vector<char>> expectSequence3 = {g_Key2, g_Key1, g_Key3, g_Key4};
189 EXPECT_EQ(ExpirelruCacheTestCheckSequence(cache, expectSequence3), true);
190
191 cache.Remove(g_Key3);
192 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 3), true);
193 {
194 std::shared_ptr<vector<char>> retVal;
195 retVal = cache.Get(g_Key3);
196 EXPECT_EQ(retVal, nullptr);
197 }
198
199 cache.Clear();
200 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 0), true);
201
202 {
203 std::shared_ptr<vector<char>> retVal;
204 retVal = cache.Get(g_Key2);
205 ASSERT_TRUE(retVal == nullptr);
206 }
207 {
208 std::shared_ptr<vector<char>> retVal;
209 retVal = cache.Get(g_Key4);
210 ASSERT_TRUE(retVal == nullptr);
211 }
212 DTEST_LOG << "ADD_GET_CLEAR_Test001 end" << std::endl;
213 }
214
215 /**
216 * @tc.name: LRUTest001
217 * @tc.desc: test the cache map LRU
218 * @tc.type: FUNC
219 * @tc.require:
220 */
221 HWTEST_F(ExpireLruCacheTest, LRUTest001, TestSize.Level2)
222 {
223 DTEST_LOG << "LRUTest001 start" << std::endl;
224 // cacheMapSize 3 expireTime 10000000us
225 ExpireLruCache<std::vector<char>, std::vector<char>> cache(3, 10000);
226
227 cache.Add(g_Key1, g_Val1);
228 cache.Add(g_Key2, g_Val2);
229 cache.Add(g_Key3, g_Val3);
230 // when [g_Key4, g_Val4] is added, the cache is full and the leasted recently used [g_Key1, g_Val1] will be deleted
231 cache.Add(g_Key4, g_Val4);
232
233 {
234 std::list<vector<char>> expectSequence = {g_Key4, g_Key3, g_Key2};
235 auto iterA = expectSequence.begin();
236 auto iterB = cache.keys_.begin();
237 for (int i = 0; i < cache.keys_.size(); i++) {
238 ASSERT_TRUE(*iterA == *iterB);
239 iterA++;
240 iterB++;
241 }
242 auto retVal = cache.Get(g_Key1);
243 EXPECT_EQ(retVal, nullptr);
244 }
245 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 3), true);
246
247 {
248 auto retVal = cache.Get(g_Key2);
249 EXPECT_EQ(*retVal, g_Val2);
250 }
251 // when [g_Key5, g_Val5] is added, the cache is full and the leasted recently used [g_Key3, g_Val3] will be deleted
252 cache.Add(g_Key5, g_Val5);
253 {
254 std::list<vector<char>> expectSequence = {g_Key5, g_Key2, g_Key4};
255 auto iterA = expectSequence.begin();
256 auto iterB = cache.keys_.begin();
257 for (int i = 0; i < cache.keys_.size(); i++) {
258 ASSERT_TRUE(*iterA == *iterB);
259 iterA++;
260 iterB++;
261 }
262 auto retVal = cache.Get(g_Key3);
263 EXPECT_EQ(retVal, nullptr);
264 }
265 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 3), true);
266 DTEST_LOG << "LRUTest001 end" << std::endl;
267 }
268
269 /**
270 * @tc.name: LRUTest002
271 * @tc.desc: test the cache map LRU
272 * @tc.type: FUNC
273 * @tc.require:
274 */
275 HWTEST_F(ExpireLruCacheTest, LRUTest002, TestSize.Level2)
276 {
277 DTEST_LOG << "LRUTest002 start" << std::endl;
278 // cacheMapSize 3 expireTime 40000us
279 ExpireLruCache<std::vector<char>, std::vector<char>> cache(3, 40);
280
281 cache.Add(g_Key1, g_Val1);
282 usleep(30000);
283 cache.Add(g_Key2, g_Val2);
284 cache.Add(g_Key3, g_Val3);
285
286 {
287 auto retVal = cache.Get(g_Key1);
288 EXPECT_EQ(*retVal, g_Val1);
289 std::list<vector<char>> expectSequence = {g_Key1, g_Key3, g_Key2};
290 auto iterA = expectSequence.begin();
291 auto iterB = cache.keys_.begin();
292 for (int i = 0; i < cache.keys_.size(); i++) {
293 ASSERT_TRUE(*iterA == *iterB);
294 iterA++;
295 iterB++;
296 }
297 }
298 usleep(20000);
299 // [g_Key1, g_Val1] is expired, add [g_Key4, g_Val4] will eliminate [g_Key1, g_Val1]
300 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 3), true);
301 cache.Add(g_Key4, g_Val4);
302 {
303 std::list<vector<char>> expectSequence = {g_Key4, g_Key3, g_Key2};
304 auto iterA = expectSequence.begin();
305 auto iterB = cache.keys_.begin();
306 for (int i = 0; i < cache.keys_.size(); i++) {
307 ASSERT_TRUE(*iterA == *iterB);
308 iterA++;
309 iterB++;
310 }
311 auto retVal = cache.Get(g_Key1);
312 EXPECT_EQ(retVal, nullptr);
313 }
314 usleep(50000);
315 // all caches are expired, add [g_Key5, g_Val5] will eliminate [g_Key2, g_Val2][g_Key3, g_Val3][g_Key4, g_Val4]
316 cache.Add(g_Key5, g_Val5);
317 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 1), true);
318 {
319 auto retVal = cache.Get(g_Key5);
320 EXPECT_EQ(*retVal, g_Val5);
321 }
322 DTEST_LOG << "LRUTest002 end" << std::endl;
323 }
324
325 /**
326 * @tc.name: GetTest001
327 * @tc.desc: test get api
328 * @tc.type: FUNC
329 * @tc.require:
330 */
331 HWTEST_F(ExpireLruCacheTest, GetTest001, TestSize.Level0)
332 {
333 DTEST_LOG << "GetTest001 start" << std::endl;
334 ExpireLruCache<std::vector<char>, std::vector<char>> cache(3, 50);
335
336 {
337 auto retVal = cache.Get(g_Key1);
338 EXPECT_EQ(retVal, nullptr);
339 }
340
341 cache.Add(g_Key1, g_Val1);
342 {
343 auto retVal = cache.Get(g_Key1);
344 EXPECT_EQ(*retVal, g_Val1);
345 }
346 usleep(70000);
347 // [g_Key1, g_Val1] is expired, get(g_Key1) will return nullptr and clear invalid cache [g_Key1, g_Val1]
348 {
349 auto retVal = cache.Get(g_Key1);
350 EXPECT_EQ(retVal, nullptr);
351 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 0), true);
352 }
353
354 cache.Add(g_Key2, g_Val2);
355 cache.Add(g_Key3, g_Val3);
356 cache.Add(g_Key4, g_Val4);
357 // Verify the cache sequence in the list
358 {
359 std::list<vector<char>> expectSequence = {g_Key4, g_Key3, g_Key2};
360 auto iterA = expectSequence.begin();
361 auto iterB = cache.keys_.begin();
362 for (int i = 0; i < cache.keys_.size(); i++) {
363 ASSERT_TRUE(*iterA == *iterB);
364 iterA++;
365 iterB++;
366 }
367 }
368 {
369 auto retVal = cache.Get(g_Key2);
370 EXPECT_EQ(*retVal, g_Val2);
371 auto retVal2 = cache.Get(g_Key3);
372 EXPECT_EQ(*retVal2, g_Val3);
373 }
374 // Verify the cache sequence in the list
375 {
376 std::list<vector<char>> expectSequence = {g_Key3, g_Key2, g_Key4};
377 auto iterA = expectSequence.begin();
378 auto iterB = cache.keys_.begin();
379 for (int i = 0; i < cache.keys_.size(); i++) {
380 ASSERT_TRUE(*iterA == *iterB);
381 iterA++;
382 iterB++;
383 }
384 }
385 DTEST_LOG << "GetTest001 end" << std::endl;
386 }
387
388 /**
389 * @tc.name: Timestamp001
390 * @tc.desc: test Class Timestamp
391 * @tc.type: FUNC
392 * @tc.require:
393 */
394 HWTEST_F(ExpireLruCacheTest, Timestamp001, TestSize.Level2)
395 {
396 DTEST_LOG << "Timestamp001 start" << std::endl;
397 // test operator '-' and timestamp is increasing
398 ExpireLruCache<int, int>::Timestamp t1;
399 usleep(3000);
400 ExpireLruCache<int, int>::Timestamp t2;
401 int64_t diff = t2 - t1;
402 bool ret;
403 ASSERT_TRUE(diff > 0);
404
405 // test expired func, expired
406 usleep(5000);
407 ret = t1.IsExpired(1);
408 EXPECT_EQ(ret, true);
409
410 // test expired func, not expired
411 ExpireLruCache<int, int>::Timestamp t3;
412 usleep(2000);
413 ret = t3.IsExpired(10);
414 EXPECT_EQ(ret, false);
415 DTEST_LOG << "Timestamp001 end" << std::endl;
416 }
417
418 /**
419 * @tc.name: RemoveTest001
420 * @tc.desc: test remove api
421 * @tc.type: FUNC
422 * @tc.require:
423 */
424 HWTEST_F(ExpireLruCacheTest, RemoveTest001, TestSize.Level0)
425 {
426 DTEST_LOG << "RemoveTest001 start" << std::endl;
427 ExpireLruCache<std::vector<char>, std::vector<char>> cache(3, 2000);
428
429 cache.Add(g_Key1, g_Val1);
430 cache.Add(g_Key3, g_Val3);
431 cache.Add(g_Key2, g_Val2);
432 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 3), true);
433
434 std::list<vector<char>> expectSequence1 = {g_Key2, g_Key3, g_Key1};
435 EXPECT_EQ(ExpirelruCacheTestCheckSequence(cache, expectSequence1), true);
436
437 cache.Remove(g_Key4);
438 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 3), true);
439 std::list<vector<char>> expectSequence2 = {g_Key2, g_Key3, g_Key1};
440 EXPECT_EQ(ExpirelruCacheTestCheckSequence(cache, expectSequence2), true);
441
442 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key1, g_Val1), true);
443 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key3, g_Val3), true);
444 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key2, g_Val2), true);
445
446 cache.Remove(g_Key3);
447 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 2), true);
448
449 std::list<vector<char>> expectSequence3 = {g_Key2, g_Key1};
450 EXPECT_EQ(ExpirelruCacheTestCheckSequence(cache, expectSequence3), true);
451 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key2, g_Val2), true);
452 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key1, g_Val1), true);
453 {
454 auto retVal3 = cache.Get(g_Key3);
455 EXPECT_EQ(retVal3, nullptr);
456 }
457 cache.Remove(g_Key2);
458 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 1), true);
459
460 EXPECT_EQ(ExpirelruCacheTestCheckGetRet(cache, g_Key1, g_Val1), true);
461 {
462 auto retVal2 = cache.Get(g_Key2);
463 EXPECT_EQ(retVal2, nullptr);
464 }
465 cache.Remove(g_Key1);
466 EXPECT_EQ(ExpirelruCacheTestCheckNums(cache, 0), true);
467 {
468 auto retval1 = cache.Get(g_Key1);
469 EXPECT_EQ(retval1, nullptr);
470 }
471 DTEST_LOG << "RemoveTest001 end" << std::endl;
472 }
473 }