• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include <cstdio>
17 #include <climits>
18 #include <thread>
19 
20 #include "gtest/gtest.h"
21 #include "purgeable_memory.h"
22 
23 namespace {
24 using namespace testing;
25 using namespace testing::ext;
26 
27 struct AlphabetInitParam {
28     char start;
29     char end;
30 };
31 
32 struct AlphabetModifyParam {
33     char src;
34     char dst;
35 };
36 
37 static constexpr int PRINT_INTERVAL_SECONDS = 1;
38 static constexpr int RECLAIM_INTERVAL_SECONDS = 1;
39 static constexpr int MODIFY_INTERVAL_SECONDS = 2;
40 
41 bool InitData(void *data, size_t size, char start, char end);
42 bool ModifyData(void *data, size_t size, char src, char dst);
43 bool InitAlphabet(void *data, size_t size, void *param);
44 bool ModifyAlphabetX2Y(void *data, size_t size, void *param);
45 void LoopPrintAlphabet(OH_PurgeableMemory *pdata, unsigned int loopCount);
46 bool ReclaimPurgeable(void);
47 void LoopReclaimPurgeable(unsigned int loopCount);
48 void ModifyPurgMemByFunc(OH_PurgeableMemory *pdata, OH_PurgeableMemory_ModifyFunc Modfunc, void *param);
49 
50 class PurgeableMemoryTest : public testing::Test {
51 public:
52     static void SetUpTestCase();
53     static void TearDownTestCase();
54     void SetUp() override;
55     void TearDown() override;
56 };
57 
SetUpTestCase()58 void PurgeableMemoryTest::SetUpTestCase()
59 {
60 }
61 
TearDownTestCase()62 void PurgeableMemoryTest::TearDownTestCase()
63 {
64 }
65 
SetUp()66 void PurgeableMemoryTest::SetUp()
67 {
68 }
69 
TearDown()70 void PurgeableMemoryTest::TearDown()
71 {
72 }
73 
74 HWTEST_F(PurgeableMemoryTest, MultiObjCreateTest, TestSize.Level1)
75 {
76     const char alphabetFinal[] = "BBCDEFGHIJKLMNOPQRSTUVWXYZ\0";
77     struct AlphabetInitParam initPara = {'A', 'Z'};
78     OH_PurgeableMemory *pobj1 = OH_PurgeableMemory_Create(27, InitAlphabet, &initPara);
79     LoopPrintAlphabet(pobj1, 1);
80     struct AlphabetModifyParam a2b = {'A', 'B'};
81     ModifyPurgMemByFunc(pobj1, ModifyAlphabetX2Y, static_cast<void *>(&a2b));
82     LoopPrintAlphabet(pobj1, 1);
83     LoopReclaimPurgeable(1);
84 
85     if (OH_PurgeableMemory_BeginRead(pobj1)) {
86         ASSERT_STREQ(alphabetFinal, static_cast<char *>(OH_PurgeableMemory_GetContent(pobj1)));
87         OH_PurgeableMemory_EndRead(pobj1);
88     }
89 
90     EXPECT_EQ(OH_PurgeableMemory_Destroy(pobj1), true);
91 }
92 
93 
94 HWTEST_F(PurgeableMemoryTest, WriteTest, TestSize.Level1)
95 {
96     const char alphabet[] = "CCCDEFGHIJKLMNOPQRSTUVWXYZ\0";
97     struct AlphabetInitParam initPara = {'A', 'Z'};
98     OH_PurgeableMemory *pobj = OH_PurgeableMemory_Create(27, InitAlphabet, &initPara);
99     LoopReclaimPurgeable(1);
100 
101     struct AlphabetModifyParam a2b = {'A', 'B'};
102     struct AlphabetModifyParam b2c = {'B', 'C'};
103     ModifyPurgMemByFunc(pobj, ModifyAlphabetX2Y, static_cast<void *>(&a2b));
104     ModifyPurgMemByFunc(pobj, ModifyAlphabetX2Y, static_cast<void *>(&b2c));
105 
106     if (OH_PurgeableMemory_BeginRead(pobj)) {
107         ASSERT_STREQ(alphabet, static_cast<char *>(OH_PurgeableMemory_GetContent(pobj)));
108         OH_PurgeableMemory_EndRead(pobj);
109     } else {
110         std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
111     }
112 
113     OH_PurgeableMemory_Destroy(pobj);
114     LoopReclaimPurgeable(3);
115 }
116 
InitData(void * data,size_t size,char start,char end)117 bool InitData(void *data, size_t size, char start, char end)
118 {
119     char *str = (char *)data;
120     size_t len = 0;
121     for (char ch = start; ch <= end && len < size; ch++) {
122         str[len++] = ch;
123     }
124     str[len] = 0;
125     return true;
126 }
127 
InitAlphabet(void * data,size_t size,void * param)128 bool InitAlphabet(void *data, size_t size, void *param)
129 {
130     struct AlphabetInitParam *para = (struct AlphabetInitParam *)param;
131     std::cout << "inter " << __func__ << std::endl;
132     bool ret = InitData(data, size, para->start, para->end);
133     std::cout << "quit " << __func__ << ": " << para->start << "-" << para->end <<
134         ", data=[" << (char *)data << "]" << ", ret=" << (ret ? "true" : "false") << std::endl;
135     return ret;
136 }
137 
ModifyData(void * data,size_t size,char src,char dst)138 bool ModifyData(void *data, size_t size, char src, char dst)
139 {
140     char *str = (char *)data;
141     size_t i = 0;
142     for (; i < size && str[i]; i++) {
143         if (str[i] == src) {
144             str[i] = dst;
145         }
146     }
147     str[i] = 0;
148     return true;
149 }
150 
ModifyAlphabetX2Y(void * data,size_t size,void * param)151 bool ModifyAlphabetX2Y(void *data, size_t size, void *param)
152 {
153     struct AlphabetModifyParam *para = (struct AlphabetModifyParam *)param;
154     std::cout << "inter " << __func__ << ": " << para->src << "->" << para->dst <<
155         ", data=[" << (char *)data << "]" << std::endl;
156     bool ret = ModifyData(data, size, para->src, para->dst);
157     std::cout << "quit , data=[" << (char *)data << "]" << __func__ <<
158         ", ret=" << (ret ? "true" : "false") << std::endl;
159     return ret;
160 }
161 
LoopPrintAlphabet(OH_PurgeableMemory * pdata,unsigned int loopCount)162 void LoopPrintAlphabet(OH_PurgeableMemory *pdata, unsigned int loopCount)
163 {
164     std::cout << "inter " << __func__ << std::endl;
165     for (unsigned int i = 0; i < loopCount; i++) {
166         if (!OH_PurgeableMemory_BeginRead(pdata)) {
167             std::cout << __func__ << ": " << i << ". ERROR! BeginRead failed." << std::endl;
168             break;
169         }
170         std::cout << __func__ << ": " << i << ". data=[" <<
171             (char *)OH_PurgeableMemory_GetContent(pdata) << "]" << std::endl;
172         OH_PurgeableMemory_EndRead(pdata);
173         std::this_thread::sleep_for(std::chrono::seconds(PRINT_INTERVAL_SECONDS));
174     }
175     std::cout << "quit " << __func__ << std::endl;
176 }
177 
ReclaimPurgeable(void)178 bool ReclaimPurgeable(void)
179 {
180     FILE *f = fopen("/proc/sys/kernel/purgeable", "w");
181     if (!f) {
182         std::cout << __func__ << ": open file failed" << std::endl;
183         return false;
184     }
185     bool succ = true;
186     if (fputs("1", f) == EOF) {
187         succ = false;
188     }
189 
190     if (fclose(f) == EOF) {
191         std::cout << __func__ << ": close file failed" << std::endl;
192     }
193 
194     return succ;
195 }
196 
LoopReclaimPurgeable(unsigned int loopCount)197 void LoopReclaimPurgeable(unsigned int loopCount)
198 {
199     bool ret = false;
200     std::cout << "inter " << __func__ << std::endl;
201     for (unsigned int i = 0; i < loopCount; i++) {
202         ret = ReclaimPurgeable();
203         std::cout << __func__ << ": " << i << ". Reclaim result=" << (ret ? "succ" : "fail") << std::endl;
204         std::this_thread::sleep_for(std::chrono::seconds(RECLAIM_INTERVAL_SECONDS)); /* wait reclaim finish */
205     }
206     std::cout << "quit " << __func__ << std::endl;
207 }
208 
ModifyPurgMemByFunc(OH_PurgeableMemory * pdata,OH_PurgeableMemory_ModifyFunc Modfunc,void * param)209 void ModifyPurgMemByFunc(OH_PurgeableMemory *pdata, OH_PurgeableMemory_ModifyFunc Modfunc, void *param)
210 {
211     if (OH_PurgeableMemory_BeginWrite(pdata)) {
212         std::this_thread::sleep_for(std::chrono::seconds(MODIFY_INTERVAL_SECONDS));
213         OH_PurgeableMemory_AppendModify(pdata, Modfunc, param);
214         std::cout<< __func__ << " after mod data=[" << (char *)OH_PurgeableMemory_GetContent(pdata) << "]" << std::endl;
215 
216         std::cout << __func__ << " data=[" << (char *)OH_PurgeableMemory_GetContent(pdata) << "]" << std::endl;
217         OH_PurgeableMemory_EndWrite(pdata);
218     }
219 }
220 } /* namespace */
221