• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-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 
16 #include "hitrace_dump.h"
17 
18 #include <cstdio>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <fstream>
22 #include <gtest/gtest.h>
23 #include <iostream>
24 #include <map>
25 #include <memory>
26 #include <sstream>
27 #include <string>
28 #include <unistd.h>
29 #include <vector>
30 
31 #include "common_define.h"
32 #include "common_utils.h"
33 #include "hitrace_define.h"
34 #include "hilog/log.h"
35 #include "parameters.h"
36 #include "securec.h"
37 #include "test_utils.h"
38 #include "trace_file_utils.h"
39 #include "trace_json_parser.h"
40 
41 using namespace OHOS::HiviewDFX::Hitrace;
42 using namespace testing::ext;
43 using OHOS::HiviewDFX::HiLog;
44 
45 namespace {
46 #ifdef LOG_DOMAIN
47 #undef LOG_DOMAIN
48 #define LOG_DOMAIN 0xD002D33
49 #endif
50 #ifdef LOG_TAG
51 #undef LOG_TAG
52 #define LOG_TAG "HitraceTest"
53 #endif
54 const int BUFFER_SIZE = 255;
55 constexpr uint32_t SLEEP_TIME = 15;
56 constexpr uint32_t TWO_SEC = 2;
57 constexpr uint32_t TEN_SEC = 10;
58 constexpr uint32_t S_TO_MS = 1000;
59 constexpr uint32_t MAX_RATIO_UNIT = 1000;
60 constexpr int DEFAULT_FULL_TRACE_LENGTH = 30;
61 const std::string TRACE_SNAPSHOT_PREFIX = "trace_";
62 const std::string TRACE_RECORDING_PREFIX = "record_trace_";
63 const std::string TRACE_CACHE_PREFIX = "cache_trace_";
64 struct FileWithTime {
65     std::string filename;
66     time_t ctime;
67     uint64_t fileSize;
68 };
69 
70 std::map<TraceDumpType, std::string> tracePrefixMap = {
71     {TraceDumpType::TRACE_SNAPSHOT, TRACE_SNAPSHOT_PREFIX},
72     {TraceDumpType::TRACE_RECORDING, TRACE_RECORDING_PREFIX},
73     {TraceDumpType::TRACE_CACHE, TRACE_CACHE_PREFIX},
74 };
75 
76 constexpr int ALIGNMENT_COEFFICIENT = 4;
77 
78 struct alignas(ALIGNMENT_COEFFICIENT) TraceFileHeader {
79     uint16_t magicNumber;
80     uint8_t fileType;
81     uint16_t versionNumber;
82     uint32_t reserved;
83 };
84 
85 struct alignas(ALIGNMENT_COEFFICIENT) TraceFileContentHeader {
86     uint8_t type;
87     uint32_t length;
88 };
89 
TraverseFiles(std::vector<std::string> files,std::string outputFileName)90 bool TraverseFiles(std::vector<std::string> files, std::string outputFileName)
91 {
92     int i = 1;
93     bool isExists = false;
94     for (std::vector<std::string>::iterator iter = files.begin(); iter != files.end(); iter++) {
95         isExists |= (strcmp(iter->c_str(), outputFileName.c_str()) == 0);
96         HILOG_INFO(LOG_CORE, "ret.outputFile%{public}d: %{public}s", i++, iter->c_str());
97     }
98     return isExists;
99 }
100 
HasProcessWithName(const std::string & name)101 int HasProcessWithName(const std::string& name)
102 {
103     std::array<char, BUFFER_SIZE> buffer;
104     std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("ps -ef | grep HitraceDump", "r"), pclose);
105     if (pipe == nullptr) {
106         HILOG_ERROR(LOG_CORE, "Error: run command failed.");
107         return -1;
108     }
109     while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
110         std::string line(buffer.data());
111         size_t found = line.rfind(name);
112         if (found != std::string::npos && (found == line.length() - name.length() ||
113             line[found + name.length()] == ' ')) {
114                 return 1;
115             }
116     }
117     return 0;
118 }
119 
GetFileStatInfo(const std::string & filePath)120 struct stat GetFileStatInfo(const std::string& filePath)
121 {
122     struct stat fileStat;
123     if (stat(filePath.c_str(), &fileStat) != 0) {
124         HILOG_ERROR(LOG_CORE, "Error getting file status: %{public}d.", errno);
125     }
126     return fileStat;
127 }
128 
GetTraceFilesInDir(const TraceDumpType & traceType)129 std::vector<FileWithTime> GetTraceFilesInDir(const TraceDumpType& traceType)
130 {
131     struct stat fileStat;
132     std::vector<FileWithTime> fileList;
133     for (const auto &entry : std::filesystem::directory_iterator(TRACE_FILE_DEFAULT_DIR)) {
134         if (!entry.is_regular_file()) {
135             continue;
136         }
137         std::string fileName = entry.path().filename().string();
138         if (fileName.substr(0, tracePrefixMap[traceType].size()) == tracePrefixMap[traceType]) {
139             if (stat((TRACE_FILE_DEFAULT_DIR + fileName).c_str(), &fileStat) == 0) {
140                 fileList.push_back({TRACE_FILE_DEFAULT_DIR + fileName, fileStat.st_ctime,
141                     static_cast<uint64_t>(fileStat.st_size)});
142             }
143         }
144     }
145     std::sort(fileList.begin(), fileList.end(), [](const FileWithTime& a, const FileWithTime& b) {
146         return a.ctime < b.ctime;
147     });
148     return fileList;
149 }
150 
DeleteTraceFileInDir(const std::vector<FileWithTime> fileLists)151 void DeleteTraceFileInDir(const std::vector<FileWithTime> fileLists)
152 {
153     for (size_t i = 0; i < fileLists.size(); ++i) {
154         if (remove(fileLists[i].filename.c_str()) == 0) {
155             GTEST_LOG_(INFO) << "remove " << fileLists[i].filename.c_str() << " success.";
156         } else {
157             GTEST_LOG_(INFO) << "remove " << fileLists[i].filename.c_str() << " fail.";
158         }
159     }
160 }
161 
InitFileFromDir()162 void InitFileFromDir()
163 {
164     DeleteTraceFileInDir(GetTraceFilesInDir(TraceDumpType::TRACE_CACHE));
165     DeleteTraceFileInDir(GetTraceFilesInDir(TraceDumpType::TRACE_SNAPSHOT));
166 }
167 
GetRecordTrace()168 static std::vector<std::string> GetRecordTrace()
169 {
170     std::vector<std::string> result;
171     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
172     auto errorCode = OpenTrace(args);
173     if (errorCode!= TraceErrorCode::SUCCESS) {
174         GTEST_LOG_(INFO) << "GetRecordTrace OpenTrace failed, errorCode: " << static_cast<int>(errorCode);
175         return result;
176     }
177     errorCode = RecordTraceOn();
178     if (errorCode != TraceErrorCode::SUCCESS) {
179         GTEST_LOG_(INFO) << "GetRecordTrace RecordTraceOn failed, errorCode: " << static_cast<int>(errorCode);
180         CloseTrace();
181         return result;
182     }
183     sleep(1);
184     TraceRetInfo ret = RecordTraceOff();
185     if (ret.errorCode != TraceErrorCode::SUCCESS) {
186         GTEST_LOG_(INFO) << "GetRecordTrace RecordTraceOff failed, errorCode: " << static_cast<int>(ret.errorCode);
187         CloseTrace();
188         return result;
189     }
190     CloseTrace();
191     return ret.outputFiles;
192 }
193 
GetCacheTrace()194 static std::vector<std::string> GetCacheTrace()
195 {
196     std::vector<std::string> result;
197     const std::vector<std::string> tagGroups = {"scene_performance"};
198     auto errorCode = OpenTrace(tagGroups);
199     if (errorCode != TraceErrorCode::SUCCESS) {
200         GTEST_LOG_(INFO) << "GetCacheTrace OpenTrace failed, errorCode: " << static_cast<int>(errorCode);
201         return result;
202     }
203     errorCode = CacheTraceOn();
204     if (errorCode != TraceErrorCode::SUCCESS) {
205         GTEST_LOG_(INFO) << "GetCacheTrace CacheTraceOn failed, errorCode: " << static_cast<int>(errorCode);
206         CloseTrace();
207         return result;
208     }
209     sleep(1);
210     TraceRetInfo ret = DumpTrace();
211     if (ret.errorCode != TraceErrorCode::SUCCESS) {
212         GTEST_LOG_(INFO) << "GetCacheTrace DumpTrace failed, errorCode: " << static_cast<int>(errorCode);
213         CloseTrace();
214         return result;
215     }
216     errorCode = CacheTraceOff();
217     if (errorCode != TraceErrorCode::SUCCESS) {
218         GTEST_LOG_(INFO) << "GetCacheTrace CacheTraceOff failed, errorCode: " << static_cast<int>(errorCode);
219         CloseTrace();
220         return result;
221     }
222     CloseTrace();
223     return ret.outputFiles;
224 }
225 
GetSnapShotTrace()226 static std::vector<std::string> GetSnapShotTrace()
227 {
228     std::vector<std::string> result;
229     const std::vector<std::string> tagGroups = {"scene_performance"};
230     auto errorCode = OpenTrace(tagGroups);
231     if (errorCode != TraceErrorCode::SUCCESS) {
232         GTEST_LOG_(INFO) << "GetSnapShotTrace OpenTrace failed, errorCode: " << static_cast<int>(errorCode);
233         return result;
234     }
235     sleep(1);
236     TraceRetInfo ret = DumpTrace();
237     if (ret.errorCode != TraceErrorCode::SUCCESS) {
238         GTEST_LOG_(INFO) << "GetSnapShotTrace DumpTrace failed, errorCode: " << static_cast<int>(errorCode);
239         CloseTrace();
240         return result;
241     }
242     CloseTrace();
243     return ret.outputFiles;
244 }
245 
CheckBaseInfo(const std::string filePath)246 static bool CheckBaseInfo(const std::string filePath)
247 {
248     int fd = open(filePath.c_str(), O_RDONLY);
249     if (fd == -1) {
250         GTEST_LOG_(INFO) << "open file failed, errno: " << strerror(errno);
251         return false;
252     }
253     if (lseek(fd, sizeof(TraceFileHeader), SEEK_SET) == -1) {
254         GTEST_LOG_(INFO) << "lseek failed, errno: " << strerror(errno);
255         close(fd);
256         return false;
257     }
258 
259     TraceFileContentHeader contentHeader;
260     ssize_t bytesRead = read(fd, &contentHeader, sizeof(TraceFileContentHeader));
261     if (bytesRead != static_cast<ssize_t>(sizeof(TraceFileContentHeader))) {
262         GTEST_LOG_(INFO) << "read content header failed, errno: " << strerror(errno);
263         close(fd);
264         return false;
265     }
266     std::string baseInfo(contentHeader.length, '\0');
267     bytesRead = read(fd, &baseInfo[0], contentHeader.length);
268     if (bytesRead != static_cast<ssize_t>(contentHeader.length)) {
269         GTEST_LOG_(INFO) << "read base info failed, errno: " << strerror(errno);
270         close(fd);
271         return false;
272     }
273     close(fd);
274 
275     std::vector<std::string> segments;
276     std::istringstream iss(baseInfo);
277     std::string segment;
278     while (std::getline(iss, segment, '\n')) {
279         segments.push_back(segment);
280     }
281 
282     std::vector<std::string> checkList = {
283         "KERNEL_VERSION"
284     };
285     int count = 0;
286     for (auto& key : checkList) {
287         for (auto& segment : segments) {
288             if (segment.find(key) != std::string::npos) {
289                 count++;
290                 GTEST_LOG_(INFO) << segment;
291                 break;
292             }
293         }
294     }
295     return (count == checkList.size());
296 }
297 
298 class HitraceDumpTest : public testing::Test {
299 public:
SetUpTestCase(void)300     static void SetUpTestCase(void)
301     {
302         system("service_control stop hiview");
303     }
304 
TearDownTestCase(void)305     static void TearDownTestCase(void)
306     {
307         system("service_control start hiview");
308     }
309 
310     void SetUp();
TearDown()311     void TearDown() {}
312 };
313 
SetUp()314 void HitraceDumpTest::SetUp()
315 {
316     CloseTrace();
317 }
318 
319 /**
320  * @tc.name: GetTraceModeTest_001
321  * @tc.desc: test trace state for OpenTrace and CloseTrace
322  * @tc.type: FUNC
323  */
324 HWTEST_F(HitraceDumpTest, GetTraceModeTest_001, TestSize.Level0)
325 {
326     // check OpenTrace(tagGroup)
327     const std::vector<std::string> tagGroups = {"scene_performance"};
328     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
329     uint8_t traceMode = GetTraceMode();
330     ASSERT_EQ(traceMode, TraceMode::OPEN);
331 
332     // check close trace
333     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
334     traceMode = GetTraceMode();
335     ASSERT_EQ(traceMode, TraceMode::CLOSE);
336 
337     // check OpenTrace(args)
338     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
339     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
340     traceMode = GetTraceMode();
341     ASSERT_EQ(traceMode, TraceMode::OPEN);
342 
343     // check close trace
344     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
345     traceMode = GetTraceMode();
346     ASSERT_EQ(traceMode, TraceMode::CLOSE);
347 }
348 
349 /**
350  * @tc.name: GetTraceModeTest_002
351  * @tc.desc: test trace state for RecordOn and RecordOff
352  * @tc.type: FUNC
353  */
354 HWTEST_F(HitraceDumpTest, GetTraceModeTest_002, TestSize.Level0)
355 {
356     const std::vector<std::string> tagGroups = {"scene_performance"};
357     ASSERT_EQ(OpenTrace(tagGroups), TraceErrorCode::SUCCESS);
358     ASSERT_EQ(RecordTraceOn(), TraceErrorCode::SUCCESS);
359     uint8_t traceMode = GetTraceMode();
360     ASSERT_EQ(traceMode, TraceMode::OPEN | TraceMode::RECORD);
361 
362     TraceRetInfo ret = RecordTraceOff();
363     ASSERT_EQ(ret.errorCode, TraceErrorCode::SUCCESS);
364     traceMode = GetTraceMode();
365     ASSERT_EQ(traceMode, TraceMode::OPEN);
366 
367     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
368     traceMode = GetTraceMode();
369     ASSERT_EQ(traceMode, TraceMode::CLOSE);
370 }
371 
372 /**
373  * @tc.name: GetTraceModeTest_003
374  * @tc.desc: test trace state for CacheOn and CacheOff
375  * @tc.type: FUNC
376  */
377 HWTEST_F(HitraceDumpTest, GetTraceModeTest_003, TestSize.Level0)
378 {
379     const std::vector<std::string> tagGroups = {"scene_performance"};
380     ASSERT_EQ(OpenTrace(tagGroups), TraceErrorCode::SUCCESS);
381     ASSERT_EQ(CacheTraceOn(), TraceErrorCode::SUCCESS);
382     uint8_t traceMode = GetTraceMode();
383     ASSERT_EQ(traceMode, TraceMode::OPEN | TraceMode::CACHE);
384 
385     ASSERT_EQ(CacheTraceOff(), TraceErrorCode::SUCCESS);
386     traceMode = GetTraceMode();
387     ASSERT_EQ(traceMode, TraceMode::OPEN);
388 
389     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
390     traceMode = GetTraceMode();
391     ASSERT_EQ(traceMode, TraceMode::CLOSE);
392 }
393 
394 /**
395  * @tc.name: DumpTraceTest_001
396  * @tc.desc: Test DumpTrace(int maxDuration) for valid input.
397  * The no arg version DumpTrace() is implicitly tested in other tests.
398  * @tc.type: FUNC
399  */
400 HWTEST_F(HitraceDumpTest, DumpTraceTest_001, TestSize.Level0)
401 {
402     const std::vector<std::string> tagGroups = {"default"};
403     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
404     sleep(1); // wait 1s
405     int maxDuration = 1;
406     TraceRetInfo ret = DumpTrace(maxDuration);
407     ASSERT_EQ(static_cast<int>(ret.errorCode), static_cast<int>(TraceErrorCode::SUCCESS));
408     ASSERT_GT(ret.outputFiles.size(), 0);
409     ASSERT_EQ(ret.tags, tagGroups);
410     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
411 }
412 
413 /**
414  * @tc.name: DumpTraceTest_002
415  * @tc.desc: Test DumpTrace(int maxDuration) for invalid input.
416  * @tc.type: FUNC
417  */
418 HWTEST_F(HitraceDumpTest, DumpTraceTest_002, TestSize.Level0)
419 {
420     const std::vector<std::string> tagGroups = {"default"};
421     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
422     sleep(1); // wait 1s
423     int maxDuration = -1;
424     TraceRetInfo ret = DumpTrace(maxDuration);
425     ASSERT_TRUE(ret.errorCode == TraceErrorCode::INVALID_MAX_DURATION);
426     ASSERT_TRUE(ret.outputFiles.empty());
427     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
428 }
429 
430 /**
431  * @tc.name: DumpTraceTest_003
432  * @tc.desc: Test DumpTrace(int maxDuration, uint64_t happenTime) for valid input.
433  * @tc.type: FUNC
434  */
435 HWTEST_F(HitraceDumpTest, DumpTraceTest_003, TestSize.Level0)
436 {
437     const std::vector<std::string> tagGroups = {"scene_performance"};
438     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
439     sleep(TWO_SEC); // need at least one second of trace in cpu due to the input unit of 1 second to avoid OUT_OF_TIME.
440     uint64_t traceEndTime = static_cast<uint64_t>(std::time(nullptr));
441     TraceRetInfo ret = DumpTrace(0, traceEndTime);
442     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
443     ASSERT_TRUE(ret.outputFiles.size() > 0);
444     ASSERT_EQ(ret.tags, tagGroups);
445     ASSERT_GE(ret.coverDuration, TWO_SEC - 1);
446     ASSERT_GE(ret.coverRatio, MAX_RATIO_UNIT * (TWO_SEC - 1) / DEFAULT_FULL_TRACE_LENGTH);
447     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
448 
449     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
450     sleep(TWO_SEC);
451     traceEndTime = static_cast<uint64_t>(std::time(nullptr));
452     ret = DumpTrace(TEN_SEC, traceEndTime);
453     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(ret.errorCode);
454     ASSERT_TRUE(ret.outputFiles.size() > 0);
455     ASSERT_EQ(ret.tags, tagGroups);
456     ASSERT_GE(ret.coverDuration, TWO_SEC - 1);
457     ASSERT_GE(ret.coverRatio, MAX_RATIO_UNIT * (TWO_SEC - 1) / TEN_SEC);
458     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
459 }
460 
461 /**
462  * @tc.name: DumpTraceTest_004
463  * @tc.desc: Test DumpTrace(int maxDuration, uint64_t happenTime) for invalid input.
464  * @tc.type: FUNC
465  */
466 HWTEST_F(HitraceDumpTest, DumpTraceTest_004, TestSize.Level0)
467 {
468     const std::vector<std::string> tagGroups = {"default"};
469     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
470     sleep(1); // wait 1s
471     uint64_t traceEndTime = static_cast<uint64_t>(std::time(nullptr)) + 10; // current time + 10 seconds
472     TraceRetInfo ret = DumpTrace(0, traceEndTime);
473     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
474     ASSERT_FALSE(ret.outputFiles.empty());
475     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
476 
477     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
478     sleep(1); // wait 1s
479     traceEndTime = 10; // 1970-01-01 08:00:10
480     int maxDuration = -1;
481     ret = DumpTrace(maxDuration, traceEndTime);
482     ASSERT_TRUE(ret.errorCode == TraceErrorCode::INVALID_MAX_DURATION);
483     ASSERT_TRUE(ret.outputFiles.empty());
484     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
485 
486     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
487     sleep(1); // wait 1s
488     traceEndTime = static_cast<uint64_t>(std::time(nullptr)) + 10; // current time + 10 seconds
489     maxDuration = -1;
490     ret = DumpTrace(maxDuration, traceEndTime);
491     ASSERT_TRUE(ret.errorCode == TraceErrorCode::INVALID_MAX_DURATION);
492     ASSERT_TRUE(ret.outputFiles.empty());
493     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
494 }
495 
496 /**
497  * @tc.name: DumpTraceTest_005
498  * @tc.desc: Test DumpTrace(int maxDuration, uint64_t happenTime) for OUT_OF_TIME.
499  * @tc.type: FUNC
500  */
501 HWTEST_F(HitraceDumpTest, DumpTraceTest_005, TestSize.Level0)
502 {
503     const std::vector<std::string> tagGroups = {"scene_performance"};
504     InitFileFromDir();
505     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
506     sleep(1); // wait 1s
507     uint64_t traceEndTime = 1;
508     TraceRetInfo ret = DumpTrace(0, traceEndTime);
509     ASSERT_TRUE(ret.errorCode == TraceErrorCode::OUT_OF_TIME);
510     ASSERT_TRUE(ret.outputFiles.empty());
511     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
512 
513     InitFileFromDir();
514     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
515     sleep(1); // wait 1s
516     traceEndTime = 10; // 1970-01-01 08:00:10
517     uint64_t maxDuration = 10;
518     ret = DumpTrace(maxDuration, traceEndTime);
519     ASSERT_TRUE(ret.errorCode == TraceErrorCode::OUT_OF_TIME);
520     ASSERT_TRUE(ret.outputFiles.empty());
521     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
522 
523     InitFileFromDir();
524     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
525     sleep(TWO_SEC);
526     traceEndTime = static_cast<uint64_t>(std::time(nullptr)) - 20; // current time - 20 seconds
527     ret = DumpTrace(0, traceEndTime);
528     ASSERT_EQ(ret.errorCode, TraceErrorCode::OUT_OF_TIME);
529     ASSERT_TRUE(ret.outputFiles.empty());
530     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
531 
532     InitFileFromDir();
533     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
534     sleep(TWO_SEC);
535     traceEndTime = static_cast<uint64_t>(std::time(nullptr)) - 20; // current time - 20 seconds
536     ret = DumpTrace(TEN_SEC, traceEndTime);
537     ASSERT_TRUE(ret.errorCode == TraceErrorCode::OUT_OF_TIME);
538     ASSERT_TRUE(ret.outputFiles.empty());
539     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
540 }
541 
542 /**
543  * @tc.name: DumpTraceTest_006
544  * @tc.desc: Test DumpTrace(int maxDuration, uint64_t happenTime) for maxDuration is bigger than boot_time
545  * @tc.type: FUNC
546  */
547 HWTEST_F(HitraceDumpTest, DumpTraceTest_006, TestSize.Level0)
548 {
549     const std::vector<std::string> tagGroups = {"scene_performance"};
550     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
551     sleep(TWO_SEC);
552     uint64_t traceEndTime = static_cast<uint64_t>(std::time(nullptr)); // current time
553 
554     TraceRetInfo ret = DumpTrace(INT_MAX, traceEndTime);
555     ASSERT_EQ(ret.errorCode, TraceErrorCode::SUCCESS);
556     ASSERT_TRUE(!ret.outputFiles.empty());
557     ASSERT_EQ(ret.tags, tagGroups);
558     ASSERT_GE(ret.coverDuration, (TWO_SEC - 1) * S_TO_MS);
559     ASSERT_GE(ret.coverRatio, MAX_RATIO_UNIT * (TWO_SEC - 1) / DEFAULT_FULL_TRACE_LENGTH);
560     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
561 }
562 
563 /**
564  * @tc.name: DumpTraceTest_007
565  * @tc.desc: Test DumpTrace(int maxDuration, uint64_t happenTime) for INVALID_MAX_DURATION.
566  * @tc.type: FUNC
567  */
568 HWTEST_F(HitraceDumpTest, DumpTraceTest_007, TestSize.Level0)
569 {
570     const std::vector<std::string> tagGroups = {"default"};
571     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
572     sleep(TWO_SEC);
573     uint64_t traceEndTime = static_cast<uint64_t>(std::time(nullptr));
574     TraceRetInfo ret = DumpTrace(-1, traceEndTime);
575     ASSERT_TRUE(ret.errorCode == TraceErrorCode::INVALID_MAX_DURATION) << "errorCode: "
576         << static_cast<int>(ret.errorCode);
577     ASSERT_TRUE(ret.outputFiles.empty());
578     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
579 }
580 
581 /**
582  * @tc.name: DumpTraceTest_008
583  * @tc.desc: Test Test DumpTrace(int maxDuration) for check process is recycled.
584  * @tc.type: FUNC
585  */
586 HWTEST_F(HitraceDumpTest, DumpTraceTest_008, TestSize.Level0)
587 {
588     const std::vector<std::string> tagGroups = {"default"};
589     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
590     for (int i = 0; i < 10; i++) {
591         int maxDuration = 1;
592         TraceRetInfo ret = DumpTrace(maxDuration);
593         ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
594         sleep(1);
595         ASSERT_TRUE(HasProcessWithName("HitraceDump") == 0);
596     }
597     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
598 }
599 
600 /**
601  * @tc.name: DumpTraceTest_009
602  * @tc.desc: Test DumpTrace() result in cache_on is opening 8s and slice time is 5s.
603  * The no arg version DumpTrace() is implicitly tested in other tests.
604  * @tc.type: FUNC
605  */
606 HWTEST_F(HitraceDumpTest, DumpTraceTest_009, TestSize.Level0)
607 {
608     const std::vector<std::string> tagGroups = {"default"};
609     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
610     // total cache filesize limit: 800MB, sliceduration: 5s
611     ASSERT_TRUE(CacheTraceOn(800, 5) == TraceErrorCode::SUCCESS);
612     sleep(8); // wait 8s
613     ASSERT_TRUE(CacheTraceOff() == TraceErrorCode::SUCCESS);
614     sleep(2); // wait 2s
615     TraceRetInfo ret = DumpTrace();
616     ASSERT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(ret.errorCode);
617     for (int i = 0; i < ret.outputFiles.size(); i++) {
618         GTEST_LOG_(INFO) << "outputFiles:" << ret.outputFiles[i].c_str();
619     }
620     ASSERT_GE(ret.outputFiles.size(), 3); // compare file count
621     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
622 }
623 
624 /**
625  * @tc.name: DumpTraceTest_010
626  * @tc.desc: Test DumpTrace() result in cache_on is opening 40s and slice time is 10s.
627  * The no arg version DumpTrace() is implicitly tested in other tests.
628  * @tc.type: FUNC
629  */
630 HWTEST_F(HitraceDumpTest, DumpTraceTest_010, TestSize.Level0)
631 {
632     const std::vector<std::string> tagGroups = {"scene_performance"};
633     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
634     // total cache filesize limit: 800MB, sliceduration: 10s
635     ASSERT_TRUE(CacheTraceOn(800, 10) == TraceErrorCode::SUCCESS);
636     sleep(40); // wait 40s, over 30s
637     TraceRetInfo ret = DumpTrace();
638     ASSERT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(ret.errorCode);
639     ASSERT_EQ(ret.mode, TraceMode::OPEN | TraceMode::CACHE);
640     for (int i = 0; i < ret.outputFiles.size(); i++) {
641         GTEST_LOG_(INFO) << "outputFiles:" << ret.outputFiles[i].c_str();
642     }
643     ASSERT_GE(ret.outputFiles.size(), 3); // at least 3 slices
644     // almost fully cover max 30s guaranteed duration
645     ASSERT_GE(ret.coverDuration, (DEFAULT_FULL_TRACE_LENGTH - 1) * S_TO_MS);
646     ASSERT_GE(ret.coverRatio, MAX_RATIO_UNIT - 100); // 100: 10% tolerance
647     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
648 }
649 
650 /**
651  * @tc.name: DumpTraceTest_011
652  * @tc.desc: Test result when calling DumpTrace() twice with cache_on is opening 20s and slice time is 5s.
653  * The no arg version DumpTrace() is implicitly tested in other tests.
654  * @tc.type: FUNC
655  */
656 HWTEST_F(HitraceDumpTest, DumpTraceTest_011, TestSize.Level0)
657 {
658     const std::vector<std::string> tagGroups = {"scene_performance"};
659     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
660     // total cache filesize limit: 800MB, sliceduration: 5s
661     ASSERT_TRUE(CacheTraceOn(800, 5) == TraceErrorCode::SUCCESS);
662     sleep(8); // wait 8s
663     TraceRetInfo ret = DumpTrace();
664     ASSERT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(ret.errorCode);
665     ASSERT_EQ(ret.mode, TraceMode::OPEN | TraceMode::CACHE);
666     for (int i = 0; i < ret.outputFiles.size(); i++) {
667         GTEST_LOG_(INFO) << "outputFiles:" << ret.outputFiles[i].c_str();
668     }
669     ASSERT_GE(ret.outputFiles.size(), 2); // compare file count
670     ASSERT_GE(ret.coverDuration, 7 * S_TO_MS); // coverDuration >= 7s
671     ASSERT_GE(ret.coverRatio, MAX_RATIO_UNIT * 7 / DEFAULT_FULL_TRACE_LENGTH); // coverRatio >= 7/30
672     sleep(1);
673     ret = DumpTrace();
674     ASSERT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " <<
675         static_cast<int>(ret.errorCode);
676     for (int i = 0; i < ret.outputFiles.size(); i++) {
677         GTEST_LOG_(INFO) << "outputFiles:" << ret.outputFiles[i].c_str();
678     }
679     ASSERT_TRUE(ret.outputFiles.size() >= 3); // compare file count
680     ASSERT_GE(ret.coverDuration, 8 * S_TO_MS); // coverDuration >= 8s
681     ASSERT_GE(ret.coverRatio, MAX_RATIO_UNIT * 8 / DEFAULT_FULL_TRACE_LENGTH); // coverRatio >= 8/30
682     ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
683 }
684 
685 /**
686  * @tc.name: DumpTraceTest_012
687  * @tc.desc: Test correct calculation of coverDuration and coverRatio for regular DumpTrace.
688  * @tc.type: FUNC
689  */
690 HWTEST_F(HitraceDumpTest, DumpTraceTest_012, TestSize.Level0)
691 {
692     const std::vector<std::string> tagGroups = {"scene_performance"};
693     sleep(TEN_SEC + 1); // wait 11s before OpenTrace
694     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
695     sleep(TEN_SEC); // wait 10s
696     TraceRetInfo ret = DumpTrace(TEN_SEC * 2); // get passed 20s trace
697     ASSERT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " <<
698         static_cast<int>(ret.errorCode);
699     ASSERT_GE(ret.outputFiles.size(), 1);
700     ASSERT_GE(ret.coverDuration, (TEN_SEC - 1) * S_TO_MS); // coverDuration >= 9s
701     ASSERT_LE(ret.coverDuration, (TEN_SEC + 2) * S_TO_MS); // coverDuration <= 12s
702     ASSERT_GE(ret.coverRatio, MAX_RATIO_UNIT * (TEN_SEC - 1) / (TEN_SEC * 2)); // coverRatio >= 9/20
703     ASSERT_LE(ret.coverRatio, MAX_RATIO_UNIT * (TEN_SEC + 2) / (TEN_SEC * 2)); // coverRatio <= 12/20
704     ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
705 }
706 
707 /**
708  * @tc.name: DumpTraceTest_013
709  * @tc.desc: Test correct calculation of coverDuration and coverRatio for DumpTrace during cache.
710  * @tc.type: FUNC
711  */
712 HWTEST_F(HitraceDumpTest, DumpTraceTest_013, TestSize.Level0)
713 {
714     const std::vector<std::string> tagGroups = {"scene_performance"};
715     sleep(TEN_SEC + 1); // wait 11s before OpenTrace and CacheTraceOn
716     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
717     ASSERT_TRUE(CacheTraceOn(800, 10) == TraceErrorCode::SUCCESS);
718     sleep(TEN_SEC); // wait 10s
719     TraceRetInfo ret = DumpTrace(TEN_SEC * 2); // get passed 20s trace
720     ASSERT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " <<
721         static_cast<int>(ret.errorCode);
722     ASSERT_EQ(ret.mode, TraceMode::OPEN | TraceMode::CACHE);
723     ASSERT_GE(ret.outputFiles.size(), 1);
724     ASSERT_GE(ret.coverDuration, (TEN_SEC - 1) * S_TO_MS); // coverDuration >= 9s
725     ASSERT_LE(ret.coverDuration, (TEN_SEC + 2) * S_TO_MS); // coverDuration <= 12s
726     ASSERT_GE(ret.coverRatio, MAX_RATIO_UNIT * (TEN_SEC - 1) / (TEN_SEC * 2)); // coverRatio >= 9/20
727     ASSERT_LE(ret.coverRatio, MAX_RATIO_UNIT * (TEN_SEC + 2) / (TEN_SEC * 2)); // coverRatio <= 12/20
728     ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
729 }
730 
731 /**
732  * @tc.name: DumpTraceTest_014
733  * @tc.desc: Test BaseInfo content in raw trace file.
734  * @tc.type: FUNC
735  */
736 HWTEST_F(HitraceDumpTest, DumpTraceTest_014, TestSize.Level0)
737 {
738     std::vector<std::string> outputFiles;
739     outputFiles = GetRecordTrace();
740     ASSERT_FALSE(outputFiles.empty());
741     ASSERT_TRUE(CheckBaseInfo(outputFiles[0])) << outputFiles[0];
742 
743     outputFiles = GetCacheTrace();
744     ASSERT_FALSE(outputFiles.empty());
745     ASSERT_TRUE(CheckBaseInfo(outputFiles[0])) << outputFiles[0];
746 
747     outputFiles = GetSnapShotTrace();
748     ASSERT_FALSE(outputFiles.empty());
749     ASSERT_TRUE(CheckBaseInfo(outputFiles[0])) << outputFiles[0];
750 }
751 
752 /**
753  * @tc.name: DumpForServiceMode_001
754  * @tc.desc: Correct capturing trace using default OpenTrace.
755  * @tc.type: FUNC
756  */
757 HWTEST_F(HitraceDumpTest, DumpForServiceMode_001, TestSize.Level0)
758 {
759     const std::vector<std::string> tagGroups = {"scene_performance"};
760     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
761 
762     TraceRetInfo ret = DumpTrace();
763     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
764     ASSERT_TRUE(ret.outputFiles.size() > 0);
765     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
766 }
767 
768 /**
769  * @tc.name: DumpForServiceMode_002
770  * @tc.desc: Test invalid tag groups for default OpenTrace.
771  * @tc.type: FUNC
772  */
773 HWTEST_F(HitraceDumpTest, DumpForServiceMode_002, TestSize.Level0)
774 {
775     const std::vector<std::string> tagGroups;
776     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::TAG_ERROR);
777 
778     const std::vector<std::string> tagGroups1 = {"scene_performance1"};
779     ASSERT_TRUE(OpenTrace(tagGroups1) == TraceErrorCode::TAG_ERROR);
780     TraceRetInfo ret = DumpTrace();
781     ASSERT_TRUE(ret.errorCode == TraceErrorCode::WRONG_TRACE_MODE);
782     ASSERT_TRUE(ret.outputFiles.empty());
783     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
784 }
785 
786 /**
787  * @tc.name: DumpForServiceMode_003
788  * @tc.desc: Enable the service mode in CMD_MODE.
789  * @tc.type: FUNC
790  */
791 HWTEST_F(HitraceDumpTest, DumpForServiceMode_003, TestSize.Level0)
792 {
793     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
794     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
795 
796     const std::vector<std::string> tagGroups = {"scene_performance"};
797     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::WRONG_TRACE_MODE);
798 
799     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
800 
801     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
802 
803     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::WRONG_TRACE_MODE);
804 
805     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
806 }
807 
808 /**
809  * @tc.name: DumpForServiceMode_004
810  * @tc.desc: Invalid parameter verification in CMD_MODE.
811  * @tc.type: FUNC
812  */
813 HWTEST_F(HitraceDumpTest, DumpForServiceMode_004, TestSize.Level0)
814 {
815     const std::vector<std::string> tagGroups = {"scene_performance"};
816     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
817     ASSERT_TRUE(access(TRACE_FILE_DEFAULT_DIR.c_str(), F_OK) == 0) << "/data/log/hitrace not exists.";
818 
819     SetSysInitParamTags(123);
820     ASSERT_TRUE(SetCheckParam() == false);
821 
822     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
823 }
824 
825 /**
826  * @tc.name: DumpForServiceMode_005
827  * @tc.desc: Test TRACE_IS_OCCUPIED.
828  * @tc.type: FUNC
829  */
830 HWTEST_F(HitraceDumpTest, DumpForServiceMode_005, TestSize.Level0)
831 {
832     const std::vector<std::string> tagGroups = {"scene_performance"};
833     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
834 
835     SetSysInitParamTags(123);
836     OHOS::system::SetParameter("debug.hitrace.tags.enableflags", std::to_string(0));
837     ASSERT_TRUE(DumpTrace().errorCode == TraceErrorCode::TRACE_IS_OCCUPIED);
838 
839     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
840 }
841 
842 /**
843  * @tc.name: DumpForServiceMode_006
844  * @tc.desc: Test mix calling RecordTraceOn & RecordTraceOff in opening cache and closing cache.
845  * The no arg version DumpTrace() is implicitly tested in other tests.
846  * @tc.type: FUNC
847  */
848 HWTEST_F(HitraceDumpTest, DumpForServiceMode_006, TestSize.Level0)
849 {
850     const std::vector<std::string> tagGroups = {"default"};
851     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
852     ASSERT_TRUE(CacheTraceOn() == TraceErrorCode::SUCCESS);
853     ASSERT_TRUE(CacheTraceOn() == TraceErrorCode::WRONG_TRACE_MODE);
854     ASSERT_TRUE(RecordTraceOn() == TraceErrorCode::WRONG_TRACE_MODE);
855     TraceRetInfo ret = RecordTraceOff();
856     ASSERT_TRUE(ret.errorCode == TraceErrorCode::WRONG_TRACE_MODE);
857     ASSERT_TRUE(CacheTraceOff() == TraceErrorCode::SUCCESS);
858     ASSERT_TRUE(CacheTraceOff() == TraceErrorCode::WRONG_TRACE_MODE);
859     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
860     ASSERT_TRUE(CacheTraceOn() == TraceErrorCode::WRONG_TRACE_MODE);
861     ASSERT_TRUE(CacheTraceOff() == TraceErrorCode::WRONG_TRACE_MODE);
862 }
863 
864 /**
865  * @tc.name: DumpForServiceMode_007
866  * @tc.desc: Test all tag groups for default OpenTrace.
867  * @tc.type: FUNC
868  */
869 HWTEST_F(HitraceDumpTest, DumpForServiceMode_007, TestSize.Level0)
870 {
871     ASSERT_TRUE(OpenTrace("default") == TraceErrorCode::SUCCESS);
872     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
873     ASSERT_TRUE(OpenTrace("scene_performance") == TraceErrorCode::SUCCESS);
874     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
875     ASSERT_TRUE(OpenTrace("telemetry") == TraceErrorCode::SUCCESS);
876     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
877 }
878 
879 /**
880  * @tc.name: DumpForCmdMode_001
881  * @tc.desc: The correct usage of grasping trace in CMD_MODE.
882  * @tc.type: FUNC
883  */
884 HWTEST_F(HitraceDumpTest, DumpForCmdMode_001, TestSize.Level0)
885 {
886     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
887     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
888 
889     TraceErrorCode retCode = RecordTraceOn();
890     ASSERT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
891     sleep(1);
892 
893     TraceRetInfo ret = RecordTraceOff();
894     ASSERT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
895     ASSERT_GE(ret.outputFiles.size(), 0);
896 
897     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
898 }
899 
900 /**
901  * @tc.name: DumpForCmdMode_002
902  * @tc.desc: Specifies the path of the command in CMD_MODE.
903  * @tc.type: FUNC
904  */
905 HWTEST_F(HitraceDumpTest, DumpForCmdMode_002, TestSize.Level0)
906 {
907     std::string filePathName = "/data/local/tmp/mytrace.sys";
908     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1 output:" + filePathName;
909     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
910     TraceErrorCode retCode = RecordTraceOn();
911     ASSERT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
912     sleep(1);
913 
914     TraceRetInfo ret = RecordTraceOff();
915     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
916 
917     ASSERT_TRUE(TraverseFiles(ret.outputFiles, filePathName))
918         << "unspport set outputfile, default generate file in /data/log/hitrace.";
919 
920     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
921 }
922 
923 /**
924  * @tc.name: DumpForCmdMode_003
925  * @tc.desc: Invalid args verification in CMD_MODE.
926  * @tc.type: FUNC
927  */
928 HWTEST_F(HitraceDumpTest, DumpForCmdMode_003, TestSize.Level0)
929 {
930     std::string args = "clockType:boot bufferSize:1024 overwrite:1 ";
931     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
932     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
933 
934     args = "tags:hdc clockType:boot bufferSize:1024 overwrite:1 descriptions:123";
935     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::TAG_ERROR);
936 
937     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
938 }
939 
940 /**
941  * @tc.name: DumpForCmdMode_004
942  * @tc.desc: The CMD_MODE cannot be interrupted by the SERVICE_MODE.
943  * @tc.type: FUNC
944  */
945 HWTEST_F(HitraceDumpTest, DumpForCmdMode_004, TestSize.Level0)
946 {
947     std::string args = "tags:memory clockType:boot1 bufferSize:1024 overwrite:0";
948     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
949 
950     const std::vector<std::string> tagGroups = {"scene_performance"};
951     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::WRONG_TRACE_MODE);
952 
953     TraceErrorCode retCode = RecordTraceOn();
954     ASSERT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
955     sleep(1);
956 
957     TraceRetInfo ret = RecordTraceOff();
958     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
959     ASSERT_TRUE(ret.outputFiles.size() > 0);
960 
961     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
962 
963     args = "tags:memory clockType: bufferSize:1024 overwrite:1";
964     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
965     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
966 
967     args = "tags:memory clockType:perf bufferSize:1024 overwrite:1";
968     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
969     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
970 }
971 
972 /**
973  * @tc.name: DumpForCmdMode_005
974  * @tc.desc: Enable the cmd mode in non-close mode.
975  * @tc.type: FUNC
976  */
977 HWTEST_F(HitraceDumpTest, DumpForCmdMode_005, TestSize.Level0)
978 {
979     const std::vector<std::string> tagGroups = {"scene_performance"};
980     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
981     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
982     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::WRONG_TRACE_MODE);
983     TraceErrorCode retCode = RecordTraceOn();
984     ASSERT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
985     ASSERT_EQ(GetTraceMode(), TraceMode::OPEN | TraceMode::RECORD);
986     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
987 }
988 
989 /**
990  * @tc.name: DumpForCmdMode_006
991  * @tc.desc: Test the CMD_MODE when there's extra space in args.
992  * @tc.type: FUNC
993  */
994 HWTEST_F(HitraceDumpTest, DumpForCmdMode_006, TestSize.Level0)
995 {
996     std::string args = "tags: sched clockType: boot bufferSize:1024 overwrite: 1";
997     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
998     TraceErrorCode retCode = RecordTraceOn();
999     ASSERT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
1000     sleep(1);
1001 
1002     TraceRetInfo ret = RecordTraceOff();
1003     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
1004     ASSERT_TRUE(ret.outputFiles.size() > 0);
1005 
1006     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1007 }
1008 
1009 /**
1010  * @tc.name: DumpForCmdMode_007
1011  * @tc.desc: Test the CMD_MODE when set fileLimit in args.
1012  * @tc.type: FUNC
1013  */
1014 HWTEST_F(HitraceDumpTest, DumpForCmdMode_007, TestSize.Level0)
1015 {
1016     std::string args = "tags:sched,ace,app,disk,distributeddatamgr,freq,graphic,idle,irq,load,mdfs,mmc,";
1017     args += "notification,ohos,pagecache,regulators,sync,ufs,workq,zaudio,zcamera,zimage,zmedia ";
1018     args += "clockType: boot bufferSize:1024 overwrite: 1 fileLimit: 2 fileSize: 51200";
1019     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
1020 
1021     TraceErrorCode retCode = RecordTraceOn();
1022     ASSERT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
1023     sleep(1);
1024 
1025     TraceRetInfo ret = RecordTraceOff();
1026     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
1027     ASSERT_TRUE(ret.outputFiles.size() > 0);
1028 
1029     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1030 }
1031 
1032 /**
1033  * @tc.name: DumpForCmdMode_008
1034  * @tc.desc: Test the CMD_MODE when there's extra space in args.
1035  * @tc.type: FUNC
1036  */
1037 HWTEST_F(HitraceDumpTest, DumpForCmdMode_008, TestSize.Level0)
1038 {
1039     std::string filePathName = "/data/local/tmp/mylongtrace.sys";
1040     std::string args = "tags:sched,ace,app,disk,distributeddatamgr,freq,graphic,idle,irq,load,mdfs,mmc,";
1041     args += "notification,ohos,pagecache,regulators,sync,ufs,workq,zaudio,zcamera,zimage,zmedia ";
1042     args += "clockType: boot bufferSize:1024 overwrite: 1 output:" + filePathName;
1043     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
1044 
1045     TraceErrorCode retCode = RecordTraceOn();
1046     ASSERT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
1047     if (remove(filePathName.c_str()) == 0) {
1048         HILOG_INFO(LOG_CORE, "Delete mylongtrace.sys success.");
1049     } else {
1050         HILOG_ERROR(LOG_CORE, "Delete mylongtrace.sys failed.");
1051     }
1052     sleep(SLEEP_TIME);
1053 
1054     TraceRetInfo ret = RecordTraceOff();
1055     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
1056     ASSERT_TRUE(ret.outputFiles.size() > 0);
1057 
1058     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1059 }
1060 
1061 /**
1062  * @tc.name: DumpForCmdMode_009
1063  * @tc.desc: Test the CMD_MODE when set fileLimit in args.
1064  * @tc.type: FUNC
1065  */
1066 HWTEST_F(HitraceDumpTest, DumpForCmdMode_009, TestSize.Level0)
1067 {
1068     std::string args = "tags:sched,ace,app,disk,distributeddatamgr,freq,graphic,idle,irq,load,mdfs,mmc,";
1069     args += "notification,ohos,pagecache,regulators,sync,ufs,workq,zaudio,zcamera,zimage,zmedia ";
1070     args += "clockType: boot bufferSize:1024 overwrite: 1 fileLimit: 2";
1071     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
1072 
1073     TraceErrorCode retCode = RecordTraceOn();
1074     ASSERT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
1075     sleep(1);
1076 
1077     TraceRetInfo ret = RecordTraceOff();
1078     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
1079     ASSERT_TRUE(ret.outputFiles.size() > 0);
1080 
1081     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1082 }
1083 
1084 /**
1085  * @tc.name: DumpForCmdMode_010
1086  * @tc.desc: Test the multi-process task CMD_MODE when set fileLimit in args.
1087  * @tc.type: FUNC
1088  */
1089 HWTEST_F(HitraceDumpTest, DumpForCmdMode_010, TestSize.Level0)
1090 {
1091     std::string args = "tags:sched,ace,app,disk,distributeddatamgr,freq,graphic,idle,irq,load,mdfs,mmc,";
1092     args += "notification,ohos,pagecache,regulators,sync,ufs,workq,zaudio,zcamera,zimage,zmedia ";
1093     args += "clockType: boot bufferSize:1024 overwrite: 1 fileLimit: 2";
1094     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
1095 
1096     pid_t pid = fork();
1097     if (pid < 0) {
1098         HILOG_ERROR(LOG_CORE, "fork error.");
1099     } else if (pid == 0) {
1100         ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::WRONG_TRACE_MODE);
1101         _exit(EXIT_SUCCESS);
1102     }
1103 
1104     TraceErrorCode retCode = RecordTraceOn();
1105     ASSERT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
1106     sleep(1);
1107     TraceRetInfo ret = RecordTraceOff();
1108     ASSERT_EQ(static_cast<int>(ret.errorCode), static_cast<int>(TraceErrorCode::SUCCESS));
1109     ASSERT_TRUE(ret.outputFiles.size() > 0);
1110 
1111     ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
1112 }
1113 
1114 /**
1115  * @tc.name: DumpForCmdMode_011
1116  * @tc.desc: Test the multi-process task SERVICE_MODE and Enable the cmd mode in non-close mode.
1117  * @tc.type: FUNC
1118  */
1119 HWTEST_F(HitraceDumpTest, DumpForCmdMode_011, TestSize.Level0)
1120 {
1121     const std::vector<std::string> tagGroups = {"scene_performance"};
1122     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
1123 
1124     pid_t pid = fork();
1125     if (pid < 0) {
1126         HILOG_ERROR(LOG_CORE, "fork error.");
1127     } else if (pid == 0) {
1128         ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::WRONG_TRACE_MODE);
1129         _exit(EXIT_SUCCESS);
1130     }
1131 
1132     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
1133     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::WRONG_TRACE_MODE);
1134     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1135 }
1136 
1137 /**
1138  * @tc.name: DumpForCmdMode_012
1139  * @tc.desc: Test saved_events_format regenerate.
1140  * @tc.type: FUNC
1141  */
1142 HWTEST_F(HitraceDumpTest, DumpForCmdMode_012, TestSize.Level0)
1143 {
1144     std::string args = "tags: sched clockType: boot bufferSize:1024 overwrite: 1";
1145     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
1146     sleep(1);
1147     struct stat beforeStat = GetFileStatInfo(TRACE_FILE_DEFAULT_DIR + TRACE_SAVED_EVENTS_FORMAT);
1148     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1149     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
1150     sleep(1);
1151     struct stat afterStat = GetFileStatInfo(TRACE_FILE_DEFAULT_DIR + TRACE_SAVED_EVENTS_FORMAT);
1152     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1153     ASSERT_TRUE(afterStat.st_ctime != beforeStat.st_ctime);
1154 }
1155 
1156 HWTEST_F(HitraceDumpTest, DumpForCmdMode_013, TestSize.Level0)
1157 {
1158     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
1159     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
1160     const int recordCnt = 30; // 30 : dump 30 times
1161     const int recordFileAge = 16;
1162     TraceJsonParser& parser = TraceJsonParser::Instance();
1163     bool rootAgeingEnable = parser.recordAgeingParam_.rootEnable;
1164     parser.recordAgeingParam_.rootEnable = true;
1165 
1166     for (int i = 0; i < recordCnt; i++) {
1167         TraceErrorCode retCode = RecordTraceOn();
1168         EXPECT_EQ(retCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
1169         sleep(1);
1170 
1171         TraceRetInfo ret = RecordTraceOff();
1172         EXPECT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(retCode);
1173     }
1174 
1175     int count = CountRecordingTraceFile();
1176     EXPECT_GT(count, 0);
1177     EXPECT_LE(count, recordFileAge);
1178 
1179     EXPECT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1180     parser.recordAgeingParam_.rootEnable = rootAgeingEnable;
1181 }
1182 
1183 /**
1184  * @tc.name: ParammeterCheck_001
1185  * @tc.desc: Check parameter after interface call.
1186  * @tc.type: FUNC
1187  */
1188 HWTEST_F(HitraceDumpTest, ParammeterCheck_001, TestSize.Level0)
1189 {
1190     const std::vector<std::string> tagGroups = {"scene_performance"};
1191     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
1192 
1193     // check Property("debug.hitrace.tags.enableflags")
1194     uint64_t openTags = OHOS::system::GetUintParameter<uint64_t>(TRACE_TAG_ENABLE_FLAGS, 0);
1195     ASSERT_TRUE(openTags > 0);
1196 
1197     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1198 
1199     // check Property("debug.hitrace.tags.enableflags")
1200     uint64_t closeTags = OHOS::system::GetUintParameter<uint64_t>(TRACE_TAG_ENABLE_FLAGS, 0);
1201     ASSERT_TRUE(closeTags == 0);
1202 }
1203 
1204 HWTEST_F(HitraceDumpTest, SetTraceStatus_001, TestSize.Level0)
1205 {
1206     std::string traceRootPath = "";
1207     ASSERT_TRUE(IsTraceMounted(traceRootPath));
1208 
1209     EXPECT_EQ(SetTraceStatus(true), TraceErrorCode::SUCCESS);
1210     EXPECT_EQ(IsTracingOn(traceRootPath), true);
1211 
1212     EXPECT_EQ(SetTraceStatus(false), TraceErrorCode::SUCCESS);
1213     EXPECT_EQ(IsTracingOn(traceRootPath), false);
1214 }
1215 
1216 /**
1217  * @tc.name: DumpTraceAsyncTest001
1218  * @tc.desc: Test DumpTraceAsync func, execute within 5 seconds timeout
1219  * @tc.type: FUNC
1220  */
1221 HWTEST_F(HitraceDumpTest, DumpTraceAsyncTest001, TestSize.Level2)
1222 {
1223     const std::vector<std::string> tagGroups = {"scene_performance"};
1224     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
1225 
__anonabe3daa80302(TraceRetInfo traceInfo) 1226     std::function<void(TraceRetInfo)> func = [](TraceRetInfo traceInfo) {
1227         off_t totalFileSz = 0;
1228         for (auto& files : traceInfo.outputFiles) {
1229             totalFileSz += GetFileSize(files);
1230             GTEST_LOG_(INFO) << "output: " << files << " file size: " << GetFileSize(files);
1231         }
1232         EXPECT_EQ(totalFileSz, traceInfo.fileSize);
1233     };
1234     auto ret = DumpTraceAsync(0, 0, INT64_MAX, func);
1235     EXPECT_EQ(ret.errorCode, TraceErrorCode::SUCCESS);
1236     GTEST_LOG_(INFO) << "interface return file size :" << ret.fileSize;
1237     for (auto file : ret.outputFiles) {
1238         GTEST_LOG_(INFO) << "interface return file :" << file;
1239     }
1240     // Close trace after async dump
1241     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1242 }
1243 
1244 /**
1245  * @tc.name: DumpTraceAsyncTest002
1246  * @tc.desc: Test DumpTraceAsync func, filesizelimit parameter
1247  * @tc.type: FUNC
1248  */
1249 HWTEST_F(HitraceDumpTest, DumpTraceAsyncTest002, TestSize.Level2)
1250 {
1251     const std::vector<std::string> tagGroups = {"scene_performance"};
1252     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
1253 
__anonabe3daa80402(TraceRetInfo traceInfo) 1254     std::function<void(TraceRetInfo)> func = [](TraceRetInfo traceInfo) {
1255         EXPECT_EQ(traceInfo.isOverflowControl, true);
1256         off_t totalFileSz = 0;
1257         for (auto& files : traceInfo.outputFiles) {
1258             totalFileSz += GetFileSize(files);
1259             GTEST_LOG_(INFO) << "output: " << files << " file size: " << GetFileSize(files);
1260         }
1261         EXPECT_EQ(totalFileSz, traceInfo.fileSize);
1262     };
1263     auto ret = DumpTraceAsync(0, 0, 100, func); // 100 : 100 bytes
1264     EXPECT_EQ(ret.isOverflowControl, true) << "errorCode: " << static_cast<int>(ret.errorCode);
1265     GTEST_LOG_(INFO) << "interface return file size :" << ret.fileSize;
1266     for (auto file : ret.outputFiles) {
1267         GTEST_LOG_(INFO) << "interface return file :" << file;
1268     }
1269     // Close trace after async dump
1270     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1271 }
1272 
1273 /**
1274  * @tc.name: DumpTraceAsyncTest003
1275  * @tc.desc: Test DumpTraceAsync func, execute within 5 seconds timeout
1276  * @tc.type: FUNC
1277  */
1278 HWTEST_F(HitraceDumpTest, DumpTraceAsyncTest003, TestSize.Level2)
1279 {
1280     const std::vector<std::string> tagGroups = {"scene_performance"};
1281     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
1282 
__anonabe3daa80502(TraceRetInfo traceInfo) 1283     std::function<void(TraceRetInfo)> func = [](TraceRetInfo traceInfo) {
1284         EXPECT_EQ(traceInfo.errorCode, TraceErrorCode::SUCCESS);
1285         off_t totalFileSz = 0;
1286         for (auto& files : traceInfo.outputFiles) {
1287             totalFileSz += GetFileSize(files);
1288             GTEST_LOG_(INFO) << "output: " << files << " file size: " << GetFileSize(files);
1289         }
1290         EXPECT_EQ(totalFileSz, traceInfo.fileSize);
1291     };
1292     auto ret = DumpTraceAsync(0, 0, INT64_MAX, func);
1293     EXPECT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(ret.errorCode);
1294     GTEST_LOG_(INFO) << "interface return file size :" << ret.fileSize;
1295     for (auto file : ret.outputFiles) {
1296         GTEST_LOG_(INFO) << "interface return file :" << file;
1297     }
1298     ret = DumpTraceAsync(0, 0, INT64_MAX, func);
1299     EXPECT_EQ(ret.errorCode, TraceErrorCode::SUCCESS) << "errorCode: " << static_cast<int>(ret.errorCode);
1300     GTEST_LOG_(INFO) << "interface return file size :" << ret.fileSize;
1301     for (auto file : ret.outputFiles) {
1302         GTEST_LOG_(INFO) << "interface return file :" << file;
1303     }
1304     // Close trace after async dump
1305     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1306 }
1307 
1308 /**
1309  * @tc.name: DumpTraceAsyncTest004
1310  * @tc.desc: Test DumpTraceAsync func, test out of time.
1311  * @tc.type: FUNC
1312  */
1313 HWTEST_F(HitraceDumpTest, DumpTraceAsyncTest004, TestSize.Level2)
1314 {
1315     const std::vector<std::string> tagGroups = {"scene_performance"};
1316     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
1317     sleep(3); // 3 : 3 seconds
1318     uint64_t traceEndTime = static_cast<uint64_t>(std::time(nullptr));
1319     auto ret = DumpTrace(0, traceEndTime);
1320     EXPECT_EQ(ret.errorCode, TraceErrorCode::SUCCESS);
1321     for (auto& file : ret.outputFiles) {
1322         GTEST_LOG_(INFO) << "interface return file :" << file;
1323     }
1324 
__anonabe3daa80602(TraceRetInfo traceInfo) 1325     std::function<void(TraceRetInfo)> func = [](TraceRetInfo traceInfo) {
1326         EXPECT_EQ(traceInfo.errorCode, TraceErrorCode::SUCCESS);
1327         off_t totalFileSz = 0;
1328         for (auto& files : traceInfo.outputFiles) {
1329             totalFileSz += GetFileSize(files);
1330             GTEST_LOG_(INFO) << "output: " << files << " file size: " << GetFileSize(files);
1331         }
1332         EXPECT_EQ(totalFileSz, traceInfo.fileSize);
1333     };
1334     ret = DumpTraceAsync(1, traceEndTime - 2, INT64_MAX, func); // 2 : 2 seconds
1335     EXPECT_EQ(ret.errorCode, TraceErrorCode::SUCCESS);
1336     GTEST_LOG_(INFO) << "interface return file size :" << ret.fileSize;
1337     for (auto& file : ret.outputFiles) {
1338         GTEST_LOG_(INFO) << "interface return file :" << file;
1339     }
1340     // Close trace after async dump
1341     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1342 }
1343 
1344 /**
1345  * @tc.name: DumpTraceAsyncTest005
1346  * @tc.desc: Test DumpTraceAsync func execute in cache trace mode.
1347  * @tc.type: FUNC
1348  */
1349 HWTEST_F(HitraceDumpTest, DumpTraceAsyncTest005, TestSize.Level2)
1350 {
1351     const std::vector<std::string> tagGroups = {"scene_performance"};
1352     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
1353     // total cache filesize limit: 800MB, sliceduration: 5s
1354     ASSERT_TRUE(CacheTraceOn(800, 5) == TraceErrorCode::SUCCESS);
1355     sleep(8); // wait 8s
__anonabe3daa80702(TraceRetInfo traceInfo) 1356     std::function<void(TraceRetInfo)> func = [](TraceRetInfo traceInfo) {
1357         EXPECT_EQ(traceInfo.errorCode, TraceErrorCode::SUCCESS);
1358         EXPECT_EQ(traceInfo.outputFiles.size(), 2); // 2 : 2 files
1359         off_t totalFileSz = 0;
1360         for (auto& files : traceInfo.outputFiles) {
1361             totalFileSz += GetFileSize(files);
1362             GTEST_LOG_(INFO) << "output: " << files << " file size: " << GetFileSize(files);
1363         }
1364         EXPECT_EQ(totalFileSz, traceInfo.fileSize);
1365     };
1366     auto ret = DumpTraceAsync(8, 0, INT64_MAX, func); // 8 : 8 seconds
1367     EXPECT_EQ(ret.errorCode, TraceErrorCode::SUCCESS);
1368     EXPECT_EQ(ret.outputFiles.size(), 2); // 2 : 2 files
1369     GTEST_LOG_(INFO) << "interface return file size :" << ret.fileSize;
1370     for (auto& file : ret.outputFiles) {
1371         GTEST_LOG_(INFO) << "interface return file :" << file;
1372     }
1373     ASSERT_TRUE(CacheTraceOff() == TraceErrorCode::SUCCESS);
1374     // Close trace after async dump
1375     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
1376 }
1377 } // namespace
1378