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 #include <fcntl.h>
16 #include <vector>
17 #include <unistd.h>
18 #include <cstdlib>
19 #include <gtest/gtest.h>
20 #include <string_ex.h>
21 #include "inner/dump_service_id.h"
22 #include "dump_client_main.h"
23 #include "dump_controller.h"
24 #include "dump_manager_client.h"
25 #include "app_mgr_client.h"
26
27 using namespace testing::ext;
28 using namespace std;
29 using OHOS::HiviewDFX::DumpClientMain;
30 using OHOS::AppExecFwk::AppMgrClient;
31 using OHOS::AppExecFwk::RunningProcessInfo;
32 namespace OHOS {
33 namespace HiviewDFX {
34 const std::string TOOL_NAME = "hidumper";
35 const int BUFFER_SIZE = 1024;
36 class HidumperClientTest : 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 HidumperClientTest::SetUpTestCase(void)
45 {
46 }
47
TearDownTestCase(void)48 void HidumperClientTest::TearDownTestCase(void)
49 {
50 }
51
SetUp(void)52 void HidumperClientTest::SetUp(void)
53 {
54 }
55
TearDown(void)56 void HidumperClientTest::TearDown(void)
57 {
58 }
59
60 /**
61 * @tc.name: ClientMainTest001
62 * @tc.desc: Test too many arguments.
63 * @tc.type: FUNC
64 */
65 HWTEST_F(HidumperClientTest, ClientMainTest001, TestSize.Level0)
66 {
67 char *argv[] = {
68 const_cast<char *>(TOOL_NAME.c_str()),
69 };
70 int argc = ARG_MAX_COUNT + 1;
71 int ret = DumpClientMain::GetInstance().Main(argc, argv, STDOUT_FILENO);
72 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG);
73 }
74
75 /**
76 * @tc.name: ClientMainTest002
77 * @tc.desc: Test empty argument.
78 * @tc.type: FUNC
79 */
80 HWTEST_F(HidumperClientTest, ClientMainTest002, TestSize.Level0)
81 {
82 char *argv[] = {
83 const_cast<char *>(TOOL_NAME.c_str()),
84 const_cast<char *>("--mem"),
85 const_cast<char *>("-1"),
86 const_cast<char *>(""),
87 const_cast<char *>("--mem"),
88 };
89 int argc = sizeof(argv) / sizeof(argv[0]) - 1;
90 int ret = DumpClientMain::GetInstance().Main(argc, argv, STDOUT_FILENO);
91 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG);
92 }
93
94 /**
95 * @tc.name: ClientMainTest003
96 * @tc.desc: Test too long argument .
97 * @tc.type: FUNC
98 */
99 HWTEST_F(HidumperClientTest, ClientMainTest003, TestSize.Level0)
100 {
101 std::string longArg;
102 longArg.assign(SINGLE_ARG_MAXLEN + 1, 'c');
103 char *argv[] = {
104 const_cast<char *>(TOOL_NAME.c_str()),
105 const_cast<char *>("-h"),
106 const_cast<char *>(longArg.c_str()),
107 };
108 int argc = sizeof(argv) / sizeof(argv[0]);
109 int ret = DumpClientMain::GetInstance().Main(argc, argv, STDOUT_FILENO);
110 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG);
111 }
112
113 /**
114 * @tc.name: ClientMainTest004
115 * @tc.desc: Test null argument.
116 * @tc.type: FUNC
117 */
118 HWTEST_F(HidumperClientTest, ClientMainTest004, TestSize.Level0)
119 {
120 char *argv[] = {
121 const_cast<char *>(TOOL_NAME.c_str()),
122 nullptr,
123 };
124 int argc = sizeof(argv) / sizeof(argv[0]);
125 int ret = DumpClientMain::GetInstance().Main(argc, argv, STDOUT_FILENO);
126 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG);
127 }
128
129 /**
130 * @tc.name: ClientMainTest005
131 * @tc.desc: Test null fd.
132 * @tc.type: FUNC
133 */
134 HWTEST_F(HidumperClientTest, ClientMainTest005, TestSize.Level0)
135 {
136 char *argv[] = {
137 const_cast<char *>("hidumper"),
138 const_cast<char *>("--mem"),
139 const_cast<char *>("1"),
140 };
141 int argc = sizeof(argv) / sizeof(argv[0]);
142 int fd = open("/dev/null", O_RDWR | O_CREAT | O_TRUNC, 0664);
143 if (fd <= 0) {
144 fd = STDERR_FILENO;
145 }
146 int ret = DumpClientMain::GetInstance().Main(argc, argv, fd);
147 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
148 }
149
150 /**
151 * @tc.name: ClientMainTest006
152 * @tc.desc: Test null argv.
153 * @tc.type: FUNC
154 */
155 HWTEST_F(HidumperClientTest, ClientMainTest006, TestSize.Level0)
156 {
157 int argc = ARG_MAX_COUNT;
158 int ret = DumpClientMain::GetInstance().Main(argc, nullptr, STDOUT_FILENO);
159 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG);
160 }
161
162 /**
163 * @tc.name: ClientMainTest007
164 * @tc.desc: Test null fd from hiview.
165 * @tc.type: FUNC
166 */
167 HWTEST_F(HidumperClientTest, ClientMainTest007, TestSize.Level0)
168 {
169 char *argv[] = {
170 const_cast<char *>("hidumper"),
171 const_cast<char *>("-s"),
172 const_cast<char *>("1213"),
173 const_cast<char *>("-a"),
174 const_cast<char *>("--Logbackup"),
175 };
176 int argc = sizeof(argv) / sizeof(argv[0]);
177 int fd = open("/dev/null", O_CREAT | O_TRUNC, 0664);
178 if (fd <= 0) {
179 fd = STDERR_FILENO;
180 }
181 setuid(1201); //hiview uid
182 int ret = DumpClientMain::GetInstance().Main(argc, argv, fd);
183 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
184 }
185
186 /**
187 * @tc.name: ManagerClientTest001
188 * @tc.desc: Test emtpy argument list.
189 * @tc.type: FUNC
190 */
191 HWTEST_F(HidumperClientTest, ManagerClientTest001, TestSize.Level0)
192 {
193 vector<u16string> args{};
194 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
195 ASSERT_EQ(ret, DumpStatus::DUMP_FAIL);
196 }
197
198 /**
199 * @tc.name: ManagerClientTest002
200 * @tc.desc: Test emtpy argument.
201 * @tc.type: FUNC
202 */
203 HWTEST_F(HidumperClientTest, ManagerClientTest002, TestSize.Level0)
204 {
205 vector<u16string> args{
206 std::u16string(),
207 };
208 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
209 ASSERT_EQ(ret, DumpStatus::DUMP_FAIL);
210 }
211
212 /**
213 * @tc.name: ManagerClientTest003
214 * @tc.desc: Test mamanage client Request.
215 * @tc.type: FUNC
216 */
217 HWTEST_F(HidumperClientTest, ManagerClientTest003, TestSize.Level0)
218 {
219 vector<u16string> args{
220 std::u16string(u"hidumper"),
221 std::u16string(u"-s"),
222 std::u16string(u"1212"),
223 };
224 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
225 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
226 }
227
228 /**
229 * @tc.name: ManagerClientTest004
230 * @tc.desc: Test mamanage client ScanPidOverLimit.
231 * @tc.type: FUNC
232 */
233 HWTEST_F(HidumperClientTest, ManagerClientTest004, TestSize.Level0)
234 {
235 sptr<IDumpBroker> proxy_ {nullptr};
236 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
237 ASSERT_TRUE(sam != nullptr) << "ManagerClientTest004 fail to get GetSystemAbilityManager";
238 sptr<IRemoteObject> remoteObject = sam->CheckSystemAbility(DFX_HI_DUMPER_SERVICE_ABILITY_ID);
239 ASSERT_TRUE(remoteObject != nullptr) << "Get SystemAbility failed.";
240 proxy_ = iface_cast<IDumpBroker>(remoteObject);
241 std::string requestType = "fd";
242 std::vector<int32_t> pidList;
243 int ret = proxy_->ScanPidOverLimit(requestType, LIMIT_SIZE, pidList);
244 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
245 }
246
247 /**
248 * @tc.name: ManagerClientTest005
249 * @tc.desc: Test mamanage client CountFdNums.
250 * @tc.type: FUNC
251 */
252 HWTEST_F(HidumperClientTest, ManagerClientTest005, TestSize.Level0)
253 {
254 sptr<IDumpBroker> proxy_ {nullptr};
255 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
256 ASSERT_TRUE(sam != nullptr) << "ManagerClientTest005 fail to get GetSystemAbilityManager";
257 sptr<IRemoteObject> remoteObject = sam->CheckSystemAbility(DFX_HI_DUMPER_SERVICE_ABILITY_ID);
258 ASSERT_TRUE(remoteObject != nullptr) << "Get SystemAbility failed.";
259 proxy_ = iface_cast<IDumpBroker>(remoteObject);
260 int32_t pid = 1;
261 uint32_t fdNums = 0;
262 std::string detailFdInfo;
263 std::vector<std::string> topLeakedTypeList;
264 int ret = proxy_->CountFdNums(pid, fdNums, detailFdInfo, topLeakedTypeList);
265 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
266 }
267
268 /**
269 * @tc.name: ManagerClientTest006
270 * @tc.desc: Test ipc stat dump with pid.
271 * @tc.type: FUNC
272 */
273 HWTEST_F(HidumperClientTest, ManagerClientTest006, TestSize.Level0)
274 {
275 string pid;
276 FILE* file = popen("pidof samgr", "r");
277 if (file) {
278 char buffer[BUFFER_SIZE];
279 if (fgets(buffer, sizeof(buffer), file) != nullptr) {
280 pid.assign(buffer);
281 };
282 pid = pid.substr(0, pid.length() - 1);
283 pclose(file);
284 } else {
285 std::cerr << "Failed to execute command" << std::endl;
286 }
287 vector<u16string> args{
288 std::u16string(u"hidumper"),
289 std::u16string(u"--ipc"),
290 Str8ToStr16(pid),
291 std::u16string(u"--start-stat"),
292 };
293 int32_t ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
294 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
295 }
296
297 /**
298 * @tc.name: ManagerClientTest007
299 * @tc.desc: Test ipc stat dump all.
300 * @tc.type: FUNC
301 */
302 HWTEST_F(HidumperClientTest, ManagerClientTest007, TestSize.Level0)
303 {
304 vector<u16string> args{
305 std::u16string(u"hidumper"),
306 std::u16string(u"--ipc"),
307 std::u16string(u"-a"),
308 std::u16string(u"--start-stat"),
309 };
310 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
311 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
312 }
313
314 /**
315 * @tc.name: ManagerClientTest008
316 * @tc.desc: Test cpuusage of all processes.
317 * @tc.type: FUNC
318 */
319 HWTEST_F(HidumperClientTest, ManagerClientTest008, TestSize.Level0)
320 {
321 vector<u16string> args{
322 std::u16string(u"hidumper"),
323 std::u16string(u"--cpuusage"),
324 };
325 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
326 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
327 }
328
329 /**
330 * @tc.name: ManagerClientTest009
331 * @tc.desc: Test cpuusage with pid.
332 * @tc.type: FUNC
333 */
334 HWTEST_F(HidumperClientTest, ManagerClientTest009, TestSize.Level0)
335 {
336 vector<u16string> args{
337 std::u16string(u"hidumper"),
338 std::u16string(u"--cpuusage"),
339 std::u16string(u"1"),
340 };
341 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
342 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
343 }
344
345 /**
346 * @tc.name: ManagerClientTest010
347 * @tc.desc: Test cpufreq.
348 * @tc.type: FUNC
349 */
350 HWTEST_F(HidumperClientTest, ManagerClientTest010, TestSize.Level0)
351 {
352 vector<u16string> args{
353 std::u16string(u"hidumper"),
354 std::u16string(u"--cpufreq"),
355 };
356 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
357 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
358 }
359
360 /**
361 * @tc.name: ManagerClientTest011
362 * @tc.desc: Test --mem-jsheap.
363 * @tc.type: FUNC
364 */
365 HWTEST_F(HidumperClientTest, ManagerClientTest011, TestSize.Level0)
366 {
367 vector<u16string> args{
368 std::u16string(u"hidumper"),
369 std::u16string(u"--mem-jsheap"),
370 };
371 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
372 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
373 }
374
375 /**
376 * @tc.name: ManagerClientTest012
377 * @tc.desc: Test --mem-jsheap.
378 * @tc.type: FUNC
379 */
380 HWTEST_F(HidumperClientTest, ManagerClientTest012, TestSize.Level0)
381 {
382 string pid;
383 auto appMgrClient = std::make_unique<AppMgrClient>();
384 std::vector<RunningProcessInfo> runningProcessInfos;
385 appMgrClient->GetAllRunningProcesses(runningProcessInfos);
386 ASSERT_TRUE(runningProcessInfos.size() > 0);
387
388 pid = to_string(runningProcessInfos[0].pid_);
389 vector<u16string> args{
390 std::u16string(u"hidumper"),
391 std::u16string(u"--mem-jsheap"),
392 Str8ToStr16(pid)
393 };
394 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
395 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
396 }
397
398 /**
399 * @tc.name: ManagerClientTest013
400 * @tc.desc: Test --mem-cjheap.
401 * @tc.type: FUNC
402 */
403 HWTEST_F(HidumperClientTest, ManagerClientTest013, TestSize.Level0)
404 {
405 vector<u16string> args{
406 std::u16string(u"hidumper"),
407 std::u16string(u"--mem-cjheap"),
408 };
409 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
410 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
411 }
412
413 /**
414 * @tc.name: ManagerClientTest014
415 * @tc.desc: Test --mem-cjheap.
416 * @tc.type: FUNC
417 */
418 HWTEST_F(HidumperClientTest, ManagerClientTest014, TestSize.Level0)
419 {
420 string pid;
421 auto appMgrClient = std::make_unique<AppMgrClient>();
422 std::vector<RunningProcessInfo> runningProcessInfos;
423 appMgrClient->GetAllRunningProcesses(runningProcessInfos);
424 ASSERT_TRUE(runningProcessInfos.size() > 0);
425
426 pid = to_string(runningProcessInfos[0].pid_);
427 vector<u16string> args{
428 std::u16string(u"hidumper"),
429 std::u16string(u"--mem-cjheap"),
430 Str8ToStr16(pid)
431 };
432 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
433 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
434 }
435
436 /**
437 * @tc.name: ManagerClientTest015
438 * @tc.desc: Test --mem 1 --show-dmabuf.
439 * @tc.type: FUNC
440 */
441 HWTEST_F(HidumperClientTest, ManagerClientTest015, TestSize.Level0)
442 {
443 vector<u16string> args{
444 std::u16string(u"hidumper"),
445 std::u16string(u"--mem"),
446 std::u16string(u"1"),
447 std::u16string(u"--show-dmabuf"),
448 };
449 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
450 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
451 }
452 } // namespace HiviewDFX
453 } // namespace OHOS