1 /*
2  * Copyright (c) 2022 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 <fstream>
16 #include "bbox_detector_unit_test.h"
17 
18 #include "bbox_detector_plugin.h"
19 #include "bbox_detectors_mock.h"
20 #include "panic_report_recovery.h"
21 #include "hisysevent_util_mock.h"
22 #include "sys_event.h"
23 #include "sys_event_dao.h"
24 #include "smart_parser.h"
25 #include "tbox.h"
26 using namespace std;
27 
28 namespace OHOS {
29 namespace HiviewDFX {
30 using namespace testing;
31 using namespace testing::ext;
SetUpTestCase(void)32 void BBoxDetectorUnitTest::SetUpTestCase(void) {}
33 
TearDownTestCase(void)34 void BBoxDetectorUnitTest::TearDownTestCase(void) {}
35 
SetUp(void)36 void BBoxDetectorUnitTest::SetUp(void)
37 {
38     FileUtil::ForceCreateDirectory("/data/test/bbox/panic_log/");
39     FileUtil::ForceCreateDirectory("/data/test/bbox/ap_log/");
40 }
41 
TearDown(void)42 void BBoxDetectorUnitTest::TearDown(void)
43 {
44     FileUtil::ForceRemoveDirectory("/data/test/bbox/");
45 }
46 
GenerateFile(const std::string & path,unsigned int size)47 void GenerateFile(const std::string &path, unsigned int size)
48 {
49     constexpr int bufferSize = 1024;
50     constexpr int charSize = 26;
51     std::ofstream ofs;
52     ofs.open(path, std::ios::out | std::ios::trunc);
53     for (unsigned int i = 0; i < size; i++) {
54         for (int j = 0; j < bufferSize; ++j) {
55             ofs << static_cast<char>(rand() % charSize + 'a');
56         }
57     }
58     ofs << std::endl;
59     ofs.close();
60 }
61 
62 /**
63  * @tc.name: BBoxDetectorUnitTest001
64  * @tc.desc: check bbox config parser whether it is passed.
65  *           1.parse bbox config;
66  *           2.check result;
67  * @tc.type: FUNC
68  * @tc.require:
69  * @tc.author: liuwei
70  */
71 HWTEST_F(BBoxDetectorUnitTest, BBoxDetectorUnitTest001, TestSize.Level1)
72 {
73     /**
74      * @tc.steps: step1. init bboxDetector and parse hisysevent.
75      */
76 
77     /**
78      * @tc.steps: step2. check func.
79      * @tc.expect: get right result for checking
80      */
81     SysEventCreator sysEventCreator("KERNEL_VENDOR", "PANIC", SysEventCreator::FAULT);
82     auto sysEvent = make_shared<SysEvent>("test", nullptr, sysEventCreator);
83     auto testPlugin = make_shared<BBoxDetectorPlugin>();
84     shared_ptr<Event> event = dynamic_pointer_cast<Event>(sysEvent);
85     EXPECT_EQ(testPlugin->CanProcessEvent(event), true);
86 }
87 
88 /**
89  * @tc.name: BBoxDetectorUnitTest002
90  * @tc.desc: check whether fault is processed,and check whether fault file is pasered
91  *           1. check whether fault file is pasered;
92  * @tc.type: FUNC
93  * @tc.require:
94  * @tc.author: liuwei
95  */
96 HWTEST_F(BBoxDetectorUnitTest, BBoxDetectorUnitTest002, TestSize.Level1)
97 {
98     /**
99      * @tc.steps: step1. construct panic file path
100      * @tc.steps: step2. Analysis panic event
101      * @tc.steps: step3. check result
102      */
103     string stack = R"("dump_backtrace+0x0/0x184"
104                      "show_stack+0x2c/0x3c",
105                      "dump_stack+0xc0/0x11c",
106                      "panic+0x1cc/0x3dc",
107                      "sysrq_handle_term+0x0/0x94",
108                      "__handle_sysrq+0x15c/0x184",
109                      "write_sysrq_trigger+0xb0/0xf4",
110                      "proc_reg_write+0x94/0x120",
111                      "vfs_write+0x184/0x380",
112                      "ksys_write+0x74/0xc8",
113                      "__arm64_sys_write+0x24/0x34",
114                      "el0_svc_common+0x104/0x180",
115                      "do_el0_svc+0x2c/0x3c",
116                      "el0_svc+0x10/0x1c",
117                      "vks_write+0x123/0xa6",
118                      "el0_sync+0x180/0x1c0"
119                     )";
120 
121     std::map<std::string, std::string> eventInfos;
122     eventInfos.insert(std::pair("END_STACK", stack));
123     eventInfos.insert(std::pair("PNAME", "PANIC"));
124     eventInfos.insert(std::pair("Eventid", "901000002"));
125     Tbox::FilterTrace(eventInfos);
126 
127     EXPECT_STREQ(eventInfos["FIRST_FRAME"].c_str(), "sysrq_handle_term+0x0/0x94");
128     EXPECT_STREQ(eventInfos["SECOND_FRAME"].c_str(), "__handle_sysrq+0x15c/0x184");
129 }
130 
131 /**
132  * @tc.name: BBoxDetectorUnitTest003
133  * @tc.desc: check the interface IsRecoveryPanicEvent.
134  * @tc.type: FUNC
135  * @tc.require:
136  * @tc.author: liuwei
137  */
138 HWTEST_F(BBoxDetectorUnitTest, BBoxDetectorUnitTest003, TestSize.Level1)
139 {
140     SysEventCreator sysEventCreator("KERNEL_VENDOR", "PANIC", SysEventCreator::FAULT);
141     auto sysEvent = make_shared<SysEvent>("test", nullptr, sysEventCreator);
142     sysEvent->SetEventValue("LOG_PATH", "/data/test/bbox/panic_log/test");
143     ASSERT_TRUE(PanicReport::IsRecoveryPanicEvent(sysEvent));
144     sysEvent->SetEventValue("LOG_PATH", "OTHERS");
145     ASSERT_FALSE(PanicReport::IsRecoveryPanicEvent(sysEvent));
146 }
147 
148 /**
149  * @tc.name: BBoxDetectorUnitTest004
150  * @tc.desc: check whether the param of isShortStartUp work.
151  * @tc.type: FUNC
152  * @tc.require:
153  * @tc.author: liuwei
154  */
155 HWTEST_F(BBoxDetectorUnitTest, BBoxDetectorUnitTest004, TestSize.Level1)
156 {
157     ASSERT_TRUE(PanicReport::InitPanicReport());
158     ASSERT_FALSE(PanicReport::IsLastShortStartUp());
159     ASSERT_TRUE(PanicReport::InitPanicReport());
160     ASSERT_TRUE(PanicReport::IsLastShortStartUp());
161 }
162 
163 /**
164  * @tc.name: BBoxDetectorUnitTest005
165  * @tc.desc: check whether the file will be deleted when it is over limit.
166  * @tc.type: FUNC
167  * @tc.require:
168  * @tc.author: liuwei
169  */
170 HWTEST_F(BBoxDetectorUnitTest, BBoxDetectorUnitTest005, TestSize.Level1)
171 {
172     constexpr const char* testFile = "/data/test/bbox/panic_log/test";
173     constexpr const unsigned int testFileSize = 5 * 1024 + 1;
174     GenerateFile(testFile, testFileSize);
175     ASSERT_TRUE(FileUtil::FileExists(testFile));
176     ASSERT_TRUE(PanicReport::InitPanicReport());
177     ASSERT_FALSE(FileUtil::FileExists(testFile));
178 }
179 
180 /**
181  * @tc.name: BBoxDetectorUnitTest006
182  * @tc.desc: check whether the process of compress is work.
183  * @tc.type: FUNC
184  * @tc.require:
185  * @tc.author: liuwei
186  */
187 HWTEST_F(BBoxDetectorUnitTest, BBoxDetectorUnitTest006, TestSize.Level1)
188 {
189     constexpr const char* testHmKLog = "/data/test/bbox/ap_log/hm_klog.txt";
190     GenerateFile(testHmKLog, 0);
191     constexpr const char* testLastFastBootLog = "/data/test/bbox/ap_log/last_fastboot_log";
192     GenerateFile(testLastFastBootLog, 0);
193 
194     constexpr const char* testHmSnap = "/data/test/bbox/ap_log/hm_snapshot.txt";
195     GenerateFile(testHmSnap, 0);
196     constexpr const char* testHappenTimeStr1 = "20170805171207-00000001";
197     PanicReport::CompressAndCopyLogFiles("/data/test/bbox/", testHappenTimeStr1);
198     auto bboxSaveLogFlags = PanicReport::LoadBboxSaveFlagFromFile();
199     ASSERT_EQ(bboxSaveLogFlags.happenTime, testHappenTimeStr1);
200     ASSERT_TRUE(FileUtil::FileExists(PanicReport::GetBackupFilePath(testHappenTimeStr1)));
201 
202     GenerateFile(testHmSnap, 40 * 1024);
203     constexpr const char* testHappenTimeStr2 = "20170805171207-00000002";
204     PanicReport::CompressAndCopyLogFiles("/data/test/bbox/", testHappenTimeStr2);
205     ASSERT_EQ(FileUtil::GetFolderSize("/data/test/bbox/panic_log/"), 0);
206 
207     GenerateFile(testHmSnap, 6 * 1024);
208     constexpr const char* testHappenTimeStr3 = "20170805171207-00000003";
209     PanicReport::CompressAndCopyLogFiles("/data/test/bbox/", testHappenTimeStr3);
210     bboxSaveLogFlags = PanicReport::LoadBboxSaveFlagFromFile();
211     ASSERT_EQ(bboxSaveLogFlags.happenTime, testHappenTimeStr3);
212     ASSERT_TRUE(FileUtil::FileExists(PanicReport::GetBackupFilePath(testHappenTimeStr3)));
213 }
214 
215 /**
216  * @tc.name: BBoxDetectorUnitTest007
217  * @tc.desc: check whether the plugin initialize success.
218  * @tc.type: FUNC
219  * @tc.require:
220  * @tc.author: liuwei
221  */
222 HWTEST_F(BBoxDetectorUnitTest, BBoxDetectorUnitTest007, TestSize.Level1)
223 {
224     auto bboxSaveFlags = PanicReport::LoadBboxSaveFlagFromFile();
225     bboxSaveFlags.factoryRecoveryTime = "testTime";
226     PanicReport::SaveBboxLogFlagsToFile(bboxSaveFlags);
227     MockHiviewContext hiviewContext;
228     auto eventLoop = std::make_shared<MockEventLoop>();
229     eventLoop->StartLoop();
230     EXPECT_CALL(*(eventLoop.get()), GetMockInterval()).WillRepeatedly(Return(1));
231     EXPECT_CALL(hiviewContext, GetSharedWorkLoop()).WillRepeatedly(Return(eventLoop));
232     EXPECT_CALL(MockHisyseventUtil::GetInstance(), IsEventProcessed).WillRepeatedly(Return(true));
233     auto testPlugin = make_shared<BBoxDetectorPlugin>();
234     testPlugin->SetHiviewContext(&hiviewContext);
235     testPlugin->OnLoad();
236     std::this_thread::sleep_for(std::chrono::seconds(5));
237     ASSERT_TRUE(PanicReport::LoadBboxSaveFlagFromFile().isPanicUploaded);
238 }
239 }  // namespace HiviewDFX
240 }  // namespace OHOS
241