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