1/*
2 * Copyright (c) 2022-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
16#include <gtest/gtest.h>
17
18#include <string>
19#include <thread>
20#include <vector>
21
22#include <unistd.h>
23
24#include "dfx_define.h"
25#include "dfx_dump_catcher.h"
26#include "dfx_json_formatter.h"
27#include "dfx_test_util.h"
28#include "faultloggerd_client.h"
29#include "procinfo.h"
30
31using namespace testing;
32using namespace testing::ext;
33
34namespace OHOS {
35namespace HiviewDFX {
36class DumpCatcherInterfacesTest : public testing::Test {
37public:
38    static void SetUpTestCase();
39    static void TearDownTestCase();
40    void SetUp();
41    void TearDown();
42};
43
44static const int THREAD_ALIVE_TIME = 2;
45
46static const int CREATE_THREAD_TIMEOUT = 300000;
47
48static pid_t g_threadId = 0;
49
50static pid_t g_processId = 0;
51
52int g_testPid = 0;
53
54void DumpCatcherInterfacesTest::SetUpTestCase()
55{
56    InstallTestHap("/data/FaultloggerdJsTest.hap");
57    std::string testBundleName = TEST_BUNDLE_NAME;
58    std::string testAbiltyName = testBundleName + ".MainAbility";
59    g_testPid = LaunchTestHap(testAbiltyName, testBundleName);
60}
61
62void DumpCatcherInterfacesTest::TearDownTestCase()
63{
64    StopTestHap(TEST_BUNDLE_NAME);
65    UninstallTestHap(TEST_BUNDLE_NAME);
66}
67
68void DumpCatcherInterfacesTest::SetUp()
69{}
70
71void DumpCatcherInterfacesTest::TearDown()
72{}
73
74static void TestFunRecursive(int recursiveCount)
75{
76    GTEST_LOG_(INFO) << "Enter TestFunRecursive recursiveCount:" << recursiveCount;
77    if (recursiveCount <= 0) {
78        GTEST_LOG_(INFO) << "start enter sleep" << gettid();
79        sleep(THREAD_ALIVE_TIME);
80        GTEST_LOG_(INFO) << "sleep end.";
81    } else {
82        TestFunRecursive(recursiveCount - 1);
83    }
84}
85
86static void* CreateRecursiveThread(void *argv)
87{
88    g_threadId = gettid();
89    GTEST_LOG_(INFO) << "create Recursive MultiThread " << gettid();
90    TestFunRecursive(266); // 266: set recursive count to 266, used for dumpcatcher get stack info
91    GTEST_LOG_(INFO) << "Recursive MultiThread thread sleep end.";
92    return nullptr;
93}
94
95static int RecursiveMultiThreadConstructor(void)
96{
97    pthread_t thread;
98    pthread_create(&thread, nullptr, CreateRecursiveThread, nullptr);
99    pthread_detach(thread);
100    usleep(CREATE_THREAD_TIMEOUT);
101    return 0;
102}
103
104static void* CreateThread(void *argv)
105{
106    g_threadId = gettid();
107    GTEST_LOG_(INFO) << "create MultiThread " << gettid();
108    sleep(THREAD_ALIVE_TIME);
109    GTEST_LOG_(INFO) << "create MultiThread thread sleep end.";
110    return nullptr;
111}
112
113static int MultiThreadConstructor(void)
114{
115    pthread_t thread;
116    pthread_create(&thread, nullptr, CreateThread, nullptr);
117    pthread_detach(thread);
118    usleep(CREATE_THREAD_TIMEOUT);
119    return 0;
120}
121
122static void ForkMultiThreadProcess(void)
123{
124    int pid = fork();
125    if (pid == 0) {
126        MultiThreadConstructor();
127        _exit(0);
128    } else if (pid < 0) {
129        GTEST_LOG_(INFO) << "ForkMultiThreadProcess fail. ";
130    } else {
131        g_processId = pid;
132        GTEST_LOG_(INFO) << "ForkMultiThreadProcess success, pid: " << pid;
133    }
134}
135
136/**
137 * @tc.name: DumpCatcherInterfacesTest001
138 * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr), PID(foundation)}
139 * @tc.type: FUNC
140 */
141HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest001, TestSize.Level2)
142{
143    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest001: start.";
144    std::string testProcess1 = "accountmgr";
145    int testPid1 = GetProcessPid(testProcess1);
146    GTEST_LOG_(INFO) << "testPid1:" << testPid1;
147    std::string testProcess2 = "foundation";
148    int testPid2 = GetProcessPid(testProcess2);
149    GTEST_LOG_(INFO) << "testPid2:" << testPid2;
150    std::vector<int> multiPid {testPid1, testPid2};
151    DfxDumpCatcher dumplog;
152    std::string msg = "";
153    bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
154    GTEST_LOG_(INFO) << ret;
155    string log[] = {"Tid:", "Name:", "Tid:", "Name:"};
156    log[0] = log[0] + std::to_string(testPid1);
157    log[1] = log[1] + testProcess1;
158    log[2] = log[2] + std::to_string(testPid2);
159    log[3] = log[3] + testProcess2;
160    int len = sizeof(log) / sizeof(log[0]);
161    int count = GetKeywordsNum(msg, log, len);
162    EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest001 Failed";
163    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest001: end.";
164}
165
166/**
167 * @tc.name: DumpCatcherInterfacesTest002
168 * @tc.desc: test DumpCatchMultiPid API: multiPid{0, 0}
169 * @tc.type: FUNC
170 */
171HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest002, TestSize.Level2)
172{
173    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest002: start.";
174    int testPid1 = 0;
175    GTEST_LOG_(INFO) << "testPid1:" << testPid1;
176    int testPid2 = 0;
177    GTEST_LOG_(INFO) << "testPid2:" << testPid2;
178    std::vector<int> multiPid {testPid1, testPid2};
179    DfxDumpCatcher dumplog;
180    std::string msg = "";
181    bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
182    GTEST_LOG_(INFO) << ret;
183    EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest002 Failed";
184    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest002: end.";
185}
186
187/**
188 * @tc.name: DumpCatcherInterfacesTest003
189 * @tc.desc: test DumpCatchMultiPid API: multiPid{-11, -11}
190 * @tc.type: FUNC
191 */
192HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest003, TestSize.Level2)
193{
194    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest003: start.";
195    int testPid1 = -11;
196    GTEST_LOG_(INFO) << "testPid1:" << testPid1;
197    int testPid2 = -11;
198    GTEST_LOG_(INFO) << "testPid2:" << testPid2;
199    std::vector<int> multiPid {testPid1, testPid2};
200    DfxDumpCatcher dumplog;
201    std::string msg = "";
202    bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
203    GTEST_LOG_(INFO) << ret;
204    EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest003 Failed";
205    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest003: end.";
206}
207
208/**
209 * @tc.name: DumpCatcherInterfacesTest004
210 * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr), 0}
211 * @tc.type: FUNC
212 */
213HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest004, TestSize.Level2)
214{
215    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest004: start.";
216    std::string testProcess = "accountmgr";
217    int applyPid1 = GetProcessPid(testProcess);
218    GTEST_LOG_(INFO) << "applyPid1:" << applyPid1;
219    int applyPid2 = 0;
220    GTEST_LOG_(INFO) << "applyPid2:" << applyPid2;
221    std::vector<int> multiPid {applyPid1, applyPid2};
222    DfxDumpCatcher dumplog;
223    std::string msg = "";
224    bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
225    GTEST_LOG_(INFO) << ret;
226    string log[] = { "Tid:", "Name:", "Failed" };
227    log[0] = log[0] + std::to_string(applyPid1);
228    log[1] = log[1] + "accountmgr";
229    int len = sizeof(log) / sizeof(log[0]);
230    int count = GetKeywordsNum(msg, log, len);
231    EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest004 Failed";
232    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest004: end.";
233}
234
235/**
236 * @tc.name: DumpCatcherInterfacesTest005
237 * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr),PID(foundation),PID(systemui)}
238 * @tc.type: FUNC
239 */
240HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest005, TestSize.Level2)
241{
242    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest005: start.";
243    std::vector<string> testProcessName = { "accountmgr", "foundation", "com.ohos.systemui" };
244    string matchProcessName[] = { "accountmgr", "foundation", "m.ohos.systemui" };
245    std::vector<int> multiPid;
246    std::vector<string> matchLog;
247    int index = 0;
248    for (string oneProcessName : testProcessName) {
249        int testPid = GetProcessPid(oneProcessName);
250        if (testPid == 0) {
251            GTEST_LOG_(INFO) << "process:" << oneProcessName << " pid is empty, skip";
252            index++;
253            continue;
254        }
255        multiPid.emplace_back(testPid);
256        matchLog.emplace_back("Tid:" + std::to_string(testPid));
257        matchLog.emplace_back("Name:" + matchProcessName[index]);
258        index++;
259    }
260
261    // It is recommended that the number of effective pids be greater than 1,
262    // otherwise the testing purpose will not be achieved
263    EXPECT_GT(multiPid.size(), 1) << "DumpCatcherInterfacesTest005 Failed";
264
265    DfxDumpCatcher dumplog;
266    std::string msg = "";
267    bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
268    GTEST_LOG_(INFO) << "ret:" << ret;
269
270    int matchLogCount = matchLog.size();
271    auto matchLogArray = std::make_unique<string[]>(matchLogCount);
272    index = 0;
273    for (string info : matchLog) {
274        matchLogArray[index] = info;
275        index++;
276    }
277    int count = GetKeywordsNum(msg, matchLogArray.get(), matchLogCount);
278    EXPECT_EQ(count, matchLogCount) << msg << "DumpCatcherInterfacesTest005 Failed";
279    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest005: end.";
280}
281
282/**
283 * @tc.name: DumpCatcherInterfacesTest006
284 * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr), -11}
285 * @tc.type: FUNC
286 */
287HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest006, TestSize.Level2)
288{
289    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest006: start.";
290    std::string testProcess = "accountmgr";
291    int testPid1 = GetProcessPid(testProcess);
292    GTEST_LOG_(INFO) << "applyPid1:" << testPid1;
293    int testPid2 = -11;
294    GTEST_LOG_(INFO) << "applyPid2:" << testPid2;
295    std::vector<int> multiPid {testPid1, testPid2};
296    DfxDumpCatcher dumplog;
297    std::string msg = "";
298    bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
299    GTEST_LOG_(INFO) << ret;
300    string log[] = { "Tid:", "Name:", "Failed"};
301    log[0] = log[0] + std::to_string(testPid1);
302    log[1] = log[1] + "accountmgr";
303    int len = sizeof(log) / sizeof(log[0]);
304    int count = GetKeywordsNum(msg, log, len);
305    EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest006 Failed";
306    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest006: end.";
307}
308
309/**
310 * @tc.name: DumpCatcherInterfacesTest007
311 * @tc.desc: test DumpCatchMultiPid API: multiPid{9999, 9999}
312 * @tc.type: FUNC
313 */
314HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest007, TestSize.Level2)
315{
316    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest007: start.";
317    int applyPid = 9999;
318    GTEST_LOG_(INFO) << "applyPid1:" << applyPid;
319    std::vector<int> multiPid {applyPid, applyPid};
320    DfxDumpCatcher dumplog;
321    std::string msg = "";
322    bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
323    GTEST_LOG_(INFO) << ret;
324    EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest007 Failed";
325    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest007: end.";
326}
327
328/**
329 * @tc.name: DumpCatcherInterfacesTest008
330 * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr), 9999}
331 * @tc.type: FUNC
332 */
333HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest008, TestSize.Level2)
334{
335    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest008: start.";
336    std::string apply = "accountmgr";
337    int applyPid1 = GetProcessPid(apply);
338    GTEST_LOG_(INFO) << "applyPid1:" << applyPid1;
339    int applyPid2 = 9999;
340    GTEST_LOG_(INFO) << "applyPid2:" << applyPid2;
341    std::vector<int> multiPid {applyPid1, applyPid2};
342    DfxDumpCatcher dumplog;
343    std::string msg = "";
344    bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
345    GTEST_LOG_(INFO) << ret;
346    string log[] = { "Tid:", "Name:", "Failed"};
347    log[0] = log[0] + std::to_string(applyPid1);
348    log[1] = log[1] + apply;
349    int len = sizeof(log) / sizeof(log[0]);
350    int count = GetKeywordsNum(msg, log, len);
351    EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest008 Failed";
352    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest008: end.";
353}
354
355/**
356 * @tc.name: DumpCatcherInterfacesTest014
357 * @tc.desc: test DumpCatch API: PID(test hap), TID(0)
358 * @tc.type: FUNC
359 * @tc.require: issueI5PJ9O
360 */
361HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest014, TestSize.Level2)
362{
363    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest014: start.";
364    bool isSuccess = g_testPid != 0;
365    if (!isSuccess) {
366        ASSERT_FALSE(isSuccess);
367        GTEST_LOG_(ERROR) << "Failed to launch target hap.";
368        return;
369    }
370    isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
371    if (!isSuccess) {
372        ASSERT_FALSE(isSuccess);
373        GTEST_LOG_(ERROR) << "Error process comm";
374        return;
375    }
376    DfxDumpCatcher dumplog;
377    std::string msg = "";
378    bool ret = dumplog.DumpCatch(g_testPid, 0, msg);
379    GTEST_LOG_(INFO) << ret;
380    string log[] = { "Tid:", "Name:", "#00", "/system/bin/appspawn", "Name:OS_DfxWatchdog" };
381    log[0] += std::to_string(g_testPid);
382    log[1] += TRUNCATE_TEST_BUNDLE_NAME;
383    int len = sizeof(log) / sizeof(log[0]);
384    int count = GetKeywordsNum(msg, log, len);
385    EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest014 Failed";
386    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest014: end.";
387}
388
389/**
390 * @tc.name: DumpCatcherInterfacesTest015
391 * @tc.desc: test DumpCatch API: PID(test hap), TID(test hap main thread)
392 * @tc.type: FUNC
393 * @tc.require: issueI5PJ9O
394 */
395HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest015, TestSize.Level2)
396{
397    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest015: start.";
398    bool isSuccess = g_testPid != 0;
399    if (!isSuccess) {
400        ASSERT_FALSE(isSuccess);
401        GTEST_LOG_(ERROR) << "Failed to launch target hap.";
402        return;
403    }
404    isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
405    if (!isSuccess) {
406        ASSERT_FALSE(isSuccess);
407        GTEST_LOG_(ERROR) << "Error process comm";
408        return;
409    }
410    DfxDumpCatcher dumplog;
411    std::string msg = "";
412    bool ret = dumplog.DumpCatch(g_testPid, g_testPid, msg);
413    GTEST_LOG_(INFO) << ret;
414    string log[] = { "Tid:", "Name:", "#00", "/system/bin/appspawn"};
415    log[0] += std::to_string(g_testPid);
416    log[1] += TRUNCATE_TEST_BUNDLE_NAME;
417    int len = sizeof(log) / sizeof(log[0]);
418    int count = GetKeywordsNum(msg, log, len);
419    GTEST_LOG_(INFO) << msg;
420    EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest015 Failed";
421    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest015: end.";
422}
423
424/**
425 * @tc.name: DumpCatcherInterfacesTest016
426 * @tc.desc: test DumpCatch API: PID(test hap), TID(-1)
427 * @tc.type: FUNC
428 * @tc.require: issueI5PJ9O
429 */
430HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest016, TestSize.Level2)
431{
432    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest016: start.";
433    bool isSuccess = g_testPid != 0;
434    if (!isSuccess) {
435        ASSERT_FALSE(isSuccess);
436        GTEST_LOG_(ERROR) << "Failed to launch target hap.";
437        return;
438    }
439    isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
440    if (!isSuccess) {
441        ASSERT_FALSE(isSuccess);
442        GTEST_LOG_(ERROR) << "Error process comm";
443        return;
444    }
445    DfxDumpCatcher dumplog;
446    std::string msg = "";
447    bool ret = dumplog.DumpCatch(g_testPid, -1, msg);
448    GTEST_LOG_(INFO) << ret;
449    EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest016 Failed";
450    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest016: end.";
451}
452
453/**
454 * @tc.name: DumpCatcherInterfacesTest017
455 * @tc.desc: test DumpCatch API: PID(-1), TID(-1)
456 * @tc.type: FUNC
457 * @tc.require: issueI5PJ9O
458 */
459HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest017, TestSize.Level2)
460{
461    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest017: start.";
462    DfxDumpCatcher dumplog;
463    std::string msg = "";
464    bool ret = dumplog.DumpCatch(-1, -1, msg);
465    GTEST_LOG_(INFO) << ret;
466    EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest017 Failed";
467    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest017: end.";
468}
469
470/**
471 * @tc.name: DumpCatcherInterfacesTest018
472 * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(gettid())
473 * @tc.type: FUNC
474 */
475HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest018, TestSize.Level2)
476{
477    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest018: start.";
478    DfxDumpCatcher dumplog;
479    std::string msg = "";
480    bool ret = dumplog.DumpCatchFd(getpid(), gettid(), msg, 1);
481    GTEST_LOG_(INFO) << ret;
482    EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest018 Failed";
483    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest018: end.";
484}
485
486/**
487 * @tc.name: DumpCatcherInterfacesTest019
488 * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(0)
489 * @tc.type: FUNC
490 */
491HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest019, TestSize.Level2)
492{
493    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest019: start.";
494    DfxDumpCatcher dumplog;
495    std::string msg = "";
496    bool ret = dumplog.DumpCatchFd(getpid(), 0, msg, 1);
497    GTEST_LOG_(INFO) << ret;
498    EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest019 Failed";
499    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest019: end.";
500}
501
502/**
503 * @tc.name: DumpCatcherInterfacesTest020
504 * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(-1)
505 * @tc.type: FUNC
506 */
507HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest020, TestSize.Level2)
508{
509    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest020: start.";
510    DfxDumpCatcher dumplog;
511    std::string msg = "";
512    bool ret = dumplog.DumpCatchFd(getpid(), -1, msg, 1);
513    GTEST_LOG_(INFO) << ret;
514    EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest020 Failed";
515    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest020: end.";
516}
517
518
519/**
520 * @tc.name: DumpCatcherInterfacesTest021
521 * @tc.desc: test DumpCatchFd API: PID(accountmgr), TID(0)
522 * @tc.type: FUNC
523 */
524HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest021, TestSize.Level2)
525{
526    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest021: start.";
527    std::string apply = "accountmgr";
528    int applyPid = GetProcessPid(apply);
529    GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
530    DfxDumpCatcher dumplog;
531    std::string msg = "";
532    bool ret = dumplog.DumpCatchFd(applyPid, 0, msg, 1);
533    GTEST_LOG_(INFO) << ret;
534    EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest021 Failed";
535    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest021: end.";
536}
537
538/**
539 * @tc.name: DumpCatcherInterfacesTest022
540 * @tc.desc: test DumpCatchFd API: PID(accountmgr), TID(accountmgr main thread)
541 * @tc.type: FUNC
542 */
543HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest022, TestSize.Level2)
544{
545    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest022: start.";
546    std::string apply = "accountmgr";
547    int applyPid = GetProcessPid(apply);
548    GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
549    DfxDumpCatcher dumplog;
550    std::string msg = "";
551    bool ret = dumplog.DumpCatchFd(applyPid, applyPid, msg, 1);
552    GTEST_LOG_(INFO) << ret;
553    EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest022 Failed";
554    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest022: end.";
555}
556
557/**
558 * @tc.name: DumpCatcherInterfacesTest023
559 * @tc.desc: test DumpCatchFd API: PID(accountmgr), TID(-1)
560 * @tc.type: FUNC
561 */
562HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest023, TestSize.Level2)
563{
564    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest023: start.";
565    std::string apply = "accountmgr";
566    int applyPid = GetProcessPid(apply);
567    GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
568    DfxDumpCatcher dumplog;
569    std::string msg = "";
570    bool ret = dumplog.DumpCatchFd(applyPid, -1, msg, 1);
571    GTEST_LOG_(INFO) << ret;
572    EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest023 Failed";
573    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest023: end.";
574}
575
576/**
577 * @tc.name: DumpCatcherInterfacesTest024
578 * @tc.desc: test DumpCatchFd API: PID(accountmgr), TID(9999)
579 * @tc.type: FUNC
580 */
581HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest024, TestSize.Level2)
582{
583    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest024: start.";
584    std::string apply = "accountmgr";
585    int applyPid = GetProcessPid(apply);
586    GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
587    DfxDumpCatcher dumplog;
588    std::string msg = "";
589    bool ret = dumplog.DumpCatchFd(applyPid, 9999, msg, 1);
590    GTEST_LOG_(INFO) << ret;
591    EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest024 Failed";
592    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest024: end.";
593}
594
595/**
596 * @tc.name: DumpCatcherInterfacesTest025
597 * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(9999)
598 * @tc.type: FUNC
599 */
600HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest025, TestSize.Level2)
601{
602    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest025: start.";
603    DfxDumpCatcher dumplog;
604    std::string msg = "";
605    bool ret = dumplog.DumpCatchFd(getpid(), 9999, msg, 1);
606    GTEST_LOG_(INFO) << ret;
607    EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest025 Failed";
608    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest025: end.";
609}
610
611/**
612 * @tc.name: DumpCatcherInterfacesTest026
613 * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(child thread)
614 * @tc.type: FUNC
615 */
616HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest026, TestSize.Level2)
617{
618    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest026: start.";
619    MultiThreadConstructor();
620    DfxDumpCatcher dumplog;
621    std::string msg = "";
622    GTEST_LOG_(INFO) << "dump local process, "  << " tid:" << g_threadId;
623    bool ret = dumplog.DumpCatchFd(getpid(), g_threadId, msg, 1);
624    GTEST_LOG_(INFO) << ret;
625    EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest026 Failed";
626    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest026: end.";
627}
628
629/**
630 * @tc.name: DumpCatcherInterfacesTest027
631 * @tc.desc: test DumpCatchFd API: PID(child process), TID(child thread of child process)
632 * @tc.type: FUNC
633 */
634HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest027, TestSize.Level2)
635{
636    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest027: start.";
637    ForkMultiThreadProcess();
638    std::vector<int> tids;
639    std::vector<int> nstids;
640    bool isSuccess = GetTidsByPid(g_processId, tids, nstids);
641    if (!isSuccess) {
642        ASSERT_FALSE(isSuccess);
643        return;
644    }
645    int childTid = tids[1]; // 1 : child thread
646    GTEST_LOG_(INFO) << "dump remote process, "  << " pid:" << g_processId << ", tid:" << childTid;
647    DfxDumpCatcher dumplog;
648    std::string msg = "";
649    bool ret = dumplog.DumpCatchFd(g_processId, childTid, msg, 1);
650    GTEST_LOG_(INFO) << ret;
651    EXPECT_TRUE(ret) << "DumpCatcherInterfacesTest027 Failed";
652    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest027: end.";
653}
654
655/**
656 * @tc.name: DumpCatcherInterfacesTest028
657 * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(child thread) and config FrameNum
658 * @tc.type: FUNC
659 */
660HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest028, TestSize.Level2)
661{
662    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest028: start.";
663    RecursiveMultiThreadConstructor();
664    DfxDumpCatcher dumplog;
665    std::string msg = "";
666    GTEST_LOG_(INFO) << "dump local process, "  << " tid:" << g_threadId;
667    bool ret = dumplog.DumpCatchFd(getpid(), g_threadId, msg, 1, 10); // 10 means backtrace frames is 10
668    GTEST_LOG_(INFO) << "message:"  << msg;
669    GTEST_LOG_(INFO) << ret;
670    EXPECT_TRUE(msg.find("#09") != std::string::npos);
671    EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest028 Failed";
672    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest028: end.";
673}
674
675/**
676 * @tc.name: DumpCatcherInterfacesTest029
677 * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(child thread) and DEFAULT_MAX_FRAME_NUM
678 * @tc.type: FUNC
679 */
680HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest029, TestSize.Level2)
681{
682    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest029: start.";
683    RecursiveMultiThreadConstructor();
684    usleep(CREATE_THREAD_TIMEOUT);
685    DfxDumpCatcher dumplog;
686    std::string msg = "";
687    GTEST_LOG_(INFO) << "dump local process, "  << " tid:" << g_threadId;
688    bool ret = dumplog.DumpCatchFd(getpid(), g_threadId, msg, 1);
689    GTEST_LOG_(INFO) << "message:"  << msg;
690    GTEST_LOG_(INFO) << ret;
691#if defined(__aarch64__)
692    std::string stackKeyword = std::string("#") + std::to_string(DEFAULT_MAX_LOCAL_FRAME_NUM - 1);
693#else
694    std::string stackKeyword = std::string("#") + std::to_string(DEFAULT_MAX_FRAME_NUM - 1);
695#endif
696    GTEST_LOG_(INFO) << "stackKeyword:"  << stackKeyword;
697    EXPECT_TRUE(msg.find(stackKeyword.c_str()) != std::string::npos);
698    EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest029 Failed";
699    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest029: end.";
700}
701
702#ifndef is_ohos_lite
703/**
704 * @tc.name: DumpCatcherInterfacesTest030
705 * @tc.desc: test DumpCatch remote API: PID(getpid()), TID(child thread)
706 *     and maxFrameNums(DEFAULT_MAX_FRAME_NUM), isJson(true)
707 * @tc.type: FUNC
708 */
709HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest030, TestSize.Level2)
710{
711    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest030: start.";
712    pid_t pid = fork();
713    if (pid == 0) {
714        std::this_thread::sleep_for(std::chrono::seconds(10));
715        _exit(0);
716    }
717    GTEST_LOG_(INFO) << "dump remote process, "  << " pid:" << pid << ", tid:" << 0;
718    DfxDumpCatcher dumplog;
719    DfxJsonFormatter format;
720    string msg = "";
721    bool ret = dumplog.DumpCatch(pid, 0, msg);
722    EXPECT_TRUE(ret) << "DumpCatch remote msg Failed.";
723    string jsonMsg = "";
724    bool jsonRet = dumplog.DumpCatch(pid, 0, jsonMsg, DEFAULT_MAX_FRAME_NUM, true);
725    std::cout << jsonMsg << std::endl;
726    EXPECT_TRUE(jsonRet) << "DumpCatch remote json Failed.";
727    string stackMsg = "";
728    bool formatRet = format.FormatJsonStack(jsonMsg, stackMsg);
729    EXPECT_TRUE(formatRet) << "FormatJsonStack Failed.";
730    size_t pos = msg.find("Process name:");
731    if (pos != std::string::npos) {
732        msg = msg.erase(0, pos);
733        msg = msg.erase(0, msg.find("\n") + 1);
734    } else {
735        msg = msg.erase(0, msg.find("\n") + 1);
736    }
737    EXPECT_EQ(stackMsg == msg, true) << "stackMsg != msg";
738    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest030: end.";
739}
740
741/**
742 * @tc.name: DumpCatcherInterfacesTest031
743 * @tc.desc: test DumpCatchProcess
744 * @tc.type: FUNC
745 */
746HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest031, TestSize.Level2)
747{
748    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest031: start.";
749    std::string res = ExecuteCommands("uname");
750    bool isSuccess = res.find("Linux") == std::string::npos;
751    if (!isSuccess) {
752        ASSERT_FALSE(isSuccess);
753        return;
754    }
755    isSuccess = g_testPid != 0;
756    if (!isSuccess) {
757        ASSERT_FALSE(isSuccess);
758        GTEST_LOG_(ERROR) << "Failed to launch target hap.";
759        return;
760    }
761    isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
762    if (!isSuccess) {
763        ASSERT_FALSE(isSuccess);
764        GTEST_LOG_(ERROR) << "Error process comm";
765        return;
766    }
767    std::string stopProcessCmd = "kill -s SIGSTOP $(pidof com.example.myapplication)";
768    ExecuteCommands(stopProcessCmd);
769    DfxDumpCatcher dumplog;
770    std::string msg = "";
771    ASSERT_EQ(dumplog.DumpCatchProcess(g_testPid, msg), 1); //kernel stack
772    GTEST_LOG_(INFO) << msg;
773    std::string formattedStack = "";
774    ASSERT_TRUE(DfxJsonFormatter::FormatKernelStack(msg, formattedStack, false));
775    ASSERT_GT(formattedStack.size(), 0);
776    GTEST_LOG_(INFO) << formattedStack;
777    ASSERT_NE(formattedStack.find("#"), std::string::npos);
778    ASSERT_TRUE(DfxJsonFormatter::FormatKernelStack(msg, formattedStack, true));
779    GTEST_LOG_(INFO) << formattedStack;
780    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest031: end.";
781}
782#endif
783
784#ifndef is_ohos_lite
785/**
786 * @tc.name: DumpCatcherInterfacesTest032
787 * @tc.desc: test DfxJsonFormatter
788 * @tc.type: FUNC
789 */
790HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest032, TestSize.Level2)
791{
792    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest032: start.";
793    DfxJsonFormatter format;
794    string outStackStr = "";
795    string errorJsonMsg = "{\"test\"}";
796    bool formatRet = format.FormatJsonStack(errorJsonMsg, outStackStr);
797    EXPECT_FALSE(formatRet);
798
799    outStackStr = "";
800    string noThreadJsonMsg = "[{\"tid\" : \"1\"}]";
801    formatRet = format.FormatJsonStack(noThreadJsonMsg, outStackStr);
802    EXPECT_TRUE(formatRet);
803
804    outStackStr = "";
805    string noTidJsonMsg = "[{\"thread_name\" : \"test\"}]";
806    formatRet = format.FormatJsonStack(noTidJsonMsg, outStackStr);
807    EXPECT_TRUE(formatRet);
808
809    outStackStr = "";
810    string jsJsonMsg = R"~([{"frames":[{"buildId":"", "file":"/system/lib/ld-musl-arm.so.1",
811        "offset":0, "pc":"000fdf4c", "symbol":""}, {"line":"1", "file":"/system/lib/ld-musl-arm.so.1",
812        "offset":628, "pc":"000ff7f4", "symbol":"__pthread_cond_timedwait_time64"}],
813        "thread_name":"OS_SignalHandle", "tid":1608}])~";
814    formatRet = format.FormatJsonStack(jsJsonMsg, outStackStr);
815    EXPECT_TRUE(formatRet);
816    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest032: end.";
817}
818#endif
819
820/**
821@tc.name: DumpCatcherInterfacesTest033
822@tc.desc: testDump after crashed
823@tc.type: FUNC
824*/
825HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest033, TestSize.Level2)
826{
827    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest033: start.";
828    pid_t pid = fork();
829    if (pid == 0) {
830        int32_t fd = RequestFileDescriptor(FaultLoggerType::CPP_CRASH);
831        ASSERT_GT(fd, 0);
832        close(fd);
833        std::this_thread::sleep_for(std::chrono::seconds(10));
834        _exit(0);
835    } else if (pid < 0) {
836        GTEST_LOG_(INFO) << "Fail in fork.";
837    } else {
838        GTEST_LOG_(INFO) << "dump remote process, " << "pid:" << pid << ", tid:" << 0;
839        DfxDumpCatcher dumplog;
840        string msg = "";
841        EXPECT_FALSE(dumplog.DumpCatch(pid, 0, msg));
842        constexpr int validTime = 8;
843        sleep(validTime);
844        msg = "";
845        EXPECT_TRUE(dumplog.DumpCatch(pid, 0, msg));
846    }
847    GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest033: end.";
848}
849} // namespace HiviewDFX
850} // namepsace OHOS