1 /*
2  * Copyright (c) 2021 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 
16 #include "cache_manager_tdd_test.h"
17 
18 #include "ace_mem_base.h"
19 
20 namespace OHOS {
21 namespace ACELite {
22 const CacheUnit CacheManagerTddTest::TEST_CONFIG_TABLE[] = {
23     {USER_LOCALIZATION, 16}, // localization key-value cache, lowest 16KB
24 };
25 
SetUp()26 void CacheManagerTddTest::SetUp()
27 {
28     const size_t count = 1;
29     CacheManager::GetInstance().SetConfigTable(TEST_CONFIG_TABLE, count);
30 }
31 
32 /**
33  * @tc.name: CacheDistributeTest001
34  * @tc.desc: Verify the cache distribution process
35  */
36 HWTEST_F(CacheManagerTddTest, CacheDistribute001, TestSize.Level1)
37 {
38     /**
39      * @tc.steps: step1. prepare cache buffer
40      */
41     const size_t totalSize = 20 * 1024; // 20KB
42     char *buffer = static_cast<char *>(ace_malloc(sizeof(char) * totalSize));
43     if (buffer == nullptr) {
44         return;
45     }
46     /**
47      * @tc.steps: step2. trigger the cache setup
48      */
49     uintptr_t startAddr = reinterpret_cast<uintptr_t>(buffer);
50     CacheManager::GetInstance().SetupCacheMemInfo(startAddr, totalSize);
51     /**
52      * @tc.steps: step3. verify the result
53      */
54     uintptr_t localizationPos = CacheManager::GetInstance().GetCacheBufAddress(CacheUser::USER_LOCALIZATION);
55     size_t localizationBufSize = CacheManager::GetInstance().GetCacheBufLength(CacheUser::USER_LOCALIZATION);
56     const uintptr_t targetPos = startAddr + MAGIC_NUMBER_LENGTH;
57     const size_t unit = 1024;
58     const uint8_t localizationMin = 16;
59     const size_t targetLength = localizationMin * unit;
60     EXPECT_EQ(localizationPos, targetPos);
61     EXPECT_EQ(localizationBufSize, targetLength);
62     ace_free(buffer);
63     buffer = nullptr;
64 }
65 
66 /**
67  * @tc.name: CacheDistributeTest002
68  * @tc.desc: Verify the cache distribution process
69  */
70 HWTEST_F(CacheManagerTddTest, CacheDistribute002, TestSize.Level1)
71 {
72     /**
73      * @tc.steps: step1. prepare cache buffer
74      */
75     const size_t totalSize = 20 * 1024; // 40KB
76     char *buffer = static_cast<char *>(ace_malloc(sizeof(char) * totalSize));
77     if (buffer == nullptr) {
78         return;
79     }
80     const uint8_t pageFileBufLength = 6;
81     const uint8_t localizationBufLength = 8;
82     const CacheUnit customerCacheUnitTable[] = {
83         {USER_PAGE_FILE, pageFileBufLength},
84         {USER_LOCALIZATION, localizationBufLength},
85     };
86     /**
87      * @tc.steps: step2. trigger the cache setup
88      */
89     const size_t count = 2;
90     CacheManager::GetInstance().SetConfigTable(customerCacheUnitTable, count);
91     uintptr_t startAddr = reinterpret_cast<uintptr_t>(buffer);
92     CacheManager::GetInstance().SetupCacheMemInfo(startAddr, totalSize);
93     /**
94      * @tc.steps: step3. verify the result
95      */
96     uintptr_t bufferPos = CacheManager::GetInstance().GetCacheBufAddress(CacheUser::USER_LOCALIZATION);
97     size_t bufSize = CacheManager::GetInstance().GetCacheBufLength(CacheUser::USER_LOCALIZATION);
98     const size_t unit = 1024;
99     const uint8_t magicNumberCount = MAGIC_NUMBER_COUNT;
100     uintptr_t targetPos =
101         startAddr + (pageFileBufLength * unit) + (magicNumberCount * MAGIC_NUMBER_LENGTH) + MAGIC_NUMBER_LENGTH;
102     const size_t targetLength = localizationBufLength * unit;
103     EXPECT_EQ(bufferPos, targetPos);
104     EXPECT_EQ(bufSize, targetLength);
105     ace_free(buffer);
106     buffer = nullptr;
107 }
108 
109 /**
110  * @tc.name: CacheDistributeTest003
111  * @tc.desc: Verify the cache distribution process
112  */
113 HWTEST_F(CacheManagerTddTest, CacheDistribute003, TestSize.Level1)
114 {
115     /**
116      * @tc.steps: step1. prepare cache buffer
117      */
118     const size_t totalSize = 2 * 1024; // 2KB
119     char *buffer = static_cast<char *>(ace_malloc(sizeof(char) * totalSize));
120     if (buffer == nullptr) {
121         return;
122     }
123 
124     /**
125      * @tc.steps: step2. trigger the cache setup
126      */
127     uintptr_t startAddr = reinterpret_cast<uintptr_t>(buffer);
128     CacheManager::GetInstance().SetupCacheMemInfo(startAddr, totalSize);
129     /**
130      * @tc.steps: step3. verify the result
131      */
132     uintptr_t localPos = CacheManager::GetInstance().GetCacheBufAddress(CacheUser::USER_LOCALIZATION);
133     size_t localBufSize = CacheManager::GetInstance().GetCacheBufLength(CacheUser::USER_LOCALIZATION);
134     EXPECT_EQ(localPos, 0);
135     EXPECT_EQ(localBufSize, 0);
136     ace_free(buffer);
137     buffer = nullptr;
138 }
139 
140 /**
141  * @tc.name: CacheDistributeTest004
142  * @tc.desc: Verify the cache distribution process
143  */
144 HWTEST_F(CacheManagerTddTest, CacheDistribute004, TestSize.Level1)
145 {
146     /**
147      * @tc.steps: step1. prepare cache buffer
148      */
149     const size_t totalSize = 20 * 1024; // 20KB
150     char *buffer = static_cast<char *>(ace_malloc(sizeof(char) * totalSize));
151     if (buffer == nullptr) {
152         return;
153     }
154 
155     /**
156      * @tc.steps: step2. trigger the cache setup
157      */
158     uintptr_t startAddr = reinterpret_cast<uintptr_t>(buffer);
159     CacheManager::GetInstance().SetupCacheMemInfo(startAddr, totalSize);
160     /**
161      * @tc.steps: step3. verify the result
162      */
163     uintptr_t bufStartPos = CacheManager::GetInstance().GetCacheBufAddress(CacheUser::USER_LOCALIZATION);
164     size_t bufLength = CacheManager::GetInstance().GetCacheBufLength(CacheUser::USER_LOCALIZATION);
165     uint32_t headMagicNumber = *reinterpret_cast<uint32_t *>(bufStartPos - MAGIC_NUMBER_LENGTH);
166     EXPECT_EQ(headMagicNumber, CACHE_MEM_MAGIC_NUMBER);
167     uint32_t tailMagicNumber = *reinterpret_cast<uint32_t *>(bufStartPos + bufLength);
168     EXPECT_EQ(tailMagicNumber, CACHE_MEM_MAGIC_NUMBER);
169     ace_free(buffer);
170     buffer = nullptr;
171 }
172 
173 /**
174  * @tc.name: CacheDistributeTest005
175  * @tc.desc: Verify the cache distribution process and overflow checking
176  */
177 HWTEST_F(CacheManagerTddTest, CacheDistribute005, TestSize.Level0)
178 {
179     /**
180      * @tc.steps: step1. prepare cache buffer
181      */
182     const size_t totalSize = 20 * 1024; // 20KB
183     char *buffer = static_cast<char *>(ace_malloc(sizeof(char) * totalSize));
184     if (buffer == nullptr) {
185         return;
186     }
187 
188     /**
189      * @tc.steps: step2. trigger the cache setup
190      */
191     uintptr_t startAddr = reinterpret_cast<uintptr_t>(buffer);
192     CacheManager::GetInstance().SetupCacheMemInfo(startAddr, totalSize);
193     size_t bufLength = CacheManager::GetInstance().GetCacheBufLength(CacheUser::USER_LOCALIZATION);
194     if (bufLength < MAGIC_NUMBER_LENGTH) {
195         ace_free(buffer);
196         buffer = nullptr;
197         return;
198     }
199     /**
200      * @tc.steps: step3. overflow the cache head and tail
201      */
202     buffer[0] = 0x11;
203     size_t tailPos = bufLength - MAGIC_NUMBER_LENGTH;
204     buffer[tailPos] = 0x22;
205     EXPECT_TRUE(CacheManager::GetInstance().IsCacheOverflow(CacheUser::USER_LOCALIZATION));
206     EXPECT_FALSE(CacheManager::GetInstance().IsWholeCacheHealthy());
207     ace_free(buffer);
208     buffer = nullptr;
209 }
210 
211 /**
212  * @tc.name: CacheDistributeTest006
213  * @tc.desc: Verify the cache distribution process, considering the magic number length
214  */
215 HWTEST_F(CacheManagerTddTest, CacheDistribute006, TestSize.Level1)
216 {
217     /**
218      * @tc.steps: step1. prepare cache buffer
219      */
220     const size_t totalSize = 16 * 1024; // 16KB, the total length equals to the requirement
221     char *buffer = static_cast<char *>(ace_malloc(sizeof(char) * totalSize));
222     if (buffer == nullptr) {
223         return;
224     }
225 
226     /**
227      * @tc.steps: step2. trigger the cache setup, will failed, as no extra space for the magic numbers
228      */
229     uintptr_t startAddr = reinterpret_cast<uintptr_t>(buffer);
230     CacheManager::GetInstance().SetupCacheMemInfo(startAddr, totalSize);
231 
232     /**
233      * @tc.steps: step3. check the result, the distributing will fail
234      */
235     uintptr_t bufStartPos = CacheManager::GetInstance().GetCacheBufAddress(CacheUser::USER_LOCALIZATION);
236     size_t bufLength = CacheManager::GetInstance().GetCacheBufLength(CacheUser::USER_LOCALIZATION);
237     EXPECT_EQ(bufStartPos, 0);
238     EXPECT_EQ(bufLength, 0);
239     ace_free(buffer);
240     buffer = nullptr;
241 }
242 
243 /**
244  * used for debugging TDD implementation on simulator
245  */
RunTests()246 void CacheManagerTddTest::RunTests()
247 {
248 #ifndef TDD_ASSERTIONS
249     CacheDistribute001();
250     CacheDistribute002();
251     CacheDistribute003();
252     CacheDistribute004();
253     CacheDistribute005();
254     CacheDistribute006();
255 #endif // TDD_ASSERTIONS
256 }
257 } // namespace ACELite
258 } // namespace OHOS
259