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