1 /*
2 * Copyright (C) 2024-2025 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 "hitrace_dump.h"
16
17 #include <dlfcn.h>
18 #include <filesystem>
19 #include <fstream>
20 #include <gtest/gtest.h>
21 #include <iostream>
22 #include <string>
23 #include <unistd.h>
24 #include <vector>
25
26 #include "common_define.h"
27 #include "common_utils.h"
28 #include "hitrace_define.h"
29 #include "test_utils.h"
30 #include "securec.h"
31
32 namespace OHOS {
33 namespace HiviewDFX {
34 namespace Hitrace {
35 using namespace testing::ext;
36 namespace {
37 const int TIME_COUNT = 10000;
38 const int CMD_OUTPUT_BUF = 1024;
39 const int BYTE_PER_MB = 1024 * 1024;
40 constexpr uint64_t S_TO_MS = 1000;
41 const std::string TRACE_SNAPSHOT_PREFIX = "trace_";
42 const std::string TRACE_RECORDING_PREFIX = "record_trace_";
43 const std::string TRACE_CACHE_PREFIX = "cache_trace_";
44 struct FileWithInfo {
45 std::string filename;
46 time_t ctime;
47 uint64_t fileSize;
48 uint64_t duration;
49 };
50
51 std::map<TraceDumpType, std::string> tracePrefixMap = {
52 {TraceDumpType::TRACE_SNAPSHOT, TRACE_SNAPSHOT_PREFIX},
53 {TraceDumpType::TRACE_RECORDING, TRACE_RECORDING_PREFIX},
54 {TraceDumpType::TRACE_CACHE, TRACE_CACHE_PREFIX},
55 };
56 }
57 class HitraceSystemTest : public testing::Test {
58 public:
SetUpTestCase(void)59 static void SetUpTestCase(void) {}
TearDownTestCase(void)60 static void TearDownTestCase(void)
61 {
62 ASSERT_TRUE(RunCmd("hitrace --trace_finish_nodump"));
63 ASSERT_TRUE(RunCmd("hitrace --trace_finish --record"));
64 ASSERT_TRUE(RunCmd("hitrace --stop_bgsrv"));
65 }
66
SetUp()67 void SetUp()
68 {
69 ASSERT_TRUE(RunCmd("hitrace --trace_finish_nodump"));
70 ASSERT_TRUE(RunCmd("hitrace --trace_finish --record"));
71 ASSERT_TRUE(RunCmd("hitrace --stop_bgsrv"));
72 }
TearDown()73 void TearDown() {}
74
RunCmd(const string & cmdstr)75 static bool RunCmd(const string& cmdstr)
76 {
77 if (cmdstr.empty()) {
78 return false;
79 }
80 FILE *fp = popen(cmdstr.c_str(), "r");
81 if (fp == nullptr) {
82 return false;
83 }
84 char res[CMD_OUTPUT_BUF] = { '\0' };
85 while (fgets(res, sizeof(res), fp) != nullptr) {
86 std::cout << res;
87 }
88 pclose(fp);
89 return true;
90 }
91 };
92
93 namespace {
CheckTraceCommandOutput(const std::string & cmd,const std::vector<std::string> & keywords,std::vector<std::string> & traceLists)94 bool CheckTraceCommandOutput(const std::string& cmd, const std::vector<std::string>& keywords,
95 std::vector<std::string>& traceLists)
96 {
97 if (cmd.empty()) {
98 return false;
99 }
100 FILE* fp = popen(cmd.c_str(), "r");
101 if (fp == nullptr) {
102 return false;
103 }
104
105 char buffer[CMD_OUTPUT_BUF];
106 int checkIdx = 0;
107 while (fgets(buffer, sizeof(buffer), fp) != nullptr) {
108 while (checkIdx < keywords.size() && strstr(buffer, keywords[checkIdx].c_str()) != nullptr) {
109 GTEST_LOG_(INFO) << "match keyword :" << keywords[checkIdx];
110 checkIdx++;
111 if (checkIdx == keywords.size()) {
112 break;
113 }
114 }
115 char* tracefile = strstr(buffer, TRACE_FILE_DEFAULT_DIR.c_str());
116 tracefile += TRACE_FILE_DEFAULT_DIR.length();
117 if (tracefile != nullptr) {
118 tracefile[strcspn(tracefile, "\n")] = '\0'; // replace "\n" with "\0"
119 GTEST_LOG_(INFO) << "match trace file : " << tracefile;
120 traceLists.push_back(std::string(tracefile));
121 }
122 }
123
124 pclose(fp);
125 if (checkIdx < keywords.size()) {
126 GTEST_LOG_(ERROR) << "Failed to match keyword : " << keywords[checkIdx];
127 }
128 return checkIdx == keywords.size();
129 }
130
IsTracingOn()131 bool IsTracingOn()
132 {
133 std::ifstream tracingOnFile(TRACEFS_DIR + TRACING_ON_NODE);
134 if (!tracingOnFile.is_open()) {
135 std::cout << "Failed to open /sys/kernel/tracing/tracing_on." << std::endl;
136 return false;
137 }
138 std::string content;
139 getline(tracingOnFile, content);
140 tracingOnFile.close();
141 return content == "1";
142 }
143
IsFileIncludeAllKeyWords(const string & fileName,const std::vector<std::string> & keywords)144 bool IsFileIncludeAllKeyWords(const string& fileName, const std::vector<std::string>& keywords)
145 {
146 std::ifstream readFile;
147 readFile.open(fileName.c_str(), std::ios::in);
148 if (readFile.fail()) {
149 GTEST_LOG_(ERROR) << "Failed to open file " << fileName;
150 return false;
151 }
152 int keywordIdx = 0;
153 std::string readLine;
154 while (getline(readFile, readLine, '\n') && keywordIdx < keywords.size()) {
155 if (readLine.find(keywords[keywordIdx]) == std::string::npos) {
156 continue;
157 }
158 keywordIdx++;
159 }
160 readFile.close();
161 if (keywordIdx < keywords.size()) {
162 GTEST_LOG_(ERROR) << "Failed to find keyword: " << keywords[keywordIdx];
163 }
164 return keywordIdx == keywords.size();
165 }
166
IsFileExcludeAllKeyWords(const string & fileName,const std::vector<std::string> & keywords)167 bool IsFileExcludeAllKeyWords(const string& fileName, const std::vector<std::string>& keywords)
168 {
169 std::ifstream readFile;
170 readFile.open(fileName.c_str(), std::ios::in);
171 if (readFile.fail()) {
172 GTEST_LOG_(ERROR) << "Failed to open file " << fileName;
173 return false;
174 }
175 std::string readLine;
176 while (getline(readFile, readLine, '\n')) {
177 for (auto& word : keywords) {
178 if (readLine.find(word) != std::string::npos) {
179 GTEST_LOG_(ERROR) << "File contained keyword: " << word;
180 readFile.close();
181 return false;
182 }
183 }
184 }
185 readFile.close();
186 return true;
187 }
188
ReadBufferSizeKB()189 std::string ReadBufferSizeKB()
190 {
191 std::ifstream file(TRACEFS_DIR + "buffer_size_kb");
192 if (!file.is_open()) {
193 GTEST_LOG_(ERROR) << "Failed to open buffer_size_kb";
194 return "Unknown";
195 }
196 std::string line;
197 if (std::getline(file, line)) {
198 GTEST_LOG_(INFO) << "Reading buffer_size_kb: " << line;
199 return line;
200 }
201 return "Unknown";
202 }
203
GetDurationFromFileName(const std::string & fileName,uint64_t & duration)204 bool GetDurationFromFileName(const std::string& fileName, uint64_t& duration)
205 {
206 auto index = fileName.find("-");
207 if (index == std::string::npos) {
208 return false;
209 }
210 uint32_t number;
211 if (sscanf_s(fileName.substr(index, fileName.size() - index).c_str(), "-%u.sys", &number) != 1) {
212 GTEST_LOG_(INFO) << "sscanf_s failed.";
213 return false;
214 }
215 duration = static_cast<uint64_t>(number);
216 return true;
217 }
218
GetFileInfo(const TraceDumpType & traceType,const std::vector<std::string> & outputFiles,std::vector<FileWithInfo> & fileList)219 bool GetFileInfo(const TraceDumpType& traceType, const std::vector<std::string>& outputFiles,
220 std::vector<FileWithInfo>& fileList)
221 {
222 struct stat fileStat;
223 for (auto i = 0; i < outputFiles.size(); i++) {
224 if (outputFiles[i].substr(TRACE_FILE_DEFAULT_DIR.size(), tracePrefixMap[traceType].size()) ==
225 tracePrefixMap[traceType]) {
226 uint64_t duration = 0;
227 if (GetDurationFromFileName(outputFiles[i].substr(TRACE_FILE_DEFAULT_DIR.size(),
228 outputFiles[i].size() - TRACE_FILE_DEFAULT_DIR.size()), duration)) {
229 if (stat(outputFiles[i].c_str(), &fileStat) == 0) {
230 fileList.push_back({outputFiles[i], fileStat.st_ctime, static_cast<uint64_t>(fileStat.st_size),
231 duration});
232 } else {
233 GTEST_LOG_(INFO) << "stat file failed, file is " << outputFiles[i].c_str();
234 return false;
235 }
236 } else {
237 GTEST_LOG_(INFO) << "GetDurationFromFileName failed, file is " << outputFiles[i].c_str();
238 return false;
239 }
240 }
241 }
242 std::sort(fileList.begin(), fileList.end(), [](const FileWithInfo& a, const FileWithInfo& b) {
243 return a.ctime < b.ctime;
244 });
245 return true;
246 }
247
GetTraceFilesInDir(const TraceDumpType & traceType)248 std::vector<std::string> GetTraceFilesInDir(const TraceDumpType& traceType)
249 {
250 std::vector<std::string> fileVec;
251 for (const auto &entry : std::filesystem::directory_iterator(TRACE_FILE_DEFAULT_DIR)) {
252 if (!entry.is_regular_file()) {
253 continue;
254 }
255 std::string fileName = entry.path().filename().string();
256 if (fileName.substr(0, tracePrefixMap[traceType].size()) == tracePrefixMap[traceType]) {
257 fileVec.push_back(TRACE_FILE_DEFAULT_DIR + fileName);
258 }
259 }
260 return fileVec;
261 }
262
GetTraceMarkerFdNum()263 int32_t GetTraceMarkerFdNum()
264 {
265 std::filesystem::path debugPath = std::filesystem::canonical("/sys/kernel/debug/tracing/trace_marker");
266 std::filesystem::path tracePath = std::filesystem::canonical("/sys/kernel/tracing/trace_marker");
267
268 int32_t fds = 0;
269 for (const auto& entry : std::filesystem::directory_iterator("/proc/self/fd")) {
270 if (!std::filesystem::is_symlink(entry.path())) {
271 continue;
272 }
273
274 auto symlink_path = std::filesystem::read_symlink(entry.path());
275 if (!symlink_path.is_absolute()) {
276 continue;
277 }
278
279 auto resolved_path = std::filesystem::canonical(symlink_path);
280 if (resolved_path == debugPath || resolved_path == tracePath) {
281 fds++;
282 }
283 }
284
285 return fds;
286 }
287
288 /**
289 * @tc.name: HitraceSystemTest001
290 * @tc.desc: when excute hitrace record command, check tracing_on switcher status
291 * @tc.type: FUNC
292 */
293 HWTEST_F(HitraceSystemTest, HitraceSystemTest001, TestSize.Level2)
294 {
295 ASSERT_TRUE(RunCmd("hitrace --trace_begin ace"));
296 int testCnt = TIME_COUNT;
297 while (testCnt > 0) {
298 usleep(10);
299 ASSERT_TRUE(IsTracingOn()) << "tracing_on switcher status is not 1";
300 testCnt--;
301 }
302 ASSERT_TRUE(RunCmd("hitrace --trace_finish_nodump"));
303 }
304
305 /**
306 * @tc.name: HitraceSystemTest002
307 * @tc.desc: when excute hitrace record command, check record file aging rules.
308 * @tc.type: FUNC
309 */
310 HWTEST_F(HitraceSystemTest, HitraceSystemTest002, TestSize.Level2)
311 {
312 if (IsRootVersion()) {
313 const int recordCnt = 20;
314 for (int i = 0; i < recordCnt; ++i) {
315 ASSERT_TRUE(RunCmd("hitrace --trace_begin --record sched"));
316 sleep(1);
317 ASSERT_TRUE(RunCmd("hitrace --trace_finish --record"));
318 }
319 int filecnt = CountRecordingTraceFile();
320 GTEST_LOG_(INFO) << "Filecnt: " << filecnt;
321 ASSERT_GE(filecnt, recordCnt);
322 }
323 }
324
325 /**
326 * @tc.name: SnapShotModeTest001
327 * @tc.desc: test open snapshot mode
328 * @tc.type: FUNC
329 */
330 HWTEST_F(HitraceSystemTest, SnapShotModeTest001, TestSize.Level1)
331 {
332 std::vector<std::string> traceLists = {};
333 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --start_bgsrv", {"SNAPSHOT_START", "OpenSnapshot done"}, traceLists));
334 ASSERT_TRUE(traceLists.empty());
335 }
336
337 /**
338 * @tc.name: SnapShotModeTest002
339 * @tc.desc: test open snapshot mode duplicately
340 * @tc.type: FUNC
341 */
342 HWTEST_F(HitraceSystemTest, SnapShotModeTest002, TestSize.Level1)
343 {
344 ASSERT_TRUE(RunCmd("hitrace --start_bgsrv"));
345 std::vector<std::string> traceLists = {};
346 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --start_bgsrv",
347 {"SNAPSHOT_START", "OpenSnapshot failed", "errorCode(1103)"}, traceLists));
348 ASSERT_TRUE(traceLists.empty());
349 }
350
351 /**
352 * @tc.name: SnapShotModeTest003
353 * @tc.desc: test close snapshot mode
354 * @tc.type: FUNC
355 */
356 HWTEST_F(HitraceSystemTest, SnapShotModeTest003, TestSize.Level1)
357 {
358 ASSERT_TRUE(RunCmd("hitrace --start_bgsrv"));
359 std::vector<std::string> traceLists = {};
360 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --stop_bgsrv", {"SNAPSHOT_STOP", "CloseSnapshot done"}, traceLists));
361 ASSERT_TRUE(traceLists.empty());
362 }
363
364 /**
365 * @tc.name: SnapShotModeTest004
366 * @tc.desc: test close snapshot mode duplicately
367 * @tc.type: FUNC
368 */
369 HWTEST_F(HitraceSystemTest, SnapShotModeTest004, TestSize.Level2)
370 {
371 ASSERT_TRUE(RunCmd("hitrace --start_bgsrv"));
372 ASSERT_TRUE(RunCmd("hitrace --stop_bgsrv"));
373 std::vector<std::string> traceLists = {};
374 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --stop_bgsrv", {"SNAPSHOT_STOP", "CloseSnapshot done"}, traceLists));
375 ASSERT_TRUE(traceLists.empty());
376 }
377
378 /**
379 * @tc.name: SnapShotModeTest005
380 * @tc.desc: test dump snapshot trace
381 * @tc.type: FUNC
382 */
383 HWTEST_F(HitraceSystemTest, SnapShotModeTest005, TestSize.Level1)
384 {
385 ASSERT_TRUE(RunCmd("hitrace --start_bgsrv"));
386 std::vector<std::string> traceLists = {};
387 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --dump_bgsrv", {"SNAPSHOT_DUMP", "DumpSnapshot done"}, traceLists));
388 ASSERT_FALSE(traceLists.empty());
389 ASSERT_TRUE(RunCmd("hitrace --stop_bgsrv"));
390 }
391
392 /**
393 * @tc.name: SnapShotModeTest006
394 * @tc.desc: test dump snapshot trace when snapshot mode not open
395 * @tc.type: FUNC
396 */
397 HWTEST_F(HitraceSystemTest, SnapShotModeTest006, TestSize.Level1)
398 {
399 std::vector<std::string> traceLists = {};
400 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --dump_bgsrv",
401 {"SNAPSHOT_DUMP", "DumpSnapshot failed", "errorCode(1102)"}, traceLists));
402 ASSERT_TRUE(traceLists.empty());
403 }
404
405 /**
406 * @tc.name: SnapShotModeTest007
407 * @tc.desc: test dump snapshot trace twice within 30s offset
408 * @tc.type: FUNC
409 */
410 HWTEST_F(HitraceSystemTest, SnapShotModeTest007, TestSize.Level1)
411 {
412 ASSERT_TRUE(RunCmd("hitrace --start_bgsrv"));
413 sleep(30);
414 std::vector<std::string> traceLists1 = {};
415 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --dump_bgsrv", {"SNAPSHOT_DUMP", "DumpSnapshot done"}, traceLists1));
416 ASSERT_FALSE(traceLists1.empty());
417 sleep(10); // 10 : sleep 10 seconds
418 std::vector<std::string> traceLists2 = {};
419 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --dump_bgsrv", {"SNAPSHOT_DUMP", "DumpSnapshot done"}, traceLists2));
420 ASSERT_FALSE(traceLists2.empty());
421 for (const auto& tracefile : traceLists1) {
422 ASSERT_NE(std::find(traceLists2.begin(), traceLists2.end(), tracefile), traceLists2.end());
423 }
424 ASSERT_TRUE(RunCmd("hitrace --stop_bgsrv"));
425 }
426
427 /**
428 * @tc.name: SnapShotModeTest008
429 * @tc.desc: test dump snapshot trace twice with 30s offset
430 * @tc.type: FUNC
431 */
432 HWTEST_F(HitraceSystemTest, SnapShotModeTest008, TestSize.Level1)
433 {
434 ASSERT_TRUE(RunCmd("hitrace --start_bgsrv"));
435 std::vector<std::string> traceLists1 = {};
436 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --dump_bgsrv", {"SNAPSHOT_DUMP", "DumpSnapshot done"}, traceLists1));
437 ASSERT_FALSE(traceLists1.empty());
438 sleep(31); // 31 : sleep 32 seconds, 1s is tolorance
439 std::vector<std::string> traceLists2 = {};
440 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --dump_bgsrv", {"SNAPSHOT_DUMP", "DumpSnapshot done"}, traceLists2));
441 ASSERT_FALSE(traceLists2.empty());
442 for (const auto& tracefile : traceLists1) {
443 ASSERT_EQ(std::find(traceLists2.begin(), traceLists2.end(), tracefile), traceLists2.end());
444 }
445 ASSERT_TRUE(RunCmd("hitrace --stop_bgsrv"));
446 }
447
448 /**
449 * @tc.name: SnapShotModeTest009
450 * @tc.desc: test dump snapshot trace with 15 files aging
451 * @tc.type: FUNC
452 */
453 HWTEST_F(HitraceSystemTest, SnapShotModeTest009, TestSize.Level1)
454 {
455 EXPECT_TRUE(RunCmd("hitrace --start_bgsrv"));
456 const int count = 15;
457 for (int i = 0; i < count; ++i) {
458 EXPECT_TRUE(RunCmd("hitrace --dump_bgsrv"));
459 sleep(1); // wait 1s
460 }
461 std::vector<std::string> traceLists = {};
462 EXPECT_TRUE(CheckTraceCommandOutput("hitrace --dump_bgsrv", {"SNAPSHOT_DUMP", "DumpSnapshot done"}, traceLists));
463 EXPECT_GE(traceLists.size(), count + 1);
464 EXPECT_TRUE(RunCmd("hitrace --stop_bgsrv"));
465 }
466
467 /**
468 * @tc.name: SnapShotModeTest010
469 * @tc.desc: test dump snapshot trace with 20 files aging
470 * @tc.type: FUNC
471 */
472 HWTEST_F(HitraceSystemTest, SnapShotModeTest010, TestSize.Level1)
473 {
474 ASSERT_TRUE(RunCmd("hitrace --start_bgsrv"));
475 const int dumpCnt = 30; // 30 : dump 30 times
476 for (int i = 0; i < dumpCnt; ++i) {
477 EXPECT_TRUE(RunCmd("hitrace --dump_bgsrv"));
478 sleep(1); // wait 1s
479 }
480 const int snapshotFileAge = 21;
481 std::vector<std::string> traceLists = {};
482 EXPECT_TRUE(CheckTraceCommandOutput("hitrace --dump_bgsrv", {"SNAPSHOT_DUMP", "DumpSnapshot done"}, traceLists));
483 EXPECT_GE(traceLists.size(), snapshotFileAge);
484 EXPECT_TRUE(RunCmd("hitrace --stop_bgsrv"));
485 std::vector<std::string> dirTraceLists = {};
486 GetSnapShotTraceFileList(dirTraceLists);
487 EXPECT_LE(dirTraceLists.size(), snapshotFileAge);
488 for (int i = 0; i < dirTraceLists.size(); ++i) {
489 EXPECT_NE(std::find(traceLists.begin(), traceLists.end(), dirTraceLists[i]), traceLists.end()) <<
490 "not found: " << dirTraceLists[i];
491 }
492 }
493
494 /**
495 * @tc.name: SnapShotModeTest011
496 * @tc.desc: test open snapshot mode can not be opened when reocording mode was opened.
497 * @tc.type: FUNC
498 */
499 HWTEST_F(HitraceSystemTest, SnapShotModeTest011, TestSize.Level1)
500 {
501 EXPECT_TRUE(RunCmd("hitrace --trace_begin --record ohos"));
502 std::vector<std::string> traceLists = {};
503 EXPECT_TRUE(CheckTraceCommandOutput("hitrace --start_bgsrv",
504 {"SNAPSHOT_START", "OpenSnapshot failed", "errorCode(1103)"}, traceLists));
505 EXPECT_TRUE(traceLists.empty());
506 EXPECT_TRUE(RunCmd("hitrace --trace_finish --record"));
507 }
508
509 /**
510 * @tc.name: CacheModeTest001
511 * @tc.desc: test dumptrace when cache trace was opened.
512 * @tc.type: FUNC
513 */
514 HWTEST_F(HitraceSystemTest, CacheModeTest001, TestSize.Level1)
515 {
516 const std::vector<std::string> tagGroups = {"default"};
517 EXPECT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
518 // total cache filesize limit: 800MB, sliceduration: 20s
519 EXPECT_TRUE(CacheTraceOn(800, 5) == TraceErrorCode::SUCCESS);
520 sleep(8); // wait 8s
521 TraceRetInfo ret = DumpTrace();
522 EXPECT_EQ(ret.errorCode, TraceErrorCode::SUCCESS);
523 EXPECT_EQ(ret.mode, TraceMode::OPEN | TraceMode::CACHE);
524 std::vector<FileWithInfo> fileList;
525 EXPECT_TRUE(GetFileInfo(TraceDumpType::TRACE_SNAPSHOT, ret.outputFiles, fileList));
526 EXPECT_GE(fileList.size(), 2); // cache_trace_ file count > 2
527 uint64_t totalDuartion = 0;
528 for (auto i = 0; i < fileList.size(); i++) {
529 GTEST_LOG_(INFO) << "file: " << fileList[i].filename.c_str() << ", size: " << fileList[i].fileSize
530 << ", duration:" << fileList[i].duration;
531 EXPECT_LE(fileList[i].fileSize, 154 * BYTE_PER_MB); // 154: single cache trace file max size limit(MB)
532 totalDuartion += fileList[i].duration;
533 EXPECT_TRUE(IsFileIncludeAllKeyWords(fileList[i].filename, {"name: sched_wakeup"}));
534 }
535 totalDuartion /= S_TO_MS;
536 EXPECT_GE(totalDuartion, 7); // total trace duration over 7s, given 1 second of tolerance
537 EXPECT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
538 }
539
540 /**
541 * @tc.name: CacheModeTest002
542 * @tc.desc: test dumptrace when cache trace was closed.
543 * @tc.type: FUNC
544 */
545 HWTEST_F(HitraceSystemTest, CacheModeTest002, TestSize.Level1)
546 {
547 const std::vector<std::string> tagGroups = {"default"};
548 TraceErrorCode retCode = OpenTrace(tagGroups);
549 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
550 // total cache filesize limit: 800MB, sliceduration: 20s
551 retCode = CacheTraceOn(800, 5);
552 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
553 sleep(8); // wait 8s
554 retCode = CacheTraceOff();
555 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
556 sleep(2); // wait 2s
557 TraceRetInfo ret = DumpTrace();
558 EXPECT_EQ(ret.errorCode, TraceErrorCode::SUCCESS);
559 std::vector<FileWithInfo> cacheFileList;
560 std::vector<FileWithInfo> traceFileList;
561 EXPECT_TRUE(GetFileInfo(TraceDumpType::TRACE_SNAPSHOT, ret.outputFiles, cacheFileList));
562 EXPECT_TRUE(GetFileInfo(TraceDumpType::TRACE_SNAPSHOT, ret.outputFiles, traceFileList));
563 uint64_t totalDuartion = 0;
564 EXPECT_GE(cacheFileList.size(), 2); // cache_trace_ file count > 2
565 for (auto i = 0; i < cacheFileList.size(); i++) {
566 GTEST_LOG_(INFO) << "file: " << cacheFileList[i].filename.c_str() << ", size: " << cacheFileList[i].fileSize
567 << ", duration:" << cacheFileList[i].duration;
568 EXPECT_LE(cacheFileList[i].fileSize, 154 * BYTE_PER_MB); // 154: single cache trace file max size limit(MB)
569 totalDuartion += cacheFileList[i].duration;
570 EXPECT_TRUE(IsFileIncludeAllKeyWords(cacheFileList[i].filename, {"name: sched_wakeup"}));
571 }
572 EXPECT_GE(traceFileList.size(), 1); // cache_trace_ file count > 1
573 for (auto i = 0; i < traceFileList.size(); i++) {
574 GTEST_LOG_(INFO) << "file: " << traceFileList[i].filename.c_str() << ", size: " << traceFileList[i].fileSize
575 << ", duration:" << traceFileList[i].duration;
576 totalDuartion += traceFileList[i].duration;
577 EXPECT_TRUE(IsFileIncludeAllKeyWords(traceFileList[i].filename, {"name: sched_wakeup"}));
578 }
579 totalDuartion /= S_TO_MS;
580 EXPECT_GE(totalDuartion, 10); // total trace duration over 10s
581 EXPECT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
582 }
583
584 /**
585 * @tc.name: CacheModeTest003
586 * @tc.desc: Test aging cache trace file when OpenTrace over 30s.
587 * @tc.type: FUNC
588 */
589 HWTEST_F(HitraceSystemTest, CacheModeTest003, TestSize.Level0)
590 {
591 const std::vector<std::string> tagGroups = {"default"};
592 TraceErrorCode retCode = OpenTrace(tagGroups);
593 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
594 // total cache filesize limit: 800MB, sliceduration: 5s
595 retCode = CacheTraceOn(800, 5);
596 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
597 sleep(8); // wait 8s
598 retCode = CloseTrace();
599 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
600 sleep(30); // wait 30s: start aging file
601 retCode = OpenTrace(tagGroups);
602 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
603 EXPECT_EQ(GetTraceFilesInDir(TraceDumpType::TRACE_CACHE).size(), 0); // no cache trace file
604 retCode = CloseTrace();
605 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
606 }
607
608 /**
609 * @tc.name: CacheModeTest004
610 * @tc.desc: Test aging cache trace file when file size overflow
611 * @tc.type: FUNC
612 */
613 HWTEST_F(HitraceSystemTest, CacheModeTest004, TestSize.Level0)
614 {
615 const std::vector<std::string> tagGroups = {"default"};
616 TraceErrorCode retCode = OpenTrace(tagGroups);
617 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
618 // total cache filesize limit: 5MB, sliceduration: 2s
619 retCode = CacheTraceOn(5, 2);
620 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
621 sleep(10); // wait 10s
622 retCode = CacheTraceOff();
623 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
624 std::vector<std::string> fileVec = GetTraceFilesInDir(TraceDumpType::TRACE_CACHE);
625 std::vector<FileWithInfo> cacheFileList;
626 EXPECT_TRUE(GetFileInfo(TraceDumpType::TRACE_CACHE, fileVec, cacheFileList));
627 uint64_t totalFileSize = 0;
628 for (auto i = 0; i < cacheFileList.size(); i++) {
629 GTEST_LOG_(INFO) << "file: " << cacheFileList[i].filename.c_str() << ", size: " << cacheFileList[i].fileSize;
630 totalFileSize += cacheFileList[i].fileSize;
631 }
632 EXPECT_LT(totalFileSize, 6 * BYTE_PER_MB); // aging file in 5MB - 6MB
633 retCode = CloseTrace();
634 EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
635 }
636
637 /**
638 * @tc.name: RecordingModeTest001
639 * @tc.desc: test open recording mode with sched tag
640 * @tc.type: FUNC
641 */
642 HWTEST_F(HitraceSystemTest, RecordingModeTest001, TestSize.Level1)
643 {
644 std::vector<std::string> traceLists = {};
645 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched",
646 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:18432", "trace capturing"}, traceLists));
647 ASSERT_TRUE(traceLists.empty());
648 ASSERT_TRUE(IsFileIncludeAllKeyWords(TRACE_FILE_DEFAULT_DIR + TRACE_SAVED_EVENTS_FORMAT,
649 {"name: print", "name: sched_wakeup", "name: sched_switch"}));
650 ASSERT_TRUE(IsFileExcludeAllKeyWords(TRACE_FILE_DEFAULT_DIR + TRACE_SAVED_EVENTS_FORMAT,
651 {"name: binder_transaction", "name: binder_transaction_received"}));
652 }
653
654 /**
655 * @tc.name: RecordingModeTest002
656 * @tc.desc: test open recording mode twice, the recording mode should be closed
657 * @tc.type: FUNC
658 */
659 HWTEST_F(HitraceSystemTest, RecordingModeTest002, TestSize.Level2)
660 {
661 std::vector<std::string> traceLists = {};
662 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched",
663 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:18432", "trace capturing"}, traceLists));
664 ASSERT_TRUE(traceLists.empty());
665 ASSERT_TRUE(IsTracingOn());
666 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched",
667 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:18432", "OpenRecording failed", "errorCode(1103)"},
668 traceLists));
669 ASSERT_TRUE(traceLists.empty());
670 ASSERT_TRUE(IsTracingOn());
671 }
672
673 /**
674 * @tc.name: RecordingModeTest003
675 * @tc.desc: test close recording mode twice, the record trace contain tag format
676 * @tc.type: FUNC
677 */
678 HWTEST_F(HitraceSystemTest, RecordingModeTest003, TestSize.Level1)
679 {
680 std::vector<std::string> traceLists = {};
681 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched",
682 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:18432", "trace capturing"}, traceLists));
683 ASSERT_TRUE(traceLists.empty());
684 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_finish --record",
685 {"RECORDING_LONG_FINISH_RECORD", "capture done, output files"}, traceLists));
686 ASSERT_FALSE(traceLists.empty());
687 for (const auto& trace : traceLists) {
688 ASSERT_TRUE(IsFileIncludeAllKeyWords(TRACE_FILE_DEFAULT_DIR + trace,
689 {"name: print", "name: sched_wakeup", "name: sched_switch"}));
690 }
691 }
692
693 /**
694 * @tc.name: RecordingModeTest004
695 * @tc.desc: test close recording if close already
696 * @tc.type: FUNC
697 */
698 HWTEST_F(HitraceSystemTest, RecordingModeTest004, TestSize.Level2)
699 {
700 std::vector<std::string> traceLists = {};
701 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_finish --record",
702 {"RECORDING_LONG_FINISH_RECORD", "RecordingOff failed", "errorCode(1102)"}, traceLists));
703 ASSERT_TRUE(traceLists.empty());
704 }
705
706 /**
707 * @tc.name: RecordingModeTest005
708 * @tc.desc: test recording mode file aging
709 * @tc.type: FUNC
710 */
711 HWTEST_F(HitraceSystemTest, RecordingModeTest005, TestSize.Level2)
712 {
713 int testCnt = 30; // 30 : test cnt
714 while (testCnt-- > 0) {
715 ASSERT_TRUE(RunCmd("hitrace --trace_begin --record sched"));
716 ASSERT_TRUE(RunCmd("hitrace --trace_finish --record"));
717 }
718 std::vector<std::string> dirTraceLists = {};
719 GetRecordingTraceFileList(dirTraceLists);
720 if (IsRootVersion()) {
721 ASSERT_GE(dirTraceLists.size(), 30); // 30 : file cnt
722 } else {
723 ASSERT_LE(dirTraceLists.size(), 16); // 16 : max file cnt
724 }
725 }
726
727 /**
728 * @tc.name: RecordingModeTest006
729 * @tc.desc: test recording mode has a higher priority than snapshot mode
730 * @tc.type: FUNC
731 */
732 HWTEST_F(HitraceSystemTest, RecordingModeTest006, TestSize.Level1)
733 {
734 std::vector<std::string> traceLists = {};
735 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --start_bgsrv", {"SNAPSHOT_START", "OpenSnapshot done"}, traceLists));
736 ASSERT_TRUE(traceLists.empty());
737 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched",
738 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:18432", "errorCode(1103)"}, traceLists));
739 ASSERT_TRUE(traceLists.empty());
740 }
741
742 /**
743 * @tc.name: RecordingModeTest007
744 * @tc.desc: test recording mode buffer size customization
745 * @tc.type: FUNC
746 */
747 HWTEST_F(HitraceSystemTest, RecordingModeTest007, TestSize.Level1)
748 {
749 std::vector<std::string> traceLists = {};
750 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched -b 102400",
751 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:102400", "trace capturing"}, traceLists));
752 ASSERT_TRUE(traceLists.empty());
753 ASSERT_EQ(ReadBufferSizeKB(), IsHmKernel() ? "102400" : "102402");
754 }
755
756 /**
757 * @tc.name: RecordingModeTest008
758 * @tc.desc: test recording mode buffer size customization in hm kernel:[256, 1048576]
759 * @tc.type: FUNC
760 */
761 HWTEST_F(HitraceSystemTest, RecordingModeTest008, TestSize.Level1)
762 {
763 if (IsHmKernel()) {
764 std::vector<std::string> traceLists = {};
765 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched -b 255",
766 {"buffer size must be from 256 KB to 1024 MB", "parsing args failed, exit"}, traceLists));
767 ASSERT_TRUE(traceLists.empty());
768 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched -b 256",
769 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:256", "trace capturing"}, traceLists));
770 ASSERT_TRUE(traceLists.empty());
771 ASSERT_EQ(ReadBufferSizeKB(), "512");
772 }
773 }
774
775 /**
776 * @tc.name: RecordingModeTest009
777 * @tc.desc: test recording mode buffer size customization in hm kernel:[256, 1048576]
778 * @tc.type: FUNC
779 */
780 HWTEST_F(HitraceSystemTest, RecordingModeTest009, TestSize.Level1)
781 {
782 if (IsHmKernel()) {
783 std::vector<std::string> traceLists = {};
784 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched -b 1048577",
785 {"buffer size must be from 256 KB to 1024 MB", "parsing args failed, exit"}, traceLists));
786 ASSERT_TRUE(traceLists.empty());
787 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched -b 1048576",
788 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:1048576", "trace capturing"}, traceLists));
789 ASSERT_TRUE(traceLists.empty());
790 ASSERT_EQ(ReadBufferSizeKB(), "1048576");
791 }
792 }
793
794 /**
795 * @tc.name: RecordingModeTest010
796 * @tc.desc: test recording mode buffer size customization in linux kernel:[256, 307200], hm kernel:[256, 1048576]
797 * @tc.type: FUNC
798 */
799 HWTEST_F(HitraceSystemTest, RecordingModeTest010, TestSize.Level1)
800 {
801 if (!IsHmKernel()) {
802 std::vector<std::string> traceLists = {};
803 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched -b 255",
804 {"buffer size must be from 256 KB to 300 MB", "parsing args failed, exit"}, traceLists));
805 ASSERT_TRUE(traceLists.empty());
806 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched -b 256",
807 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:256", "trace capturing"}, traceLists));
808 ASSERT_TRUE(traceLists.empty());
809 ASSERT_EQ(ReadBufferSizeKB(), "258");
810 }
811 }
812
813 /**
814 * @tc.name: RecordingModeTest011
815 * @tc.desc: test recording mode buffer size customization in linux kernel: [256, 307200]
816 * @tc.type: FUNC
817 */
818 HWTEST_F(HitraceSystemTest, RecordingModeTest011, TestSize.Level1)
819 {
820 if (!IsHmKernel()) {
821 std::vector<std::string> traceLists = {};
822 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched -b 307201",
823 {"buffer size must be from 256 KB to 300 MB", "parsing args failed, exit"}, traceLists));
824 ASSERT_TRUE(traceLists.empty());
825 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin --record sched -b 307200",
826 {"RECORDING_LONG_BEGIN_RECORD", "tags:sched", "bufferSize:307200", "trace capturing"}, traceLists));
827 ASSERT_TRUE(traceLists.empty());
828 }
829 }
830
831 /**
832 * @tc.name: HitraceSystemTestErr001
833 * @tc.desc: when excute hitrace record command failed, -b abc
834 * @tc.type: FUNC
835 */
836 HWTEST_F(HitraceSystemTest, HitraceSystemTestErr001, TestSize.Level2)
837 {
838 std::vector<std::string> traceLists = {};
839 EXPECT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin ace -b abc",
840 {"buffer size is illegal input"}, traceLists));
841 ASSERT_TRUE(traceLists.empty());
842 }
843
844 /**
845 * @tc.name: HitraceSystemTestErr002
846 * @tc.desc: when excute hitrace record command failed, -t abc
847 * @tc.type: FUNC
848 */
849 HWTEST_F(HitraceSystemTest, HitraceSystemTestErr002, TestSize.Level2)
850 {
851 std::vector<std::string> traceLists = {};
852 EXPECT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin ace -t abc",
853 {"the time is illegal input"}, traceLists));
854 ASSERT_TRUE(traceLists.empty());
855 }
856
857 /**
858 * @tc.name: HitraceSystemTestErr003
859 * @tc.desc: when excute hitrace record command failed, -t 0
860 * @tc.type: FUNC
861 */
862 HWTEST_F(HitraceSystemTest, HitraceSystemTestErr003, TestSize.Level2)
863 {
864 std::vector<std::string> traceLists = {};
865 EXPECT_TRUE(CheckTraceCommandOutput("hitrace --trace_begin ace -t 0",
866 {"to be greater than zero"}, traceLists));
867 ASSERT_TRUE(traceLists.empty());
868 }
869
870 /**
871 * @tc.name: HitraceSystemTestErr004
872 * @tc.desc: when excute hitrace record command failed, --abc
873 * @tc.type: FUNC
874 */
875 HWTEST_F(HitraceSystemTest, HitraceSystemTestErr004, TestSize.Level2)
876 {
877 std::vector<std::string> traceLists = {};
878 EXPECT_TRUE(CheckTraceCommandOutput("hitrace --abc", {"parsing args failed"}, traceLists));
879 ASSERT_TRUE(traceLists.empty());
880 }
881
882 /**
883 * @tc.name: HitraceSystemHelpTest
884 * @tc.desc: excute hitrace help command
885 * @tc.type: FUNC
886 */
887 HWTEST_F(HitraceSystemTest, HitraceSystemHelpTest, TestSize.Level2)
888 {
889 std::vector<std::string> traceLists = {};
890 EXPECT_TRUE(CheckTraceCommandOutput("hitrace -h", {"trace_begin", "trace_finish"}, traceLists));
891 ASSERT_TRUE(traceLists.empty());
892 }
893
894 /**
895 * @tc.name: HitraceSystemCompressesTest
896 * @tc.desc: when excute hitrace record command with -z
897 * @tc.type: FUNC
898 */
899 HWTEST_F(HitraceSystemTest, HitraceSystemCompressesTest, TestSize.Level2)
900 {
901 std::vector<std::string> traceLists = {};
902 ASSERT_TRUE(RunCmd("hitrace --trace_begin app"));
903 ASSERT_TRUE(RunCmd("hitrace --trace_dump"));
904 ASSERT_FALSE(CheckTraceCommandOutput("hitrace --trace_finish -z", {"TASK-PID"}, traceLists));
905 ASSERT_TRUE(traceLists.empty());
906 }
907
908 /**
909 * @tc.name: HitraceSystemRawTest
910 * @tc.desc: when excute hitrace command with --raw
911 * @tc.type: FUNC
912 */
913 HWTEST_F(HitraceSystemTest, HitraceSystemRawTest, TestSize.Level2)
914 {
915 std::vector<std::string> traceLists = {};
916 ASSERT_TRUE(CheckTraceCommandOutput("hitrace -t 2 app --raw",
917 {"RECORDING_SHORT_RAW", "capture done, output files:"}, traceLists));
918 ASSERT_FALSE(traceLists.empty());
919 for (size_t i = 0; i < traceLists.size(); i++) {
920 std::string traceFilePath = "/data/log/hitrace/" + traceLists[i];
921 ASSERT_TRUE(access(traceFilePath.c_str(), F_OK) != -1);
922 }
923 }
924
925 /**
926 * @tc.name: HitraceSystemSetLevelTest001
927 * @tc.desc: when excute hitrace command with --trace_level level, success to set level
928 * @tc.type: FUNC
929 */
930 HWTEST_F(HitraceSystemTest, HitraceSystemSetLevelTest001, TestSize.Level2)
931 {
932 std::vector<std::string> traceLists = {};
933 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_level I",
934 {"SET_TRACE_LEVEL", "success to set trace level"}, traceLists));
935 }
936
937 /**
938 * @tc.name: HitraceSystemSetLevelTest002
939 * @tc.desc: when excute hitrace command with --trace_level level, fail to set level
940 * @tc.type: FUNC
941 */
942 HWTEST_F(HitraceSystemTest, HitraceSystemSetLevelTest002, TestSize.Level2)
943 {
944 std::vector<std::string> traceLists = {};
945 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --trace_level K",
946 {"error: trace level is illegal input.", "parsing args failed"}, traceLists));
947 }
948
949 /**
950 * @tc.name: HitraceSystemGetLevelTest001
951 * @tc.desc: when excute hitrace command with --get_level, success to get level
952 * @tc.type: FUNC
953 */
954 HWTEST_F(HitraceSystemTest, HitraceSystemGetLevelTest001, TestSize.Level2)
955 {
956 std::vector<std::string> traceLists = {};
957 ASSERT_TRUE(CheckTraceCommandOutput("hitrace --get_level",
958 {"GET_TRACE_LEVEL", "the current trace level threshold is"}, traceLists));
959 }
960
961 /**
962 * @tc.name: HitraceSystemGetLevelTest002
963 * @tc.desc: when excute hitrace command with --get_level, fail to get level
964 * @tc.type: FUNC
965 */
966 HWTEST_F(HitraceSystemTest, HitraceSystemGetLevelTest002, TestSize.Level2)
967 {
968 constexpr int invalidLevel = -1;
969 constexpr int hitraceOutputLevelInfo = 1;
970 ASSERT_TRUE(SetPropertyInner(TRACE_LEVEL_THRESHOLD, std::to_string(invalidLevel)));
971 std::vector<std::string> traceLists = {};
972 EXPECT_TRUE(CheckTraceCommandOutput("hitrace --get_level",
973 {"GET_TRACE_LEVEL", "error: get trace level threshold failed"}, traceLists));
974 ASSERT_TRUE(SetPropertyInner(TRACE_LEVEL_THRESHOLD, std::to_string(hitraceOutputLevelInfo)));
975 }
976
977 HWTEST_F(HitraceSystemTest, HitraceDlcoseTest001, TestSize.Level2)
978 {
979 const int cycles = 10;
980 const int fdNums = 2;
981 const char* libraryPath = "libhitrace_meter.so";
982 int count = 0;
983
984 for (int i = 0; i < cycles; ++i) {
985 void* handle = dlopen(libraryPath, RTLD_LAZY);
986 ASSERT_NE(handle, nullptr);
987
988 auto func = reinterpret_cast<void(*)(uint64_t, const char*)>(dlsym(handle, "StartTraceWrapper"));
989
990 if (func == nullptr) {
991 dlclose(handle);
992 continue;
993 }
994
995 func(1, libraryPath);
996 EXPECT_GT(GetTraceMarkerFdNum(), 0);
997 EXPECT_EQ(dlclose(handle), 0);
998 count++;
999 }
1000
1001 EXPECT_LE(GetTraceMarkerFdNum(), fdNums);
1002 EXPECT_EQ(count, cycles);
1003 }
1004
1005 HWTEST_F(HitraceSystemTest, HitraceDlcoseTest002, TestSize.Level2)
1006 {
1007 const char* libraryPath = "libhitrace_meter.so";
1008
1009 void* handle = dlopen(libraryPath, RTLD_LAZY);
1010 ASSERT_NE(handle, nullptr);
1011
1012 auto func = reinterpret_cast<void(*)(uint64_t, const char*)>(dlsym(handle, "StartTraceWrapper"));
1013 if (func == nullptr) {
1014 dlclose(handle);
1015 ASSERT_TRUE(false);
1016 }
1017 func(1, libraryPath);
1018
1019 std::vector<const char*> libPaths = { "libhitracemeter_napi.z.so", "libhitracechain.so" };
1020 for (const char* path : libPaths) {
1021 void* sHandle = dlopen(path, RTLD_LAZY);
1022 EXPECT_NE(sHandle, nullptr);
1023
1024 if (sHandle != nullptr) {
1025 dlclose(sHandle);
1026 }
1027 }
1028
1029 EXPECT_NE(GetTraceMarkerFdNum(), 0);
1030 EXPECT_EQ(dlclose(handle), 0);
1031 }
1032 } // namespace
1033 } // namespace Hitrace
1034 } // namespace HiviewDFX
1035 } // namespace OHOS
1036