1 /*
2  * Copyright (c) 2022 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 "gtest/gtest.h"
17 #include "utils.h"
18 
19 #define private public
20 #define protected public
21 #include "kernel_interface.h"
22 #undef private
23 #undef protected
24 
25 namespace OHOS {
26 namespace Memory {
27 using namespace testing;
28 using namespace testing::ext;
29 
30 class KernelInterfaceTest : public testing::Test {
31 public:
32     static void SetUpTestCase();
33     static void TearDownTestCase();
34     void SetUp();
35     void TearDown();
36 };
37 
SetUpTestCase()38 void KernelInterfaceTest::SetUpTestCase()
39 {
40 }
41 
TearDownTestCase()42 void KernelInterfaceTest::TearDownTestCase()
43 {
44 }
45 
SetUp()46 void KernelInterfaceTest::SetUp()
47 {
48 }
49 
TearDown()50 void KernelInterfaceTest::TearDown()
51 {
52 }
53 
54 HWTEST_F(KernelInterfaceTest, EchoToPath_InvalidPath, TestSize.Level1)
55 {
56     bool ret = KernelInterface::GetInstance().EchoToPath("", "");
57     EXPECT_EQ(ret, false);
58 }
59 
60 HWTEST_F(KernelInterfaceTest, PathDelimiterAddAndRmTest, TestSize.Level1)
61 {
62     std::string base = "/test/tmp";
63     // add delimiter test
64     std::string pathWithDeli = KernelInterface::GetInstance().AddDelimiter(base);
65     EXPECT_EQ(pathWithDeli.compare(base + "/"), 0);
66 
67     std::string pathTmp = KernelInterface::GetInstance().AddDelimiter("");
68     EXPECT_EQ(pathTmp.length(), 0u);
69 
70     // rm delimiter test
71     pathTmp = KernelInterface::GetInstance().RmDelimiter(pathWithDeli);
72     EXPECT_EQ(pathTmp.compare(base), 0);
73 
74     pathTmp = KernelInterface::GetInstance().RmDelimiter("");
75     EXPECT_EQ(pathTmp.length(), 0u);
76 
77     pathTmp = KernelInterface::GetInstance().RmDelimiter(base);
78     EXPECT_EQ(pathTmp.compare(base), 0);
79 }
80 
81 HWTEST_F(KernelInterfaceTest, JoinPathTest, TestSize.Level1)
82 {
83     std::string first = "/test/tmp";
84     std::string second = "2";
85     std::string third = "3";
86     std::string empty = "";
87     // JoinPath with 2 param test
88     std::string path = KernelInterface::GetInstance().JoinPath(first, second);
89     EXPECT_EQ(path.compare(first + "/" + second), 0);
90     path = KernelInterface::GetInstance().JoinPath(empty, second);
91     EXPECT_EQ(path.compare(second), 0);
92     path = KernelInterface::GetInstance().JoinPath(first, empty);
93     EXPECT_EQ(path.compare(first + "/"), 0);
94     path = KernelInterface::GetInstance().JoinPath(empty, empty);
95     EXPECT_EQ(path.compare(empty), 0);
96 
97     // JoinPath with 3 param test
98     path = KernelInterface::GetInstance().JoinPath(first, second, third);
99     EXPECT_EQ(path.compare(first + "/" + second + "/" + third), 0);
100     path = KernelInterface::GetInstance().JoinPath(empty, second, third);
101     EXPECT_EQ(path.compare(second + "/" + third), 0);
102     path = KernelInterface::GetInstance().JoinPath(first, empty, third);
103     EXPECT_EQ(path.compare(first + "/" + third), 0);
104     path = KernelInterface::GetInstance().JoinPath(first, second, empty);
105     EXPECT_EQ(path.compare(first + "/" + second + "/"), 0);
106 
107     path = KernelInterface::GetInstance().JoinPath(empty, empty, third);
108     EXPECT_EQ(path.compare(third), 0);
109     path = KernelInterface::GetInstance().JoinPath(empty, second, empty);
110     EXPECT_EQ(path.compare(second + "/"), 0);
111     path = KernelInterface::GetInstance().JoinPath(first, empty, empty);
112     EXPECT_EQ(path.compare(first + "/"), 0);
113 
114     path = KernelInterface::GetInstance().JoinPath(empty, empty, empty);
115     EXPECT_EQ(path.compare(empty), 0);
116 }
117 
118 HWTEST_F(KernelInterfaceTest, FileCreateTest, TestSize.Level1)
119 {
120     const std::string BASE_PATH = "/data/local/tmp";
121     bool ret = KernelInterface::GetInstance().IsDirExists(BASE_PATH);
122     EXPECT_EQ(ret, true);
123 
124     std::string path = KernelInterface::GetInstance().JoinPath(BASE_PATH, "testFile");
125     ret = KernelInterface::GetInstance().CreateFile(path);
126     EXPECT_EQ(ret, true);
127     ret = KernelInterface::GetInstance().IsFileExists(path);
128     EXPECT_EQ(ret, true);
129     KernelInterface::GetInstance().RemoveFile(path);
130 }
131 
132 HWTEST_F(KernelInterfaceTest, FileRemoveTest, TestSize.Level1)
133 {
134     const std::string BASE_PATH = "/data/local/tmp";
135     std::string path = KernelInterface::GetInstance().JoinPath(BASE_PATH, "testFile");
136     KernelInterface::GetInstance().RemoveFile(path);
137     bool ret = KernelInterface::GetInstance().CreateFile(path);
138     ret = ret && KernelInterface::GetInstance().IsFileExists(path);
139     ret = ret && KernelInterface::GetInstance().RemoveFile(path);
140     EXPECT_EQ(ret, true);
141     ret = KernelInterface::GetInstance().IsFileExists(path);
142     EXPECT_EQ(ret, false);
143 }
144 
145 HWTEST_F(KernelInterfaceTest, SingleLineFileReadWriteTest, TestSize.Level1)
146 {
147     const std::string BASE_PATH = "/data/local/tmp";
148     std::string path = KernelInterface::GetInstance().JoinPath(BASE_PATH, "testFile");
149     KernelInterface::GetInstance().RemoveFile(path);
150     bool ret = KernelInterface::GetInstance().CreateFile(path);
151     ret = ret && KernelInterface::GetInstance().IsFileExists(path);
152     EXPECT_EQ(ret, true);
153     std::string line1 = "line1";
154     std::string output;
155 
156     ret = KernelInterface::GetInstance().WriteToFile(path, line1); // curr content: "line1"
157     ret = ret && KernelInterface::GetInstance().ReadFromFile(path, output);
158     EXPECT_EQ(ret, true);
159     EXPECT_EQ(output.compare(line1), 0);
160 
161     ret = KernelInterface::GetInstance().WriteToFile(path, line1, false); // curr content: "line1line1"
162     ret = ret && KernelInterface::GetInstance().ReadFromFile(path, output);
163     EXPECT_EQ(ret, true);
164     EXPECT_EQ(output.compare(line1 + line1), 0);
165 
166     ret = KernelInterface::GetInstance().WriteToFile(path, "", false); // curr content: "line1line1"
167     ret = ret && KernelInterface::GetInstance().ReadFromFile(path, output);
168     EXPECT_EQ(ret, true);
169     EXPECT_EQ(output.compare(line1 + line1), 0);
170 
171     ret = KernelInterface::GetInstance().WriteToFile(path, "", true); // curr content: ""
172     ret = ret && KernelInterface::GetInstance().ReadFromFile(path, output);
173     EXPECT_EQ(ret, true);
174     EXPECT_EQ(output.compare(""), 0);
175     KernelInterface::GetInstance().RemoveFile(path);
176 }
177 
178 HWTEST_F(KernelInterfaceTest, MultLinesFileReadWriteTest, TestSize.Level1)
179 {
180     const std::string BASE_PATH = "/data/local/tmp";
181     std::string path = KernelInterface::GetInstance().JoinPath(BASE_PATH, "testFile");
182     KernelInterface::GetInstance().RemoveFile(path);
183     bool ret = KernelInterface::GetInstance().CreateFile(path);
184     ret = ret && KernelInterface::GetInstance().IsFileExists(path);
185     EXPECT_EQ(ret, true);
186     std::string line1 = "line1";
187     std::string line2 = "line2";
188     std::string line3 = "line3";
189     std::string lines = line1 + "\n" + line2 + "\n" + line3; // "line1\nline2\nline3"
190     std::string output;
191 
192     ret = KernelInterface::GetInstance().WriteToFile(path, line1); // curr content: "line1"
193     ret = ret && KernelInterface::GetInstance().WriteToFile(path, "\n", false); // curr content: "line1\n"
194     ret = ret && KernelInterface::GetInstance().WriteToFile(path, line2, false); // curr content: "line1\nline2"
195     ret = ret && KernelInterface::GetInstance().ReadFromFile(path, output);
196     EXPECT_EQ(ret, true);
197     EXPECT_EQ(output.compare(line1 + "\n" + line2), 0);
198 
199     ret = KernelInterface::GetInstance().WriteToFile(path, lines); // curr content: "line1\nline2\nline3"
200     ret = ret && KernelInterface::GetInstance().ReadFromFile(path, output);
201     EXPECT_EQ(ret, true);
202     EXPECT_EQ(output.compare(lines), 0);
203     KernelInterface::GetInstance().RemoveFile(path);
204 }
205 
206 HWTEST_F(KernelInterfaceTest, NoSuchFileCreateTest, TestSize.Level1)
207 {
208     std::string basedir = "/NoSuchDir";
209     std::string path = "/NoSuchDir/file";
210     KernelInterface::GetInstance().RemoveDirRecursively(basedir);
211     bool ret = KernelInterface::GetInstance().CreateFile("");
212     ret = ret || KernelInterface::GetInstance().CreateFile(path);
213     ret = ret || KernelInterface::GetInstance().IsFileExists(path);
214     EXPECT_EQ(ret, false);
215 }
216 
217 HWTEST_F(KernelInterfaceTest, NoSuchFileRemoveTest, TestSize.Level1)
218 {
219     std::string basedir = "/NoSuchDir";
220     std::string path1 = "/NoSuchDir/file";
221     std::string path2 = "/proc/NoSuchFile";
222     KernelInterface::GetInstance().RemoveDirRecursively(basedir);
223     KernelInterface::GetInstance().RemoveFile(path2);
224     bool ret = KernelInterface::GetInstance().RemoveFile(path1);
225     ret = ret && KernelInterface::GetInstance().RemoveFile(path2);
226     EXPECT_EQ(ret, true);
227 }
228 
229 HWTEST_F(KernelInterfaceTest, NoSuchFileReadWriteTest, TestSize.Level1)
230 {
231     std::string path = "/NoSuchDir/NoSuchFile";
232     KernelInterface::GetInstance().RemoveFile(path);
233     std::string line1 = "line1";
234     std::string line2 = "line2";
235     std::string line3 = "line3";
236     std::string output;
237     std::vector<std::string> outputLines;
238     std::vector<std::string> inputLines = {line1, line2, line3};
239 
240     bool ret = KernelInterface::GetInstance().WriteToFile(path, line1, false);
241     ret = ret || KernelInterface::GetInstance().WriteToFile(path, line1);
242     ret = ret || KernelInterface::GetInstance().WriteToFile("", line1);
243     ret = ret || KernelInterface::GetInstance().ReadFromFile(path, output);
244     ret = ret || KernelInterface::GetInstance().ReadFromFile("", output);
245     EXPECT_EQ(ret, false);
246 
247     ret = ret || KernelInterface::GetInstance().ReadLinesFromFile(path, outputLines);
248     ret = ret || KernelInterface::GetInstance().ReadLinesFromFile("", outputLines);
249     EXPECT_EQ(ret, false);
250 }
251 
252 HWTEST_F(KernelInterfaceTest, DirCreateTest, TestSize.Level1)
253 {
254     const std::string BASE_PATH = "/data/local/tmp";
255     bool ret = KernelInterface::GetInstance().IsDirExists(BASE_PATH);
256     std::string path = KernelInterface::GetInstance().JoinPath(BASE_PATH, "testDir");
257     KernelInterface::GetInstance().RemoveDirRecursively(path);
258     ret = ret && KernelInterface::GetInstance().CreateDir(path);
259     ret = ret && KernelInterface::GetInstance().IsDirExists(path);
260     EXPECT_EQ(ret, true);
261     KernelInterface::GetInstance().RemoveDirRecursively(path);
262 
263     path = KernelInterface::GetInstance().JoinPath(path, "midDir", "subDir");
264     ret = ret && KernelInterface::GetInstance().CreateDir(path);
265     ret = ret && KernelInterface::GetInstance().IsDirExists(path);
266     EXPECT_EQ(ret, true);
267     KernelInterface::GetInstance().RemoveDirRecursively(path);
268 }
269 
270 HWTEST_F(KernelInterfaceTest, DirRemoveTest, TestSize.Level1)
271 {
272     const std::string BASE_PATH = "/data/local/tmp";
273     bool ret = KernelInterface::GetInstance().IsDirExists(BASE_PATH);
274     std::string basedir = KernelInterface::GetInstance().JoinPath(BASE_PATH, "testDir");
275     std::string subDir1 = KernelInterface::GetInstance().JoinPath(basedir, "subDir1");
276     std::string subDir2 = KernelInterface::GetInstance().JoinPath(basedir, "subDir2");
277     std::string file1 = KernelInterface::GetInstance().JoinPath(subDir1, "testFile1");
278     std::string file2 = KernelInterface::GetInstance().JoinPath(subDir2, "testFile2");
279     KernelInterface::GetInstance().CreateDir(subDir1); // ../testDir/subDir1/
280     KernelInterface::GetInstance().CreateFile(file1); // ../testDir/subDir1/testFile1
281 
282     ret = KernelInterface::GetInstance().RemoveDirRecursively(subDir1);
283     ret = ret && KernelInterface::GetInstance().IsEmptyDir(basedir);
284     EXPECT_EQ(ret, true);
285     ret = KernelInterface::GetInstance().IsDirExists(subDir1);
286     EXPECT_EQ(ret, false);
287 
288     KernelInterface::GetInstance().CreateDir(subDir1);
289     KernelInterface::GetInstance().CreateDir(subDir2); // ../testDir/subDir2/
290     KernelInterface::GetInstance().CreateFile(file1); // ../testDir/subDir1/testFile1
291     KernelInterface::GetInstance().CreateFile(file2); // ../testDir/subDir2/testFile2
292     ret = KernelInterface::GetInstance().RemoveDirRecursively(basedir);
293     EXPECT_EQ(ret, true);
294     ret = KernelInterface::GetInstance().IsDirExists(basedir);
295     EXPECT_EQ(ret, false);
296 }
297 
298 HWTEST_F(KernelInterfaceTest, GetPidProcInfoTest, TestSize.Level1)
299 {
300     ProcInfo procInfo;
301     procInfo.pid = 1;
302     bool ret = KernelInterface::GetInstance().GetPidProcInfo(procInfo);
303     printf("pid=[%d], name=[%s], status=[%s], size=[%d KB]\n",
304            procInfo.pid, procInfo.name.c_str(), procInfo.status.c_str(), procInfo.size);
305     EXPECT_EQ(ret, true);
306 }
307 
308 HWTEST_F(KernelInterfaceTest, GetCurrentBufferTest, TestSize.Level1)
309 {
310     int buffer = KernelInterface::GetInstance().GetCurrentBuffer();
311     printf("buffer=%d", buffer);
312     EXPECT_GT(buffer, 0);
313 }
314 
315 HWTEST_F(KernelInterfaceTest, ReadSwapOutKBSinceKernelBoot, TestSize.Level1)
316 {
317     unsigned long long retFun;
318     bool ret = KernelInterface::GetInstance().ReadSwapOutKBSinceKernelBoot("/dev/memcg/memory.eswap_info",
319                                                                                 "Total Swapout Size", retFun);
320     EXPECT_EQ(ret, true);
321 }
322 
323 HWTEST_F(KernelInterfaceTest, GetMemcgPidsTest, TestSize.Level1)
324 {
325     std::string memcgPath = "/dev/memcg";
326     std::vector<int> memcgPids;
327     bool ret = KernelInterface::GetInstance().GetMemcgPids(memcgPath, memcgPids);
328     printf("pids get from /dev/memcg/cgroup.procs is: ");
329     for (auto &it : memcgPids) {
330         printf("%d ", it);
331     }
332     printf("\n");
333     EXPECT_EQ(ret, true);
334 }
335 
336 HWTEST_F(KernelInterfaceTest, GetAllUserIdsTest, TestSize.Level1)
337 {
338     std::string memcgPath = "/dev/memcg";
339     std::vector<int> userIds;
340     bool ret = KernelInterface::GetInstance().GetAllUserIds(userIds);
341     printf("userIds get from /dev/memcg/ is: ");
342     for (auto &it : userIds) {
343         printf("%d ", it);
344     }
345     printf("\n");
346     EXPECT_EQ(ret, true);
347 }
348 
349 HWTEST_F(KernelInterfaceTest, SplitOneLineByDelimTest, TestSize.Level1)
350 {
351     std::string input = "process_name,pid,adj,fd,ashmem_name,size,id,time,ref_count,purged";
352     std::vector<std::string> res;
353     KernelInterface::GetInstance().SplitOneLineByDelim(input, ',', res);
354     ASSERT_EQ(res.size(), 10);
355     EXPECT_EQ(res[0], std::string("process_name"));
356     EXPECT_EQ(res[9], std::string("purged"));
357 }
358 
359 HWTEST_F(KernelInterfaceTest, SplitOneLineByBlankTest, TestSize.Level1)
360 {
361     std::string input = "Active(purg):         0 kB";
362     std::vector<std::string> res;
363     KernelInterface::GetInstance().SplitOneLineByBlank(input, res);
364     ASSERT_EQ(res.size(), 3);
365     EXPECT_EQ(res[0], std::string("Active(purg):"));
366     EXPECT_EQ(res[1], std::string("0"));
367     EXPECT_EQ(res[2], std::string("kB"));
368 
369     input = "PurgSum:   0 kB";
370     res.clear();
371     KernelInterface::GetInstance().SplitOneLineByBlank(input, res);
372     ASSERT_EQ(res.size(), 3);
373     EXPECT_EQ(res[0], std::string("PurgSum:"));
374     EXPECT_EQ(res[1], std::string("0"));
375     EXPECT_EQ(res[2], std::string("kB"));
376 }
377 } //namespace Memory
378 } //namespace OHOS
379