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: ManagerClientTest001
164 * @tc.desc: Test emtpy argument list.
165 * @tc.type: FUNC
166 */
167 HWTEST_F(HidumperClientTest, ManagerClientTest001, TestSize.Level0)
168 {
169 vector<u16string> args{};
170 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
171 ASSERT_EQ(ret, DumpStatus::DUMP_FAIL);
172 }
173
174 /**
175 * @tc.name: ManagerClientTest002
176 * @tc.desc: Test emtpy argument.
177 * @tc.type: FUNC
178 */
179 HWTEST_F(HidumperClientTest, ManagerClientTest002, TestSize.Level0)
180 {
181 vector<u16string> args{
182 std::u16string(),
183 };
184 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
185 ASSERT_EQ(ret, DumpStatus::DUMP_FAIL);
186 }
187
188 /**
189 * @tc.name: ManagerClientTest003
190 * @tc.desc: Test mamanage client Request.
191 * @tc.type: FUNC
192 */
193 HWTEST_F(HidumperClientTest, ManagerClientTest003, TestSize.Level0)
194 {
195 vector<u16string> args{
196 std::u16string(u"hidumper"),
197 std::u16string(u"-s"),
198 std::u16string(u"1212"),
199 };
200 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
201 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
202 }
203
204 /**
205 * @tc.name: ManagerClientTest004
206 * @tc.desc: Test mamanage client ScanPidOverLimit.
207 * @tc.type: FUNC
208 */
209 HWTEST_F(HidumperClientTest, ManagerClientTest004, TestSize.Level0)
210 {
211 sptr<IDumpBroker> proxy_ {nullptr};
212 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
213 ASSERT_TRUE(sam != nullptr) << "ManagerClientTest004 fail to get GetSystemAbilityManager";
214 sptr<IRemoteObject> remoteObject = sam->CheckSystemAbility(DFX_HI_DUMPER_SERVICE_ABILITY_ID);
215 ASSERT_TRUE(remoteObject != nullptr) << "Get SystemAbility failed.";
216 proxy_ = iface_cast<IDumpBroker>(remoteObject);
217 std::string requestType = "fd";
218 std::vector<int32_t> pidList;
219 int ret = proxy_->ScanPidOverLimit(requestType, LIMIT_SIZE, pidList);
220 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
221 }
222
223 /**
224 * @tc.name: ManagerClientTest005
225 * @tc.desc: Test mamanage client CountFdNums.
226 * @tc.type: FUNC
227 */
228 HWTEST_F(HidumperClientTest, ManagerClientTest005, TestSize.Level0)
229 {
230 sptr<IDumpBroker> proxy_ {nullptr};
231 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
232 ASSERT_TRUE(sam != nullptr) << "ManagerClientTest005 fail to get GetSystemAbilityManager";
233 sptr<IRemoteObject> remoteObject = sam->CheckSystemAbility(DFX_HI_DUMPER_SERVICE_ABILITY_ID);
234 ASSERT_TRUE(remoteObject != nullptr) << "Get SystemAbility failed.";
235 proxy_ = iface_cast<IDumpBroker>(remoteObject);
236 int32_t pid = 1;
237 uint32_t fdNums = 0;
238 std::string detailFdInfo;
239 std::string topLeakedType;
240 int ret = proxy_->CountFdNums(pid, fdNums, detailFdInfo, topLeakedType);
241 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
242 }
243
244 /**
245 * @tc.name: ManagerClientTest006
246 * @tc.desc: Test ipc stat dump with pid.
247 * @tc.type: FUNC
248 */
249 HWTEST_F(HidumperClientTest, ManagerClientTest006, TestSize.Level0)
250 {
251 string pid;
252 FILE* file = popen("pidof samgr", "r");
253 if (file) {
254 char buffer[BUFFER_SIZE];
255 if (fgets(buffer, sizeof(buffer), file) != nullptr) {
256 pid.assign(buffer);
257 };
258 pid = pid.substr(0, pid.length() - 1);
259 pclose(file);
260 } else {
261 std::cerr << "Failed to execute command" << std::endl;
262 }
263 vector<u16string> args{
264 std::u16string(u"hidumper"),
265 std::u16string(u"--ipc"),
266 Str8ToStr16(pid),
267 std::u16string(u"--start-stat"),
268 };
269 int32_t ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
270 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
271 }
272
273 /**
274 * @tc.name: ManagerClientTest007
275 * @tc.desc: Test ipc stat dump all.
276 * @tc.type: FUNC
277 */
278 HWTEST_F(HidumperClientTest, ManagerClientTest007, TestSize.Level0)
279 {
280 vector<u16string> args{
281 std::u16string(u"hidumper"),
282 std::u16string(u"--ipc"),
283 std::u16string(u"-a"),
284 std::u16string(u"--start-stat"),
285 };
286 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
287 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
288 }
289
290 /**
291 * @tc.name: ManagerClientTest008
292 * @tc.desc: Test cpuusage of all processes.
293 * @tc.type: FUNC
294 */
295 HWTEST_F(HidumperClientTest, ManagerClientTest008, TestSize.Level0)
296 {
297 vector<u16string> args{
298 std::u16string(u"hidumper"),
299 std::u16string(u"--cpuusage"),
300 };
301 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
302 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
303 }
304
305 /**
306 * @tc.name: ManagerClientTest009
307 * @tc.desc: Test cpuusage with pid.
308 * @tc.type: FUNC
309 */
310 HWTEST_F(HidumperClientTest, ManagerClientTest009, TestSize.Level0)
311 {
312 vector<u16string> args{
313 std::u16string(u"hidumper"),
314 std::u16string(u"--cpuusage"),
315 std::u16string(u"1"),
316 };
317 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
318 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
319 }
320
321 /**
322 * @tc.name: ManagerClientTest010
323 * @tc.desc: Test cpufreq.
324 * @tc.type: FUNC
325 */
326 HWTEST_F(HidumperClientTest, ManagerClientTest010, TestSize.Level0)
327 {
328 vector<u16string> args{
329 std::u16string(u"hidumper"),
330 std::u16string(u"--cpufreq"),
331 };
332 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
333 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
334 }
335
336 /**
337 * @tc.name: ManagerClientTest011
338 * @tc.desc: Test --mem-jsheap.
339 * @tc.type: FUNC
340 */
341 HWTEST_F(HidumperClientTest, ManagerClientTest011, TestSize.Level0)
342 {
343 vector<u16string> args{
344 std::u16string(u"hidumper"),
345 std::u16string(u"--mem-jsheap"),
346 };
347 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
348 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
349 }
350
351 /**
352 * @tc.name: ManagerClientTest012
353 * @tc.desc: Test --mem-jsheap.
354 * @tc.type: FUNC
355 */
356 HWTEST_F(HidumperClientTest, ManagerClientTest012, TestSize.Level0)
357 {
358 string pid;
359 auto appMgrClient = std::make_unique<AppMgrClient>();
360 std::vector<RunningProcessInfo> runningProcessInfos;
361 appMgrClient->GetAllRunningProcesses(runningProcessInfos);
362 ASSERT_TRUE(runningProcessInfos.size() > 0);
363
364 pid = to_string(runningProcessInfos[0].pid_);
365 vector<u16string> args{
366 std::u16string(u"hidumper"),
367 std::u16string(u"--mem-jsheap"),
368 Str8ToStr16(pid)
369 };
370 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO);
371 ASSERT_EQ(ret, DumpStatus::DUMP_OK);
372 }
373 } // namespace HiviewDFX
374 } // namespace OHOS