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 "dump_usage.h"
17 #include "cpu_dumper.h"
18 #include "executor/memory/get_heap_info.h"
19 #include "executor/memory/memory_info.h"
20 #include "executor/memory/parse/parse_smaps_info.h"
21 #include "securec.h"
22
23 #include <gtest/gtest.h>
24 #include <unistd.h>
25
26 using namespace testing::ext;
27 namespace OHOS {
28 namespace HiviewDFX {
29 static constexpr int MALLOC_SIZE = 1024;
30 static constexpr int LAUNCHER_PID_BUFFER_SIZE = 6;
31 static int g_pid = -1;
32 static int g_appManagerPid = -1;
33 class HiDumperInnerkitsTest : public testing::Test {
34 public:
35 using ValueMap = std::map<std::string, uint64_t>;
36 using GroupMap = std::map<std::string, ValueMap>;
37 static void SetUpTestCase(void);
38 static void TearDownTestCase(void);
39 void SetUp();
40 void TearDown();
41 static void GetAppManagerPids();
42 static int GetAppManagerPid(std::string process);
43 static void StartTestProcess();
44 static void StopProcess();
45 };
46
SetUpTestCase(void)47 void HiDumperInnerkitsTest::SetUpTestCase(void)
48 {
49 GetAppManagerPids();
50 StartTestProcess();
51 if (g_pid < 0) {
52 printf("[SetUpTestCase] fork process failure!\n");
53 return;
54 }
55 if (g_pid == 0) {
56 printf("[SetUpTestCase] this process's pid is %d, it's should be child process\n", getpid());
57 return;
58 }
59 }
TearDownTestCase(void)60 void HiDumperInnerkitsTest::TearDownTestCase(void)
61 {
62 if (g_pid < 0) {
63 printf("[TearDownTestCase] fork process failure!\n");
64 return;
65 }
66 if (g_pid == 0) {
67 printf("[TearDownTestCase] this process's pid is %d, it's should be child process\n", getpid());
68 return;
69 }
70 StopProcess();
71 }
SetUp(void)72 void HiDumperInnerkitsTest::SetUp(void)
73 {
74 }
TearDown(void)75 void HiDumperInnerkitsTest::TearDown(void)
76 {
77 }
78
StartTestProcess()79 void HiDumperInnerkitsTest::StartTestProcess()
80 {
81 int processNum = fork();
82 if (processNum == 0) {
83 while (true) {
84 void* p = malloc(MALLOC_SIZE);
85 if (p == nullptr) {
86 const int bufSize = 256;
87 char buf[bufSize] = { 0 };
88 (void)strerror_r(errno, buf, bufSize);
89 printf("malloc failure, errno(%d:%s)", errno, buf);
90 return;
91 }
92 usleep(1);
93 free(p);
94 }
95 } else {
96 g_pid = processNum;
97 }
98 }
99
StopProcess()100 void HiDumperInnerkitsTest::StopProcess()
101 {
102 std::string stopCmd = "kill " + std::to_string(g_pid);
103 system(stopCmd.c_str());
104 }
105
GetAppManagerPids()106 void HiDumperInnerkitsTest::GetAppManagerPids()
107 {
108 std::vector<std::string> processes = {"com.ohos.launcher", "com.ohos.medialibrary.medialibrarydata", "hiview",
109 "com.ohos.settingsdata", "com.ohos.systemui", "render_service"};
110 for (std::vector<std::string>::iterator iter = processes.begin(); iter != processes.end(); iter++) {
111 int res = GetAppManagerPid(*iter);
112 if (res > 0) {
113 g_appManagerPid = res;
114 break;
115 }
116 }
117 }
118
GetAppManagerPid(std::string process)119 int HiDumperInnerkitsTest::GetAppManagerPid(std::string process)
120 {
121 std::string cmd = "pidof " + process;
122 char appManagerPidChar[LAUNCHER_PID_BUFFER_SIZE] = {"\0"};
123 int appManagerPid = -1;
124 FILE *fp = nullptr;
125 fp = popen(cmd.c_str(), "r");
126 if (fp == nullptr) {
127 return -1;
128 }
129 if (fgets(appManagerPidChar, sizeof(appManagerPidChar), fp) != nullptr) {
130 pclose(fp);
131 int ret = sscanf_s(appManagerPidChar, "%d", &appManagerPid);
132 if (ret <= 0) {
133 return -1;
134 }
135 return appManagerPid;
136 }
137 pclose(fp);
138 return -1;
139 }
140
141 /**
142 * @tc.name: GetMemInfoTest001
143 * @tc.desc: Test GetMemInfo.
144 * @tc.type: FUNC
145 * @tc.require: issueI5NWZQ
146 */
147 HWTEST_F(HiDumperInnerkitsTest, GetMemInfoTest001, TestSize.Level1)
148 {
149 std::unique_ptr<DumpUsage> dumpUsage = std::make_unique<DumpUsage>();
150 MemInfoData::MemInfo info;
151 EXPECT_TRUE(dumpUsage->GetMemInfo(g_pid, info));
152 EXPECT_GT(info.pss, 0);
153 }
154
155 /**
156 * @tc.name: GetPssTest001
157 * @tc.desc: Test GetPss.
158 * @tc.type: FUNC
159 * @tc.require: issueI5NWZQ
160 */
161 HWTEST_F(HiDumperInnerkitsTest, GetPssTest001, TestSize.Level1)
162 {
163 std::unique_ptr<DumpUsage> dumpUsage = std::make_unique<DumpUsage>();
164 EXPECT_GT(dumpUsage->GetPss(g_pid), 0);
165 }
166
167 /**
168 * @tc.name: GetPrivateDirtyTest001
169 * @tc.desc: Test GetPrivateDirty.
170 * @tc.type: FUNC
171 * @tc.require: issueI5NWZQ
172 */
173 HWTEST_F(HiDumperInnerkitsTest, GetPrivateDirtyTest001, TestSize.Level1)
174 {
175 std::unique_ptr<DumpUsage> dumpUsage = std::make_unique<DumpUsage>();
176 EXPECT_GE(dumpUsage->GetPrivateDirty(g_pid), 0);
177 }
178
179 /**
180 * @tc.name: GetSharedDirtyTest001
181 * @tc.desc: Test GetSharedDirty.
182 * @tc.type: FUNC
183 * @tc.require: issueI5NWZQ
184 */
185 HWTEST_F(HiDumperInnerkitsTest, GetSharedDirtyTest001, TestSize.Level1)
186 {
187 std::unique_ptr<DumpUsage> dumpUsage = std::make_unique<DumpUsage>();
188 EXPECT_GE(dumpUsage->GetSharedDirty(g_pid), 0);
189 }
190
191 /**
192 * @tc.name: GetCpuUsage001
193 * @tc.desc: Test GetCpuUsage.
194 * @tc.type: FUNC
195 * @tc.require: issueI5NWZQ
196 */
197 HWTEST_F(HiDumperInnerkitsTest, GetCpuUsage001, TestSize.Level1)
198 {
199 std::unique_ptr<DumpUsage> dumpUsage = std::make_unique<DumpUsage>();
200 EXPECT_GT(dumpUsage->GetCpuUsage(g_pid), 0);
201 }
202
203 /**
204 * @tc.name: GetProcCpuInfo001
205 * @tc.desc: Test GetProcCpuInfo when a new process appeared.
206 * @tc.type: FUNC
207 */
208 HWTEST_F(HiDumperInnerkitsTest, GetProcCpuInfo001, TestSize.Level1)
209 {
210 auto parameter = std::make_shared<DumperParameter>();
211 DumperOpts opts;
212 opts.isDumpCpuUsage_ = true;
213 opts.cpuUsagePid_ = g_pid;
214 parameter->SetOpts(opts);
215 auto dumpDatas = std::make_shared<std::vector<std::vector<std::string>>>();
216 auto cpuDumper = std::make_shared<CPUDumper>();
217 int ret = DumpStatus::DUMP_FAIL;
218 ret = cpuDumper->PreExecute(parameter, dumpDatas);
219 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
220 ret = cpuDumper->Execute();
221 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
222 ret = cpuDumper->AfterExecute();
223 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
224 }
225
226 /**
227 * @tc.name: GetProcCpuInfo001
228 * @tc.desc: Test GetProcCpuInfo when a new process appeared.
229 * @tc.type: FUNC
230 */
231 HWTEST_F(HiDumperInnerkitsTest, GetHeapInfo001, TestSize.Level1)
232 {
233 int testPid = g_pid;
234 GroupMap groupMap;
235 std::map<std::string, uint64_t> value = {};
236 value["test"] = 1;
237 groupMap["test"] = value;
238 std::unique_ptr<GetHeapInfo> getHeapInfo = std::make_unique<GetHeapInfo>();
239 ASSERT_TRUE(getHeapInfo->GetInfo(MemoryFilter::APPOINT_PID, testPid, groupMap));
240
241 if (g_appManagerPid != -1) {
242 testPid = g_appManagerPid;
243 ASSERT_TRUE(getHeapInfo->GetInfo(MemoryFilter::APPOINT_PID, testPid, groupMap));
244 }
245 }
246
247 /**
248 * @tc.name: ParseSmapsInfoGetInfoTest001
249 * @tc.desc: Test GetMemInfo.
250 * @tc.type: FUNC
251 * @tc.require: issueI5NWZQ
252 */
253 HWTEST_F(HiDumperInnerkitsTest, ParseSmapsInfoGetInfoTest001, TestSize.Level1)
254 {
255 std::unique_ptr<ParseSmapsInfo> parseSmapsInfo = std::make_unique<ParseSmapsInfo>();
256 GroupMap groupMap;
257 EXPECT_TRUE(parseSmapsInfo->GetInfo(MemoryFilter::APPOINT_PID, 1, groupMap));
258 }
259 } // namespace HiviewDFX
260 } // namespace OHOS
261