• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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