1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hitrace_dump.h"
17 #include "common_utils.h"
18 
19 #include <iostream>
20 #include <memory>
21 #include <fstream>
22 #include <string>
23 #include <vector>
24 #include <map>
25 
26 #include <unistd.h>
27 #include <cstdio>
28 #include <fcntl.h>
29 #include "securec.h"
30 
31 #include "hilog/log.h"
32 #include "parameters.h"
33 #include <gtest/gtest.h>
34 
35 using namespace OHOS::HiviewDFX::Hitrace;
36 using namespace testing::ext;
37 using OHOS::HiviewDFX::HiLog;
38 
39 namespace {
40 
41 #undef LOG_DOMAIN
42 #define LOG_DOMAIN 0xD002D33
43 
44 #undef LOG_TAG
45 #define LOG_TAG "HitraceTest"
46 
47 const std::string TAG_PROP = "debug.hitrace.tags.enableflags";
48 const std::string DEFAULT_OUTPUT_DIR = "/data/log/hitrace/";
49 const std::string LOG_DIR = "/data/log/";
50 const int SLEEP_TIME = 10; // sleep 10ms
51 
52 std::string g_traceRootPath;
53 
AddPair2Table(std::string outputFileName, int nowSec)54 void AddPair2Table(std::string outputFileName, int nowSec)
55 {
56     std::vector<std::pair<std::string, int>> traceFilesTable = GetTraceFilesTable();
57     traceFilesTable.push_back({outputFileName, nowSec});
58     SetTraceFilesTable(traceFilesTable);
59 }
60 
CreateFile(std::string outputFileName)61 bool CreateFile(std::string outputFileName)
62 {
63     std::ofstream ofs;
64     ofs.open(outputFileName, std::ios::out | std::ios::trunc);
65     bool openRes = ofs.is_open();
66     ofs.close();
67     return openRes;
68 }
69 
EraseFile(std::string outputFileName)70 void EraseFile(std::string outputFileName)
71 {
72     std::vector<std::pair<std::string, int>> traceFilesTable = GetTraceFilesTable();
73     for (auto iter = traceFilesTable.begin(); iter != traceFilesTable.end();) {
74         if (strcmp(iter->first.c_str(), outputFileName.c_str())) {
75             iter = traceFilesTable.erase(iter);
76             continue;
77         }
78         iter++;
79     }
80     SetTraceFilesTable(traceFilesTable);
81 }
82 
TraverseFiles(std::vector<std::string> files, std::string outputFileName)83 bool TraverseFiles(std::vector<std::string> files, std::string outputFileName)
84 {
85     int i = 1;
86     bool isExists = false;
87     for (std::vector<std::string>::iterator iter = files.begin(); iter != files.end(); iter++) {
88         isExists |= (strcmp(iter->c_str(), outputFileName.c_str()) == 0);
89         HILOG_INFO(LOG_CORE, "ret.outputFile%{public}d: %{public}s", i++, iter->c_str());
90     }
91     return isExists;
92 }
93 
RunCmd(const string& cmdstr)94 bool RunCmd(const string& cmdstr)
95 {
96     FILE *fp = popen(cmdstr.c_str(), "r");
97     if (fp == nullptr) {
98         return false;
99     }
100     pclose(fp);
101     return true;
102 }
103 
104 class HitraceDumpTest : public testing::Test {
105 public:
106     static void SetUpTestCase(void);
107     static void TearDownTestCase(void);
108     void SetUp();
TearDown()109     void TearDown() {}
110 };
111 
SetUp()112 void HitraceDumpTest::SetUp()
113 {
114     CloseTrace();
115 }
116 
SetUpTestCase()117 void HitraceDumpTest::SetUpTestCase()
118 {
119     const std::string debugfsDir = "/sys/kernel/debug/tracing/";
120     const std::string tracefsDir = "/sys/kernel/tracing/";
121     if (access((debugfsDir + "trace_marker").c_str(), F_OK) != -1) {
122         g_traceRootPath = debugfsDir;
123     } else if (access((tracefsDir + "trace_marker").c_str(), F_OK) != -1) {
124         g_traceRootPath = tracefsDir;
125     } else {
126         HILOG_ERROR(LOG_CORE, "Error: Finding trace folder failed.");
127     }
128 
129     /* Open CMD_MODE */
130 }
131 
TearDownTestCase()132 void HitraceDumpTest::TearDownTestCase()
133 {
134     /* Close CMD_MODE */
135 }
136 
137 /**
138  * @tc.name: GetTraceModeTest_001
139  * @tc.desc: test GetTraceMode() service mode
140  * @tc.type: FUNC
141  */
HWTEST_F(HitraceDumpTest, GetTraceModeTest_001, TestSize.Level0)142 HWTEST_F(HitraceDumpTest, GetTraceModeTest_001, TestSize.Level0)
143 {
144     // check service mode
145     const std::vector<std::string> tagGroups = {"scene_performance"};
146     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
147     TraceMode serviceMode = GetTraceMode();
148     ASSERT_TRUE(serviceMode == TraceMode::SERVICE_MODE);
149 
150     // check close mode
151     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
152     TraceMode closeMode = GetTraceMode();
153     ASSERT_TRUE(closeMode == TraceMode::CLOSE);
154 }
155 
156 /**
157  * @tc.name: GetTraceModeTest_002
158  * @tc.desc: test GetTraceMode() cmd mode
159  * @tc.type: FUNC
160  */
HWTEST_F(HitraceDumpTest, GetTraceModeTest_002, TestSize.Level0)161 HWTEST_F(HitraceDumpTest, GetTraceModeTest_002, TestSize.Level0)
162 {
163     // check cmd mode
164     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
165     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
166     TraceMode cmdMode = GetTraceMode();
167     ASSERT_TRUE(cmdMode == TraceMode::CMD_MODE);
168 
169     // check close mode
170     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
171     TraceMode closeMode = GetTraceMode();
172     ASSERT_TRUE(closeMode == TraceMode::CLOSE);
173 }
174 
175 /**
176  * @tc.name: DumpTraceTest_001
177  * @tc.desc: Test DumpTrace(int maxDuration) for valid input.
178  * The no arg version DumpTrace() is implicitly tested in other tests.
179  * @tc.type: FUNC
180  */
HWTEST_F(HitraceDumpTest, DumpTraceTest_001, TestSize.Level0)181 HWTEST_F(HitraceDumpTest, DumpTraceTest_001, TestSize.Level0)
182 {
183     const std::vector<std::string> tagGroups = {"default"};
184     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
185 
186     int maxDuration = 1;
187     TraceRetInfo ret = DumpTrace(maxDuration);
188     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
189     ASSERT_TRUE(ret.outputFiles.size() > 0);
190     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
191 }
192 
193 /**
194  * @tc.name: DumpTraceTest_002
195  * @tc.desc: Test DumpTrace(int maxDuration) for invalid input.
196  * @tc.type: FUNC
197  */
HWTEST_F(HitraceDumpTest, DumpTraceTest_002, TestSize.Level0)198 HWTEST_F(HitraceDumpTest, DumpTraceTest_002, TestSize.Level0)
199 {
200     const std::vector<std::string> tagGroups = {"default"};
201     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
202 
203     int maxDuration = -1;
204     TraceRetInfo ret = DumpTrace(maxDuration);
205     ASSERT_TRUE(ret.errorCode == TraceErrorCode::CALL_ERROR);
206     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
207 }
208 
209 /**
210  * @tc.name: DumpTraceTest_003
211  * @tc.desc: Test DumpTrace(int maxDuration, uint64_t happenTime) for valid input.
212  * @tc.type: FUNC
213  */
HWTEST_F(HitraceDumpTest, DumpTraceTest_003, TestSize.Level0)214 HWTEST_F(HitraceDumpTest, DumpTraceTest_003, TestSize.Level0)
215 {
216     const std::vector<std::string> tagGroups = {"default"};
217     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
218     sleep(2); // need at least one second of trace in cpu due to the input unit of 1 second to avoid OUT_OF_TIME.
219     uint64_t traceEndTime = static_cast<uint64_t>(std::time(nullptr));
220     TraceRetInfo ret = DumpTrace(0, traceEndTime);
221     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
222     ASSERT_TRUE(ret.outputFiles.size() > 0);
223     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
224 
225     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
226     sleep(2);
227     traceEndTime = static_cast<uint64_t>(std::time(nullptr));
228     int maxDuration = 10;
229     ret = DumpTrace(maxDuration, traceEndTime);
230     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
231     ASSERT_TRUE(ret.outputFiles.size() > 0);
232     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
233 }
234 
235 /**
236  * @tc.name: DumpTraceTest_004
237  * @tc.desc: Test DumpTrace(int maxDuration, uint64_t happenTime) for invalid input.
238  * @tc.type: FUNC
239  */
HWTEST_F(HitraceDumpTest, DumpTraceTest_004, TestSize.Level0)240 HWTEST_F(HitraceDumpTest, DumpTraceTest_004, TestSize.Level0)
241 {
242     const std::vector<std::string> tagGroups = {"default"};
243 
244     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
245     uint64_t traceEndTime = 1;
246     TraceRetInfo ret = DumpTrace(0, traceEndTime);
247     ASSERT_TRUE(ret.errorCode == TraceErrorCode::OUT_OF_TIME);
248     ASSERT_TRUE(ret.outputFiles.empty());
249     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
250 
251     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
252     traceEndTime = static_cast<uint64_t>(std::time(nullptr)) + 10; // current time + 10 seconds
253     ret = DumpTrace(0, traceEndTime);
254     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
255     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
256 
257     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
258     traceEndTime = 10; // 1970-01-01 08:00:10
259     int maxDuration = -1;
260     ret = DumpTrace(maxDuration, traceEndTime);
261     ASSERT_TRUE(ret.errorCode == TraceErrorCode::CALL_ERROR);
262     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
263 
264     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
265     traceEndTime = static_cast<uint64_t>(std::time(nullptr)) + 10; // current time + 10 seconds
266     maxDuration = -1;
267     ret = DumpTrace(maxDuration, traceEndTime);
268     ASSERT_TRUE(ret.errorCode == TraceErrorCode::CALL_ERROR);
269     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
270 
271     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
272     traceEndTime = 10;
273     maxDuration = 10;
274     ret = DumpTrace(maxDuration, traceEndTime);
275     ASSERT_TRUE(ret.errorCode == TraceErrorCode::OUT_OF_TIME);
276     ASSERT_TRUE(ret.outputFiles.empty());
277     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
278 
279     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
280     traceEndTime = static_cast<uint64_t>(std::time(nullptr)) + 100; // current time + 100 seconds
281     maxDuration = 10;
282     ret = DumpTrace(maxDuration, traceEndTime);
283     ASSERT_TRUE(ret.errorCode == TraceErrorCode::OUT_OF_TIME);
284     ASSERT_TRUE(ret.outputFiles.empty());
285     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
286 
287     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
288     traceEndTime = static_cast<uint64_t>(std::time(nullptr)) + 1; // current time + 1 seconds
289     maxDuration = 10;
290     ret = DumpTrace(maxDuration, traceEndTime);
291     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
292     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
293 }
294 
295 /**
296  * @tc.name: DumpTraceTest_005
297  * @tc.desc: Test DumpTrace(int maxDuration, uint64_t happenTime) for OUT_OF_TIME.
298  * @tc.type: FUNC
299  */
HWTEST_F(HitraceDumpTest, DumpTraceTest_005, TestSize.Level0)300 HWTEST_F(HitraceDumpTest, DumpTraceTest_005, TestSize.Level0)
301 {
302     const std::vector<std::string> tagGroups = {"default"};
303     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
304     sleep(2);
305     uint64_t traceEndTime = static_cast<uint64_t>(std::time(nullptr)) - 20; // current time - 20 seconds
306     TraceRetInfo ret = DumpTrace(0, traceEndTime);
307     ASSERT_TRUE(ret.errorCode == TraceErrorCode::OUT_OF_TIME);
308     ASSERT_TRUE(ret.outputFiles.empty());
309     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
310 
311     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
312     sleep(2);
313     traceEndTime = static_cast<uint64_t>(std::time(nullptr)) - 20; // current time - 20 seconds
314     int maxDuration = 10;
315     ret = DumpTrace(maxDuration, traceEndTime);
316     ASSERT_TRUE(ret.errorCode == TraceErrorCode::OUT_OF_TIME);
317     ASSERT_TRUE(ret.outputFiles.empty());
318     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
319 }
320 
321 /**
322  * @tc.name: DumpForServiceMode_001
323  * @tc.desc: The correct usage of grasping trace in SERVICE_MODE.
324  * @tc.type: FUNC
325  */
HWTEST_F(HitraceDumpTest, DumpForServiceMode_001, TestSize.Level0)326 HWTEST_F(HitraceDumpTest, DumpForServiceMode_001, TestSize.Level0)
327 {
328     const std::vector<std::string> tagGroups = {"scene_performance"};
329     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
330 
331     TraceRetInfo ret = DumpTrace();
332     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
333     ASSERT_TRUE(ret.outputFiles.size() > 0);
334     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
335 }
336 
337 /**
338  * @tc.name: DumpForCmdMode_001
339  * @tc.desc: The correct usage of grasping trace in CMD_MODE.
340  * @tc.type: FUNC
341  */
HWTEST_F(HitraceDumpTest, DumpForCmdMode_001, TestSize.Level0)342 HWTEST_F(HitraceDumpTest, DumpForCmdMode_001, TestSize.Level0)
343 {
344     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
345     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
346 
347     ASSERT_TRUE(DumpTraceOn() == TraceErrorCode::SUCCESS);
348     sleep(1);
349 
350     TraceRetInfo ret = DumpTraceOff();
351     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
352     ASSERT_TRUE(ret.outputFiles.size() > 0);
353 
354     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
355 }
356 
357 /**
358  * @tc.name: DumpForCmdMode_002
359  * @tc.desc: Specifies the path of the command in CMD_MODE.
360  * @tc.type: FUNC
361  */
HWTEST_F(HitraceDumpTest, DumpForCmdMode_002, TestSize.Level0)362 HWTEST_F(HitraceDumpTest, DumpForCmdMode_002, TestSize.Level0)
363 {
364     std::string filePathName = "/data/local/tmp/mytrace.sys";
365     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1 output:" + filePathName;
366     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
367     ASSERT_TRUE(DumpTraceOn() == TraceErrorCode::SUCCESS);
368     sleep(1);
369 
370     TraceRetInfo ret = DumpTraceOff();
371     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
372 
373     ASSERT_TRUE(TraverseFiles(ret.outputFiles, filePathName))
374         << "unspport set outputfile, default generate file in /data/log/hitrace.";
375 
376     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
377 }
378 
379 /**
380  * @tc.name: DumpForCmdMode_003
381  * @tc.desc: Invalid args verification in CMD_MODE.
382  * @tc.type: FUNC
383  */
HWTEST_F(HitraceDumpTest, DumpForCmdMode_003, TestSize.Level0)384 HWTEST_F(HitraceDumpTest, DumpForCmdMode_003, TestSize.Level0)
385 {
386     std::string args = "clockType:boot bufferSize:1024 overwrite:1 ";
387     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
388     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
389 
390     args = "tags:hdc clockType:boot bufferSize:1024 overwrite:1 descriptions:123";
391     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::TAG_ERROR);
392 
393     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
394 }
395 
396 /**
397  * @tc.name: DumpForCmdMode_004
398  * @tc.desc: The CMD_MODE cannot be interrupted by the SERVICE_MODE.
399  * @tc.type: FUNC
400  */
HWTEST_F(HitraceDumpTest, DumpForCmdMode_004, TestSize.Level0)401 HWTEST_F(HitraceDumpTest, DumpForCmdMode_004, TestSize.Level0)
402 {
403     std::string args = "tags:memory clockType:boot1 bufferSize:1024 overwrite:0";
404     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
405 
406     const std::vector<std::string> tagGroups = {"scene_performance"};
407     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::CALL_ERROR);
408 
409     ASSERT_TRUE(DumpTraceOn() == TraceErrorCode::SUCCESS);
410     sleep(1);
411 
412     TraceRetInfo ret = DumpTraceOff();
413     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
414     ASSERT_TRUE(ret.outputFiles.size() > 0);
415 
416     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
417 
418     args = "tags:memory clockType: bufferSize:1024 overwrite:1";
419     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
420     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
421 
422     args = "tags:memory clockType:perf bufferSize:1024 overwrite:1";
423     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
424     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
425 }
426 
427 /**
428  * @tc.name: DumpForCmdMode_005
429  * @tc.desc: Enable the cmd mode in non-close mode.
430  * @tc.type: FUNC
431  */
HWTEST_F(HitraceDumpTest, DumpForCmdMode_005, TestSize.Level0)432 HWTEST_F(HitraceDumpTest, DumpForCmdMode_005, TestSize.Level0)
433 {
434     const std::vector<std::string> tagGroups = {"scene_performance"};
435     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
436     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
437     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::CALL_ERROR);
438     ASSERT_TRUE(DumpTraceOn() == TraceErrorCode::CALL_ERROR);
439 
440     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
441 }
442 
443 /**
444  * @tc.name: DumpForCmdMode_006
445  * @tc.desc: Test the CMD_MODE when there's extra space in args.
446  * @tc.type: FUNC
447  */
HWTEST_F(HitraceDumpTest, DumpForCmdMode_006, TestSize.Level0)448 HWTEST_F(HitraceDumpTest, DumpForCmdMode_006, TestSize.Level0)
449 {
450     std::string args = "tags: sched clockType: boot bufferSize:1024 overwrite: 1";
451     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
452 
453     ASSERT_TRUE(DumpTraceOn() == TraceErrorCode::SUCCESS);
454     sleep(1);
455 
456     TraceRetInfo ret = DumpTraceOff();
457     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
458     ASSERT_TRUE(ret.outputFiles.size() > 0);
459 
460     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
461 }
462 
463 /**
464  * @tc.name: DumpForCmdMode_007
465  * @tc.desc: Test the CMD_MODE when set fileLimit in args.
466  * @tc.type: FUNC
467  */
HWTEST_F(HitraceDumpTest, DumpForCmdMode_007, TestSize.Level0)468 HWTEST_F(HitraceDumpTest, DumpForCmdMode_007, TestSize.Level0)
469 {
470     std::string args = "tags:sched,ace,app,disk,distributeddatamgr,freq,graphic,idle,irq,load,mdfs,mmc,";
471     args += "notification,ohos,pagecache,regulators,sync,ufs,workq,zaudio,zcamera,zimage,zmedia ";
472     args += "clockType: boot bufferSize:1024 overwrite: 1 fileLimit: 2 fileSize: 51200";
473     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
474 
475     ASSERT_TRUE(DumpTraceOn() == TraceErrorCode::SUCCESS);
476     sleep(1);
477 
478     TraceRetInfo ret = DumpTraceOff();
479     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
480     ASSERT_TRUE(ret.outputFiles.size() > 0);
481 
482     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
483 }
484 
485 /**
486  * @tc.name: DumpForCmdMode_008
487  * @tc.desc: Test the CMD_MODE when there's extra space in args.
488  * @tc.type: FUNC
489  */
HWTEST_F(HitraceDumpTest, DumpForCmdMode_008, TestSize.Level0)490 HWTEST_F(HitraceDumpTest, DumpForCmdMode_008, TestSize.Level0)
491 {
492     std::string filePathName = "/data/local/tmp/mylongtrace.sys";
493     std::string args = "tags:sched,ace,app,disk,distributeddatamgr,freq,graphic,idle,irq,load,mdfs,mmc,";
494     args += "notification,ohos,pagecache,regulators,sync,ufs,workq,zaudio,zcamera,zimage,zmedia ";
495     args += "clockType: boot bufferSize:1024 overwrite: 1 output:" + filePathName;
496     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
497 
498     ASSERT_TRUE(DumpTraceOn() == TraceErrorCode::SUCCESS);
499     if (remove(filePathName.c_str()) == 0) {
500         HILOG_INFO(LOG_CORE, "Delete mylongtrace.sys success.");
501     } else {
502         HILOG_ERROR(LOG_CORE, "Delete mylongtrace.sys failed.");
503     }
504     sleep(SLEEP_TIME);
505 
506     TraceRetInfo ret = DumpTraceOff();
507     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
508     ASSERT_TRUE(ret.outputFiles.size() > 0);
509 
510     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
511 }
512 
513 /**
514  * @tc.name: DumpForCmdMode_009
515  * @tc.desc: Test the CMD_MODE when set fileLimit in args.
516  * @tc.type: FUNC
517  */
HWTEST_F(HitraceDumpTest, DumpForCmdMode_009, TestSize.Level0)518 HWTEST_F(HitraceDumpTest, DumpForCmdMode_009, TestSize.Level0)
519 {
520     std::string args = "tags:sched,ace,app,disk,distributeddatamgr,freq,graphic,idle,irq,load,mdfs,mmc,";
521     args += "notification,ohos,pagecache,regulators,sync,ufs,workq,zaudio,zcamera,zimage,zmedia ";
522     args += "clockType: boot bufferSize:1024 overwrite: 1 fileLimit: 2";
523     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
524 
525     ASSERT_TRUE(DumpTraceOn() == TraceErrorCode::SUCCESS);
526     sleep(1);
527 
528     TraceRetInfo ret = DumpTraceOff();
529     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
530     ASSERT_TRUE(ret.outputFiles.size() > 0);
531 
532     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
533 }
534 
535 /**
536  * @tc.name: ParammeterCheck_001
537  * @tc.desc: Check parameter after interface call.
538  * @tc.type: FUNC
539  */
HWTEST_F(HitraceDumpTest, ParammeterCheck_001, TestSize.Level0)540 HWTEST_F(HitraceDumpTest, ParammeterCheck_001, TestSize.Level0)
541 {
542     const std::vector<std::string> tagGroups = {"scene_performance"};
543     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
544 
545     // ckeck Property("debug.hitrace.tags.enableflags")
546     uint64_t openTags = OHOS::system::GetUintParameter<uint64_t>(TAG_PROP, 0);
547     ASSERT_TRUE(openTags > 0);
548 
549     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
550 
551     // ckeck Property("debug.hitrace.tags.enableflags")
552     uint64_t closeTags = OHOS::system::GetUintParameter<uint64_t>(TAG_PROP, 0);
553     ASSERT_TRUE(closeTags == 0);
554 }
555 
556 /**
557  * @tc.name: DumpForServiceMode_002
558  * @tc.desc: Verify if files can be returned as expected in Service_MODE.
559  * @tc.type: FUNC
560  */
HWTEST_F(HitraceDumpTest, DumpForServiceMode_002, TestSize.Level0)561 HWTEST_F(HitraceDumpTest, DumpForServiceMode_002, TestSize.Level0)
562 {
563     const std::vector<std::string> tagGroups = {"scene_performance"};
564     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
565     ASSERT_TRUE(access(DEFAULT_OUTPUT_DIR.c_str(), F_OK) == 0) << "/data/log/hitrace not exists.";
566 
567     struct timeval now = {0, 0};
568     gettimeofday(&now, nullptr);
569     int nowSec = now.tv_sec;
570     int nowUsec = now.tv_usec;
571     nowSec--;
572     std::string outputFileName = DEFAULT_OUTPUT_DIR + "trace_" + std::to_string(nowSec)
573         + "_" + std::to_string(nowUsec) + ".sys";
574     ASSERT_TRUE(CreateFile(outputFileName)) << "create log file failed.";
575     HILOG_INFO(LOG_CORE, "outputFileName: %{public}s", outputFileName.c_str());
576     AddPair2Table(outputFileName, nowSec);
577 
578     TraceRetInfo ret = DumpTrace();
579     // Remove outputFileName in g_hitraceFilesTable
580     EraseFile(outputFileName);
581     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
582     ASSERT_TRUE(TraverseFiles(ret.outputFiles, outputFileName)) << "file created by user is not exists.";
583     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
584 }
585 
586 /**
587  * @tc.name: DumpForServiceMode_003
588  * @tc.desc: Verify if files can be deleted in Service_MODE.
589  * @tc.type: FUNC
590  */
HWTEST_F(HitraceDumpTest, DumpForServiceMode_003, TestSize.Level0)591 HWTEST_F(HitraceDumpTest, DumpForServiceMode_003, TestSize.Level0)
592 {
593     const std::vector<std::string> tagGroups = {"scene_performance"};
594     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
595     ASSERT_TRUE(access(DEFAULT_OUTPUT_DIR.c_str(), F_OK) == 0) << "/data/log/hitrace not exists.";
596 
597     struct timeval now = {0, 0};
598     gettimeofday(&now, nullptr);
599     int nowSec = now.tv_sec;
600     int nowUsec = now.tv_usec;
601     nowSec = nowSec - 1900;
602     std::string outputFileName = DEFAULT_OUTPUT_DIR + "trace_" + std::to_string(nowSec)
603         + "_" + std::to_string(nowUsec) + ".sys";
604     ASSERT_TRUE(CreateFile(outputFileName)) << "create log file failed.";
605     HILOG_INFO(LOG_CORE, "outputFileName: %{public}s", outputFileName.c_str());
606     AddPair2Table(outputFileName, nowSec);
607 
608     TraceRetInfo ret = DumpTrace();
609     ASSERT_TRUE(ret.errorCode == TraceErrorCode::SUCCESS);
610     ASSERT_FALSE(TraverseFiles(ret.outputFiles, outputFileName))
611         << "Returned files that should have been deleted half an hour ago.";
612     ASSERT_TRUE(access(outputFileName.c_str(), F_OK) < 0) << "The file was not deleted half an hour ago";
613     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
614 }
615 
616 /**
617  * @tc.name: DumpForServiceMode_004
618  * @tc.desc: Invalid parameter verification in CMD_MODE.
619  * @tc.type: FUNC
620  */
HWTEST_F(HitraceDumpTest, DumpForServiceMode_004, TestSize.Level0)621 HWTEST_F(HitraceDumpTest, DumpForServiceMode_004, TestSize.Level0)
622 {
623     const std::vector<std::string> tagGroups;
624     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::TAG_ERROR);
625 
626     const std::vector<std::string> tagGroups1 = {"scene_performance1"};
627     ASSERT_TRUE(OpenTrace(tagGroups1) == TraceErrorCode::TAG_ERROR);
628     ASSERT_TRUE(DumpTrace().errorCode == TraceErrorCode::CALL_ERROR);
629 
630     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
631 }
632 
633 /**
634  * @tc.name: DumpForServiceMode_005
635  * @tc.desc: Enable the service mode in CMD_MODE.
636  * @tc.type: FUNC
637  */
HWTEST_F(HitraceDumpTest, DumpForServiceMode_005, TestSize.Level0)638 HWTEST_F(HitraceDumpTest, DumpForServiceMode_005, TestSize.Level0)
639 {
640     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1";
641     ASSERT_TRUE(OpenTrace(args) == TraceErrorCode::SUCCESS);
642 
643     const std::vector<std::string> tagGroups = {"scene_performance"};
644     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::CALL_ERROR);
645 
646     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
647 
648     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
649 
650     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::CALL_ERROR);
651 
652     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
653 }
654 
655 /**
656  * @tc.name: DumpForServiceMode_006
657  * @tc.desc: Invalid parameter verification in CMD_MODE.
658  * @tc.type: FUNC
659  */
HWTEST_F(HitraceDumpTest, DumpForServiceMode_006, TestSize.Level0)660 HWTEST_F(HitraceDumpTest, DumpForServiceMode_006, TestSize.Level0)
661 {
662     const std::vector<std::string> tagGroups = {"scene_performance"};
663     ASSERT_TRUE(OpenTrace(tagGroups) == TraceErrorCode::SUCCESS);
664     ASSERT_TRUE(access(DEFAULT_OUTPUT_DIR.c_str(), F_OK) == 0) << "/data/log/hitrace not exists.";
665 
666     SetSysInitParamTags(123);
667     ASSERT_TRUE(SetCheckParam() == false);
668 
669     ASSERT_TRUE(CloseTrace() == TraceErrorCode::SUCCESS);
670 }
671 
672 /**
673  * @tc.name: CommonUtils_001
674  * @tc.desc: Test canonicalizeSpecPath(), enter an existing file path.
675  * @tc.type: FUNC
676 */
HWTEST_F(HitraceDumpTest, CommonUtils_001, TestSize.Level0)677 HWTEST_F(HitraceDumpTest, CommonUtils_001, TestSize.Level0)
678 {
679     // prepare a file
680     std::string filePath = "/data/local/tmp/tmp.txt";
681     if (access(filePath.c_str(), F_OK) != 0) {
682         int fd = open(filePath.c_str(), O_CREAT);
683         close(fd);
684     }
685     ASSERT_TRUE(CanonicalizeSpecPath(filePath.c_str()) == filePath);
686 }
687 
688 /**
689  * @tc.name: CommonUtils_002
690  * @tc.desc: Test canonicalizeSpecPath(), enter a non-existent file path.
691  * @tc.type: FUNC
692 */
HWTEST_F(HitraceDumpTest, CommonUtils_002, TestSize.Level0)693 HWTEST_F(HitraceDumpTest, CommonUtils_002, TestSize.Level0)
694 {
695     // prepare a file
696     std::string filePath = "/data/local/tmp/tmp1.txt";
697     if (access(filePath.c_str(), F_OK) != 0) {
698         ASSERT_TRUE(CanonicalizeSpecPath(filePath.c_str()) == filePath);
699     }
700 }
701 
702 /**
703  * @tc.name: CommonUtils_003
704  * @tc.desc: Test canonicalizeSpecPath(), enter a non-existent file path with "..".
705  * @tc.type: FUNC
706 */
HWTEST_F(HitraceDumpTest, CommonUtils_003, TestSize.Level0)707 HWTEST_F(HitraceDumpTest, CommonUtils_003, TestSize.Level0)
708 {
709     // prepare a file
710     std::string filePath = "../tmp2.txt";
711     if (access(filePath.c_str(), F_OK) != 0) {
712         ASSERT_TRUE(CanonicalizeSpecPath(filePath.c_str()) == "");
713     }
714 }
715 
716 /**
717  * @tc.name: CommonUtils_004
718  * @tc.desc: Test MarkClockSync().
719  * @tc.type: FUNC
720 */
HWTEST_F(HitraceDumpTest, CommonUtils_004, TestSize.Level0)721 HWTEST_F(HitraceDumpTest, CommonUtils_004, TestSize.Level0)
722 {
723     ASSERT_TRUE(MarkClockSync(g_traceRootPath) == true);
724 }
725 
726 /**
727  * @tc.name: CommonUtils_005
728  * @tc.desc: Test ParseTagInfo().
729  * @tc.type: FUNC
730 */
HWTEST_F(HitraceDumpTest, CommonUtils_005, TestSize.Level0)731 HWTEST_F(HitraceDumpTest, CommonUtils_005, TestSize.Level0)
732 {
733     std::map<std::string, OHOS::HiviewDFX::Hitrace::TagCategory> allTags;
734     std::map<std::string, std::vector<std::string>> tagGroupTable;
735     ASSERT_TRUE(ParseTagInfo(allTags, tagGroupTable) == true);
736     ASSERT_TRUE(allTags.size() > 0);
737     ASSERT_TRUE(tagGroupTable.size() > 0);
738 }
739 
740 /**
741  * @tc.name: CommonUtils_006
742  * @tc.desc: Test ParseTagInfo().
743  * @tc.type: FUNC
744 */
HWTEST_F(HitraceDumpTest, CommonUtils_006, TestSize.Level0)745 HWTEST_F(HitraceDumpTest, CommonUtils_006, TestSize.Level0)
746 {
747     std::map<std::string, OHOS::HiviewDFX::Hitrace::TagCategory> allTags;
748     std::map<std::string, std::vector<std::string>> tagGroupTable;
749 
750     ASSERT_TRUE(RunCmd("mount -o rw,remount /"));
751     ASSERT_TRUE(RunCmd("cp /system/etc/hiview/hitrace_utils.json /system/etc/hiview/hitrace_utils-bak.json"));
752     ASSERT_TRUE(RunCmd("sed -i 's/tag_groups/TestCommonUtils/g' /system/etc/hiview/hitrace_utils.json"));
753     ParseTagInfo(allTags, tagGroupTable);
754     ASSERT_TRUE(RunCmd("sed -i 's/tag_category/TestCommonUtils/g' /system/etc/hiview/hitrace_utils.json"));
755     ParseTagInfo(allTags, tagGroupTable);
756     ASSERT_TRUE(RunCmd("rm /system/etc/hiview/hitrace_utils.json"));
757     ParseTagInfo(allTags, tagGroupTable);
758     ASSERT_TRUE(RunCmd("mv /system/etc/hiview/hitrace_utils-bak.json /system/etc/hiview/hitrace_utils.json"));
759 
760     ASSERT_TRUE(IsNumber("scene_performance") == TraceErrorCode::SUCCESS);
761     ASSERT_TRUE(IsNumber("") == false);
762     ASSERT_TRUE(IsNumber("tags:sched clockType:boot bufferSize:1024 overwrite:1") == false);
763     CanonicalizeSpecPath(nullptr);
764     MarkClockSync("/sys/kernel/debug/tracing/test_trace_marker");
765 }
766 } // namespace
767