• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <gtest/gtest.h>
16 #include <map>
17 #include <unistd.h>
18 #include <vector>
19 #include <v1_0/imemory_tracker_interface.h>
20 
21 #define private public
22 #include "executor/memory_dumper.h"
23 #undef private
24 #include "dump_client_main.h"
25 #include "dump_utils.h"
26 #include "hdf_base.h"
27 #include "executor/memory/memory_filter.h"
28 #include "executor/memory/memory_util.h"
29 #include "hidumper_test_utils.h"
30 #include "util/string_utils.h"
31 
32 using namespace testing::ext;
33 using namespace OHOS::HDI::Memorytracker::V1_0;
34 namespace OHOS {
35 namespace HiviewDFX {
36 class MemoryDumperTest : public testing::Test {
37 public:
38     static void SetUpTestCase(void);
39     static void TearDownTestCase(void);
40     void SetUp();
41     void TearDown();
42 };
43 
SetUpTestCase(void)44 void MemoryDumperTest::SetUpTestCase(void)
45 {
46 }
TearDownTestCase(void)47 void MemoryDumperTest::TearDownTestCase(void)
48 {
49 }
SetUp(void)50 void MemoryDumperTest::SetUp(void)
51 {
52 }
TearDown(void)53 void MemoryDumperTest::TearDown(void)
54 {
55 }
56 
57 /**
58  * @tc.name: MemoryDumperTest001
59  * @tc.desc: Test MemoryDumper has correct group.
60  * @tc.type: FUNC
61  * @tc.require: issueI5NWZQ
62  */
63 HWTEST_F(MemoryDumperTest, MemoryDumperTest001, TestSize.Level3)
64 {
65     std::string cmd = "hidumper --mem";
66     std::string str = "Anonymous Page";
67     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
68 }
69 
70 /**
71  * @tc.name: MemoryDumperTest002
72  * @tc.desc: Test MemoryDumper has DMA group.
73  * @tc.type: FUNC
74  * @tc.require: issueI5NX04
75  */
76 HWTEST_F(MemoryDumperTest, MemoryDumperTest002, TestSize.Level3)
77 {
78     std::string cmd = "hidumper --mem";
79     std::string str = "DMA";
80     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
81 }
82 
83 /**
84  * @tc.name: MemoryDumperTest003
85  * @tc.desc: Test MemoryDumper has correct group.
86  * @tc.type: FUNC
87  * @tc.require: issueI5NWZQ
88  */
89 HWTEST_F(MemoryDumperTest, MemoryDumperTest003, TestSize.Level3)
90 {
91     std::string cmd = "hidumper --mem 1";
92     std::string str = "Total";
93     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
94     str = "native heap:";
95     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
96     str = "Purgeable:";
97     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
98     str = "        PurgSum:0 kB";
99     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
100     str = "        PurgPin:0 kB";
101     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
102     str = "DMA:";
103     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
104 }
105 
106 /**
107  * @tc.name: MemoryDumperTest004
108  * @tc.desc: Test MemoryDumper has GPU group.
109  * @tc.type: FUNC
110  * @tc.require: issueI5NWZQ
111  */
112 HWTEST_F(MemoryDumperTest, MemoryDumperTest004, TestSize.Level3)
113 {
114     std::string cmd = "hidumper --mem";
115     std::string str = "GPU";
116     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
117 }
118 
119 /**
120  * @tc.name: MemoryDumperTest005
121  * @tc.desc: Test MemoryDumper has Purgeable group.
122  * @tc.type: FUNC
123  * @tc.require: issueI5NWZQ
124  */
125 HWTEST_F(MemoryDumperTest, MemoryDumperTest005, TestSize.Level3)
126 {
127     std::string cmd = "hidumper --mem";
128     std::string str = "Total Purgeable";
129     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
130     str = "Total PurgSum";
131     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
132     str = "Total PurgPin";
133     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
134 }
135 
136 /**
137  * @tc.name: MemoryDumperTest006
138  * @tc.desc: Test MemoryDumper has Dma/PurgSum/PurgPin group.
139  * @tc.type: FUNC
140  * @tc.require: issueI5NWZQ
141  */
142 HWTEST_F(MemoryDumperTest, MemoryDumperTest006, TestSize.Level3)
143 {
144     std::string cmd = "hidumper --mem";
145     std::string str = "Dma      PurgSum      PurgPin";
146     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
147 }
148 
149 /**
150  * @tc.name: MemoryDumperTest007
151  * @tc.desc: Test zip memory not contain "Total Memory Usage by PID".
152  * @tc.type: FUNC
153  * @tc.require: issueI5NWZQ
154  */
155 HWTEST_F(MemoryDumperTest, MemoryDumperTest007, TestSize.Level3)
156 {
157     std::string cmd = "hidumper --mem --zip";
158     std::string str = "Total Memory Usage by PID";
159     ASSERT_FALSE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
160 }
161 
162 /**
163  * @tc.name: MemoryDumperTest008
164  * @tc.desc: Test dma is equal graph.
165  * @tc.type: FUNC
166  * @tc.require: issueI5NWZQ
167  */
168 HWTEST_F(MemoryDumperTest, MemoryDumperTest008, TestSize.Level3)
169 {
170     auto rsPid = static_cast<int32_t>(HidumperTestUtils::GetInstance().GetPidByName("render_service"));
171     int pid = rsPid > 0 ? rsPid : 1;
172     ASSERT_GT(pid, 0);
173     std::string cmd = "hidumper --mem " + std::to_string(pid);
174     std::string str = "Graph";
175     std::string result = "";
176     ASSERT_TRUE(HidumperTestUtils::GetInstance().GetSpecialLine(cmd, str, result));
177     std::string graphPss = HidumperTestUtils::GetInstance().GetValueInLine(result, 1);
178     ASSERT_TRUE(IsNumericStr(graphPss));
179     str = "Dma";
180     result = "";
181     ASSERT_TRUE(HidumperTestUtils::GetInstance().GetSpecialLine(cmd, str, result));
182     vector<string> values;
183     StringUtils::GetInstance().StringSplit(result, ":", values); // Dma:0 kB
184     std::string dmaStr = "";
185     if (!values.empty() && values.size() >= 2) { // 2: Dma, 0 kB
186         dmaStr = values[1];
187         if (dmaStr.size() >= 3) {
188             dmaStr = dmaStr.substr(0, dmaStr.size() - 4);  // 4: ' kB' + 1(index from to 0,1,2...)
189             ASSERT_TRUE(IsNumericStr(dmaStr));
190         }
191     }
192     ASSERT_TRUE(graphPss == dmaStr);
193 }
194 
195 /**
196  * @tc.name: MemoryDumperTest009
197  * @tc.desc: Test GL not out of bounds.
198  * @tc.type: FUNC
199  * @tc.require: issueI5NWZQ
200  */
201 HWTEST_F(MemoryDumperTest, MemoryDumperTest009, TestSize.Level3)
202 {
203     auto rsPid = static_cast<int32_t>(HidumperTestUtils::GetInstance().GetPidByName("render_service"));
204     int pid = rsPid > 0 ? rsPid : 1;
205     ASSERT_GT(pid, 0);
206     std::string cmd = "hidumper --mem " + std::to_string(pid);
207     std::string str = "GL";
208     std::string result = "";
209     ASSERT_TRUE(HidumperTestUtils::GetInstance().GetSpecialLine(cmd, str, result));
210     std::string glPss = HidumperTestUtils::GetInstance().GetValueInLine(result, 1);
211     ASSERT_TRUE(IsNumericStr(glPss));
212     uint64_t gl = static_cast<uint64_t>(std::stoi(glPss));
213     ASSERT_FALSE(gl < 0 || gl > UINT64_MAX);
214 }
215 
216 /**
217  * @tc.name: MemoryDumperTest010
218  * @tc.desc: Test HeapSize for "hidumper --mem `pidof com.ohos.sceneboard`"".
219  * @tc.type: FUNC
220  * @tc.require: issueI5NWZQ
221  */
222 HWTEST_F(MemoryDumperTest, MemoryDumperTest010, TestSize.Level3)
223 {
224     auto sceneboardPid = static_cast<int32_t>(HidumperTestUtils::GetInstance().GetPidByName("com.ohos.sceneboard"));
225     int pid = sceneboardPid > 0 ? sceneboardPid : 1;
226     ASSERT_GT(pid, 0);
227     std::string cmd = "hidumper --mem " + std::to_string(pid);
228     std::string str = "native heap";
229     std::string result = "";
230     ASSERT_TRUE(HidumperTestUtils::GetInstance().GetSpecialLine(cmd, str, result));
231     // 9: HeapSize index
232     std::string nativeHeapSizeStr = HidumperTestUtils::GetInstance().GetValueInLine(result, 9);
233     ASSERT_TRUE(IsNumericStr(nativeHeapSizeStr));
234     if (DumpUtils::IsHmKernel()) {
235         uint64_t nativeHeapSize = static_cast<uint64_t>(std::stoi(nativeHeapSizeStr));
236         ASSERT_TRUE(nativeHeapSize > 0);
237     }
238 }
239 
240 /**
241  * @tc.name: MemoryDumperTest011
242  * @tc.desc: Test MemoryDumper has correct print.
243  * @tc.type: FUNC
244  * @tc.require: issueI5NWZQ
245  */
246 HWTEST_F(MemoryDumperTest, MemoryDumperTest011, TestSize.Level3)
247 {
248     std::string cmd = "hidumper --mem";
249     std::string str = "-------------------------------[memory]-------------------------------";
250     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
251     str = "Total Memory Usage by PID:";
252     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
253     std::string titleTmp = "PID        Total Pss(xxx in SwapPss)    Total Vss    Total Rss    Total Uss";
254     str = titleTmp + "           GL        Graph          Dma      PurgSum      PurgPin     Name";
255     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
256     str = "Total Memory Usage by Size:";
257     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
258     str = "Total Pss by OOM adjustment:";
259     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
260 }
261 
262 /**
263  * @tc.name: MemoryDumperTest012
264  * @tc.desc: Test --mem-smaps has correct print.
265  * @tc.type: FUNC
266  * @tc.require: issueI5NWZQ
267  */
268 HWTEST_F(MemoryDumperTest, MemoryDumperTest012, TestSize.Level3)
269 {
270     std::string cmd = "hidumper --mem-smaps 1";
271     std::string str = "-------------------------------[memory]-------------------------------";
272     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
273     std::string titleTmp = "Size        Rss         Pss         Clean       Dirty       Clean       Dirty";
274     str = titleTmp + "       Swap        SwapPss     Counts      Category                         Name";
275     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
276     str = ".so                              /system";
277     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
278     str = "                                 Summary";
279     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
280 }
281 
282 /**
283  * @tc.name: MemoryDumperTest013
284  * @tc.desc: Test --mem-smaps -v has correct print.
285  * @tc.type: FUNC
286  * @tc.require: issueI5NWZQ
287  */
288 HWTEST_F(MemoryDumperTest, MemoryDumperTest013, TestSize.Level3)
289 {
290     std::string cmd = "hidumper --mem-smaps 1 -v";
291     std::string str = "-------------------------------[memory]-------------------------------";
292     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
293     std::string titleTmp = "Size        Rss         Pss         Clean       Dirty       Clean       Dirty       Swap";
294     str = titleTmp + "        SwapPss     Perm        Start             End         Category                   Name";
295     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
296     str = "dev                        /dev";
297     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
298     str = "                                 Summary";
299     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
300 }
301 
302 /**
303  * @tc.name: MemoryDumperTest014
304  * @tc.desc: Test hidumper --mem --prune has correct print.
305  * @tc.type: FUNC
306  * @tc.require: issueI5NWZQ
307  */
308 HWTEST_F(MemoryDumperTest, MemoryDumperTest014, TestSize.Level3)
309 {
310     std::string cmd = "hidumper --mem --prune";
311     std::string str = "-------------------------------[memory]-------------------------------";
312     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
313     str = "Total Memory Usage by PID:";
314     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
315     str = "PID        Total Pss(xxx in SwapPss)           GL     AdjLabel     Name";
316     ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str));
317 }
318 
319 /**
320  * @tc.name: MemoryUtilTest001
321  * @tc.desc: Test IsNameLine has correct ret.
322  * @tc.type: FUNC
323  */
324 HWTEST_F(MemoryDumperTest, MemoryUtilTest001, TestSize.Level1)
325 {
326     const std::string valueLine = "Rss:                  24 kB";
327     std::string name;
328     uint64_t iNode = 0;
329     ASSERT_FALSE(MemoryUtil::GetInstance().IsNameLine(valueLine, name, iNode));
330     ASSERT_EQ(name, "");
331     const std::string nameLine = "ffb84000-ffba5000 rw-p 00000000 00:00 0                                  [stack]";
332     ASSERT_TRUE(MemoryUtil::GetInstance().IsNameLine(nameLine, name, iNode));
333     ASSERT_EQ(name, "[stack]");
334 }
335 
336 /**
337  * @tc.name: MemoryUtilTest002
338  * @tc.desc: Test GetTypeAndValue has correct ret.
339  * @tc.type: FUNC
340  */
341 HWTEST_F(MemoryDumperTest, MemoryUtilTest002, TestSize.Level1)
342 {
343     std::string type;
344     uint64_t value = 0;
345     const std::string illegalStr = "aaaaaa";
346     ASSERT_FALSE(MemoryUtil::GetInstance().GetTypeAndValue(illegalStr, type, value));
347     const std::string valueStr = "MemTotal:        2010244 kB";
348     ASSERT_TRUE(MemoryUtil::GetInstance().GetTypeAndValue(valueStr, type, value));
349     ASSERT_EQ(type, "MemTotal");
350     ASSERT_EQ(value, 2010244);
351 }
352 
353 /**
354  * @tc.name: MemoryUtilTest003
355  * @tc.desc: Test RunCMD has correct ret.
356  * @tc.type: FUNC
357  */
358 HWTEST_F(MemoryDumperTest, MemoryUtilTest003, TestSize.Level1)
359 {
360     const std::string cmd = "ps -ef";
361     std::vector<std::string> vec;
362     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
363     ASSERT_GT(vec.size(), 0);
364 }
365 
366 /**
367  * @tc.name: MemoryUtilTest004
368  * @tc.desc: Test hidumper some cmd.
369  * @tc.type: FUNC
370  */
371 HWTEST_F(MemoryDumperTest, MemoryUtilTest004, TestSize.Level1)
372 {
373     std::string cmd = "hidumper --mem-smaps 1";
374     std::vector<std::string> vec;
375     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
376     cmd = "hidumper --mem-smaps 1 -v";
377     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
378     cmd = "hidumper --net 1";
379     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
380     cmd = "hidumper --storage 1";
381     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
382 }
383 
384 /**
385  * @tc.name: MemoryUtilTest005
386  * @tc.desc: Test no such pid.
387  * @tc.type: FUNC
388  */
389 HWTEST_F(MemoryDumperTest, MemoryUtilTest005, TestSize.Level1)
390 {
391     std::string cmd = "hidumper --mem-smaps 100000";
392     std::vector<std::string> vec;
393     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
394     cmd = "hidumper --mem-smaps 100000 -v";
395     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
396     cmd = "hidumper --cpuusage 100000";
397     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
398     cmd = "hidumper --mem 100000";
399     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
400     cmd = "hidumper -p 100000";
401     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
402     cmd = "hidumper --storage 100000";
403     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
404     cmd = "hidumper --net 100000";
405     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
406     cmd = "hidumper --mem-jsheap 100000";
407     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
408     cmd = "hidumper --mem-jsheap 0";
409     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
410     cmd = "hidumper --mem-cjheap 100000";
411     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
412     cmd = "hidumper --mem-cjheap 0";
413     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
414     cmd = "hidumper --ipc --stat 100000";
415     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
416 }
417 
418 /**
419  * @tc.name: MemoryUtilTest006
420  * @tc.desc: Test hidumper process exit success.
421  * @tc.type: FUNC
422  */
423 HWTEST_F(MemoryDumperTest, MemoryUtilTest006, TestSize.Level1)
424 {
425     std::vector<std::string> vec;
426     std::string cmd = "hidumper -h";
427     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
428     ASSERT_GT(vec.size(), 0);
429     vec.clear();
430     cmd = "pidof hidumper";
431     ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec));
432     ASSERT_EQ(vec.size(), 0);
433 }
434 } // namespace HiviewDFX
435 } // namespace OHOS