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 16#include <gtest/gtest.h> 17 18#include <securec.h> 19#ifndef is_ohos_lite 20#include "gmock/gmock.h" 21#endif 22#include <sys/socket.h> 23#include <sys/un.h> 24#include <unistd.h> 25#include "dfx_exception.h" 26#include "dfx_util.h" 27#include "faultloggerd_client.h" 28#include "faultloggerd_socket.h" 29#include "fault_logger_config.h" 30#include "fault_logger_daemon.h" 31#include "fault_logger_pipe.h" 32 33using namespace OHOS::HiviewDFX; 34using namespace testing::ext; 35using namespace std; 36 37namespace OHOS { 38namespace HiviewDFX { 39class FaultLoggerDaemonTest : public testing::Test { 40public: 41 static void SetUpTestCase(void) {} 42 static void TearDownTestCase(void) {} 43 void SetUp() {} 44 void TearDown() {} 45}; 46 47#ifndef is_ohos_lite 48class MockFaultLoggerDaemon : public FaultLoggerDaemon { 49public: 50 MOCK_METHOD(bool, CreateSockets, (), (override)); 51 MOCK_METHOD(bool, InitEnvironment, (), (override)); 52 MOCK_METHOD(bool, CreateEventFd, (), (override)); 53 MOCK_METHOD(void, WaitForRequest, (), (override)); 54}; 55#endif 56} // namespace HiviewDFX 57} // namespace OHOS 58 59namespace { 60constexpr int32_t FAULTLOGGERD_FUZZ_READ_BUFF = 1024; 61static constexpr uint32_t ROOT_UID = 0; 62static constexpr uint32_t BMS_UID = 1000; 63static constexpr uint32_t HIVIEW_UID = 1201; 64static constexpr uint32_t HIDUMPER_SERVICE_UID = 1212; 65static constexpr uint32_t FOUNDATION_UID = 5523; 66static constexpr uint32_t PIPE_TYPE_COUNT = 8; 67 68/** 69 * @tc.name: FaultLoggerDaemonTest001 70 * @tc.desc: test HandleDefaultClientRequest/HandleLogFileDesClientRequest func 71 * @tc.type: FUNC 72 */ 73HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest001, TestSize.Level2) 74{ 75 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest001: start."; 76 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 77 bool ret = daemon->InitEnvironment(); 78 ASSERT_TRUE(ret); 79 struct FaultLoggerdRequest faultloggerdRequest; 80 if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) { 81 GTEST_LOG_(ERROR) << "memset_s failed" ; 82 ASSERT_TRUE(false); 83 } 84 faultloggerdRequest.type = 0; 85 faultloggerdRequest.pid = getpid(); 86 faultloggerdRequest.tid = gettid(); 87 faultloggerdRequest.uid = getuid(); 88 daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest); 89 faultloggerdRequest.type = 2; // 2 : CPP_CRASH 90 daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest); 91 daemon->HandleLogFileDesClientRequest(-1, &faultloggerdRequest); 92 faultloggerdRequest.type = 101; // 101 : CPP_STACKTRACE 93 daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest); 94 faultloggerdRequest.type = 102; // 102 : JS_STACKTRACE 95 daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest); 96 faultloggerdRequest.type = 103; // 103 : JS_HEAP_SNAPSHOT 97 daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest); 98 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest001: end."; 99} 100 101/** 102 * @tc.name: FaultLoggerDaemonTest002 103 * @tc.desc: test HandleSdkDumpRequest/HandlePipeFdClientRequest func 104 * @tc.type: FUNC 105 */ 106HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest002, TestSize.Level2) 107{ 108 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest002: start."; 109 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 110 bool ret = daemon->InitEnvironment(); 111 ASSERT_TRUE(ret); 112 struct FaultLoggerdRequest faultloggerdRequest; 113 if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) { 114 GTEST_LOG_(ERROR) << "memset_s failed" ; 115 ASSERT_TRUE(false); 116 } 117 faultloggerdRequest.type = 2; // 2 : CPP_CRASH 118 faultloggerdRequest.pid = getpid(); 119 faultloggerdRequest.tid = gettid(); 120 faultloggerdRequest.uid = getuid(); 121 daemon->HandleSdkDumpRequest(-1, &faultloggerdRequest); 122 faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_READ_BUF; 123 daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest); 124 faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_WRITE_BUF; 125 daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest); 126 faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_READ_RES; 127 daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest); 128 faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_WRITE_RES; 129 daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest); 130 faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_DELETE; 131 daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest); 132 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest002: end."; 133} 134 135/** 136 * @tc.name: FaultLoggerDaemonTest003 137 * @tc.desc: test HandleSdkDumpRequest func 138 * @tc.type: FUNC 139 */ 140HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest003, TestSize.Level2) 141{ 142 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest003: start."; 143 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 144 bool ret = daemon->InitEnvironment(); 145 ASSERT_TRUE(ret); 146 struct FaultLoggerdRequest faultloggerdRequest; 147 if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) { 148 GTEST_LOG_(ERROR) << "memset_s failed" ; 149 ASSERT_TRUE(false); 150 } 151 faultloggerdRequest.type = 2; // 2 : CPP_CRASH 152 faultloggerdRequest.pid = getpid(); 153 faultloggerdRequest.tid = gettid(); 154 faultloggerdRequest.uid = getuid(); 155 daemon->HandleSdkDumpRequest(-1, &faultloggerdRequest); 156 faultloggerdRequest.tid = 0; 157 daemon->HandleSdkDumpRequest(-1, &faultloggerdRequest); 158 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest003: end."; 159} 160 161/** 162 * @tc.name: FaultLoggerDaemonTest004 163 * @tc.desc: test CreateFileForRequest func 164 * @tc.type: FUNC 165 */ 166HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest004, TestSize.Level2) 167{ 168 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest004: start."; 169 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 170 int32_t type = (int32_t)FaultLoggerType::CPP_CRASH; 171 int32_t pid = getpid(); 172 uint64_t time = GetTimeMilliSeconds(); 173 int fd = daemon->CreateFileForRequest(type, pid, 0, time); 174 ASSERT_NE(fd, -1); 175 close(fd); 176 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest004: end."; 177} 178 179/** 180 * @tc.name: FaultLoggerDaemonTest005 181 * @tc.desc: test CreateFileForRequest JIT_CODE_LOG and FFRT_CRASH_LOG branch 182 * @tc.type: FUNC 183 */ 184HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest005, TestSize.Level2) 185{ 186 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest005: start."; 187 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 188 bool ret = daemon->InitEnvironment(); 189 ASSERT_TRUE(ret); 190 191 int32_t pid = getpid(); 192 uint64_t time = GetTimeMilliSeconds(); 193 int32_t type = static_cast<int32_t>(FaultLoggerType::JIT_CODE_LOG); 194 int fd = daemon->CreateFileForRequest(type, pid, 0, time); 195 ASSERT_NE(fd, -1); 196 type = static_cast<int32_t>(FaultLoggerType::FFRT_CRASH_LOG); 197 fd = daemon->CreateFileForRequest(type, pid, 0, time); 198 ASSERT_NE(fd, -1); 199 close(fd); 200 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest005: end."; 201} 202 203void DoClientProcess(const std::string& socketFileName) 204{ 205 sleep(2); // 2 : wait 2 seconds, waiting for the service to be ready 206 int clientSocketFd = -1; 207 bool ret = StartConnect(clientSocketFd, socketFileName.c_str(), 10); // 10 : socket connect time out 10 second 208 ASSERT_TRUE(ret); 209 ASSERT_NE(clientSocketFd, -1); 210 GTEST_LOG_(INFO) << "child connect finished, client fd:" << clientSocketFd; 211 212 int data = 12345; // 12345 is for server Cred test 213 ret = SendMsgIovToSocket(clientSocketFd, reinterpret_cast<void *>(&data), sizeof(data)); 214 ASSERT_TRUE(ret); 215 216 GTEST_LOG_(INFO) << "Start read file desc"; 217 int testFd = ReadFileDescriptorFromSocket(clientSocketFd); 218 GTEST_LOG_(INFO) << "recv testFd:" << testFd; 219 ASSERT_NE(testFd, -1); 220 close(clientSocketFd); 221 close(testFd); 222} 223 224void TestSecurityCheck(const std::string& socketFileName) 225{ 226 int32_t serverSocketFd = -1; 227 bool ret = StartListen(serverSocketFd, socketFileName.c_str(), 5); // 5: means max connection count is 5 228 ASSERT_TRUE(ret); 229 ASSERT_NE(serverSocketFd, -1); 230 GTEST_LOG_(INFO) << "server start listen fd:" << serverSocketFd; 231 232 struct timeval timev = { 233 20, // 20 : recv timeout 20 seconds 234 0 235 }; 236 void* pTimev = &timev; 237 int retOpt = OHOS_TEMP_FAILURE_RETRY(setsockopt(serverSocketFd, SOL_SOCKET, SO_RCVTIMEO, 238 static_cast<const char*>(pTimev), sizeof(struct timeval))); 239 ASSERT_NE(retOpt, -1); 240 241 struct sockaddr_un clientAddr; 242 socklen_t clientAddrSize = static_cast<socklen_t>(sizeof(clientAddr)); 243 int32_t connectionFd = OHOS_TEMP_FAILURE_RETRY(accept(serverSocketFd, 244 reinterpret_cast<struct sockaddr *>(&clientAddr), &clientAddrSize)); 245 ASSERT_GT(connectionFd, 0); 246 247 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 248 struct FaultLoggerdRequest faultloggerdRequest; 249 if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) { 250 GTEST_LOG_(ERROR) << "memset_s failed" ; 251 ASSERT_TRUE(false); 252 } 253 faultloggerdRequest.type = 2; // 2 : CPP_CRASH 254 faultloggerdRequest.pid = getpid(); 255 faultloggerdRequest.tid = gettid(); 256 faultloggerdRequest.uid = getuid(); 257 258 FaultLoggerCheckPermissionResp resp = daemon->SecurityCheck(connectionFd, &faultloggerdRequest); 259 ASSERT_EQ(resp, FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT); 260 261 close(connectionFd); 262 close(serverSocketFd); 263} 264 265/** 266 * @tc.name: FaultLoggerDaemonTest006 267 * @tc.desc: test SecurityCheck abnormal branch 268 * @tc.type: FUNC 269 */ 270HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest006, TestSize.Level2) 271{ 272 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest006: start."; 273 std::string testSocketName = "faultloggerd.server.test"; 274 int32_t pid = fork(); 275 if (pid == 0) { 276 DoClientProcess(testSocketName); 277 GTEST_LOG_(INFO) << "client exit"; 278 exit(0); 279 } else if (pid > 0) { 280 TestSecurityCheck(testSocketName); 281 282 int status; 283 bool isSuccess = waitpid(pid, &status, 0) != -1; 284 if (!isSuccess) { 285 ASSERT_FALSE(isSuccess); 286 return; 287 } 288 289 int exitCode = -1; 290 if (WIFEXITED(status)) { 291 exitCode = WEXITSTATUS(status); 292 GTEST_LOG_(INFO) << "Exit status was " << exitCode; 293 } 294 ASSERT_EQ(exitCode, 0); 295 } 296 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest006: end."; 297} 298 299void TestCheckRequestCredential(const std::string& socketFileName) 300{ 301 int32_t serverSocketFd = -1; 302 bool ret = StartListen(serverSocketFd, socketFileName.c_str(), 5); // 5: means max connection count is 5 303 ASSERT_TRUE(ret); 304 ASSERT_NE(serverSocketFd, -1); 305 GTEST_LOG_(INFO) << "server start listen fd:" << serverSocketFd; 306 307 struct timeval timev = { 308 20, // 20 : recv timeout 20 seconds 309 0 310 }; 311 void* pTimev = &timev; 312 int retOpt = OHOS_TEMP_FAILURE_RETRY(setsockopt(serverSocketFd, SOL_SOCKET, SO_RCVTIMEO, 313 static_cast<const char*>(pTimev), sizeof(struct timeval))); 314 ASSERT_NE(retOpt, -1); 315 316 struct sockaddr_un clientAddr; 317 socklen_t clientAddrSize = static_cast<socklen_t>(sizeof(clientAddr)); 318 int32_t connectionFd = OHOS_TEMP_FAILURE_RETRY(accept(serverSocketFd, 319 reinterpret_cast<struct sockaddr *>(&clientAddr), &clientAddrSize)); 320 ASSERT_GT(connectionFd, 0); 321 322 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 323 struct FaultLoggerdRequest faultloggerdRequest; 324 if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) { 325 GTEST_LOG_(ERROR) << "memset_s failed" ; 326 ASSERT_TRUE(false); 327 } 328 faultloggerdRequest.type = 2; // 2 : CPP_CRASH 329 faultloggerdRequest.pid = getpid(); 330 faultloggerdRequest.tid = gettid(); 331 faultloggerdRequest.uid = getuid(); 332 333 bool result = daemon->CheckRequestCredential(connectionFd, nullptr); 334 ASSERT_EQ(result, false); 335 result = daemon->CheckRequestCredential(connectionFd, &faultloggerdRequest); 336 ASSERT_EQ(result, false); 337 338 close(connectionFd); 339 close(serverSocketFd); 340} 341 342/** 343 * @tc.name: FaultLoggerDaemonTest007 344 * @tc.desc: test CheckRequestCredential abnormal branch 345 * @tc.type: FUNC 346 */ 347HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest007, TestSize.Level2) 348{ 349 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest007: start."; 350 std::string testSocketName = "faultloggerd.server.test"; 351 int32_t pid = fork(); 352 if (pid == 0) { 353 DoClientProcess(testSocketName); 354 GTEST_LOG_(INFO) << "client exit"; 355 exit(0); 356 } else if (pid > 0) { 357 TestCheckRequestCredential(testSocketName); 358 359 int status; 360 bool isSuccess = waitpid(pid, &status, 0) != -1; 361 if (!isSuccess) { 362 ASSERT_FALSE(isSuccess); 363 return; 364 } 365 366 int exitCode = -1; 367 if (WIFEXITED(status)) { 368 exitCode = WEXITSTATUS(status); 369 GTEST_LOG_(INFO) << "Exit status was " << exitCode; 370 } 371 ASSERT_EQ(exitCode, 0); 372 } 373 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest007: end."; 374} 375 376void TestHandleExceptionRequest(const std::string& socketFileName) 377{ 378 int32_t serverSocketFd = -1; 379 bool ret = StartListen(serverSocketFd, socketFileName.c_str(), 5); // 5: means max connection count is 5 380 ASSERT_TRUE(ret); 381 ASSERT_NE(serverSocketFd, -1); 382 GTEST_LOG_(INFO) << "server start listen fd:" << serverSocketFd; 383 384 struct timeval timev = { 385 20, // 20 : recv timeout 20 seconds 386 0 387 }; 388 void* pTimev = &timev; 389 int retOpt = OHOS_TEMP_FAILURE_RETRY(setsockopt(serverSocketFd, SOL_SOCKET, SO_RCVTIMEO, 390 static_cast<const char*>(pTimev), sizeof(struct timeval))); 391 ASSERT_NE(retOpt, -1); 392 393 struct sockaddr_un clientAddr; 394 socklen_t clientAddrSize = static_cast<socklen_t>(sizeof(clientAddr)); 395 int32_t connectionFd = OHOS_TEMP_FAILURE_RETRY(accept(serverSocketFd, 396 reinterpret_cast<struct sockaddr *>(&clientAddr), &clientAddrSize)); 397 ASSERT_GT(connectionFd, 0); 398 399 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 400 struct FaultLoggerdRequest faultloggerdRequest; 401 if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) { 402 GTEST_LOG_(ERROR) << "memset_s failed" ; 403 ASSERT_TRUE(false); 404 } 405 faultloggerdRequest.type = 2; // 2 : CPP_CRASH 406 faultloggerdRequest.pid = getpid(); 407 faultloggerdRequest.tid = gettid(); 408 faultloggerdRequest.uid = getuid(); 409 410 daemon->HandleExceptionRequest(connectionFd, &faultloggerdRequest); 411 412 close(connectionFd); 413 close(serverSocketFd); 414} 415 416/** 417 * @tc.name: FaultLoggerDaemonTest008 418 * @tc.desc: test HandleExceptionRequest abnormal branch 419 * @tc.type: FUNC 420 */ 421HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest008, TestSize.Level2) 422{ 423 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest008: start."; 424 std::string testSocketName = "faultloggerd.server.test"; 425 int32_t pid = fork(); 426 if (pid == 0) { 427 DoClientProcess(testSocketName); 428 GTEST_LOG_(INFO) << "client exit"; 429 exit(0); 430 } else if (pid > 0) { 431 TestHandleExceptionRequest(testSocketName); 432 433 int status; 434 bool isSuccess = waitpid(pid, &status, 0) != -1; 435 if (!isSuccess) { 436 ASSERT_FALSE(isSuccess); 437 return; 438 } 439 440 int exitCode = -1; 441 if (WIFEXITED(status)) { 442 exitCode = WEXITSTATUS(status); 443 GTEST_LOG_(INFO) << "Exit status was " << exitCode; 444 } 445 ASSERT_EQ(exitCode, 0); 446 } 447 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest008: end."; 448} 449 450/** 451 * @tc.name: FaultLoggerDaemonTest009 452 * @tc.desc: test HandleAccept abnormal branch 453 * @tc.type: FUNC 454 */ 455HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest009, TestSize.Level2) 456{ 457 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest009: start."; 458 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 459 bool ret = daemon->InitEnvironment(); 460 ASSERT_TRUE(ret); 461 daemon->HandleAccept(1, 1); 462 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest009: end."; 463} 464 465/** 466 * @tc.name: FaultLoggerDaemonTest010 467 * @tc.desc: test HandleRequestByClientType abnormal branch 468 * @tc.type: FUNC 469 */ 470HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest010, TestSize.Level2) 471{ 472 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest010: start."; 473 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 474 bool ret = daemon->InitEnvironment(); 475 ASSERT_TRUE(ret); 476 477 int32_t connectionFd = 1; 478 479 FaultLoggerdRequest request; 480 request.clientType = FaultLoggerClientType::DEFAULT_CLIENT; 481 daemon->HandleRequestByClientType(connectionFd, &request); 482 request.clientType = FaultLoggerClientType::LOG_FILE_DES_CLIENT; 483 daemon->HandleRequestByClientType(connectionFd, &request); 484 request.clientType = FaultLoggerClientType::PRINT_T_HILOG_CLIENT; 485 daemon->HandleRequestByClientType(connectionFd, &request); 486 request.clientType = FaultLoggerClientType::PERMISSION_CLIENT; 487 daemon->HandleRequestByClientType(connectionFd, &request); 488 request.clientType = FaultLoggerClientType::PIPE_FD_CLIENT; 489 daemon->HandleRequestByClientType(connectionFd, &request); 490 request.clientType = FaultLoggerClientType::SDK_DUMP_CLIENT; 491 daemon->HandleRequestByClientType(connectionFd, &request); 492 request.clientType = FaultLoggerClientType::REPORT_EXCEPTION_CLIENT; 493 daemon->HandleRequestByClientType(connectionFd, &request); 494 request.clientType = -1; 495 daemon->HandleRequestByClientType(connectionFd, &request); 496 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest010: end."; 497} 498 499void TestHandleRequestByPipeType(std::shared_ptr<FaultLoggerDaemon> daemon, FaultLoggerPipe2* faultLoggerPipe, 500 FaultLoggerdRequest request, int32_t pipeType, bool isChangeFd) 501{ 502 int fd = -1; 503 request.pipeType = pipeType; 504 daemon->HandleRequestByPipeType(fd, 1, &request, faultLoggerPipe); 505 if (isChangeFd) { 506 ASSERT_NE(fd, -1); 507 } else { 508 ASSERT_EQ(fd, -1); 509 } 510} 511 512/** 513 * @tc.name: FaultLoggerDaemonTest011 514 * @tc.desc: test HandleRequestByPipeType abnormal branch 515 * @tc.type: FUNC 516 */ 517HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest011, TestSize.Level2) 518{ 519 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest011: start."; 520 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 521 bool ret = daemon->InitEnvironment(); 522 ASSERT_TRUE(ret); 523 524 FaultLoggerdRequest request; 525 FaultLoggerPipe2* faultLoggerPipe = new FaultLoggerPipe2(GetTimeMilliSeconds()); 526 bool isChangeFds4Pipe[PIPE_TYPE_COUNT] = {false, true, false, true, false, false, false, false}; 527 for (int i = 0; i < PIPE_TYPE_COUNT; i++) { 528 TestHandleRequestByPipeType(daemon, faultLoggerPipe, request, i, isChangeFds4Pipe[i]); 529 } 530 delete(faultLoggerPipe); 531 532 FaultLoggerPipe2* faultLoggerJsonPipe = new FaultLoggerPipe2(GetTimeMilliSeconds(), true); 533 bool isChangeFds4JsonPipe[PIPE_TYPE_COUNT] = {false, false, false, false, false, true, false, true}; 534 for (int i = 0; i < PIPE_TYPE_COUNT; i++) { 535 TestHandleRequestByPipeType(daemon, faultLoggerJsonPipe, request, i, isChangeFds4JsonPipe[i]); 536 } 537 delete(faultLoggerJsonPipe); 538 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest011: end."; 539} 540 541#ifndef is_ohos_lite 542/** 543 * @tc.name: FaultLoggerDaemonTest012 544 * @tc.desc: test FaultLoggerDaemon HandleStaticForFuzzer 545 * @tc.type: FUNC 546 */ 547HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest012, TestSize.Level2) 548{ 549 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 550 int params[][2] = { 551 {FaultLoggerType::CPP_STACKTRACE, ROOT_UID}, 552 {FaultLoggerType::JS_STACKTRACE, BMS_UID}, 553 {FaultLoggerType::LEAK_STACKTRACE, HIVIEW_UID}, 554 {FaultLoggerType::FFRT_CRASH_LOG, HIDUMPER_SERVICE_UID}, 555 {FaultLoggerType::JIT_CODE_LOG, FOUNDATION_UID}, 556 {FaultLoggerType::JS_HEAP_LEAK_LIST, FOUNDATION_UID}, 557 }; 558 bool ret = false; 559 for (int i = 0; i < sizeof(params) / sizeof(params[0]); i++) { 560 ret = daemon->HandleStaticForFuzzer(params[i][0], params[i][1]); 561 EXPECT_TRUE(ret); 562 } 563 ret = daemon->HandleStaticForFuzzer(-1, 1); 564 EXPECT_FALSE(ret); 565 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest012: end."; 566} 567 568/** 569 * @tc.name: FaultLoggerDaemonTest013 570 * @tc.desc: test FaultLoggerDaemon StartServer and AddEvent 571 * @tc.type: FUNC 572 */ 573HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest013, TestSize.Level2) 574{ 575 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest013: start."; 576 MockFaultLoggerDaemon mockDaemon; 577 578 EXPECT_CALL(mockDaemon, CreateSockets()).WillOnce(testing::Return(false)); 579 EXPECT_EQ(mockDaemon.StartServer(), -1); 580 EXPECT_CALL(mockDaemon, CreateSockets()).WillOnce(testing::Return(true)); 581 EXPECT_CALL(mockDaemon, InitEnvironment()).WillOnce(testing::Return(false)); 582 EXPECT_EQ(mockDaemon.StartServer(), -1); 583 EXPECT_CALL(mockDaemon, CreateSockets()).WillOnce(testing::Return(true)); 584 EXPECT_CALL(mockDaemon, InitEnvironment()).WillOnce(testing::Return(true)); 585 EXPECT_CALL(mockDaemon, CreateEventFd()).WillOnce(testing::Return(false)); 586 EXPECT_EQ(mockDaemon.StartServer(), -1); 587 EXPECT_CALL(mockDaemon, CreateSockets()).WillOnce(testing::Return(true)); 588 EXPECT_CALL(mockDaemon, InitEnvironment()).WillOnce(testing::Return(true)); 589 EXPECT_CALL(mockDaemon, CreateEventFd()).WillOnce(testing::Return(true)); 590 EXPECT_CALL(mockDaemon, WaitForRequest()).WillOnce(testing::Return()); 591 EXPECT_EQ(mockDaemon.StartServer(), 0); 592 593 FaultLoggerDaemon daemon; 594 EXPECT_EQ(daemon.InitEnvironment(), true); 595 EXPECT_EQ(daemon.CreateEventFd(), true); 596 daemon.CleanupEventFd(); 597 daemon.CleanupSockets(); 598 daemon.AddEvent(1, 1, 1); 599 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest013: end."; 600} 601#endif 602 603bool CheckReadResp(int sockfd) 604{ 605 char controlBuffer[SOCKET_BUFFER_SIZE] = {0}; 606 ssize_t nread = OHOS_TEMP_FAILURE_RETRY(read(sockfd, controlBuffer, sizeof(controlBuffer) - 1)); 607 if (nread != static_cast<ssize_t>(strlen(FAULTLOGGER_DAEMON_RESP))) { 608 return false; 609 } 610 return true; 611} 612 613void HandleRequestByPipeTypeCommon(std::shared_ptr<FaultLoggerDaemon> daemon, int32_t pipeType, 614 bool isPassCheck = false, bool isJson = false, bool isChangeFd = false) 615{ 616 int fd = -1; 617 FaultLoggerdRequest request; 618 request.pipeType = pipeType; 619 std::unique_ptr<FaultLoggerPipe2> ptr = std::make_unique<FaultLoggerPipe2>(GetTimeMilliSeconds(), isJson); 620 621 if (!isPassCheck) { 622 daemon->HandleRequestByPipeType(fd, 1, &request, ptr.get()); 623 if (!isChangeFd) { 624 EXPECT_EQ(fd, -1); 625 } else { 626 EXPECT_NE(fd, -1); 627 } 628 close(fd); 629 return; 630 } 631 632 int socketFd[2]; // 2 : the length of the array 633 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFd) == 0) { 634 pid_t pid = fork(); 635 if (pid == 0) { 636 sleep(1); 637 if (CheckReadResp(socketFd[1])) { 638 std::string test = "test"; 639 OHOS_TEMP_FAILURE_RETRY(write(socketFd[1], test.c_str(), sizeof(test))); 640 } 641 } else if (pid > 0) { 642 daemon->connectionMap_[socketFd[0]] = socketFd[0]; 643 daemon->HandleRequestByPipeType(fd, socketFd[0], &request, ptr.get()); 644 if (!isChangeFd) { 645 EXPECT_EQ(fd, -1); 646 } else { 647 EXPECT_NE(fd, -1); 648 } 649 close(fd); 650 close(socketFd[1]); 651 } 652 } 653} 654 655/** 656 * @tc.name: FaultLoggerDaemonTest014 657 * @tc.desc: test FaultLoggerDaemon for HandleRequestByPipeType 658 * @tc.type: FUNC 659 */ 660HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest014, TestSize.Level4) 661{ 662 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest014: start."; 663 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 664 daemon->InitEnvironment(); 665 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_READ_BUF, true, false, true); 666 sleep(2); 667 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_READ_RES, true, false, true); 668 sleep(2); 669 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_READ_BUF, true, true, true); 670 sleep(2); 671 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_READ_RES, true, true, true); 672 sleep(2); 673 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_READ_BUF, false, false, false); 674 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_WRITE_BUF, false, false, true); 675 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_READ_RES, false, false, false); 676 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_WRITE_RES, false, false, true); 677 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_READ_BUF, false, true, false); 678 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_WRITE_BUF, false, true, true); 679 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_READ_RES, false, true, false); 680 HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_WRITE_RES, false, true, true); 681 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest014: end."; 682} 683 684void HandleRequestTestCommon(std::shared_ptr<FaultLoggerDaemon> daemon, char* buff, size_t len, 685 void *(*startRoutine)(void *)) 686{ 687 int socketFd[2]; // 2 : the length of the array 688 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFd) == 0) { 689 OHOS_TEMP_FAILURE_RETRY(write(socketFd[1], buff, len)); 690 daemon->connectionMap_[socketFd[0]] = socketFd[0]; 691 692 if (!startRoutine) { 693 daemon->HandleRequest(0, socketFd[0]); 694 } else { 695 pthread_t threadId; 696 if (pthread_create(&threadId, nullptr, startRoutine, reinterpret_cast<void*>(socketFd[1])) != 0) { 697 perror("Failed to create thread"); 698 close(socketFd[0]); 699 close(socketFd[1]); 700 return; 701 } 702 703 daemon->HandleRequest(0, socketFd[0]); 704 EXPECT_NE(socketFd[0], -1); 705 706 pthread_join(threadId, nullptr); 707 } 708 close(socketFd[1]); 709 } 710} 711 712void HandleRequestByClientTypeForDefaultClientTest(std::shared_ptr<FaultLoggerDaemon> daemon) 713{ 714 FaultLoggerdRequest requst; 715 requst.clientType = FaultLoggerClientType::DEFAULT_CLIENT; 716 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr); 717 requst.type = FaultLoggerType::CPP_CRASH; 718 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr); 719 requst.type = FaultLoggerType::JS_HEAP_SNAPSHOT; 720 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr); 721 daemon->crashTimeMap_[1] = time(nullptr) - 10; // 10 : Get the first 10 seconds of the current time 722 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr); 723 daemon->crashTimeMap_[1] = time(nullptr); 724 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr); 725} 726 727void *ReadThread1(void *param) 728{ 729 long fd = reinterpret_cast<long>(param); 730 char buff[FAULTLOGGERD_FUZZ_READ_BUFF]; 731 OHOS_TEMP_FAILURE_RETRY(read(fd, buff, sizeof(buff))); 732 char msg[] = "any test str"; 733 OHOS_TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<char*>(msg), sizeof(msg))); 734 return nullptr; 735} 736 737void *ReadThread2(void *param) 738{ 739 long fd = reinterpret_cast<long>(param); 740 char buff[FAULTLOGGERD_FUZZ_READ_BUFF]; 741 OHOS_TEMP_FAILURE_RETRY(read(fd, buff, sizeof(buff))); 742 CrashDumpException test; 743 test.error = CRASH_DUMP_LOCAL_REPORT; 744 OHOS_TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<char*>(&test), sizeof(CrashDumpException))); 745 return nullptr; 746} 747 748void *ReadThread3(void *param) 749{ 750 long fd = reinterpret_cast<long>(param); 751 char buff[FAULTLOGGERD_FUZZ_READ_BUFF]; 752 OHOS_TEMP_FAILURE_RETRY(read(fd, buff, sizeof(buff))); 753 CrashDumpException test{}; 754 OHOS_TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<char*>(&test), sizeof(CrashDumpException))); 755 return nullptr; 756} 757 758void HandleRequestByClientTypeTest(std::shared_ptr<FaultLoggerDaemon> daemon) 759{ 760 { 761 FaultLoggerdRequest requst; 762 requst.clientType = FaultLoggerClientType::LOG_FILE_DES_CLIENT; 763 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr); 764 } 765 { 766 FaultLoggerdRequest requst; 767 requst.clientType = FaultLoggerClientType::PRINT_T_HILOG_CLIENT; 768 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread2); 769 } 770 { 771 FaultLoggerdRequest requst; 772 requst.clientType = FaultLoggerClientType::PERMISSION_CLIENT; 773 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread2); 774 } 775 { 776 FaultLoggerdRequest requst; 777 requst.clientType = FaultLoggerClientType::SDK_DUMP_CLIENT; 778 requst.pid = 1; 779 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread2); 780 } 781 { 782 FaultLoggerdRequest requst; 783 requst.clientType = FaultLoggerClientType::PIPE_FD_CLIENT; 784 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr); 785 } 786 { 787 FaultLoggerdRequest requst; 788 requst.clientType = FaultLoggerClientType::REPORT_EXCEPTION_CLIENT; 789 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread1); 790 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread2); 791 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread3); 792 } 793 { 794 FaultLoggerdRequest requst; 795 requst.clientType = -1; 796 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr); 797 } 798} 799 800/** 801 * @tc.name: FaultLoggerDaemonTest015 802 * @tc.desc: test FaultLoggerDaemon for HandleRequest 803 * @tc.type: FUNC 804 */ 805HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest015, TestSize.Level4) 806{ 807 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest015: start."; 808 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 809 { 810 int32_t epollFd = 1; 811 int32_t connectionFd = 4; // 4 : simulate an fd greater than 3 812 daemon->HandleRequest(epollFd, connectionFd); 813 connectionFd = 2; 814 daemon->HandleRequest(epollFd, connectionFd); 815 EXPECT_EQ(epollFd, 1); 816 epollFd = -1; 817 daemon->HandleRequest(epollFd, connectionFd); 818 EXPECT_EQ(epollFd, -1); 819 connectionFd = 4; 820 daemon->HandleRequest(epollFd, connectionFd); 821 EXPECT_EQ(epollFd, -1); 822 } 823 { 824 int socketFd[2]; // 2 : the length of the array 825 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFd) == 0) { 826 close(socketFd[1]); 827 daemon->HandleRequest(0, socketFd[0]); 828 } 829 } 830 { 831 FaultLoggerdRequest requst; 832 int socketFd[2]; // 2 : the length of the array 833 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFd) == 0) { 834 OHOS_TEMP_FAILURE_RETRY(write(socketFd[1], reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest))); 835 daemon->HandleRequest(0, socketFd[0]); 836 close(socketFd[1]); 837 } 838 EXPECT_NE(socketFd[1], -1); 839 } 840 841 if (!daemon->InitEnvironment()) { 842 daemon->CleanupSockets(); 843 } 844 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest015: end."; 845} 846 847std::vector<FaultLoggerdStatsRequest> InitStatsRequests() 848{ 849 std::vector<FaultLoggerdStatsRequest> statsRequest; 850 { 851 FaultLoggerdStatsRequest requst{}; 852 requst.type = PROCESS_DUMP; 853 requst.signalTime = GetTimeMilliSeconds(); 854 requst.pid = 1; 855 requst.processdumpStartTime = time(nullptr); 856 requst.processdumpFinishTime = time(nullptr) + 10; // 10 : Get the last 10 seconds of the current time 857 statsRequest.emplace_back(requst); 858 } 859 { 860 FaultLoggerdStatsRequest requst{}; 861 auto lastRequst = statsRequest.back(); 862 requst.type = DUMP_CATCHER; 863 requst.pid = lastRequst.pid; 864 requst.requestTime = time(nullptr); 865 requst.dumpCatcherFinishTime = time(nullptr) + 10; // 10 : Get the last 10 seconds of the current time 866 requst.result = 1; 867 statsRequest.emplace_back(requst); 868 } 869 { 870 FaultLoggerdStatsRequest requst{}; 871 requst.type = DUMP_CATCHER; 872 requst.pid = 1; 873 requst.requestTime = time(nullptr); 874 requst.dumpCatcherFinishTime = time(nullptr) + 10; // 10 : Get the last 10 seconds of the current time 875 requst.result = 1; 876 statsRequest.emplace_back(requst); 877 } 878 return statsRequest; 879} 880 881/** 882 * @tc.name: FaultLoggerDaemonTest016 883 * @tc.desc: test FaultLoggerDaemon for HandleDumpStats 884 * @tc.type: FUNC 885 */ 886HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest016, TestSize.Level4) 887{ 888 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest016: start."; 889 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 890 std::vector<FaultLoggerdStatsRequest> statsRequest = InitStatsRequests(); 891 for (auto requst : statsRequest) { 892 HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdStatsRequest), nullptr); 893 } 894 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest016: end."; 895} 896 897/** 898 * @tc.name: FaultLoggerDaemonTest017 899 * @tc.desc: test FaultLoggerDaemon for HandleRequest 900 * @tc.type: FUNC 901 */ 902HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest017, TestSize.Level4) 903{ 904 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest017: start."; 905 std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>(); 906 HandleRequestByClientTypeForDefaultClientTest(daemon); 907 HandleRequestByClientTypeTest(daemon); 908 GTEST_LOG_(INFO) << "FaultLoggerDaemonTest017: end."; 909} 910}