1 /*
2 * Copyright (c) 2023 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 <cstring>
17 #include <gtest/gtest.h>
18 #include <unistd.h>
19 #include <vector>
20
21 #include "hisysevent_manager.h"
22 #include "rustpanic_listener.h"
23
24 using namespace testing;
25 using namespace testing::ext;
26
27 namespace OHOS {
28 namespace HiviewDFX {
29 namespace {
30 static std::shared_ptr<RustPanicListener> panicListener = nullptr;
31 }
32 class PanicHandlerTest : public testing::Test {
33 public:
34 static void SetUpTestCase();
35 static void TearDownTestCase();
36 void SetUp();
37 void TearDown();
38 };
39
SetUpTestCase()40 void PanicHandlerTest::SetUpTestCase()
41 {}
42
TearDownTestCase()43 void PanicHandlerTest::TearDownTestCase()
44 {}
45
SetUp()46 void PanicHandlerTest::SetUp()
47 {
48 chmod("/data/rustpanic_maker", 0755); // 0755 : -rwxr-xr-x
49 }
50
TearDown()51 void PanicHandlerTest::TearDown()
52 {
53 panicListener = nullptr;
54 }
55
ForkAndTriggerRustPanic(bool ismain)56 static void ForkAndTriggerRustPanic(bool ismain)
57 {
58 pid_t pid = fork();
59 if (pid < 0) {
60 GTEST_LOG_(ERROR) << "ForkAndTriggerRustPanic: Failed to fork panic process.";
61 return;
62 } else if (pid == 0) {
63 if (ismain) {
64 execl("/data/rustpanic_maker", "rustpanic_maker", "main", nullptr);
65 } else {
66 execl("/data/rustpanic_maker", "rustpanic_maker", "child", nullptr);
67 }
68 }
69 }
70
ListenAndCheckHiSysevent()71 static void ListenAndCheckHiSysevent()
72 {
73 panicListener = std::make_shared<RustPanicListener>();
74 ListenerRule tagRule("RELIABILITY", "RUST_PANIC", RuleType::WHOLE_WORD);
75 std::vector<ListenerRule> sysRules;
76 sysRules.push_back(tagRule);
77 HiSysEventManager::AddListener(panicListener, sysRules);
78 }
79
80 /**
81 * @tc.name: PanicHandlerTest001
82 * @tc.desc: test panic in main thread
83 * @tc.type: FUNC
84 * @tc.require: issueI6HM7C
85 */
86 HWTEST_F(PanicHandlerTest, PanicHandlerTest001, TestSize.Level2)
87 {
88 GTEST_LOG_(INFO) << "PanicHandlerTest001: start.";
89 ListenAndCheckHiSysevent();
90 panicListener->SetKeyWord("panic in main thread");
91 ForkAndTriggerRustPanic(true);
92 if (panicListener != nullptr) {
93 GTEST_LOG_(INFO) << "PanicHandlerTest001: ready to check hisysevent reason keyword.";
94 ASSERT_TRUE(panicListener->CheckKeywordInReasons());
95 }
96 GTEST_LOG_(INFO) << "PanicHandlerTest001: end.";
97 }
98
99 /**
100 * @tc.name: PanicHandlerTest002
101 * @tc.desc: test panic in child thread
102 * @tc.type: FUNC
103 * @tc.require: issueI6HM7C
104 */
105 HWTEST_F(PanicHandlerTest, PanicHandlerTest002, TestSize.Level2)
106 {
107 GTEST_LOG_(INFO) << "PanicHandlerTest002: start.";
108 ListenAndCheckHiSysevent();
109 panicListener->SetKeyWord("panic in child thread");
110 ForkAndTriggerRustPanic(false);
111 if (panicListener != nullptr) {
112 GTEST_LOG_(INFO) << "PanicHandlerTest002: ready to check hisysevent reason keyword.";
113 ASSERT_TRUE(panicListener->CheckKeywordInReasons());
114 }
115 GTEST_LOG_(INFO) << "PanicHandlerTest002: end.";
116 }
117 } // namespace HiviewDFX
118 } // namespace OHOS