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