1 /*
2 * Copyright (C) 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 <atomic>
17 #include <gtest/gtest.h>
18 #include <string>
19 #include <sys/stat.h>
20 #include <thread>
21 #include <unistd.h>
22
23 #include "common_define.h"
24 #include "common_utils.h"
25 #include "hitrace_dump.h"
26 #include "trace_source.h"
27
28 using namespace testing::ext;
29 using namespace std;
30
31 namespace OHOS {
32 namespace HiviewDFX {
33 namespace Hitrace {
34 namespace {
35 static const char* const TEST_TRACE_TEMP_FILE = "/data/local/tmp/test_trace_file";
36 }
37
38 class HitraceSourceTest : public testing::Test {
39 public:
SetUpTestCase(void)40 static void SetUpTestCase(void) {}
TearDownTestCase(void)41 static void TearDownTestCase(void) {}
SetUp()42 void SetUp() {}
TearDown()43 void TearDown() {}
44 };
45
46 namespace {
GetFileSize(const std::string & file)47 static off_t GetFileSize(const std::string& file)
48 {
49 struct stat fileStat;
50 if (stat(file.c_str(), &fileStat) != 0) {
51 GTEST_LOG_(ERROR) << "Failed to get file size of " << file;
52 return 0;
53 }
54 return fileStat.st_size;
55 }
56
57 /**
58 * @tc.name: TraceSourceTest001
59 * @tc.desc: Test TraceSourceLinux class GetTraceFileHeader function.
60 * @tc.type: FUNC
61 */
62 HWTEST_F(HitraceSourceTest, TraceSourceTest001, TestSize.Level2)
63 {
64 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
65 ASSERT_TRUE(traceSource != nullptr);
66 auto traceFileHdr = traceSource->GetTraceFileHeader();
67 ASSERT_TRUE(traceFileHdr != nullptr);
68 ASSERT_TRUE(traceFileHdr->WriteTraceContent());
69 ASSERT_EQ(GetFileSize(TEST_TRACE_TEMP_FILE), sizeof(TraceFileHeader));
70 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
71 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
72 }
73 }
74
75 /**
76 * @tc.name: TraceSourceTest002
77 * @tc.desc: Test TraceSourceHM class GetTraceFileHeader function.
78 * @tc.type: FUNC
79 */
80 HWTEST_F(HitraceSourceTest, TraceSourceTest002, TestSize.Level2)
81 {
82 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
83 ASSERT_TRUE(traceSource != nullptr);
84 auto traceFileHdr = traceSource->GetTraceFileHeader();
85 ASSERT_TRUE(traceFileHdr != nullptr);
86 ASSERT_TRUE(traceFileHdr->WriteTraceContent());
87 ASSERT_EQ(GetFileSize(TEST_TRACE_TEMP_FILE), sizeof(TraceFileHeader));
88 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
89 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
90 }
91 }
92
93 /**
94 * @tc.name: TraceSourceTest003
95 * @tc.desc: Test TraceSourceLinux class GetTraceHeaderPage function.
96 * @tc.type: FUNC
97 */
98 HWTEST_F(HitraceSourceTest, TraceSourceTest003, TestSize.Level2)
99 {
100 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
101 ASSERT_TRUE(traceSource != nullptr);
102 auto traceHdrPage = traceSource->GetTraceHeaderPage();
103 ASSERT_TRUE(traceHdrPage != nullptr);
104 if (IsHmKernel()) {
105 ASSERT_FALSE(traceHdrPage->WriteTraceContent());
106 } else {
107 ASSERT_TRUE(traceHdrPage->WriteTraceContent());
108 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
109 }
110 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
111 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
112 }
113 }
114
115 /**
116 * @tc.name: TraceSourceTest004
117 * @tc.desc: Test TraceSourceHM class GetTraceHeaderPage function.
118 * @tc.type: FUNC
119 */
120 HWTEST_F(HitraceSourceTest, TraceSourceTest004, TestSize.Level2)
121 {
122 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
123 ASSERT_TRUE(traceSource != nullptr);
124 auto traceHdrPage = traceSource->GetTraceHeaderPage();
125 ASSERT_TRUE(traceHdrPage != nullptr);
126 ASSERT_TRUE(traceHdrPage->WriteTraceContent());
127 if (IsHmKernel()) {
128 ASSERT_EQ(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
129 }
130 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
131 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
132 }
133 }
134
135 /**
136 * @tc.name: TraceSourceTest005
137 * @tc.desc: Test TraceSourceLinux class GetTracePrintkFmt function.
138 * @tc.type: FUNC
139 */
140 HWTEST_F(HitraceSourceTest, TraceSourceTest005, TestSize.Level2)
141 {
142 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
143 ASSERT_TRUE(traceSource != nullptr);
144 auto tracePrintkFmt = traceSource->GetTracePrintkFmt();
145 ASSERT_TRUE(tracePrintkFmt != nullptr);
146 ASSERT_TRUE(tracePrintkFmt->WriteTraceContent());
147 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
148 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
149 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
150 }
151 }
152
153 /**
154 * @tc.name: TraceSourceTest006
155 * @tc.desc: Test TraceSourceHM class GetTracePrintkFmt function.
156 * @tc.type: FUNC
157 */
158 HWTEST_F(HitraceSourceTest, TraceSourceTest006, TestSize.Level2)
159 {
160 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
161 ASSERT_TRUE(traceSource != nullptr);
162 auto tracePrintkFmt = traceSource->GetTracePrintkFmt();
163 ASSERT_TRUE(tracePrintkFmt != nullptr);
164 ASSERT_TRUE(tracePrintkFmt->WriteTraceContent());
165 if (IsHmKernel()) {
166 ASSERT_EQ(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
167 }
168 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
169 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
170 }
171 }
172
173 /**
174 * @tc.name: TraceSourceTest007
175 * @tc.desc: Test TraceSourceLinux class GetTraceEventFmt function.
176 * @tc.type: FUNC
177 */
178 HWTEST_F(HitraceSourceTest, TraceSourceTest007, TestSize.Level2)
179 {
180 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
181 ASSERT_TRUE(traceSource != nullptr);
182 auto traceEventFmts = traceSource->GetTraceEventFmt();
183 ASSERT_TRUE(traceEventFmts != nullptr);
184 if (access("/data/log/hitrace/saved_events_format", F_OK) == 0) {
185 ASSERT_EQ(remove("/data/log/hitrace/saved_events_format"), 0);
186 }
187 ASSERT_TRUE(traceEventFmts->WriteTraceContent());
188 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
189 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
190 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
191 }
192 }
193
194 /**
195 * @tc.name: TraceSourceTest008
196 * @tc.desc: Test TraceSourceHM class GetTraceEventFmt function.
197 * @tc.type: FUNC
198 */
199 HWTEST_F(HitraceSourceTest, TraceSourceTest008, TestSize.Level2)
200 {
201 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
202 ASSERT_TRUE(traceSource != nullptr);
203 auto traceEventFmts = traceSource->GetTraceEventFmt();
204 ASSERT_TRUE(traceEventFmts != nullptr);
205 if (access("/data/log/hitrace/saved_events_format", F_OK) == 0) {
206 ASSERT_EQ(remove("/data/log/hitrace/saved_events_format"), 0);
207 }
208 ASSERT_TRUE(traceEventFmts->WriteTraceContent());
209 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
210 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
211 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
212 }
213 }
214
215 /**
216 * @tc.name: TraceSourceTest009
217 * @tc.desc: Test TraceSourceLinux class GetTraceCmdLines function.
218 * @tc.type: FUNC
219 */
220 HWTEST_F(HitraceSourceTest, TraceSourceTest009, TestSize.Level2)
221 {
222 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
223 ASSERT_TRUE(traceSource != nullptr);
224 auto traceCmdLines = traceSource->GetTraceCmdLines();
225 ASSERT_TRUE(traceCmdLines != nullptr);
226 ASSERT_TRUE(traceCmdLines->WriteTraceContent());
227 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
228 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
229 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
230 }
231 }
232
233 /**
234 * @tc.name: TraceSourceTest010
235 * @tc.desc: Test TraceSourceHM class GetTraceCmdLines function.
236 * @tc.type: FUNC
237 */
238 HWTEST_F(HitraceSourceTest, TraceSourceTest010, TestSize.Level2)
239 {
240 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
241 ASSERT_TRUE(traceSource != nullptr);
242 auto traceCmdLines = traceSource->GetTraceCmdLines();
243 ASSERT_TRUE(traceCmdLines != nullptr);
244 ASSERT_TRUE(traceCmdLines->WriteTraceContent());
245 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
246 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
247 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
248 }
249 }
250
251 /**
252 * @tc.name: TraceSourceTest011
253 * @tc.desc: Test TraceSourceLinux class GetTraceTgids function.
254 * @tc.type: FUNC
255 */
256 HWTEST_F(HitraceSourceTest, TraceSourceTest011, TestSize.Level2)
257 {
258 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
259 ASSERT_TRUE(traceSource != nullptr);
260 auto traceTgids = traceSource->GetTraceTgids();
261 ASSERT_TRUE(traceTgids != nullptr);
262 ASSERT_TRUE(traceTgids->WriteTraceContent());
263 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
264 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
265 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
266 }
267 }
268
269 /**
270 * @tc.name: TraceSourceTest012
271 * @tc.desc: Test TraceSourceHM class GetTraceTgids function.
272 * @tc.type: FUNC
273 */
274 HWTEST_F(HitraceSourceTest, TraceSourceTest012, TestSize.Level2)
275 {
276 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
277 ASSERT_TRUE(traceSource != nullptr);
278 auto traceTgids = traceSource->GetTraceTgids();
279 ASSERT_TRUE(traceTgids != nullptr);
280 ASSERT_TRUE(traceTgids->WriteTraceContent());
281 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
282 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
283 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
284 }
285 }
286
287 /**
288 * @tc.name: TraceSourceTest013
289 * @tc.desc: Test ITraceSource class GetTraceCpuRaw function.
290 * @tc.type: FUNC
291 */
292 HWTEST_F(HitraceSourceTest, TraceSourceTest013, TestSize.Level2)
293 {
294 ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
295 std::string appArgs = "tags:sched,binder,ohos bufferSize:102400 overwrite:1";
296 ASSERT_EQ(OpenTrace(appArgs), TraceErrorCode::SUCCESS);
297 std::shared_ptr<ITraceSource> traceSource = nullptr;
298 if (IsHmKernel()) {
299 traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
300 } else {
301 traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
302 }
303 ASSERT_TRUE(traceSource != nullptr);
304 TraceDumpRequest request = {
305 TraceDumpType::TRACE_RECORDING,
306 102400, // 102400 : set 100MB /sys/kernel/tracing/buffer_size_kb.
307 false,
308 0,
309 std::numeric_limits<uint64_t>::max()
310 };
311 auto traceCpuRaw = traceSource->GetTraceCpuRaw(request);
312 ASSERT_TRUE(traceCpuRaw != nullptr);
313 ASSERT_TRUE(traceCpuRaw->WriteTraceContent());
314 ASSERT_EQ(traceCpuRaw->GetDumpStatus(), TraceErrorCode::SUCCESS);
315 ASSERT_LT(traceCpuRaw->GetFirstPageTimeStamp(), std::numeric_limits<uint64_t>::max());
316 ASSERT_GT(traceCpuRaw->GetLastPageTimeStamp(), 0);
317 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
318 ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
319 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
320 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
321 }
322 }
323
324 /**
325 * @tc.name: TraceSourceTest014
326 * @tc.desc: Test ITraceSource class e2e features.
327 * @tc.type: FUNC
328 */
329 HWTEST_F(HitraceSourceTest, TraceSourceTest014, TestSize.Level2)
330 {
331 ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
332 std::string appArgs = "tags:sched,binder,ohos bufferSize:102400 overwrite:1";
333 ASSERT_EQ(OpenTrace(appArgs), TraceErrorCode::SUCCESS);
334 std::shared_ptr<ITraceSource> traceSource = nullptr;
335 if (IsHmKernel()) {
336 traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
337 } else {
338 traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
339 }
340 ASSERT_TRUE(traceSource != nullptr);
341 auto traceFileHdr = traceSource->GetTraceFileHeader();
342 ASSERT_TRUE(traceFileHdr != nullptr);
343 ASSERT_TRUE(traceFileHdr->WriteTraceContent());
344 auto traceEventFmts = traceSource->GetTraceEventFmt();
345 ASSERT_TRUE(traceEventFmts != nullptr);
346 ASSERT_TRUE(traceEventFmts->WriteTraceContent());
347 TraceDumpRequest request = {
348 TraceDumpType::TRACE_RECORDING,
349 1024000,
350 false,
351 0,
352 std::numeric_limits<uint64_t>::max()
353 };
354 auto traceCpuRaw = traceSource->GetTraceCpuRaw(request);
355 ASSERT_TRUE(traceCpuRaw != nullptr);
356 ASSERT_TRUE(traceCpuRaw->WriteTraceContent());
357 auto traceCmdLines = traceSource->GetTraceCmdLines();
358 ASSERT_TRUE(traceCmdLines != nullptr);
359 ASSERT_TRUE(traceCmdLines->WriteTraceContent());
360 auto traceTgids = traceSource->GetTraceTgids();
361 ASSERT_TRUE(traceTgids != nullptr);
362 ASSERT_TRUE(traceTgids->WriteTraceContent());
363 auto traceHdrPage = traceSource->GetTraceHeaderPage();
364 ASSERT_TRUE(traceHdrPage != nullptr);
365 ASSERT_TRUE(traceHdrPage->WriteTraceContent());
366 auto tracePrintkFmt = traceSource->GetTracePrintkFmt();
367 ASSERT_TRUE(tracePrintkFmt != nullptr);
368 ASSERT_TRUE(tracePrintkFmt->WriteTraceContent());
369 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
370 ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
371 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
372 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
373 }
374 }
375
376 /**
377 * @tc.name: TraceSourceTest015
378 * @tc.desc: Test ITraceSource class UpdateTraceFile/GetTraceFilePath functions.
379 * @tc.type: FUNC
380 */
381 HWTEST_F(HitraceSourceTest, TraceSourceTest015, TestSize.Level2)
382 {
383 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
384 ASSERT_TRUE(traceSource != nullptr);
385 ASSERT_EQ(traceSource->GetTraceFilePath(), TEST_TRACE_TEMP_FILE);
386 const std::string newTestFile = "/data/local/tmp/new_test_file";
387 ASSERT_TRUE(traceSource->UpdateTraceFile(newTestFile));
388 ASSERT_EQ(traceSource->GetTraceFilePath(), newTestFile);
389 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
390 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
391 }
392 if (remove(newTestFile.c_str()) != 0) {
393 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
394 }
395 }
396
397 /**
398 * @tc.name: TraceSourceTest016
399 * @tc.desc: Test TraceSourceLinux class GetTraceBaseInfo function.
400 * @tc.type: FUNC
401 */
402 HWTEST_F(HitraceSourceTest, TraceSourceTest016, TestSize.Level2)
403 {
404 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
405 ASSERT_TRUE(traceSource != nullptr);
406 auto baseInfo = traceSource->GetTraceBaseInfo();
407 ASSERT_TRUE(baseInfo != nullptr);
408 ASSERT_TRUE(baseInfo->WriteTraceContent());
409 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
410 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
411 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
412 }
413 }
414
415 /**
416 * @tc.name: TraceSourceTest017
417 * @tc.desc: Test TraceSourceHM class GetTraceBaseInfo function.
418 * @tc.type: FUNC
419 */
420 HWTEST_F(HitraceSourceTest, TraceSourceTest017, TestSize.Level2)
421 {
422 std::shared_ptr<ITraceSource> traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
423 ASSERT_TRUE(traceSource != nullptr);
424 auto baseInfo = traceSource->GetTraceBaseInfo();
425 ASSERT_TRUE(baseInfo != nullptr);
426 ASSERT_TRUE(baseInfo->WriteTraceContent());
427 ASSERT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
428 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
429 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
430 }
431 }
432
433 /**
434 * @tc.name: TraceSourceTest018
435 * @tc.desc: Test TraceSourceLinux class GetTraceCpuRawRead function.
436 * @tc.type: FUNC
437 */
438 HWTEST_F(HitraceSourceTest, TraceSourceTest018, TestSize.Level2)
439 {
440 ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
441 std::string appArgs = "tags:sched,binder,ohos bufferSize:102400 overwrite:1";
442 EXPECT_EQ(OpenTrace(appArgs), TraceErrorCode::SUCCESS);
443 sleep(1);
444 std::shared_ptr<ITraceSource> traceSource = nullptr;
445 if (IsHmKernel()) {
446 traceSource = std::make_shared<TraceSourceHM>(TRACEFS_DIR, "");
447 } else {
448 traceSource = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, "");
449 }
450 EXPECT_TRUE(traceSource != nullptr);
451 TraceDumpRequest request = { TraceDumpType::TRACE_SNAPSHOT, 0, false, 0, std::numeric_limits<uint64_t>::max(), 1 };
452 auto traceCpuRawRead = traceSource->GetTraceCpuRawRead(request);
453 EXPECT_TRUE(traceCpuRawRead != nullptr);
454 EXPECT_TRUE(traceCpuRawRead->WriteTraceContent());
455 EXPECT_GT(TraceBufferManager::GetInstance().GetTaskTotalUsedBytes(1), 0);
456 TraceBufferManager::GetInstance().ReleaseTaskBlocks(1);
457 ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
458 }
459
460 /**
461 * @tc.name: TraceSourceTest019
462 * @tc.desc: Test TraceSourceLinux class GetTraceCpuRawWrite function.
463 * @tc.type: FUNC
464 */
465 HWTEST_F(HitraceSourceTest, TraceSourceTest019, TestSize.Level2)
466 {
467 ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
468 std::string appArgs = "tags:sched,binder,ohos bufferSize:102400 overwrite:1";
469 EXPECT_EQ(OpenTrace(appArgs), TraceErrorCode::SUCCESS);
470 sleep(1);
471 std::shared_ptr<ITraceSource> traceSourceRead = nullptr;
472 std::shared_ptr<ITraceSource> traceSourceWrite = nullptr;
473 if (IsHmKernel()) {
474 traceSourceRead = std::make_shared<TraceSourceHM>(TRACEFS_DIR, "");
475 traceSourceWrite = std::make_shared<TraceSourceHM>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
476 } else {
477 traceSourceRead = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, "");
478 traceSourceWrite = std::make_shared<TraceSourceLinux>(TRACEFS_DIR, TEST_TRACE_TEMP_FILE);
479 }
480 EXPECT_TRUE(traceSourceRead != nullptr);
481 EXPECT_TRUE(traceSourceWrite != nullptr);
482 TraceDumpRequest request = { TraceDumpType::TRACE_SNAPSHOT, 0, false, 0, std::numeric_limits<uint64_t>::max(), 1 };
483 auto traceCpuRawRead = traceSourceRead->GetTraceCpuRawRead(request);
484 EXPECT_TRUE(traceCpuRawRead != nullptr);
485 EXPECT_TRUE(traceCpuRawRead->WriteTraceContent());
486 EXPECT_GT(TraceBufferManager::GetInstance().GetTaskTotalUsedBytes(1), 0);
487 auto traceCpuRawWrite = traceSourceWrite->GetTraceCpuRawWrite(1);
488 EXPECT_TRUE(traceCpuRawWrite != nullptr);
489 EXPECT_TRUE(traceCpuRawWrite->WriteTraceContent());
490 EXPECT_GT(GetFileSize(TEST_TRACE_TEMP_FILE), 0);
491 EXPECT_EQ(traceCpuRawRead->GetDumpStatus(), TraceErrorCode::SUCCESS);
492 TraceBufferManager::GetInstance().ReleaseTaskBlocks(1);
493 ASSERT_EQ(CloseTrace(), TraceErrorCode::SUCCESS);
494 if (remove(TEST_TRACE_TEMP_FILE) != 0) {
495 GTEST_LOG_(ERROR) << "Delete test trace file failed.";
496 }
497 }
498
499 /**
500 * @tc.name: TraceBufferManagerTest01
501 * @tc.desc: Test TraceBufferManager class AllocateBlock/GetTaskBuffers/GetCurrentTotalSize function.
502 * @tc.type: FUNC
503 */
504 HWTEST_F(HitraceSourceTest, TraceBufferManagerTest01, TestSize.Level2)
505 {
506 const uint64_t taskId = 1;
507 TraceBufferManager::GetInstance().AllocateBlock(taskId, 0);
508 EXPECT_EQ(TraceBufferManager::GetInstance().GetCurrentTotalSize(), DEFAULT_BLOCK_SZ);
509 TraceBufferManager::GetInstance().AllocateBlock(taskId, 0);
510 EXPECT_EQ(TraceBufferManager::GetInstance().GetCurrentTotalSize(), DEFAULT_BLOCK_SZ * 2); // 2 : 2 blocks
511 auto buffers = TraceBufferManager::GetInstance().GetTaskBuffers(1);
512 EXPECT_EQ(buffers.size(), 2);
513 for (auto& buf : buffers) {
514 EXPECT_NE(buf->data.data(), nullptr);
515 EXPECT_EQ(buf->usedBytes, 0);
516 }
517 TraceBufferManager::GetInstance().ReleaseTaskBlocks(taskId);
518 }
519
520 /**
521 * @tc.name: TraceBufferManagerTest02
522 * @tc.desc: Test TraceBufferManager class with multiple tasks and buffer sizes.
523 * @tc.type: FUNC
524 */
525 HWTEST_F(HitraceSourceTest, TraceBufferManagerTest02, TestSize.Level2)
526 {
527 // 测试多个任务的内存分配
528 const uint64_t taskId1 = 1;
529 const uint64_t taskId2 = 2;
530
531 // 为不同任务分配不同大小的缓冲区
532 TraceBufferManager::GetInstance().AllocateBlock(taskId1, 0);
533 TraceBufferManager::GetInstance().AllocateBlock(taskId2, 0);
534
535 // 验证任务1的缓冲区
536 auto buffers1 = TraceBufferManager::GetInstance().GetTaskBuffers(taskId1);
537 EXPECT_EQ(buffers1.size(), 1);
538 EXPECT_NE(buffers1.front()->data.data(), nullptr);
539 EXPECT_EQ(buffers1.front()->usedBytes, 0);
540
541 // 验证任务2的缓冲区
542 auto buffers2 = TraceBufferManager::GetInstance().GetTaskBuffers(taskId2);
543 EXPECT_EQ(buffers2.size(), 1);
544 EXPECT_NE(buffers2.front()->data.data(), nullptr);
545 EXPECT_EQ(buffers2.front()->usedBytes, 0);
546
547 // 验证总大小
548 size_t totalSize = TraceBufferManager::GetInstance().GetCurrentTotalSize();
549 EXPECT_EQ(totalSize, DEFAULT_BLOCK_SZ * 2); // 2 : 2 blocks
550
551 // 清理测试数据
552 TraceBufferManager::GetInstance().ReleaseTaskBlocks(taskId1);
553 TraceBufferManager::GetInstance().ReleaseTaskBlocks(taskId2);
554 }
555
556 /**
557 * @tc.name: TraceBufferManagerTest03
558 * @tc.desc: Test TraceBufferManager class with buffer size limits and overflow.
559 * @tc.type: FUNC
560 */
561 HWTEST_F(HitraceSourceTest, TraceBufferManagerTest03, TestSize.Level2)
562 {
563 const uint64_t taskId = 1;
564
565 // 测试正常大小分配
566 TraceBufferManager::GetInstance().AllocateBlock(taskId, 0);
567 auto buffers = TraceBufferManager::GetInstance().GetTaskBuffers(taskId);
568 EXPECT_EQ(buffers.size(), 1);
569 EXPECT_NE(buffers.front()->data.data(), nullptr);
570
571 // 测试溢出大小分配
572 for (int i = 0; i < 50; i++) { // 50 : try to allocate 50 blocks , 500MB
573 TraceBufferManager::GetInstance().AllocateBlock(taskId, 0);
574 }
575 buffers = TraceBufferManager::GetInstance().GetTaskBuffers(taskId);
576 EXPECT_EQ(buffers.size(), DEFAULT_MAX_TOTAL_SZ / DEFAULT_BLOCK_SZ);
577
578 // 验证总大小限制
579 size_t totalSize = TraceBufferManager::GetInstance().GetCurrentTotalSize();
580 EXPECT_LE(totalSize, DEFAULT_MAX_TOTAL_SZ); // 总大小不应超过最大限制的两倍
581
582 // 清理测试数据
583 TraceBufferManager::GetInstance().ReleaseTaskBlocks(taskId);
584 }
585
586 /**
587 * @tc.name: TraceBufferManagerTest04
588 * @tc.desc: Test TraceBufferManager class with task buffer reuse and cleanup.
589 * @tc.type: FUNC
590 */
591 HWTEST_F(HitraceSourceTest, TraceBufferManagerTest04, TestSize.Level2)
592 {
593 const uint64_t taskId = 1;
594
595 // 第一次分配
596 TraceBufferManager::GetInstance().AllocateBlock(taskId, 0);
597 auto buffers1 = TraceBufferManager::GetInstance().GetTaskBuffers(taskId);
598 EXPECT_EQ(buffers1.size(), 1);
599
600 // 清理缓冲区
601 TraceBufferManager::GetInstance().ReleaseTaskBlocks(taskId);
602 auto buffers2 = TraceBufferManager::GetInstance().GetTaskBuffers(taskId);
603 EXPECT_EQ(buffers2.size(), 0);
604
605 // 重新分配
606 TraceBufferManager::GetInstance().AllocateBlock(taskId, 0);
607 auto buffers3 = TraceBufferManager::GetInstance().GetTaskBuffers(taskId);
608 EXPECT_EQ(buffers3.size(), 1);
609 EXPECT_NE(buffers3.front()->data.data(), nullptr);
610 EXPECT_EQ(buffers3.front()->usedBytes, 0);
611
612 // 验证总大小
613 size_t totalSize = TraceBufferManager::GetInstance().GetCurrentTotalSize();
614 EXPECT_EQ(totalSize, DEFAULT_BLOCK_SZ);
615
616 // 清理测试数据
617 TraceBufferManager::GetInstance().ReleaseTaskBlocks(taskId);
618 }
619
620 /**
621 * @tc.name: TraceBufferManagerTest05
622 * @tc.desc: Test TraceBufferManager class with multi-thread buffer allocation.
623 * @tc.type: FUNC
624 */
625 HWTEST_F(HitraceSourceTest, TraceBufferManagerTest05, TestSize.Level2)
626 {
627 const int threadCount = 10;
628 const int allocPerThread = 5;
629 std::vector<std::thread> threads;
630 std::atomic<int> successCount(0);
631 for (int i = 0; i < threadCount; i++) {
__anon0a666d2d0302() 632 threads.emplace_back([i, &successCount]() {
633 const uint64_t taskId = i + 1;
634 int allocCount = 0;
635 for (int j = 0; j < allocPerThread; j++) {
636 auto block = TraceBufferManager::GetInstance().AllocateBlock(taskId, 0);
637 if (block != nullptr) {
638 allocCount++;
639 }
640 }
641 auto buffers = TraceBufferManager::GetInstance().GetTaskBuffers(taskId);
642 EXPECT_EQ(buffers.size(), allocCount);
643
644 successCount += allocCount;
645 });
646 }
647 for (auto& thread : threads) {
648 thread.join();
649 }
650 size_t totalSize = TraceBufferManager::GetInstance().GetCurrentTotalSize();
651 EXPECT_LE(totalSize, DEFAULT_MAX_TOTAL_SZ);
652 EXPECT_LE(successCount.load() * DEFAULT_BLOCK_SZ, DEFAULT_MAX_TOTAL_SZ);
653 for (int i = 0; i < threadCount; i++) {
654 TraceBufferManager::GetInstance().ReleaseTaskBlocks(i + 1);
655 }
656 }
657 } // namespace
658 } // namespace Hitrace
659 } // namespace HiviewDFX
660 } // namesapce OHOS