1 /*
2 * Copyright (c) 2021-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 #include <string>
16 #include <vector>
17
18 #include <fcntl.h>
19 #include <fstream>
20 #include <gtest/gtest.h>
21 #include "sys_event.h"
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <sys/inotify.h>
25 #include <sys/ioctl.h>
26 #include <unistd.h>
27
28 #include "event.h"
29 #include "faultlog_util.h"
30 #include "faultlog_database.h"
31 #define private public
32 #include "faultlogger.h"
33 #undef private
34 #include "faultevent_listener.h"
35 #include "faultlog_info_ohos.h"
36 #include "faultlogger_adapter.h"
37 #include "faultlogger_service_ohos.h"
38 #include "file_util.h"
39 #include "hisysevent_manager.h"
40 #include "hiview_global.h"
41 #include "hiview_platform.h"
42 #include "log_analyzer.h"
43 #include "sys_event.h"
44 #include "sys_event_dao.h"
45
46 using namespace testing::ext;
47 using namespace OHOS::HiviewDFX;
48 namespace OHOS {
49 namespace HiviewDFX {
50 namespace {
51 static std::shared_ptr<FaultEventListener> faultEventListener = nullptr;
52 }
53
54 class FaultloggerUnittest : public testing::Test {
55 public:
SetUp()56 void SetUp()
57 {
58 sleep(1);
59 };
TearDown()60 void TearDown(){};
61
CreateFaultloggerInstance() const62 std::shared_ptr<Faultlogger> CreateFaultloggerInstance() const
63 {
64 static std::unique_ptr<HiviewPlatform> platform = std::make_unique<HiviewPlatform>();
65 auto plugin = std::make_shared<Faultlogger>();
66 plugin->SetName("Faultlogger");
67 plugin->SetHandle(nullptr);
68 plugin->SetHiviewContext(platform.get());
69 plugin->OnLoad();
70 return plugin;
71 }
72 };
73
InitHiviewContext()74 static void InitHiviewContext()
75 {
76 OHOS::HiviewDFX::HiviewPlatform &platform = HiviewPlatform::GetInstance();
77 bool result = platform.InitEnvironment("/data/test/test_faultlogger_data/hiview_platform_config");
78 printf("InitHiviewContext result:%d\n", result);
79 }
80
StartHisyseventListen(std::string domain,std::string eventName)81 static void StartHisyseventListen(std::string domain, std::string eventName)
82 {
83 faultEventListener = std::make_shared<FaultEventListener>();
84 ListenerRule tagRule(domain, eventName, RuleType::WHOLE_WORD);
85 std::vector<ListenerRule> sysRules = {tagRule};
86 HiSysEventManager::AddListener(faultEventListener, sysRules);
87 }
88
CheckKeyWordsInFile(const std::string & filePath,std::string * keywords,int length)89 static int CheckKeyWordsInFile(const std::string& filePath, std::string *keywords, int length)
90 {
91 std::ifstream file;
92 file.open(filePath.c_str(), std::ios::in);
93 std::ostringstream infoStream;
94 infoStream << file.rdbuf();
95 std::string info = infoStream.str();
96 if (info.length() == 0) {
97 std::cout << "file is empty, file:" << filePath << std::endl;
98 return 0;
99 }
100 int matchCount = 0;
101 for (int index = 0; index < length; index++) {
102 if (info.find(keywords[index]) != std::string::npos) {
103 matchCount++;
104 } else {
105 std::cout << "can not find keyword:" << keywords[index] << std::endl;
106 }
107 }
108 file.close();
109 return matchCount;
110 }
111
112 /**
113 * @tc.name: dumpFileListTest001
114 * @tc.desc: dump with cmds, check the result
115 * @tc.type: FUNC
116 * @tc.require: SR000F7UQ6 AR000F83AF
117 */
118 HWTEST_F(FaultloggerUnittest, dumpFileListTest001, testing::ext::TestSize.Level3)
119 {
120 /**
121 * @tc.steps: step1. add multiple cmds to faultlogger
122 * @tc.expected: check the content size of the dump function
123 */
124 auto plugin = CreateFaultloggerInstance();
125 auto fd = open("/data/test/testFile", O_CREAT | O_WRONLY | O_TRUNC, 770);
126 if (fd < 0) {
127 printf("Fail to create test result file.\n");
128 return;
129 }
130
131 std::vector<std::string> cmds;
132 plugin->Dump(fd, cmds);
133 cmds.push_back("Faultlogger");
134 plugin->Dump(fd, cmds);
135 cmds.push_back("-l");
136 plugin->Dump(fd, cmds);
137 cmds.push_back("-f");
138 plugin->Dump(fd, cmds);
139 cmds.push_back("cppcrash-ModuleName-10-20201209103823");
140 plugin->Dump(fd, cmds);
141 cmds.push_back("-d");
142 plugin->Dump(fd, cmds);
143 cmds.push_back("-t");
144 plugin->Dump(fd, cmds);
145 cmds.push_back("20201209103823");
146 plugin->Dump(fd, cmds);
147 cmds.push_back("-m");
148 plugin->Dump(fd, cmds);
149 cmds.push_back("FAULTLOGGER");
150 plugin->Dump(fd, cmds);
151 close(fd);
152 fd = -1;
153
154 std::string result;
155 if (FileUtil::LoadStringFromFile("/data/test/testFile", result)) {
156 ASSERT_GT(result.length(), 0ul);
157 } else {
158 FAIL();
159 }
160 }
161
162 /**
163 * @tc.name: genCppCrashLogTest001
164 * @tc.desc: create cpp crash event and send it to faultlogger
165 * check info which send to appevent
166 * @tc.type: FUNC
167 * @tc.require: SR000F7UQ6 AR000F4380
168 */
169 HWTEST_F(FaultloggerUnittest, GenCppCrashLogTest001, testing::ext::TestSize.Level3)
170 {
171 int pipeFd[2] = {-1, -1};
172 ASSERT_EQ(pipe(pipeFd), 0) << "create pipe failed";
173 auto plugin = CreateFaultloggerInstance();
174 FaultLogInfo info;
175 info.time = 1607161163;
176 info.id = 0;
177 info.pid = 7496;
178 info.faultLogType = 2;
179 info.module = "com.example.myapplication";
180 info.sectionMap["APPVERSION"] = "1.0";
181 info.sectionMap["FAULT_MESSAGE"] = "Nullpointer";
182 info.sectionMap["TRACEID"] = "0x1646145645646";
183 info.sectionMap["KEY_THREAD_INFO"] = "Test Thread Info";
184 info.sectionMap["REASON"] = "TestReason";
185 info.sectionMap["STACKTRACE"] = "#01 xxxxxx\n#02 xxxxxx\n";
186 info.pipeFd = pipeFd[0];
187 std::string jsonInfo = R"~({"crash_type":"NativeCrash", "exception":{"frames":
188 [{"buildId":"", "file":"/system/lib/ld-musl-arm.so.1", "offset":28, "pc":"000ac0a4",
189 "symbol":"test_abc"}, {"buildId":"12345abcde",
190 "file":"/system/lib/chipset-pub-sdk/libeventhandler.z.so", "offset":278, "pc":"0000bef3",
191 "symbol":"OHOS::AppExecFwk::EpollIoWaiter::WaitFor(std::__h::unique_lock<std::__h::mutex>&, long long)"}],
192 "message":"", "signal":{"code":0, "signo":6}, "thread_name":"e.myapplication", "tid":1605}, "pid":1605,
193 "threads":[{"frames":[{"buildId":"", "file":"/system/lib/ld-musl-arm.so.1", "offset":72, "pc":"000c80b4",
194 "symbol":"ioctl"}, {"buildId":"2349d05884359058d3009e1fe27b15fa", "file":
195 "/system/lib/platformsdk/libipc_core.z.so", "offset":26, "pc":"0002cad7",
196 "symbol":"OHOS::BinderConnector::WriteBinder(unsigned long, void*)"}], "thread_name":"OS_IPC_0_1607",
197 "tid":1607}, {"frames":[{"buildId":"", "file":"/system/lib/ld-musl-arm.so.1", "offset":0, "pc":"000fdf4c",
198 "symbol":""}, {"buildId":"", "file":"/system/lib/ld-musl-arm.so.1", "offset":628, "pc":"000ff7f4",
199 "symbol":"__pthread_cond_timedwait_time64"}], "thread_name":"OS_SignalHandle", "tid":1608}],
200 "time":1701863741296, "uid":20010043, "uuid":""})~";
201 ssize_t nwrite = -1;
202 do {
203 nwrite = write(pipeFd[1], jsonInfo.c_str(), jsonInfo.size());
204 } while (nwrite == -1 && errno == EINTR);
205 close(pipeFd[1]);
206 plugin->AddFaultLog(info);
207 close(info.pipeFd);
208 std::string timeStr = GetFormatedTime(info.time);
209 std::string fileName = "/data/log/faultlog/faultlogger/cppcrash-com.example.myapplication-0-" + timeStr;
210 ASSERT_EQ(FileUtil::FileExists(fileName), true);
211 ASSERT_GT(FileUtil::GetFileSize(fileName), 0ul);
212 auto parsedInfo = plugin->GetFaultLogInfo(fileName);
213 ASSERT_EQ(parsedInfo->module, "com.example.myapplication");
214 // check appevent json info
215 std::string appeventInfofileName = "/data/test_cppcrash_info_" + std::to_string(info.pid);
216 ASSERT_EQ(FileUtil::FileExists(appeventInfofileName), true);
217 string keywords[] = { "\"time\":", "\"pid\":", "\"exception\":", "\"threads\":", "\"thread_name\":", "\"tid\":" };
218 int length = sizeof(keywords) / sizeof(keywords[0]);
219 ASSERT_EQ(CheckKeyWordsInFile(appeventInfofileName, keywords, length), length);
220 }
221
222 /**
223 * @tc.name: genCppCrashtoAnalysisFaultlog
224 * @tc.desc: create cpp crash event and check AnalysisFaultlog
225 * @tc.type: FUNC
226 * @tc.require: SR000F7UQ6 AR000F4380
227 */
228 HWTEST_F(FaultloggerUnittest, genCppCrashtoAnalysisFaultlog001, testing::ext::TestSize.Level3)
229 {
230 /**
231 * @tc.steps: step1. create a cpp crash event and pass it to faultlogger
232 * @tc.expected: AnalysisFaultlog return expected result
233 */
234 FaultLogInfo info;
235 info.time = 1607161163;
236 info.id = 0;
237 info.pid = 7497;
238 info.faultLogType = 2;
239 info.module = "com.example.testapplication";
240 info.reason = "TestReason";
241 std::map<std::string, std::string> eventInfos;
242 ASSERT_EQ(AnalysisFaultlog(info, eventInfos), false);
243 ASSERT_EQ(!eventInfos["fingerPrint"].empty(), true);
244 }
245
246 /**
247 * @tc.name: genJsCrashtoAnalysisFaultlog001
248 * @tc.desc: create Js crash FaultLogInfo and check AnalysisFaultlog
249 * @tc.type: FUNC
250 */
251 HWTEST_F(FaultloggerUnittest, genJsCrashtoAnalysisFaultlog001, testing::ext::TestSize.Level3)
252 {
253 /**
254 * @tc.steps: step1. create Js crash FaultLogInfo
255 * @tc.expected: AnalysisFaultlog return expected result
256 */
257 FaultLogInfo info;
258 info.time = 1607161163;
259 info.id = 0;
260 info.pid = 7497;
261 info.faultLogType = 3;
262 info.module = "com.example.testapplication";
263 info.reason = "TestReason";
264 std::map<std::string, std::string> eventInfos;
265 ASSERT_EQ(AnalysisFaultlog(info, eventInfos), false);
266 ASSERT_EQ(!eventInfos["fingerPrint"].empty(), true);
267 }
268
269 /**
270 * @tc.name: genjserrorLogTest002
271 * @tc.desc: create JS ERROR event and send it to faultlogger
272 * @tc.type: FUNC
273 * @tc.require: SR000F7UQ6 AR000F4380
274 */
275 HWTEST_F(FaultloggerUnittest, genjserrorLogTest002, testing::ext::TestSize.Level3)
276 {
277 /**
278 * @tc.steps: step1. create a jss_error event and pass it to faultlogger
279 * @tc.expected: the calling is success and the file has been created
280 */
281 SysEventCreator sysEventCreator("AAFWK", "JSERROR", SysEventCreator::FAULT);
282 sysEventCreator.SetKeyValue("SUMMARY", "Error message:is not callable\nStacktrace:");
283 sysEventCreator.SetKeyValue("name_", "JS_ERROR");
284 sysEventCreator.SetKeyValue("happenTime_", 1670248360359);
285 sysEventCreator.SetKeyValue("REASON", "TypeError");
286 sysEventCreator.SetKeyValue("tz_", "+0800");
287 sysEventCreator.SetKeyValue("pid_", 2413);
288 sysEventCreator.SetKeyValue("tid_", 2413);
289 sysEventCreator.SetKeyValue("what_", 3);
290 sysEventCreator.SetKeyValue("PACKAGE_NAME", "com.ohos.systemui");
291 sysEventCreator.SetKeyValue("VERSION", "1.0.0");
292 sysEventCreator.SetKeyValue("TYPE", 3);
293 sysEventCreator.SetKeyValue("VERSION", "1.0.0");
294
295 auto sysEvent = std::make_shared<SysEvent>("test", nullptr, sysEventCreator);
296 auto testPlugin = CreateFaultloggerInstance();
297 std::shared_ptr<Event> event = std::dynamic_pointer_cast<Event>(sysEvent);
298 bool result = testPlugin->OnEvent(event);
299 ASSERT_EQ(result, true);
300 }
301
302 /**
303 * @tc.name: SaveFaultLogInfoTest001
304 * @tc.desc: Test calling SaveFaultLogInfo Func
305 * @tc.type: FUNC
306 */
307 HWTEST_F(FaultloggerUnittest, SaveFaultLogInfoTest001, testing::ext::TestSize.Level3)
308 {
309 InitHiviewContext();
310 StartHisyseventListen("RELIABILITY", "CPP_CRASH");
311 time_t now = std::time(nullptr);
312 std::vector<std::string> keyWords = { std::to_string(now) };
313 faultEventListener->SetKeyWords(keyWords);
314 FaultLogDatabase *faultLogDb = new FaultLogDatabase();
315 FaultLogInfo info;
316 info.time = now;
317 info.pid = getpid();
318 info.id = 0;
319 info.faultLogType = 2;
320 info.module = "FaultloggerUnittest";
321 info.reason = "unittest for SaveFaultLogInfo";
322 info.summary = "summary for SaveFaultLogInfo";
323 info.sectionMap["APPVERSION"] = "1.0";
324 info.sectionMap["FAULT_MESSAGE"] = "abort";
325 info.sectionMap["TRACEID"] = "0x1646145645646";
326 info.sectionMap["KEY_THREAD_INFO"] = "Test Thread Info";
327 info.sectionMap["REASON"] = "TestReason";
328 info.sectionMap["STACKTRACE"] = "#01 xxxxxx\n#02 xxxxxx\n";
329 faultLogDb->SaveFaultLogInfo(info);
330 ASSERT_TRUE(faultEventListener->CheckKeyWords());
331 }
332
333 /**
334 * @tc.name: GetFaultInfoListTest001
335 * @tc.desc: Test calling GetFaultInfoList Func
336 * @tc.type: FUNC
337 */
338 HWTEST_F(FaultloggerUnittest, GetFaultInfoListTest001, testing::ext::TestSize.Level3)
339 {
340 InitHiviewContext();
341
342 std::string jsonStr = R"~({"domain_":"RELIABILITY","name_":"CPP_CRASH","type_":1,"time_":1501973701070,"tz_":
343 "+0800","pid_":1854,"tid_":1854,"uid_":0,"FAULT_TYPE":"2","PID":1854,"UID":0,"MODULE":"FaultloggerUnittest",
344 "REASON":"unittest for SaveFaultLogInfo","SUMMARY":"summary for SaveFaultLogInfo","LOG_PATH":"","VERSION":"",
345 "HAPPEN_TIME":"1501973701","PNAME":"/","FIRST_FRAME":"/","SECOND_FRAME":"/","LAST_FRAME":"/","FINGERPRINT":
346 "04c0d6f03c73da531f00eb112479a8a2f19f59fafba6a474dcbe455a13288f4d","level_":"CRITICAL","tag_":"STABILITY","id_":
347 "17165544771317691984","info_":""})~";
348 auto sysEvent = std::make_shared<SysEvent>("SysEventSource", nullptr, jsonStr);
349 sysEvent->SetLevel("MINOR");
350 sysEvent->SetEventSeq(447); // 447: test seq
351 EventStore::SysEventDao::Insert(sysEvent);
352 FaultLogDatabase *faultLogDb = new FaultLogDatabase();
353 std::list<FaultLogInfo> infoList = faultLogDb->GetFaultInfoList("FaultloggerUnittest", 0, 2, 10);
354 ASSERT_GT(infoList.size(), 0);
355 }
356
357 /**
358 * @tc.name: FaultLogManager::CreateTempFaultLogFile
359 * @tc.desc: Test calling CreateTempFaultLogFile Func
360 * @tc.type: FUNC
361 */
362 HWTEST_F(FaultloggerUnittest, FaultlogManager001, testing::ext::TestSize.Level3)
363 {
364 std::unique_ptr<FaultLogManager> faultLogManager = std::make_unique<FaultLogManager>(nullptr);
365 faultLogManager->Init();
366 int fd = faultLogManager->CreateTempFaultLogFile(1607161345, 0, 2, "FaultloggerUnittest");
367 ASSERT_GT(fd, 0);
368 }
369
370 /**
371 * @tc.name: FaultLogManager::SaveFaultInfoToRawDb
372 * @tc.desc: Test calling SaveFaultInfoToRawDb Func
373 * @tc.type: FUNC
374 */
375 HWTEST_F(FaultloggerUnittest, FaultLogManagerTest001, testing::ext::TestSize.Level3)
376 {
377 InitHiviewContext();
378 StartHisyseventListen("RELIABILITY", "CPP_CRASH");
379 time_t now = std::time(nullptr);
380 std::vector<std::string> keyWords = { std::to_string(now) };
381 faultEventListener->SetKeyWords(keyWords);
382 FaultLogInfo info;
383 info.time = now;
384 info.pid = getpid();
385 info.id = 0;
386 info.faultLogType = 2;
387 info.module = "FaultloggerUnittest1111";
388 info.reason = "unittest for SaveFaultLogInfo";
389 info.summary = "summary for SaveFaultLogInfo";
390 info.sectionMap["APPVERSION"] = "1.0";
391 info.sectionMap["FAULT_MESSAGE"] = "abort";
392 info.sectionMap["TRACEID"] = "0x1646145645646";
393 info.sectionMap["KEY_THREAD_INFO"] = "Test Thread Info";
394 info.sectionMap["REASON"] = "TestReason";
395 info.sectionMap["STACKTRACE"] = "#01 xxxxxx\n#02 xxxxxx\n";
396 std::unique_ptr<FaultLogManager> faultLogManager = std::make_unique<FaultLogManager>(nullptr);
397 faultLogManager->Init();
398 faultLogManager->SaveFaultInfoToRawDb(info);
399 ASSERT_TRUE(faultEventListener->CheckKeyWords());
400 }
401
402 /**
403 * @tc.name: FaultLogManager::SaveFaultLogToFile
404 * @tc.desc: Test calling SaveFaultLogToFile Func
405 * @tc.type: FUNC
406 */
407 HWTEST_F(FaultloggerUnittest, FaultLogManagerTest003, testing::ext::TestSize.Level3)
408 {
409 InitHiviewContext();
410
411 FaultLogInfo info;
412 std::unique_ptr<FaultLogManager> faultLogManager = std::make_unique<FaultLogManager>(nullptr);
413 faultLogManager->Init();
414 for (int i = 1; i < 7; i++) {
415 info.time = std::time(nullptr);
416 info.pid = getpid();
417 info.id = 0;
418 info.faultLogType = i;
419 info.module = "FaultloggerUnittest1111";
420 info.reason = "unittest for SaveFaultLogInfo";
421 info.summary = "summary for SaveFaultLogInfo";
422 info.sectionMap["APPVERSION"] = "1.0";
423 info.sectionMap["FAULT_MESSAGE"] = "abort";
424 info.sectionMap["TRACEID"] = "0x1646145645646";
425 info.sectionMap["KEY_THREAD_INFO"] = "Test Thread Info";
426 info.sectionMap["REASON"] = "TestReason";
427 info.sectionMap["STACKTRACE"] = "#01 xxxxxx\n#02 xxxxxx\n";
428
429 std::string fileName = faultLogManager->SaveFaultLogToFile(info);
430 if (fileName.find("FaultloggerUnittest1111") == std::string::npos) {
431 FAIL();
432 }
433 }
434 }
435
436 /**
437 * @tc.name: faultLogManager GetFaultInfoListTest001
438 * @tc.desc: Test calling faultLogManager.GetFaultInfoList Func
439 * @tc.type: FUNC
440 */
441 HWTEST_F(FaultloggerUnittest, FaultLogManagerTest002, testing::ext::TestSize.Level3)
442 {
443 InitHiviewContext();
444
445 std::string jsonStr = R"~({"domain_":"RELIABILITY","name_":"CPP_CRASH","type_":1,"time_":1501973701070,
446 "tz_":"+0800","pid_":1854,"tid_":1854,"uid_":0,"FAULT_TYPE":"2","PID":1854,"UID":0,
447 "MODULE":"FaultloggerUnittest","REASON":"unittest for SaveFaultLogInfo",
448 "SUMMARY":"summary for SaveFaultLogInfo","LOG_PATH":"","VERSION":"","HAPPEN_TIME":"1501973701",
449 "PNAME":"/","FIRST_FRAME":"/","SECOND_FRAME":"/","LAST_FRAME":"/",
450 "FINGERPRINT":"04c0d6f03c73da531f00eb112479a8a2f19f59fafba6a474dcbe455a13288f4d",
451 "level_":"CRITICAL","tag_":"STABILITY","id_":"17165544771317691984","info_":""})~";
452 auto sysEvent = std::make_shared<SysEvent>("SysEventSource", nullptr, jsonStr);
453 sysEvent->SetLevel("MINOR");
454 sysEvent->SetEventSeq(448); // 448: test seq
455 EventStore::SysEventDao::Insert(sysEvent);
456
457 std::unique_ptr<FaultLogManager> faultLogManager = std::make_unique<FaultLogManager>(nullptr);
458 auto isProcessedFault1 = faultLogManager->IsProcessedFault(1854, 0, 2);
459 ASSERT_EQ(isProcessedFault1, false);
460
461 faultLogManager->Init();
462
463 auto list = faultLogManager->GetFaultInfoList("FaultloggerUnittest", 0, 2, 10);
464 ASSERT_GT(list.size(), 0);
465
466 auto isProcessedFault2 = faultLogManager->IsProcessedFault(1854, 0, 2);
467 ASSERT_EQ(isProcessedFault2, true);
468
469 auto isProcessedFault3 = faultLogManager->IsProcessedFault(1855, 0, 2);
470 ASSERT_EQ(isProcessedFault3, false);
471
472 auto isProcessedFault4 = faultLogManager->IsProcessedFault(1855, 5, 2);
473 ASSERT_EQ(isProcessedFault4, false);
474 }
475
476 /**
477 * @tc.name: FaultLogUtilTest001
478 * @tc.desc: check ExtractInfoFromFileName Func
479 * @tc.type: FUNC
480 */
481 HWTEST_F(FaultloggerUnittest, FaultLogUtilTest001, testing::ext::TestSize.Level3)
482 {
483 std::string filename = "appfreeze-com.ohos.systemui-10006-20170805172159";
484 auto info = ExtractInfoFromFileName(filename);
485 ASSERT_EQ(info.pid, 0);
486 ASSERT_EQ(info.faultLogType, FaultLogType::APP_FREEZE); // 4 : APP_FREEZE
487 ASSERT_EQ(info.module, "com.ohos.systemui");
488 ASSERT_EQ(info.id, 10006); // 10006 : test uid
489 }
490
491 /**
492 * @tc.name: FaultLogUtilTest002
493 * @tc.desc: check ExtractInfoFromTempFile Func
494 * @tc.type: FUNC
495 */
496 HWTEST_F(FaultloggerUnittest, FaultLogUtilTest002, testing::ext::TestSize.Level3)
497 {
498 std::string filename = "appfreeze-10006-20170805172159";
499 auto info = ExtractInfoFromTempFile(filename);
500 ASSERT_EQ(info.faultLogType, FaultLogType::APP_FREEZE); // 4 : APP_FREEZE
501 ASSERT_EQ(info.pid, 10006); // 10006 : test uid
502
503 std::string filename3 = "jscrash-10006-20170805172159";
504 auto info3 = ExtractInfoFromTempFile(filename3);
505 ASSERT_EQ(info3.faultLogType, FaultLogType::JS_CRASH); // 3 : JS_CRASH
506 ASSERT_EQ(info3.pid, 10006); // 10006 : test uid
507
508 std::string filename4 = "cppcrash-10006-20170805172159";
509 auto info4 = ExtractInfoFromTempFile(filename4);
510 ASSERT_EQ(info4.faultLogType, FaultLogType::CPP_CRASH); // 2 : CPP_CRASH
511 ASSERT_EQ(info4.pid, 10006); // 10006 : test uid
512
513 std::string filename5 = "all-10006-20170805172159";
514 auto info5 = ExtractInfoFromTempFile(filename5);
515 ASSERT_EQ(info5.faultLogType, FaultLogType::ALL); // 0 : ALL
516 ASSERT_EQ(info5.pid, 10006); // 10006 : test uid
517
518 std::string filename6 = "other-10006-20170805172159";
519 auto info6 = ExtractInfoFromTempFile(filename6);
520 ASSERT_EQ(info6.faultLogType, -1); // -1 : other
521 ASSERT_EQ(info6.pid, 10006); // 10006 : test uid
522 }
523
524 /**
525 * @tc.name: FaultloggerAdapter.StartService
526 * @tc.desc: Test calling FaultloggerAdapter.StartService Func
527 * @tc.type: FUNC
528 */
529 HWTEST_F(FaultloggerUnittest, FaultloggerAdapterTest001, testing::ext::TestSize.Level3)
530 {
531 InitHiviewContext();
532 FaultloggerAdapter::StartService(nullptr);
533 ASSERT_EQ(FaultloggerServiceOhos::GetOrSetFaultlogger(nullptr), nullptr);
534
535 Faultlogger faultlogger;
536 FaultloggerAdapter::StartService(&faultlogger);
537 ASSERT_EQ(FaultloggerServiceOhos::GetOrSetFaultlogger(nullptr), &faultlogger);
538 }
539
540 /**
541 * @tc.name: FaultloggerServiceOhos.StartService
542 * @tc.desc: Test calling FaultloggerServiceOhos.StartService Func
543 * @tc.type: FUNC
544 */
545 HWTEST_F(FaultloggerUnittest, FaultloggerServiceOhosTest001, testing::ext::TestSize.Level3)
546 {
547 InitHiviewContext();
548
549 auto service = CreateFaultloggerInstance();
550 FaultloggerServiceOhos serviceOhos;
551 FaultloggerServiceOhos::StartService(service.get());
552 ASSERT_EQ(FaultloggerServiceOhos::GetOrSetFaultlogger(nullptr), service.get());
553 FaultLogInfoOhos info;
554 info.time = std::time(nullptr);
555 info.pid = getpid();
556 info.uid = 0;
557 info.faultLogType = 2;
558 info.module = "FaultloggerUnittest333";
559 info.reason = "unittest for SaveFaultLogInfo";
560 serviceOhos.AddFaultLog(info);
561 auto list = serviceOhos.QuerySelfFaultLog(2, 10);
562 ASSERT_NE(list, nullptr);
563 info.time = std::time(nullptr);
564 info.pid = getpid();
565 info.uid = 10;
566 info.faultLogType = 2;
567 info.module = "FaultloggerUnittest333";
568 info.reason = "unittest for SaveFaultLogInfo";
569 serviceOhos.AddFaultLog(info);
570 list = serviceOhos.QuerySelfFaultLog(2, 10);
571 ASSERT_EQ(list, nullptr);
572 info.time = std::time(nullptr);
573 info.pid = getpid();
574 info.uid = 0;
575 info.faultLogType = 2;
576 info.module = "FaultloggerUnittest333";
577 info.reason = "unittest for SaveFaultLogInfo";
578 serviceOhos.AddFaultLog(info);
579 list = serviceOhos.QuerySelfFaultLog(8, 10);
580 ASSERT_EQ(list, nullptr);
581
582 serviceOhos.Destroy();
583 }
584
585 /**
586 * @tc.name: FaultloggerServiceOhos.Dump
587 * @tc.desc: Test calling FaultloggerServiceOhos.Dump Func
588 * @tc.type: FUNC
589 */
590 HWTEST_F(FaultloggerUnittest, FaultloggerServiceOhosTest002, testing::ext::TestSize.Level3)
591 {
592 InitHiviewContext();
593
594 auto service = CreateFaultloggerInstance();
595 FaultloggerServiceOhos serviceOhos;
596 FaultloggerServiceOhos::StartService(service.get());
597 ASSERT_EQ(FaultloggerServiceOhos::GetOrSetFaultlogger(nullptr), service.get());
598 auto fd = open("/data/test/testFile2", O_CREAT | O_WRONLY | O_TRUNC, 770);
599 if (fd < 0) {
600 printf("Fail to create test result file.\n");
601 return;
602 }
603 std::vector<std::u16string>args;
604 args.push_back(u"Faultlogger");
605 args.push_back(u"-l");
606 serviceOhos.Dump(fd, args);
607 args.push_back(u"&@#");
608 ASSERT_EQ(serviceOhos.Dump(fd, args), -1);
609 close(fd);
610 fd = -1;
611 std::string result;
612 if (FileUtil::LoadStringFromFile("/data/test/testFile2", result)) {
613 ASSERT_GT(result.length(), 0ul);
614 } else {
615 FAIL();
616 }
617 serviceOhos.Destroy();
618 }
619
620 /**
621 * @tc.name: FaultloggerTest001
622 * @tc.desc: Test calling Faultlogger.StartBootScan Func
623 * @tc.type: FUNC
624 */
625 HWTEST_F(FaultloggerUnittest, FaultloggerTest001, testing::ext::TestSize.Level3)
626 {
627 InitHiviewContext();
628 StartHisyseventListen("RELIABILITY", "CPP_CRASH");
629 time_t now = time(nullptr);
630 std::vector<std::string> keyWords = { std::to_string(now) };
631 faultEventListener->SetKeyWords(keyWords);
632 std::string timeStr = GetFormatedTime(now);
633 std::string content = "Pid:101\nUid:0\nProcess name:BootScanUnittest\nReason:unittest for StartBootScan\n"
634 "Fault thread Info:\nTid:101, Name:BootScanUnittest\n#00 xxxxxxx\n#01 xxxxxxx\n";
635 ASSERT_TRUE(FileUtil::SaveStringToFile("/data/log/faultlog/temp/cppcrash-101-" + std::to_string(now), content));
636 auto plugin = CreateFaultloggerInstance();
637 plugin->StartBootScan();
638 //check faultlog file content
639 std::string fileName = "/data/log/faultlog/faultlogger/cppcrash-BootScanUnittest-0-" + timeStr;
640 ASSERT_TRUE(FileUtil::FileExists(fileName));
641 ASSERT_GT(FileUtil::GetFileSize(fileName), 0ul);
642 ASSERT_EQ(plugin->GetFaultLogInfo(fileName)->module, "BootScanUnittest");
643
644 // check event database
645 ASSERT_TRUE(faultEventListener->CheckKeyWords());
646 }
647
648 /**
649 * @tc.name: FaultloggerTest002
650 * @tc.desc: Test calling Faultlogger.StartBootScan Func
651 * @tc.type: FUNC
652 */
653 HWTEST_F(FaultloggerUnittest, FaultloggerTest002, testing::ext::TestSize.Level3)
654 {
655 InitHiviewContext();
656 StartHisyseventListen("RELIABILITY", "CPP_CRASH_NO_LOG");
657 std::vector<std::string> keyWords = { "BootScanUnittest" };
658 faultEventListener->SetKeyWords(keyWords);
659 time_t now = time(nullptr);
660 std::string timeStr = GetFormatedTime(now);
661 std::string content = "Pid:102\nUid:0\nProcess name:BootScanUnittest\nReason:unittest for StartBootScan\n"
662 "Fault thread Info:\nTid:102, Name:BootScanUnittest\n";
663 std::string fileName = "/data/log/faultlog/temp/cppcrash-102-" + std::to_string(now);
664 ASSERT_TRUE(FileUtil::SaveStringToFile(fileName, content));
665 auto plugin = CreateFaultloggerInstance();
666 plugin->StartBootScan();
667 ASSERT_FALSE(FileUtil::FileExists(fileName));
668
669 // check event database
670 ASSERT_TRUE(faultEventListener->CheckKeyWords());
671 }
672
673 /**
674 * @tc.name: FaultloggerTest003
675 * @tc.desc: Test calling Faultlogger.StartBootScan Func, for full log
676 * @tc.type: FUNC
677 */
678 HWTEST_F(FaultloggerUnittest, FaultloggerTest003, testing::ext::TestSize.Level3)
679 {
680 InitHiviewContext();
681 StartHisyseventListen("RELIABILITY", "CPP_CRASH");
682 time_t now = time(nullptr);
683 std::vector<std::string> keyWords = { std::to_string(now) };
684 faultEventListener->SetKeyWords(keyWords);
685 std::string timeStr = GetFormatedTime(now);
686 std::string regs = "r0:00000019 r1:0097cd3c\nr4:f787fd2c\nfp:f787fd18 ip:7fffffff pc:0097c982\n";
687 std::string otherThreadInfo =
688 "Tid:1336, Name:BootScanUnittes\n#00 xxxxxx\nTid:1337, Name:BootScanUnittes\n#00 xx\n";
689 std::string content = std::string("Pid:111\nUid:0\nProcess name:BootScanUnittest\n") +
690 "Reason:unittest for StartBootScan\n" +
691 "Fault thread Info:\nTid:111, Name:BootScanUnittest\n#00 xxxxxxx\n#01 xxxxxxx\n" +
692 "Registers:\n" + regs +
693 "Other thread info:\n" + otherThreadInfo +
694 "Memory near registers:\nr1(/data/xxxxx):\n 0097cd34 47886849\n 0097cd38 96059d05\n\n" +
695 "Maps:\n96e000-978000 r--p 00000000 /data/xxxxx\n978000-9a6000 r-xp 00009000 /data/xxxx\n";
696 ASSERT_TRUE(FileUtil::SaveStringToFile("/data/log/faultlog/temp/cppcrash-111-" + std::to_string(now), content));
697 auto plugin = CreateFaultloggerInstance();
698 plugin->StartBootScan();
699
700 //check faultlog file content
701 std::string fileName = "/data/log/faultlog/faultlogger/cppcrash-BootScanUnittest-0-" + timeStr;
702 ASSERT_TRUE(FileUtil::FileExists(fileName));
703 ASSERT_GT(FileUtil::GetFileSize(fileName), 0ul);
704 auto info = plugin->GetFaultLogInfo(fileName);
705 ASSERT_EQ(info->module, "BootScanUnittest");
706
707 // check regs and otherThreadInfo is ok
708 std::string logInfo;
709 FileUtil::LoadStringFromFile(fileName, logInfo);
710 ASSERT_TRUE(logInfo.find(regs) != std::string::npos);
711 ASSERT_TRUE(logInfo.find(otherThreadInfo) != std::string::npos);
712
713 // check event database
714 ASSERT_TRUE(faultEventListener->CheckKeyWords());
715 }
716
717 /**
718 * @tc.name: ReportJsErrorToAppEventTest001
719 * @tc.desc: create JS ERROR event and send it to hiappevent
720 * @tc.type: FUNC
721 * @tc.require: AR000IHTHV
722 */
723 HWTEST_F(FaultloggerUnittest, ReportJsErrorToAppEventTest001, testing::ext::TestSize.Level3)
724 {
725 SysEventCreator sysEventCreator("AAFWK", "JSERROR", SysEventCreator::FAULT);
726 sysEventCreator.SetKeyValue("SUMMARY", R"(Error name:TypeError\nError message:Obj is not
727 a Valid object\nSourceCode:\n get BLOCKSSvalue() {\n ^\nStacktrace:\n at
728 anonymous (entry/src/main/ets/pages/index.ets:76:10)\n)");
729 sysEventCreator.SetKeyValue("name_", "JS_ERROR");
730 sysEventCreator.SetKeyValue("happenTime_", 1670248360359);
731 sysEventCreator.SetKeyValue("REASON", "TypeError");
732 sysEventCreator.SetKeyValue("tz_", "+0800");
733 sysEventCreator.SetKeyValue("pid_", 2413);
734 sysEventCreator.SetKeyValue("tid_", 2413);
735 sysEventCreator.SetKeyValue("what_", 3);
736 sysEventCreator.SetKeyValue("PACKAGE_NAME", "com.ohos.systemui");
737 sysEventCreator.SetKeyValue("VERSION", "1.0.0");
738 sysEventCreator.SetKeyValue("TYPE", 3);
739 sysEventCreator.SetKeyValue("VERSION", "1.0.0");
740
741 auto sysEvent = std::make_shared<SysEvent>("test", nullptr, sysEventCreator);
742 auto testPlugin = CreateFaultloggerInstance();
743 std::shared_ptr<Event> event = std::dynamic_pointer_cast<Event>(sysEvent);
744 bool result = testPlugin->OnEvent(event);
745 ASSERT_EQ(result, true);
746
747 std::string keywords[] = {
748 "\"bundle_name\":", "\"bundle_version\":", "\"crash_type\":", "\"exception\":",
749 "\"foreground\":", "\"hilog\":", "\"pid\":", "\"time\":", "\"uid\":", "\"uuid\":"
750 };
751 int length = sizeof(keywords) / sizeof(keywords[0]);
752 std::cout << "length:" << length << std::endl;
753 int count = CheckKeyWordsInFile("/data/test_jsError_info", keywords, length);
754 std::cout << "count:" << count << std::endl;
755 ASSERT_EQ(count, length) << "ReportJsErrorToAppEventTest001 check keywords failed";
756 }
757 } // namespace HiviewDFX
758 } // namespace OHOS
759