• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "hidumper_service_test.h"
16 #include <fstream>
17 #include <fcntl.h>
18 #include <iservice_registry.h>
19 #include "dump_manager_client.h"
20 #include "dump_manager_service.h"
21 #include "inner/dump_service_id.h"
22 #include "dump_on_demand_load.h"
23 #include "executor/memory/memory_util.h"
24 #include "string_ex.h"
25 
26 using namespace std;
27 using namespace testing::ext;
28 using namespace OHOS;
29 using namespace OHOS::HiviewDFX;
30 namespace OHOS {
31 namespace HiviewDFX {
32 constexpr int32_t HidumperServiceTest::LIMIT_SIZE = 5000;
33 namespace {
WriteFile(const std::string & content,const std::string & filename)34 void WriteFile(const std::string &content, const std::string &filename)
35 {
36     std::ofstream outFile(filename);
37     if (!outFile) {
38         std::cerr << "open file failed: " << filename << std::endl;
39         return;
40     }
41 
42     outFile << content;
43     outFile.close();
44 
45     std::cout << "write success" << std::endl;
46 }
47 
IsProcessExist(int pid)48 bool IsProcessExist(int pid)
49 {
50     string path = "/proc/" + to_string(pid);
51     return access(path.c_str(), F_OK) == 0;
52 }
53 }
54 
SetUpTestCase(void)55 void HidumperServiceTest::SetUpTestCase(void)
56 {
57 }
58 
TearDownTestCase(void)59 void HidumperServiceTest::TearDownTestCase(void)
60 {
61 }
62 
SetUp(void)63 void HidumperServiceTest::SetUp(void)
64 {
65 }
66 
TearDown(void)67 void HidumperServiceTest::TearDown(void)
68 {
69 }
70 
71 /**
72  * @tc.name: HidumperServiceTest001
73  * @tc.desc: Test DumpManagerService service ready.
74  * @tc.type: FUNC
75  */
76 HWTEST_F(HidumperServiceTest, HidumperServiceTest001, TestSize.Level3)
77 {
78     sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
79     ASSERT_TRUE(sam != nullptr) << "HidumperServiceTest001 fail to get GetSystemAbilityManager";
80     sptr<OnDemandLoadCallback> loadCallback = new OnDemandLoadCallback();
81     int32_t result = sam->LoadSystemAbility(DFX_SYS_HIDUMPER_ABILITY_ID, loadCallback);
82     ASSERT_TRUE(result == ERR_OK) << "GetSystemAbility failed.";
83 }
84 
85 /**
86  * @tc.name: DumpManagerService002
87  * @tc.desc: Test DumpManagerService Request.
88  * @tc.type: FUNC
89  */
90 HWTEST_F(HidumperServiceTest, DumpManagerService002, TestSize.Level3)
91 {
92     auto dumpManagerService = std::make_shared<DumpManagerService>();
93     dumpManagerService->OnStart();
94     dumpManagerService->started_ = true;
95     std::vector<std::u16string> args;
96     int32_t ret = ERR_OK;
97     ret =  dumpManagerService->Dump(-1, args);
98     ASSERT_TRUE(ret == ERR_OK);
99     ret = dumpManagerService->Request(args, -1);
100     ASSERT_TRUE(ret == ERR_OK);
101 
102     dumpManagerService->OnStop();
103 }
104 
105 /**
106  * @tc.name: DumpManagerService003
107  * @tc.desc: Test DumpManagerService CountFdNums.
108  * @tc.type: FUNC
109  */
110 HWTEST_F(HidumperServiceTest, DumpManagerService003, TestSize.Level3)
111 {
112     auto dumpManagerService = std::make_shared<DumpManagerService>();
113     int32_t pid = 1;
114     uint32_t fdNums = 0;
115     std::string detailFdInfo;
116     std::vector<std::string> topLeakedTypeList;
117     int32_t ret = dumpManagerService->CountFdNums(pid, fdNums, detailFdInfo, topLeakedTypeList);
118     cout << "pid:" << pid << " fdNums:" << fdNums << endl;
119     cout << "topLeakedTypeList:" << endl;
120     for (const auto& type : topLeakedTypeList) {
121         cout << " " << type << endl;
122     }
123     cout << "detailFdInfo:" << endl << detailFdInfo << endl;
124     ASSERT_TRUE(ret == 0);
125     ASSERT_FALSE(detailFdInfo.empty());
126     ASSERT_FALSE(topLeakedTypeList.empty());
127 }
128 
129 /**
130  * @tc.name: DumpManagerService004
131  * @tc.desc: Test DumpManagerService ScanPidOverLimit.
132  * @tc.type: FUNC
133  */
134 HWTEST_F(HidumperServiceTest, DumpManagerService004, TestSize.Level3)
135 {
136     auto dumpManagerService = std::make_shared<DumpManagerService>();
137     std::string requestType = "fd";
138     std::vector<int32_t> pidList;
139     int32_t ret = dumpManagerService->ScanPidOverLimit(requestType, LIMIT_SIZE, pidList);
140     ASSERT_TRUE(ret == 0);
141     ret = dumpManagerService->ScanPidOverLimit(requestType, 0, pidList);
142     ASSERT_TRUE(ret == 0);
143 
144     ret = dumpManagerService->ScanPidOverLimit(requestType, -1, pidList);
145     ASSERT_TRUE(ret != 0);
146 
147     requestType = "..";
148     ret = dumpManagerService->ScanPidOverLimit(requestType, 1, pidList);
149     ASSERT_TRUE(ret == 0);
150 }
151 
152 /**
153  * @tc.name: DumpManagerService005
154  * @tc.desc: Test DumpManagerService Request.
155  * @tc.type: FUNC
156  */
157 HWTEST_F(HidumperServiceTest, DumpManagerService005, TestSize.Level3)
158 {
159     auto dumpManagerService = std::make_shared<DumpManagerService>();
160     dumpManagerService->OnStart();
161     dumpManagerService->started_ = true;
162     dumpManagerService->OnStart();
163 
164     std::vector<std::u16string> args;
165     dumpManagerService->blockRequest_ = true;
166     int32_t ret = dumpManagerService->Request(args, -1);
167     ASSERT_TRUE(ret != 0);
168     dumpManagerService->blockRequest_ = false;
169     dumpManagerService->started_ = false;
170     ret = dumpManagerService->Request(args, -1);
171     ASSERT_TRUE(ret != 0);
172     dumpManagerService->OnStop();
173     dumpManagerService->started_ = false;
174     dumpManagerService->OnStop();
175 }
176 
177 /**
178  * @tc.name: DumpManagerService006
179  * @tc.desc: Test DumpManagerService error request.
180  * @tc.type: FUNC
181  */
182 HWTEST_F(HidumperServiceTest, DumpManagerService006, TestSize.Level3)
183 {
184     auto dumpManagerService = std::make_shared<DumpManagerService>();
185     std::vector<std::u16string> args;
186     int outfd = -1;
187     dumpManagerService->HandleRequestError(args, outfd, -1, "test");
188     ASSERT_TRUE(args.size() == 0);
189     args.push_back(Str8ToStr16("test"));
190     dumpManagerService->HandleRequestError(args, outfd, -1, "test");
191     ASSERT_TRUE(args.size() == 0);
192 }
193 
194 /**
195  * @tc.name: DumpManagerService007
196  * @tc.desc: Test DumpManagerService OnIdle.
197  * @tc.type: FUNC
198  */
199 HWTEST_F(HidumperServiceTest, DumpManagerService007, TestSize.Level3)
200 {
201     auto dumpManagerService = std::make_shared<DumpManagerService>();
202     SystemAbilityOnDemandReason idleReason;
203     int32_t ret = dumpManagerService->OnIdle(idleReason);
204     ASSERT_TRUE(ret == 0);
205     idleReason.SetId(OnDemandReasonId::INTERFACE_CALL);
206     ret = dumpManagerService->OnIdle(idleReason);
207     ASSERT_TRUE(ret == 0);
208     std::vector<std::u16string> args;
209     args.push_back(Str8ToStr16("test"));
210     dumpManagerService->AddRequestRawParam(args, -1);
211     ret = dumpManagerService->OnIdle(idleReason);
212     ASSERT_TRUE(ret == 120000);
213     dumpManagerService->SetCpuSchedAffinity();
214 }
215 
216 /**
217  * @tc.name: DumpManagerService008
218  * @tc.desc: Test DumpManagerService GetFdLink with invalid symlink.
219  * @tc.type: FUNC
220  */
221 HWTEST_F(HidumperServiceTest, DumpManagerService008, TestSize.Level3)
222 {
223     const std::string invalidLinkPath = "/tmp/nonexistent_link";
224     auto dumpManagerService = std::make_shared<DumpManagerService>();
225     std::string result = dumpManagerService->GetFdLink(invalidLinkPath);
226     printf("Retrieved symlink content: '%s'\n", result.c_str());
227     ASSERT_TRUE(result == "unknown");
228     WriteFile(result, "/data/local/tmp/DumpManagerService008_result");
229 }
230 
231 /**
232  * @tc.name: DumpManagerService009
233  * @tc.desc: Test DumpManagerService GetFdLinks with valid symlinks.
234  * @tc.type: FUNC
235  */
236 HWTEST_F(HidumperServiceTest, DumpManagerService009, TestSize.Level1)
237 {
238     int pid = 1;
239     auto dumpService = std::make_shared<DumpManagerService>();
240     std::vector<std::string> links = dumpService->GetFdLinks(pid);
241 
242     cout << "links.size:" << links.size() << endl;
243 
244     EXPECT_GT(links.size(), 0);
245 
246     std::cout << "DumpManagerService009 passed with " << links.size() << " links." << std::endl;
247 }
248 
249 /**
250  * @tc.name: DumpManagerService010
251  * @tc.desc: Test DumpManagerService GetFdLinks with non-existent fd directory.
252  * @tc.type: FUNC
253  */
254 HWTEST_F(HidumperServiceTest, DumpManagerService010, TestSize.Level1)
255 {
256     int pid = 65533;
257     // 确保该进程不存在
258     if (IsProcessExist(pid)) {
259         GTEST_SKIP() << "进程 " << pid << " 已经存在,跳过测试。";
260     }
261 
262     auto dumpService = std::make_shared<DumpManagerService>();
263     std::vector<std::string> links = dumpService->GetFdLinks(pid);
264     EXPECT_TRUE(links.empty());
265     std::cout << "DumpManagerService010 passed with empty links." << std::endl;
266 }
267 
268 /**
269  * @tc.name: DumpManagerService011
270  * @tc.desc: Test MaybeKnownType with valid eventfd type in link.
271  * @tc.type: FUNC
272  */
273 HWTEST_F(HidumperServiceTest, DumpManagerService011, TestSize.Level3)
274 {
275     std::string link = "eventfd";
276     auto dumpManagerService = std::make_shared<DumpManagerService>();
277     std::string result = dumpManagerService->MaybeKnownType(link);
278     ASSERT_TRUE(result == "eventfd");
279     std::cout << "DumpManagerService011 passed for eventfd." << std::endl;
280 }
281 
282 /**
283  * @tc.name: DumpManagerService012
284  * @tc.desc: Test MaybeKnownType with valid eventpoll type in link.
285  * @tc.type: FUNC
286  */
287 HWTEST_F(HidumperServiceTest, DumpManagerService012, TestSize.Level3)
288 {
289     std::string link = "eventpoll";
290     auto dumpManagerService = std::make_shared<DumpManagerService>();
291     std::string result = dumpManagerService->MaybeKnownType(link);
292     ASSERT_TRUE(result == "eventpoll");
293     std::cout << "DumpManagerService012 passed for eventpoll." << std::endl;
294 }
295 
296 /**
297  * @tc.name: DumpManagerService013
298  * @tc.desc: Test MaybeKnownType with valid sync_file type in link.
299  * @tc.type: FUNC
300  */
301 HWTEST_F(HidumperServiceTest, DumpManagerService013, TestSize.Level3)
302 {
303     std::string link = "/proc/123/fd/4->sync_file";
304     auto dumpManagerService = std::make_shared<DumpManagerService>();
305     std::string result = dumpManagerService->MaybeKnownType(link);
306     ASSERT_TRUE(result == "sync_file");
307     std::cout << "DumpManagerService013 passed for sync_file." << std::endl;
308 }
309 
310 /**
311  * @tc.name: DumpManagerService014
312  * @tc.desc: Test MaybeKnownType with valid dmabuf type in link.
313  * @tc.type: FUNC
314  */
315 HWTEST_F(HidumperServiceTest, DumpManagerService014, TestSize.Level3)
316 {
317     std::string link = "dmabuf";
318     auto dumpManagerService = std::make_shared<DumpManagerService>();
319     std::string result = dumpManagerService->MaybeKnownType(link);
320     ASSERT_TRUE(result == "dmabuf");
321     std::cout << "DumpManagerService014 passed for dmabuf." << std::endl;
322 }
323 
324 /**
325  * @tc.name: DumpManagerService015
326  * @tc.desc: Test MaybeKnownType with valid socket type in link.
327  * @tc.type: FUNC
328  */
329 HWTEST_F(HidumperServiceTest, DumpManagerService015, TestSize.Level3)
330 {
331     std::string link = "socket:[12345]";
332     auto dumpManagerService = std::make_shared<DumpManagerService>();
333     std::string result = dumpManagerService->MaybeKnownType(link);
334     ASSERT_TRUE(result == "socket");
335     std::cout << "DumpManagerService015 passed for socket." << std::endl;
336 }
337 
338 /**
339  * @tc.name: DumpManagerService016
340  * @tc.desc: Test MaybeKnownType with valid pipe type in link.
341  * @tc.type: FUNC
342  */
343 HWTEST_F(HidumperServiceTest, DumpManagerService016, TestSize.Level3)
344 {
345     std::string link = "pipe:1234";
346     auto dumpManagerService = std::make_shared<DumpManagerService>();
347     std::string result = dumpManagerService->MaybeKnownType(link);
348     ASSERT_TRUE(result == "pipe");
349     std::cout << "DumpManagerService016 passed for pipe." << std::endl;
350 }
351 
352 /**
353  * @tc.name: DumpManagerService017
354  * @tc.desc: Test MaybeKnownType with valid ashmem type in link.
355  * @tc.type: FUNC
356  */
357 HWTEST_F(HidumperServiceTest, DumpManagerService017, TestSize.Level3)
358 {
359     std::string link = "ashmem: /dev/ashmem";
360     auto dumpManagerService = std::make_shared<DumpManagerService>();
361     std::string result = dumpManagerService->MaybeKnownType(link);
362     ASSERT_TRUE(result == "ashmem");
363     std::cout << "DumpManagerService017 passed for ashmem." << std::endl;
364 }
365 
366 /**
367  * @tc.name: DumpManagerService018
368  * @tc.desc: Test MaybeKnownType with unknown type in link.
369  * @tc.type: FUNC
370  */
371 HWTEST_F(HidumperServiceTest, DumpManagerService018, TestSize.Level3)
372 {
373     std::string link = "/dev/random-file";
374     auto dumpManagerService = std::make_shared<DumpManagerService>();
375     std::string result = dumpManagerService->MaybeKnownType(link);
376     ASSERT_TRUE(result == "unknown");
377     std::cout << "DumpManagerService018 passed for unknown type." << std::endl;
378 }
379 
380 /**
381  * @tc.name: DumpManagerService019
382  * @tc.desc: Test MaybeKnownType with multiple known types in link (returns first match).
383  * @tc.type: FUNC
384  */
385 HWTEST_F(HidumperServiceTest, DumpManagerService019, TestSize.Level3)
386 {
387     std::string link = "eventfd_with_pipe";
388     auto dumpManagerService = std::make_shared<DumpManagerService>();
389     std::string result = dumpManagerService->MaybeKnownType(link);
390     ASSERT_TRUE(result == "eventfd");
391     std::cout << "DumpManagerService019 passed for priority match." << std::endl;
392 }
393 
394 /**
395  * @tc.name: DumpManagerService020
396  * @tc.desc: Test CountPaths with multiple paths, check if counts are correct.
397  * @tc.type: FUNC
398  */
399 HWTEST_F(HidumperServiceTest, DumpManagerService020, TestSize.Level3)
400 {
401     // 准备测试数据
402     std::vector<std::string> links = {
403         "/data/log/a.txt",
404         "/data/log/b.txt",
405         "/data/log/a.txt",
406         "/data/log/c.txt",
407         "/data/log/b.txt",
408         "/data/log/b.txt"
409     };
410 
411     // 创建 DumpManagerService 实例
412     auto dumpManagerService = std::make_shared<DumpManagerService>();
413 
414     // 调用待测函数
415     std::unordered_map<std::string, int> result = dumpManagerService->CountPaths(links);
416 
417     // 预期结果
418     std::unordered_map<std::string, int> expected = {
419         { "/data/log/a.txt", 2 },
420         { "/data/log/b.txt", 3 },
421         { "/data/log/c.txt", 1 }
422     };
423 
424     // 断言结果是否与预期一致
425     ASSERT_TRUE(result == expected);
426     std::cout << "DumpManagerService020 passed for path counting." << std::endl;
427 }
428 
429 /**
430  * @tc.name: DumpManagerService021
431  * @tc.desc: Test TopN with valid input and n >= counter size.
432  * @tc.type: FUNC
433  */
434 HWTEST_F(HidumperServiceTest, DumpManagerService021, TestSize.Level3)
435 {
436     std::unordered_map<std::string, int> counter = {
437         {"eventfd", 10}, {"pipe", 8}, {"ashmem", 7}, {"socket", 12}, {"unknown1", 5}
438     };
439     size_t n = 3;
440     auto dumpManagerService = std::make_shared<DumpManagerService>();
441     std::vector<std::pair<std::string, int>> result = dumpManagerService->TopN(counter, n);
442 
443     EXPECT_EQ(result.size(), 3);
444     EXPECT_EQ(result[0].first, "socket");
445     EXPECT_EQ(result[0].second, 12);
446     EXPECT_EQ(result[1].first, "eventfd");
447     EXPECT_EQ(result[1].second, 10);
448     EXPECT_EQ(result[2].first, "pipe");
449     EXPECT_EQ(result[2].second, 8);
450     std::cout << "DumpManagerService021 passed: Top3 entries correct." << std::endl;
451 }
452 
453 /**
454  * @tc.name: DumpManagerService022
455  * @tc.desc: Test TopN when n is larger than counter size.
456  * @tc.type: FUNC
457  */
458 HWTEST_F(HidumperServiceTest, DumpManagerService022, TestSize.Level3)
459 {
460     std::unordered_map<std::string, int> counter = {{"a", 3}, {"b", 2}, {"c", 1}};
461     size_t n = 5;
462     auto dumpManagerService = std::make_shared<DumpManagerService>();
463     std::vector<std::pair<std::string, int>> result = dumpManagerService->TopN(counter, n);
464 
465     EXPECT_EQ(result.size(), 3);
466     EXPECT_EQ(result[0].first, "a");
467     EXPECT_EQ(result[1].first, "b");
468     EXPECT_EQ(result[2].first, "c");
469     std::cout << "DumpManagerService022 passed: All entries returned when n > size." << std::endl;
470 }
471 
472 /**
473  * @tc.name: DumpManagerService023
474  * @tc.desc: Test TopN with empty counter.
475  * @tc.type: FUNC
476  */
477 HWTEST_F(HidumperServiceTest, DumpManagerService023, TestSize.Level3)
478 {
479     std::unordered_map<std::string, int> counter = {};
480     size_t n = 2;
481     auto dumpManagerService = std::make_shared<DumpManagerService>();
482     std::vector<std::pair<std::string, int>> result = dumpManagerService->TopN(counter, n);
483 
484     EXPECT_TRUE(result.empty());
485     std::cout << "DumpManagerService023 passed: Empty counter returns empty list." << std::endl;
486 }
487 
488 /**
489  * @tc.name: DumpManagerService024
490  * @tc.desc: Test heap replacement logic in TopN.
491  * @tc.type: FUNC
492  */
493 HWTEST_F(HidumperServiceTest, DumpManagerService024, TestSize.Level3)
494 {
495     std::unordered_map<std::string, int> counter = {
496         {"a", 1}, {"b", 3}, {"c", 2}, {"d", 5}, {"e", 4}
497     };
498     size_t n = 3;
499     auto dumpManagerService = std::make_shared<DumpManagerService>();
500     std::vector<std::pair<std::string, int>> result = dumpManagerService->TopN(counter, n);
501 
502     EXPECT_EQ(result.size(), 3);
503     EXPECT_EQ(result[0].first, "d");
504     EXPECT_EQ(result[0].second, 5);
505     EXPECT_EQ(result[1].first, "e");
506     EXPECT_EQ(result[1].second, 4);
507     EXPECT_EQ(result[2].first, "b");
508     EXPECT_EQ(result[2].second, 3);
509     std::cout << "DumpManagerService024 passed: Heap replacement logic works as expected." << std::endl;
510 }
511 
512 /**
513  * @tc.name: DumpManagerService025
514  * @tc.desc: Test GetTopFdInfo with normal input containing multiple entries.
515  * @tc.type: FUNC
516  */
517 HWTEST_F(HidumperServiceTest, DumpManagerService025, TestSize.Level3)
518 {
519     std::vector<std::pair<std::string, int>> topLinks = {
520         {"eventfd", 3},
521         {"pipe", 5},
522         {"ashmem", 2}
523     };
524     auto dumpManagerService = std::make_shared<DumpManagerService>();
525     std::string result = dumpManagerService->GetTopFdInfo(topLinks);
526     std::string expected = "3\teventfd\n5\tpipe\n2\tashmem\n";
527     EXPECT_EQ(result, expected);
528     std::cout << "DumpManagerService025 passed: Normal input format correct." << std::endl;
529 }
530 
531 /**
532  * @tc.name: DumpManagerService026
533  * @tc.desc: Test GetTopFdInfo with empty input.
534  * @tc.type: FUNC
535  */
536 HWTEST_F(HidumperServiceTest, DumpManagerService026, TestSize.Level3)
537 {
538     std::vector<std::pair<std::string, int>> topLinks = {};
539     auto dumpManagerService = std::make_shared<DumpManagerService>();
540     std::string result = dumpManagerService->GetTopFdInfo(topLinks);
541     std::string expected = "";
542     EXPECT_EQ(result, expected);
543     std::cout << "DumpManagerService026 passed: Empty input returns empty string." << std::endl;
544 }
545 
546 /**
547  * @tc.name: DumpManagerService027
548  * @tc.desc: Test GetTopFdInfo with single entry.
549  * @tc.type: FUNC
550  */
551 HWTEST_F(HidumperServiceTest, DumpManagerService027, TestSize.Level3)
552 {
553     std::vector<std::pair<std::string, int>> topLinks = {{"socket", 1}};
554     auto dumpManagerService = std::make_shared<DumpManagerService>();
555     std::string result = dumpManagerService->GetTopFdInfo(topLinks);
556     std::string expected = "1\tsocket\n";
557     EXPECT_EQ(result, expected);
558     std::cout << "DumpManagerService027 passed: Single entry returns correct string." << std::endl;
559 }
560 
561 /**
562  * @tc.name: DumpManagerService028
563  * @tc.desc: Test GetTopFdInfo with non-ASCII characters in names.
564  * @tc.type: FUNC
565  */
566 HWTEST_F(HidumperServiceTest, DumpManagerService028, TestSize.Level3)
567 {
568     std::vector<std::pair<std::string, int>> topLinks = {
569         {"fd\\twith\\tnull", 2},
570         {"file\\nwith\\nnewline", 3}
571     };
572     auto dumpManagerService = std::make_shared<DumpManagerService>();
573     std::string result = dumpManagerService->GetTopFdInfo(topLinks);
574     std::string expected = "2\tfd\\twith\\tnull\n3\tfile\\nwith\\nnewline\n";
575     EXPECT_EQ(result, expected);
576     std::cout << "DumpManagerService028 passed: Non-ASCII characters in names handled properly." << std::endl;
577 }
578 
579 /**
580  * @tc.name: DumpManagerService029
581  * @tc.desc: Test GetTopDirInfo with paths exceeding FD_TOP_CNT (10).
582  * @tc.type: FUNC
583  */
584 HWTEST_F(HidumperServiceTest, DumpManagerService029, TestSize.Level3)
585 {
586     std::vector<std::pair<std::string, int>> topTypes = {
587         {"eventfd", 50}  // Arbitrary value for total
588     };
589     std::map<std::string, std::unordered_map<std::string, int>> typePaths = {
590         {"eventfd", {
591             {"path1", 5},
592             {"path2", 4},
593             {"path3", 3},
594             {"path4", 2},
595             {"path5", 1},
596             {"path6", 6},
597             {"path7", 7},
598             {"path8", 8},
599             {"path9", 9},
600             {"path10", 10},
601             {"path11", 11}, // Exceed FD_TOP_CNT (10)
602             {"path12", 12},
603         }}
604     };
605     auto dumpManagerService = std::make_shared<DumpManagerService>();
606     std::string result = dumpManagerService->GetTopDirInfo(topTypes, typePaths);
607     std::string expected = "50\teventfd\n012\tpath12\n011\tpath11\n010\tpath10\n09\tpath9\n08\tpath8\n"
608                            "07\tpath7\n06\tpath6\n05\tpath1\n04\tpath2\n03\tpath3\n";
609     EXPECT_EQ(result, expected);
610     std::cout << "DumpManagerService029 passed: Paths exceeding FD_TOP_CNT add ellipsis." << std::endl;
611 }
612 
613 /**
614  * @tc.name: DumpManagerService030
615  * @tc.desc: Test GetTopDirInfo with empty input
616  * @tc.type: FUNC
617  */
618 HWTEST_F(HidumperServiceTest, DumpManagerService030, TestSize.Level3)
619 {
620     std::vector<std::pair<std::string, int>> topTypes = {};
621     std::map<std::string, std::unordered_map<std::string, int>> typePaths = {};
622     auto dumpManagerService = std::make_shared<DumpManagerService>();
623     std::string result = dumpManagerService->GetTopDirInfo(topTypes, typePaths);
624     std::string expected = "";
625     EXPECT_EQ(result, expected);
626     std::cout << "DumpManagerService030 passed: Empty input returns empty string." << std::endl;
627 }
628 
629 /**
630  * @tc.name: DumpManagerService031
631  * @tc.desc: Test GetTopDirInfo with type path equal to type name
632  * @tc.type: FUNC
633  */
634 HWTEST_F(HidumperServiceTest, DumpManagerService031, TestSize.Level3)
635 {
636     std::vector<std::pair<std::string, int>> topTypes = {
637         {"socket", 5}
638     };
639     std::map<std::string, std::unordered_map<std::string, int>> typePaths = {
640         {"socket", {
641             {"socket_2", 3},
642             {"socket_1", 2}
643         }}
644     };
645     auto dumpManagerService = std::make_shared<DumpManagerService>();
646     std::string result = dumpManagerService->GetTopDirInfo(topTypes, typePaths);
647     std::string expected = "5	socket\n03\tsocket_2\n02\tsocket_1\n";
648     EXPECT_EQ(result, expected);
649     std::cout << "DumpManagerService031 passed: Skip path equal to type name." << std::endl;
650 }
651 
652 /**
653  * @tc.name: DumpManagerService032
654  * @tc.desc: Test GetSummary when both vectors are empty
655  * @tc.type: FUNC
656  */
657 HWTEST_F(HidumperServiceTest, DumpManagerService032, TestSize.Level3)
658 {
659     std::vector<std::pair<std::string, int>> topLinks{};
660     std::vector<std::pair<std::string, int>> topTypes{};
661     auto dumpManagerService = std::make_shared<DumpManagerService>();
662     std::string result = dumpManagerService->GetSummary(topLinks, topTypes);
663     std::string expected = "";
664     EXPECT_EQ(result, expected);
665     std::cout << "DumpManagerService032 passed: Both vectors empty returns empty." << std::endl;
666 }
667 
668 /**
669  * @tc.name: DumpManagerService033
670  * @tc.desc: Test GetSummary when only topLinks is empty
671  * @tc.type: FUNC
672  */
673 HWTEST_F(HidumperServiceTest, DumpManagerService033, TestSize.Level3)
674 {
675     std::vector<std::pair<std::string, int>> topLinks{};
676     std::vector<std::pair<std::string, int>> topTypes = {{"dir_inode", 10}};
677     auto dumpManagerService = std::make_shared<DumpManagerService>();
678     std::string result = dumpManagerService->GetSummary(topLinks, topTypes);
679     std::string expected = "Leaked dir:dir_inode";
680     EXPECT_EQ(result, expected);
681     std::cout << "DumpManagerService033 passed: Only topTypes has data." << std::endl;
682 }
683 
684 /**
685  * @tc.name: DumpManagerService034
686  * @tc.desc: Test GetSummary when only topTypes is empty
687  * @tc.type: FUNC
688  */
689 HWTEST_F(HidumperServiceTest, DumpManagerService034, TestSize.Level3)
690 {
691     std::vector<std::pair<std::string, int>> topLinks = {{"fd_pipe", 7}};
692     std::vector<std::pair<std::string, int>> topTypes{};
693     auto dumpManagerService = std::make_shared<DumpManagerService>();
694     std::string result = dumpManagerService->GetSummary(topLinks, topTypes);
695     std::string expected = "Leaked fd:fd_pipe";
696     EXPECT_EQ(result, expected);
697     std::cout << "DumpManagerService034 passed: Only topLinks has data." << std::endl;
698 }
699 
700 /**
701  * @tc.name: DumpManagerService035
702  * @tc.desc: Test GetSummary when topLinks count is greater
703  * @tc.type: FUNC
704  */
705 HWTEST_F(HidumperServiceTest, DumpManagerService035, TestSize.Level3)
706 {
707     std::vector<std::pair<std::string, int>> topLinks = {{"fd_char", 10}};
708     std::vector<std::pair<std::string, int>> topTypes = {{"dir_block", 5}};
709     auto dumpManagerService = std::make_shared<DumpManagerService>();
710     std::string result = dumpManagerService->GetSummary(topLinks, topTypes);
711     std::string expected = "Leaked fd:fd_char";
712     EXPECT_EQ(result, expected);
713     std::cout << "DumpManagerService035 passed: Link count dominates." << std::endl;
714 }
715 
716 /**
717  * @tc.name: DumpManagerService036
718  * @tc.desc: Test GetSummary when counts are equal
719  * @tc.type: FUNC
720  */
721 HWTEST_F(HidumperServiceTest, DumpManagerService036, TestSize.Level3)
722 {
723     std::vector<std::pair<std::string, int>> topLinks = {{"fd_dev", 8}};
724     std::vector<std::pair<std::string, int>> topTypes = {{"dir_dev", 8}};
725     auto dumpManagerService = std::make_shared<DumpManagerService>();
726     std::string result = dumpManagerService->GetSummary(topLinks, topTypes);
727     std::string expected = "Leaked fd:fd_dev";
728     EXPECT_EQ(result, expected);
729     std::cout << "DumpManagerService036 passed: Equal counts choose fd." << std::endl;
730 }
731 } // namespace HiviewDFX
732 } // namespace OHOS
733