• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "perf_event_record_test.h"
17 
18 #include <cstring>
19 #include <thread>
20 
21 using namespace testing::ext;
22 
23 namespace OHOS {
24 namespace Developtools {
25 namespace HiPerf {
26 class PerfEventRecordTest : public testing::Test {
27 public:
28     static void SetUpTestCase(void);
29     static void TearDownTestCase(void);
30     void SetUp();
31     void TearDown();
32 
33     static constexpr size_t HEADER_SIZE = sizeof(perf_event_header);
34 };
35 
SetUpTestCase()36 void PerfEventRecordTest::SetUpTestCase() {}
37 
TearDownTestCase()38 void PerfEventRecordTest::TearDownTestCase() {}
39 
SetUp()40 void PerfEventRecordTest::SetUp() {}
41 
TearDown()42 void PerfEventRecordTest::TearDown() {}
43 
CompareByteStream(const uint8_t * a,const uint8_t * b,size_t size)44 static int CompareByteStream(const uint8_t *a, const uint8_t *b, size_t size)
45 {
46     for (size_t i = 0; i < size; i++) {
47         if (a[i] > b[i]) {
48             return (a[i] - b[i]);
49         } else if (a[i] < b[i]) {
50             return (int(a[i]) - int(b[i]));
51         }
52     }
53     return 0;
54 }
55 
56 /**
57  * @tc.name: Test
58  * @tc.desc:
59  * @tc.type: FUNC
60  */
61 const std::string RECORDNAME_MMAP = "mmap";
62 HWTEST_F(PerfEventRecordTest, Mmap, TestSize.Level1)
63 {
64     PerfRecordMmapData data {1, 2, 3, 4, 5, "testdatammap"};
65     PerfRecordMmap recordIn {true,     data.pid,   data.tid,     data.addr,
66                              data.len, data.pgoff, data.filename};
67 
68     ASSERT_EQ(recordIn.GetType(), PERF_RECORD_MMAP);
69     ASSERT_EQ(recordIn.GetName(), RECORDNAME_MMAP);
70     ASSERT_EQ(recordIn.GetMisc(), PERF_RECORD_MISC_KERNEL);
71     ASSERT_EQ(recordIn.GetHeaderSize(), HEADER_SIZE);
72 
73     std::vector<uint8_t> header;
74     recordIn.GetHeaderBinary(header);
75     std::vector<uint8_t> buff;
76     ASSERT_TRUE(recordIn.GetBinary(buff));
77     ASSERT_EQ(CompareByteStream(header.data(), buff.data(), HEADER_SIZE), 0);
78 
79     size_t buffSize = HEADER_SIZE + sizeof(PerfRecordMmapData) - KILO + strlen(data.filename) + 1;
80     ASSERT_EQ(recordIn.GetSize(), buffSize);
81 
82     PerfRecordMmap recordOut;
83     recordOut.Init(buff.data());
84     ASSERT_EQ(recordOut.GetType(), PERF_RECORD_MMAP);
85     ASSERT_EQ(recordOut.GetName(), RECORDNAME_MMAP);
86     ASSERT_EQ(recordOut.GetMisc(), PERF_RECORD_MISC_KERNEL);
87     ASSERT_EQ(recordOut.GetHeaderSize(), HEADER_SIZE);
88     ASSERT_EQ(recordOut.GetSize(), buffSize);
89     ASSERT_EQ(recordOut.data_.pid, data.pid);
90     ASSERT_EQ(recordOut.data_.tid, data.tid);
91     ASSERT_EQ(recordOut.data_.addr, data.addr);
92     ASSERT_EQ(recordOut.data_.len, data.len);
93     ASSERT_EQ(recordOut.data_.pgoff, data.pgoff);
94     ASSERT_EQ(strcmp(recordOut.data_.filename, data.filename), 0);
95 }
96 
97 const std::string RECORDNAME_MMAP2 = "mmap2";
98 HWTEST_F(PerfEventRecordTest, Mmap2, TestSize.Level1)
99 {
100     PerfRecordMmap2Data data {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, "testdatammap2"};
101     PerfRecordMmap2 recordIn {true,     data.pid, data.tid, data.addr, data.len,   data.pgoff,
102                               data.maj, data.min, data.ino, data.prot, data.flags, data.filename};
103 
104     ASSERT_EQ(recordIn.GetType(), PERF_RECORD_MMAP2);
105     ASSERT_EQ(recordIn.GetName(), RECORDNAME_MMAP2);
106     ASSERT_EQ(recordIn.GetMisc(), PERF_RECORD_MISC_KERNEL);
107     ASSERT_EQ(recordIn.GetHeaderSize(), HEADER_SIZE);
108 
109     std::vector<uint8_t> header;
110     recordIn.GetHeaderBinary(header);
111     std::vector<uint8_t> buff;
112     ASSERT_TRUE(recordIn.GetBinary(buff));
113     ASSERT_EQ(CompareByteStream(header.data(), buff.data(), HEADER_SIZE), 0);
114 
115     size_t buffSize = HEADER_SIZE + sizeof(PerfRecordMmap2Data) - KILO + strlen(data.filename) + 1;
116     ASSERT_EQ(recordIn.GetSize(), buffSize);
117 
118     PerfRecordMmap2 recordOut;
119     recordOut.Init(buff.data());
120     ASSERT_EQ(recordOut.GetType(), PERF_RECORD_MMAP2);
121     ASSERT_EQ(recordOut.GetName(), RECORDNAME_MMAP2);
122     ASSERT_EQ(recordOut.GetMisc(), PERF_RECORD_MISC_KERNEL);
123     ASSERT_EQ(recordOut.GetHeaderSize(), HEADER_SIZE);
124     ASSERT_EQ(recordOut.GetSize(), buffSize);
125     ASSERT_EQ(recordOut.data_.pid, data.pid);
126     ASSERT_EQ(recordOut.data_.tid, data.tid);
127     ASSERT_EQ(recordOut.data_.addr, data.addr);
128     ASSERT_EQ(recordOut.data_.len, data.len);
129     ASSERT_EQ(recordOut.data_.pgoff, data.pgoff);
130     ASSERT_EQ(recordOut.data_.maj, data.maj);
131     ASSERT_EQ(recordOut.data_.min, data.min);
132     ASSERT_EQ(recordOut.data_.ino, data.ino);
133     ASSERT_EQ(recordOut.data_.prot, data.prot);
134     ASSERT_EQ(recordOut.data_.flags, data.flags);
135     ASSERT_EQ(strcmp(recordOut.data_.filename, data.filename), 0);
136 }
137 
138 const std::string RECORDNAME_COMM = "comm";
139 HWTEST_F(PerfEventRecordTest, Comm, TestSize.Level1)
140 {
141     PerfRecordCommData data {1, 2, "testdatcomm"};
142     PerfRecordComm recordIn {true, data.pid, data.tid, data.comm};
143 
144     ASSERT_EQ(recordIn.GetType(), PERF_RECORD_COMM);
145     ASSERT_EQ(recordIn.GetName(), RECORDNAME_COMM);
146     ASSERT_EQ(recordIn.GetMisc(), PERF_RECORD_MISC_KERNEL);
147     ASSERT_EQ(recordIn.GetHeaderSize(), HEADER_SIZE);
148 
149     std::vector<uint8_t> header;
150     recordIn.GetHeaderBinary(header);
151     std::vector<uint8_t> buff;
152     ASSERT_TRUE(recordIn.GetBinary(buff));
153     ASSERT_EQ(CompareByteStream(header.data(), buff.data(), HEADER_SIZE), 0);
154 
155     size_t buffSize = HEADER_SIZE + sizeof(PerfRecordCommData) - KILO + strlen(data.comm) + 1;
156     ASSERT_EQ(recordIn.GetSize(), buffSize);
157     PerfRecordComm recordOut;
158     recordOut.Init(buff.data());
159     ASSERT_EQ(recordOut.GetType(), PERF_RECORD_COMM);
160     ASSERT_EQ(recordOut.GetName(), RECORDNAME_COMM);
161     ASSERT_EQ(recordOut.GetMisc(), PERF_RECORD_MISC_KERNEL);
162     ASSERT_EQ(recordOut.GetHeaderSize(), HEADER_SIZE);
163     ASSERT_EQ(recordOut.GetSize(), buffSize);
164     ASSERT_EQ(recordOut.data_.pid, data.pid);
165     ASSERT_EQ(recordOut.data_.tid, data.tid);
166     ASSERT_EQ(strcmp(recordOut.data_.comm, data.comm), 0);
167 }
168 
169 const std::string RECORDNAME_LOST = "lost";
170 HWTEST_F(PerfEventRecordTest, Lost, TestSize.Level1)
171 {
172     struct TestRecordLostst {
173         perf_event_header h;
174         PerfRecordLostData d;
175     };
176     TestRecordLostst data = {
177         {PERF_RECORD_LOST_SAMPLES, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordLostst)},
178         {1, 2}};
179 
180     PerfRecordLost record;
181     record.Init((uint8_t *)&data);
182     ASSERT_EQ(record.GetType(), PERF_RECORD_LOST_SAMPLES);
183     ASSERT_EQ(record.GetName(), RECORDNAME_LOST);
184     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
185     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
186     ASSERT_EQ(record.GetSize(), sizeof(data));
187 
188     std::vector<uint8_t> buff;
189     ASSERT_TRUE(record.GetBinary(buff));
190     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
191 }
192 
193 const std::string RECORDNAME_EXIT = "exit";
194 HWTEST_F(PerfEventRecordTest, Exit, TestSize.Level1)
195 {
196     struct TestRecordExitst {
197         perf_event_header h;
198         PerfRecordExitData d;
199     };
200     TestRecordExitst data = {{PERF_RECORD_EXIT, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordExitst)},
201                              {1, 2, 3, 4, 5}};
202 
203     PerfRecordExit record;
204     record.Init((uint8_t *)&data);
205     ASSERT_EQ(record.GetType(), PERF_RECORD_EXIT);
206     ASSERT_EQ(record.GetName(), RECORDNAME_EXIT);
207     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
208     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
209     ASSERT_EQ(record.GetSize(), sizeof(data));
210 
211     std::vector<uint8_t> buff;
212     ASSERT_TRUE(record.GetBinary(buff));
213     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
214 }
215 
216 const std::string RECORDNAME_THROTTLE = "throttle";
217 HWTEST_F(PerfEventRecordTest, Throttle, TestSize.Level1)
218 {
219     struct TestRecordThrottlest {
220         perf_event_header h;
221         PerfRecordThrottleData d;
222     };
223     TestRecordThrottlest data = {
224         {PERF_RECORD_THROTTLE, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordThrottlest)},
225         {1, 2, 3}};
226 
227     PerfRecordThrottle record;
228     record.Init((uint8_t *)&data);
229     ASSERT_EQ(record.GetType(), PERF_RECORD_THROTTLE);
230     ASSERT_EQ(record.GetName(), RECORDNAME_THROTTLE);
231     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
232     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
233     ASSERT_EQ(record.GetSize(), sizeof(data));
234 
235     std::vector<uint8_t> buff;
236     ASSERT_TRUE(record.GetBinary(buff));
237     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
238 }
239 
240 const std::string RECORDNAME_UNTHROTTLE = "unthrottle";
241 HWTEST_F(PerfEventRecordTest, Unthrottle, TestSize.Level1)
242 {
243     struct TestRecordUNThrottlest {
244         perf_event_header h;
245         PerfRecordThrottleData d;
246     };
247     TestRecordUNThrottlest data = {
248         {PERF_RECORD_UNTHROTTLE, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordUNThrottlest)},
249         {1, 2, 3}};
250 
251     PerfRecordUnthrottle record;
252     record.Init((uint8_t *)&data);
253     ASSERT_EQ(record.GetType(), PERF_RECORD_UNTHROTTLE);
254     ASSERT_EQ(record.GetName(), RECORDNAME_UNTHROTTLE);
255     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
256     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
257     ASSERT_EQ(record.GetSize(), sizeof(data));
258 
259     std::vector<uint8_t> buff;
260     ASSERT_TRUE(record.GetBinary(buff));
261     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
262 }
263 
264 const std::string RECORDNAME_FORK = "fork";
265 HWTEST_F(PerfEventRecordTest, Fork, TestSize.Level1)
266 {
267     struct TestRecordForkst {
268         perf_event_header h;
269         PerfRecordForkData d;
270     };
271     TestRecordForkst data = {{PERF_RECORD_FORK, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordForkst)},
272                              {1, 2, 3, 4, 5}};
273 
274     PerfRecordFork record;
275     record.Init((uint8_t *)&data);
276     ASSERT_EQ(record.GetType(), PERF_RECORD_FORK);
277     ASSERT_EQ(record.GetName(), RECORDNAME_FORK);
278     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
279     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
280     ASSERT_EQ(record.GetSize(), sizeof(data));
281 
282     std::vector<uint8_t> buff;
283     ASSERT_TRUE(record.GetBinary(buff));
284     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
285 }
286 
287 struct TestRecordSamplest {
288     perf_event_header header_;
289     PerfRecordSampleData data_;
290 };
291 
InitTestRecordSample(TestRecordSamplest & record)292 static void InitTestRecordSample(TestRecordSamplest &record)
293 {
294     record.header_.size = sizeof(perf_event_header);
295     record.header_.size +=
296         sizeof(record.data_.sample_id) + sizeof(record.data_.sample_id) + sizeof(record.data_.ip) +
297         sizeof(record.data_.pid) + sizeof(record.data_.tid) + sizeof(record.data_.time) +
298         sizeof(record.data_.addr) + sizeof(record.data_.id) + sizeof(record.data_.stream_id) +
299         sizeof(record.data_.cpu) + sizeof(record.data_.res) + sizeof(record.data_.period);
300 
301     // v??
302 
303     record.data_.nr = 0;
304     record.data_.ips = nullptr;
305     record.header_.size += sizeof(record.data_.nr);
306     record.data_.raw_size = 0;
307     record.data_.raw_data = nullptr;
308     record.header_.size += sizeof(record.data_.raw_size);
309     record.data_.bnr = 0;
310     record.data_.lbr = nullptr;
311     record.header_.size += sizeof(record.data_.bnr);
312     record.data_.user_abi = 0;
313     record.data_.reg_mask = 0;
314     record.header_.size += sizeof(record.data_.user_abi);
315     record.data_.stack_size = 0;
316     record.header_.size += sizeof(record.data_.stack_size);
317     // others
318 }
319 
CompareRecordSample50(const TestRecordSamplest & record,const std::vector<u8> & buf,size_t offset)320 static bool CompareRecordSample50(const TestRecordSamplest &record, const std::vector<u8> &buf,
321                                   size_t offset)
322 {
323     const uint8_t *p = buf.data() + offset;
324 
325     if (record.data_.nr != *(reinterpret_cast<const u64 *>(p))) {
326         return false;
327     }
328     p += sizeof(u64);
329 
330     if (record.data_.raw_size != *(reinterpret_cast<const u32 *>(p))) {
331         return false;
332     }
333     p += sizeof(u32);
334 
335     if (record.data_.bnr != *(reinterpret_cast<const u64 *>(p))) {
336         return false;
337     }
338     p += sizeof(u64);
339 
340     if (record.data_.user_abi != *(reinterpret_cast<const u64 *>(p))) {
341         return false;
342     }
343     p += sizeof(u64);
344 
345     if (record.data_.stack_size != *(reinterpret_cast<const u64 *>(p))) {
346         return false;
347     }
348     p += sizeof(u64);
349 
350     return true;
351 }
352 
CompareRecordSample(const TestRecordSamplest & record,const std::vector<u8> & buf)353 static bool CompareRecordSample(const TestRecordSamplest &record, const std::vector<u8> &buf)
354 {
355     if (buf.size() < record.header_.size) {
356         return false;
357     }
358     const uint8_t *p = buf.data();
359     p += sizeof(perf_event_header);
360 
361     if (record.data_.sample_id != *(reinterpret_cast<const u64 *>(p))) {
362         return false;
363     }
364     p += sizeof(u64);
365 
366     if (record.data_.ip != *(reinterpret_cast<const u64 *>(p))) {
367         return false;
368     }
369     p += sizeof(u64);
370 
371     if (record.data_.pid != *(reinterpret_cast<const u32 *>(p))) {
372         return false;
373     }
374     p += sizeof(u32);
375 
376     if (record.data_.tid != *(reinterpret_cast<const u32 *>(p))) {
377         return false;
378     }
379     p += sizeof(u32);
380 
381     if (record.data_.time != *(reinterpret_cast<const u64 *>(p))) {
382         return false;
383     }
384     p += sizeof(u64);
385 
386     if (record.data_.addr != *(reinterpret_cast<const u64 *>(p))) {
387         return false;
388     }
389     p += sizeof(u64);
390 
391     if (record.data_.id != *(reinterpret_cast<const u64 *>(p))) {
392         return false;
393     }
394     p += sizeof(u64);
395 
396     if (record.data_.stream_id != *(reinterpret_cast<const u64 *>(p))) {
397         return false;
398     }
399     p += sizeof(u64);
400 
401     if (record.data_.cpu != *(reinterpret_cast<const u32 *>(p))) {
402         return false;
403     }
404     p += sizeof(u32);
405 
406     if (record.data_.res != *(reinterpret_cast<const u32 *>(p))) {
407         return false;
408     }
409     p += sizeof(u32);
410 
411     if (record.data_.period != *(reinterpret_cast<const u64 *>(p))) {
412         return false;
413     }
414     p += sizeof(u64);
415 
416     return CompareRecordSample50(record, buf, p - buf.data());
417 }
418 
419 const std::string RECORDNAME_SAMPLE = "sample";
420 HWTEST_F(PerfEventRecordTest, Sample, TestSize.Level1)
421 {
422     perf_event_attr attr {};
423     attr.sample_type = UINT64_MAX;
424     TestRecordSamplest data = {
425         {PERF_RECORD_SAMPLE, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordSamplest)},
426         {}};
427     InitTestRecordSample(data);
428 
429     PerfRecordSample record;
430     record.Init((uint8_t *)&data, attr);
431     ASSERT_EQ(record.GetType(), PERF_RECORD_SAMPLE);
432     ASSERT_EQ(record.GetName(), RECORDNAME_SAMPLE);
433     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
434     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
435 
436     std::vector<uint8_t> buff;
437     ASSERT_TRUE(record.GetBinary(buff));
438     ASSERT_TRUE(CompareRecordSample(data, buff));
439 }
440 
441 HWTEST_F(PerfEventRecordTest, SampleReplaceWithCallStack1, TestSize.Level1)
442 {
443     perf_event_attr attr {};
444     attr.sample_type = UINT64_MAX;
445     TestRecordSamplest data = {
446         {PERF_RECORD_SAMPLE, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordSamplest)},
447         {}};
448     InitTestRecordSample(data);
449 
450     PerfRecordSample record;
451     record.Init((uint8_t *)&data, attr);
452     record.sampleType_ |= PERF_SAMPLE_REGS_USER;
453     record.sampleType_ |= PERF_SAMPLE_STACK_USER;
454     record.sampleType_ |= PERF_SAMPLE_CALLCHAIN;
455 
456     std::vector<u64> ips = {};
457     record.data_.ips = ips.data();
458     record.data_.nr = ips.size();
459     record.callFrames_ = {1, 2, 3, 4, 5, 6, 7, 8, 9};
460     record.ReplaceWithCallStack();
461     ASSERT_EQ(record.data_.reg_nr, 0u);
462     ASSERT_EQ(record.data_.user_abi, 0u);
463     ASSERT_EQ(record.data_.stack_size, 0u);
464     ASSERT_EQ(record.data_.dyn_size, 0u);
465 
466     // include PERF_CONTEXT_USER
467     ASSERT_EQ(record.callFrames_.size() + 1, record.data_.nr);
468     ASSERT_EQ(record.data_.ips[0], PERF_CONTEXT_USER);
469     for (size_t i = 1; i < record.data_.nr; i++) {
470         ASSERT_EQ(record.data_.ips[i], record.callFrames_.at(i - 1).pc);
471     }
472     // result is 1 - 9
473 }
474 
475 HWTEST_F(PerfEventRecordTest, SampleReplaceWithCallStack2, TestSize.Level1)
476 {
477     perf_event_attr attr {};
478     attr.sample_type = UINT64_MAX;
479     TestRecordSamplest data = {
480         {PERF_RECORD_SAMPLE, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordSamplest)},
481         {}};
482     InitTestRecordSample(data);
483 
484     PerfRecordSample record;
485     record.Init((uint8_t *)&data, attr);
486     record.sampleType_ |= PERF_SAMPLE_CALLCHAIN;
487 
488     std::vector<u64> ips = {};
489     record.data_.ips = ips.data();
490     record.data_.nr = ips.size();
491     record.callFrames_ = {1, 2, 3, 4, 5, 6, 7, 8, 9};
492     record.ReplaceWithCallStack();
493     // include PERF_CONTEXT_USER
494     ASSERT_EQ(record.callFrames_.size() + 1, record.data_.nr);
495     ASSERT_EQ(record.data_.ips[0], PERF_CONTEXT_USER);
496     for (size_t i = 1; i < record.data_.nr; i++) {
497         ASSERT_EQ(record.data_.ips[i], record.callFrames_.at(i - 1).pc);
498     }
499     // result is 1 - 9
500 }
501 
502 HWTEST_F(PerfEventRecordTest, SampleReplaceWithCallStack3, TestSize.Level1)
503 {
504     perf_event_attr attr {};
505     attr.sample_type = UINT64_MAX;
506     TestRecordSamplest data = {
507         {PERF_RECORD_SAMPLE, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordSamplest)},
508         {}};
509     InitTestRecordSample(data);
510 
511     PerfRecordSample record;
512     record.Init((uint8_t *)&data, attr);
513     record.sampleType_ |= PERF_SAMPLE_CALLCHAIN;
514 
515     record.callFrames_ = {4, 5, 6, 7, 8, 9};
516     std::vector<u64> ips = {0, 1, 2, 3};
517     record.data_.ips = ips.data();
518     record.data_.nr = ips.size();
519     record.ReplaceWithCallStack();
520     // include PERF_CONTEXT_USER
521     ASSERT_EQ(record.callFrames_.size() + ips.size() + 1, record.data_.nr);
522     for (size_t i = 0; i < ips.size(); i++) {
523         ASSERT_EQ(record.data_.ips[i], ips[i]);
524     }
525     ASSERT_EQ(record.data_.ips[ips.size()], PERF_CONTEXT_USER);
526     for (size_t i = 0; i < record.callFrames_.size(); i++) {
527         ASSERT_EQ(record.data_.ips[i + ips.size() + 1], record.callFrames_.at(i).pc);
528     }
529     // result is 0 - 3 , PERF_CONTEXT_USER , 4 - 9
530 }
531 
532 HWTEST_F(PerfEventRecordTest, SampleReplaceWithCallStack4, TestSize.Level1)
533 {
534     perf_event_attr attr {};
535     attr.sample_type = UINT64_MAX;
536     TestRecordSamplest data = {
537         {PERF_RECORD_SAMPLE, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordSamplest)},
538         {}};
539     InitTestRecordSample(data);
540 
541     PerfRecordSample record;
542     record.Init((uint8_t *)&data, attr);
543     record.sampleType_ |= PERF_SAMPLE_CALLCHAIN;
544 
545     record.callFrames_ = {};
546     std::vector<u64> ips = {0, 1, 2, 3};
547     record.data_.ips = ips.data();
548     record.data_.nr = ips.size();
549     record.ReplaceWithCallStack();
550     // not PERF_CONTEXT_USER will add
551     ASSERT_EQ(ips.size(), record.data_.nr);
552     for (size_t i = 0; i < record.data_.nr; i++) {
553         ASSERT_EQ(record.data_.ips[i], ips[i]);
554     }
555     // result is 0 - 3
556 }
557 
558 const std::string RECORDNAME_READ = "read";
559 HWTEST_F(PerfEventRecordTest, Read, TestSize.Level1)
560 {
561     struct PerfRecordReadst {
562         perf_event_header h;
563         PerfRecordReadData d;
564     };
565     PerfRecordReadst data = {{PERF_RECORD_READ, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordReadst)},
566                              {1, 2, {11, 12, 13, 14}}};
567 
568     PerfRecordRead record;
569     record.Init((uint8_t *)&data);
570     ASSERT_EQ(record.GetType(), PERF_RECORD_READ);
571     ASSERT_EQ(record.GetName(), RECORDNAME_READ);
572     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
573     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
574     ASSERT_EQ(record.GetSize(), sizeof(data));
575 
576     std::vector<uint8_t> buff;
577     ASSERT_TRUE(record.GetBinary(buff));
578     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
579 }
580 
581 const std::string RECORDNAME_AUX = "aux";
582 HWTEST_F(PerfEventRecordTest, Aux, TestSize.Level1)
583 {
584     struct PerfRecordAuxst {
585         perf_event_header h;
586         PerfRecordAuxData d;
587     };
588     PerfRecordAuxst data = {{PERF_RECORD_AUX, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordAuxst)},
589                             {1, 2, 3}};
590 
591     PerfRecordAux record;
592     record.Init((uint8_t *)&data);
593     ASSERT_EQ(record.GetType(), PERF_RECORD_AUX);
594     ASSERT_EQ(record.GetName(), RECORDNAME_AUX);
595     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
596     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
597     ASSERT_EQ(record.GetSize(), sizeof(data));
598 
599     std::vector<uint8_t> buff;
600     ASSERT_TRUE(record.GetBinary(buff));
601     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
602 }
603 
604 const std::string RECORDNAME_ITRACE_START = "itraceStart";
605 HWTEST_F(PerfEventRecordTest, ItraceStart, TestSize.Level1)
606 {
607     struct PerfRecordItraceStartst {
608         perf_event_header h;
609         PerfRecordItraceStartData d;
610     };
611     PerfRecordItraceStartst data = {
612         {PERF_RECORD_ITRACE_START, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordItraceStartst)},
613         {1, 2}};
614 
615     PerfRecordItraceStart record;
616     record.Init((uint8_t *)&data);
617     ASSERT_EQ(record.GetType(), PERF_RECORD_ITRACE_START);
618     ASSERT_EQ(record.GetName(), RECORDNAME_ITRACE_START);
619     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
620     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
621     ASSERT_EQ(record.GetSize(), sizeof(data));
622 
623     std::vector<uint8_t> buff;
624     ASSERT_TRUE(record.GetBinary(buff));
625     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
626 }
627 
628 const std::string RECORDNAME_LOST_SAMPLES = "lostSamples";
629 HWTEST_F(PerfEventRecordTest, LostSamples, TestSize.Level1)
630 {
631     struct PerfRecordLostSamplesst {
632         perf_event_header h;
633         PerfRecordLostSamplesData d;
634     };
635     PerfRecordLostSamplesst data = {
636         {PERF_RECORD_LOST_SAMPLES, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordLostSamplesst)},
637         {1}};
638 
639     PerfRecordLostSamples record;
640     record.Init((uint8_t *)&data);
641     ASSERT_EQ(record.GetType(), PERF_RECORD_LOST_SAMPLES);
642     ASSERT_EQ(record.GetName(), RECORDNAME_LOST_SAMPLES);
643     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
644     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
645     ASSERT_EQ(record.GetSize(), sizeof(data));
646 
647     std::vector<uint8_t> buff;
648     ASSERT_TRUE(record.GetBinary(buff));
649     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
650 }
651 
652 const std::string RECORDNAME_SWITCH = "switch";
653 HWTEST_F(PerfEventRecordTest, Switch, TestSize.Level1)
654 {
655     struct PerfRecordSwitchst {
656         perf_event_header h;
657         PerfRecordSwitchData d;
658     };
659     PerfRecordSwitchst data = {
660         {PERF_RECORD_SWITCH, PERF_RECORD_MISC_KERNEL, sizeof(perf_event_header)},
661         {}};
662 
663     PerfRecordSwitch record;
664     record.Init((uint8_t *)&data);
665     ASSERT_EQ(record.GetType(), PERF_RECORD_SWITCH);
666     ASSERT_EQ(record.GetName(), RECORDNAME_SWITCH);
667     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
668     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
669     ASSERT_EQ(record.GetSize(), HEADER_SIZE);
670 
671     std::vector<uint8_t> buff;
672     ASSERT_TRUE(record.GetBinary(buff));
673     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), HEADER_SIZE), 0);
674 }
675 
676 const std::string RECORDNAME_SWITCH_CPU_WIDE = "switchCpuWide";
677 HWTEST_F(PerfEventRecordTest, SwitchCpuWide, TestSize.Level1)
678 {
679     struct PerfRecordSwitchCpuWidest {
680         perf_event_header h;
681         PerfRecordSwitchCpuWideData d;
682     };
683     PerfRecordSwitchCpuWidest data = {
684         {PERF_RECORD_SWITCH_CPU_WIDE, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordSwitchCpuWidest)},
685         {}};
686 
687     PerfRecordSwitchCpuWide record;
688     record.Init((uint8_t *)&data);
689     ASSERT_EQ(record.GetType(), PERF_RECORD_SWITCH_CPU_WIDE);
690     ASSERT_EQ(record.GetName(), RECORDNAME_SWITCH_CPU_WIDE);
691     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
692     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
693     ASSERT_EQ(record.GetSize(), sizeof(data));
694 
695     std::vector<uint8_t> buff;
696     ASSERT_TRUE(record.GetBinary(buff));
697     ASSERT_EQ(CompareByteStream((uint8_t *)&data, buff.data(), sizeof(data)), 0);
698 }
699 
700 HWTEST_F(PerfEventRecordTest, GetPerfEventRecord, TestSize.Level1)
701 {
702     struct PerfRecordSwitchCpuWidest {
703         perf_event_header h;
704         PerfRecordSwitchCpuWideData d;
705     };
706     PerfRecordSwitchCpuWidest data = {
707         {PERF_RECORD_SWITCH_CPU_WIDE, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordSwitchCpuWidest)},
708         {}};
709     perf_event_attr attr {};
710     attr.sample_type = UINT64_MAX;
711     for (size_t type = PERF_RECORD_MMAP; type <= PERF_RECORD_MAX; type++) {
712         if (type == PERF_RECORD_SAMPLE) {
713             continue;
714         }
715         PerfEventRecord& perfEventRecord =
716             PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(type),
717                                                        reinterpret_cast<uint8_t *>(&data), attr);
718         if (type < PERF_RECORD_NAMESPACES) {
719             ASSERT_EQ(perfEventRecord.GetName() != nullptr, true);
720         }
721     }
722     PerfEventRecord& perfEventRecord =
723         PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(PERF_RECORD_AUXTRACE),
724                                                    reinterpret_cast<uint8_t *>(&data), attr);
725     ASSERT_EQ(perfEventRecord.GetName() != nullptr, true);
726 }
727 
728 HWTEST_F(PerfEventRecordTest, GetPerfEventRecord2, TestSize.Level1)
729 {
730     struct PerfRecordSwitchCpuWidest {
731         perf_event_header h;
732         PerfRecordSwitchCpuWideData d;
733     };
734     PerfRecordSwitchCpuWidest data = {
735         {PERF_RECORD_SWITCH_CPU_WIDE, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordSwitchCpuWidest)},
736         {}};
737     perf_event_attr attr {};
738     attr.sample_type = UINT64_MAX;
739     PerfEventRecord& perfEventRecord1 =
740         PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(PERF_RECORD_AUXTRACE),
741                                                    reinterpret_cast<uint8_t *>(&data), attr);
742     PerfEventRecord& perfEventRecord2 =
743         PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(PERF_RECORD_AUXTRACE),
744                                                    reinterpret_cast<uint8_t *>(&data), attr);
745 
746     ASSERT_TRUE(&perfEventRecord1 == &perfEventRecord2);
747 }
748 
749 HWTEST_F(PerfEventRecordTest, GetPerfEventRecord3, TestSize.Level1)
750 {
751     struct PerfRecordSwitchCpuWidest {
752         perf_event_header h;
753         PerfRecordSwitchCpuWideData d;
754     };
755     PerfRecordSwitchCpuWidest data = {
756         {PERF_RECORD_SWITCH_CPU_WIDE, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordSwitchCpuWidest)},
757         {}};
758     perf_event_attr attr {};
759     attr.sample_type = UINT64_MAX;
760     PerfEventRecord& perfEventRecord1 =
761         PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(PERF_RECORD_AUXTRACE),
762                                                    reinterpret_cast<uint8_t *>(&data), attr);
763     PerfEventRecord& perfEventRecord2 =
764         PerfEventRecordFactory::GetPerfEventRecord(INT32_MAX,
765                                                    reinterpret_cast<uint8_t *>(&data), attr);
766     ASSERT_TRUE(perfEventRecord1.GetName() != nullptr);
767     ASSERT_TRUE(perfEventRecord2.GetName() == nullptr);
768 }
769 
770 HWTEST_F(PerfEventRecordTest, GetPerfEventRecord4, TestSize.Level1)
771 {
772     static constexpr size_t sizeOffset = 20;
773     std::vector<PerfRecordType> types = {
774         PERF_RECORD_MMAP,
775         PERF_RECORD_MMAP2,
776         PERF_RECORD_LOST,
777         PERF_RECORD_COMM,
778         PERF_RECORD_EXIT,
779         PERF_RECORD_THROTTLE,
780         PERF_RECORD_UNTHROTTLE,
781         PERF_RECORD_FORK,
782         PERF_RECORD_READ,
783         PERF_RECORD_AUX,
784         PERF_RECORD_AUXTRACE,
785         PERF_RECORD_ITRACE_START,
786         PERF_RECORD_LOST_SAMPLES,
787         PERF_RECORD_SWITCH,
788         PERF_RECORD_SWITCH_CPU_WIDE
789     };
790     perf_event_header header;
791     size_t size = sizeof(perf_event_header) + sizeOffset;
792     header.size = size;
793     uint8_t* data = static_cast<uint8_t*>(malloc(size));
794     ASSERT_EQ(memset_s(data, size, 0, size), 0);
795     ASSERT_EQ(memcpy_s(data, sizeof(perf_event_header),
796         reinterpret_cast<uint8_t*>(&header), sizeof(perf_event_header)), 0);
797     for (PerfRecordType type : types) {
798         perf_event_attr attr = {};
799         PerfEventRecord& record =
800             PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(type),
801                                                        data, attr);
802         EXPECT_NE(record.GetName(), nullptr);
803     }
804     free(data);
805 }
806 
807 HWTEST_F(PerfEventRecordTest, GetPerfEventRecordMmap2, TestSize.Level1)
808 {
809     struct PerfRecordMmap2est {
810         perf_event_header h;
811         PerfRecordMmap2Data d;
812     };
813     constexpr uint32_t pid = 10;
814     constexpr uint32_t tid = 11;
815     constexpr uint32_t testNum1 = 12;
816     constexpr uint64_t addr = 111;
817     constexpr uint64_t testNum2 = 13;
818     PerfRecordMmap2est data = {
819         {PERF_RECORD_MMAP2, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordMmap2est)},
820         {pid, tid, addr, testNum2, testNum2, testNum1, testNum1, testNum2, testNum2,
821          testNum1, testNum1, "testdatammap2"}};
822     size_t size = HEADER_SIZE + sizeof(PerfRecordMmap2Data) - KILO + strlen(data.d.filename) + 1;
823     data.h.size = size;
824     perf_event_attr attr {};
825     attr.sample_type = UINT64_MAX;
826     PerfEventRecord& perfEventRecord1 =
827         PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(PERF_RECORD_MMAP2),
828                                                    reinterpret_cast<uint8_t *>(&data), attr);
829     PerfRecordMmap2& record1 = static_cast<PerfRecordMmap2&>(perfEventRecord1);
830     EXPECT_EQ(record1.discard_, false);
831     record1.discard_ = true;
832     PerfEventRecord& perfEventRecord2 =
833         PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(PERF_RECORD_MMAP2),
834                                                    reinterpret_cast<uint8_t *>(&data), attr);
835     PerfRecordMmap2& record2 = static_cast<PerfRecordMmap2&>(perfEventRecord2);
836     EXPECT_EQ(record2.discard_, false);
837     EXPECT_EQ(record2.GetType(), PERF_RECORD_MMAP2);
838     EXPECT_EQ(record2.GetName(), RECORDNAME_MMAP2);
839     EXPECT_EQ(record2.GetMisc(), PERF_RECORD_MISC_KERNEL);
840     EXPECT_EQ(record2.GetHeaderSize(), HEADER_SIZE);
841     EXPECT_EQ(record2.GetSize(), size);
842     EXPECT_EQ(record2.data_.pid, data.d.pid);
843     EXPECT_EQ(record2.data_.tid, data.d.tid);
844     EXPECT_EQ(record2.data_.addr, data.d.addr);
845     EXPECT_EQ(record2.data_.len, data.d.len);
846     EXPECT_EQ(record2.data_.pgoff, data.d.pgoff);
847     EXPECT_EQ(record2.data_.maj, data.d.maj);
848     EXPECT_EQ(record2.data_.min, data.d.min);
849     EXPECT_EQ(record2.data_.ino, data.d.ino);
850     EXPECT_EQ(record2.data_.prot, data.d.prot);
851     EXPECT_EQ(record2.data_.flags, data.d.flags);
852     EXPECT_EQ(strcmp(record2.data_.filename, data.d.filename), 0);
853 }
854 
855 HWTEST_F(PerfEventRecordTest, MultiThreadGetPerfEventRecord, TestSize.Level1)
856 {
857     struct PerfRecordSwitchCpuWidest {
858         perf_event_header h;
859         PerfRecordSwitchCpuWideData d;
860     };
861     PerfRecordSwitchCpuWidest data = {
862         {PERF_RECORD_SWITCH_CPU_WIDE, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordSwitchCpuWidest)},
863         {}};
864     perf_event_attr attr {};
865     attr.sample_type = UINT64_MAX;
866     PerfEventRecord& perfEventRecord1 =
867         PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(PERF_RECORD_AUXTRACE),
868                                                    reinterpret_cast<uint8_t *>(&data), attr);
869 
__anon5b235bed0102() 870     std::thread t1([&perfEventRecord1, &data, attr]() {
871         PerfEventRecord& perfEventRecord2 =
872             PerfEventRecordFactory::GetPerfEventRecord(static_cast<perf_event_type>(PERF_RECORD_AUXTRACE),
873                                                        reinterpret_cast<uint8_t *>(&data), attr);
874         ASSERT_TRUE(&perfEventRecord1 != &perfEventRecord2);
875     });
876     t1.join();
877 }
878 
879 HWTEST_F(PerfEventRecordTest, CreatePerfRecordMmap, TestSize.Level1)
880 {
881     perf_event_header header;
882     header.size = sizeof(PerfRecordMmapData) + sizeof(perf_event_header);
883     PerfRecordMmapData data;
884     for (uint32_t i = 0; i < KILO; i++) {
885         data.filename[i] = 'a';
886     }
887     size_t size = sizeof(PerfRecordMmapData) + sizeof(perf_event_header) + 10;
888     uint8_t* p = static_cast<uint8_t*>(malloc(size));
889     ASSERT_EQ(memset_s(p, size, 5, size), 0);
890     ASSERT_EQ(memcpy_s(p, sizeof(perf_event_header),
891         reinterpret_cast<uint8_t*>(&header), sizeof(perf_event_header)), 0);
892     ASSERT_EQ(memcpy_s(p + sizeof(perf_event_header), sizeof(PerfRecordMmapData),
893         reinterpret_cast<uint8_t*>(&data), sizeof(PerfRecordMmapData)), 0);
894 
895     PerfRecordMmap record;
896     record.Init(p);
897     std::string str = record.data_.filename;
898     ASSERT_EQ(str.size(), KILO - 1);
899     for (char c : str) {
900         EXPECT_EQ(c, 'a');
901     }
902     free(p);
903 }
904 
905 HWTEST_F(PerfEventRecordTest, CreatePerfRecordComm, TestSize.Level1)
906 {
907     perf_event_header header;
908     header.size = sizeof(PerfRecordCommData) + sizeof(perf_event_header);
909     PerfRecordCommData data;
910     for (uint32_t i = 0; i < KILO; i++) {
911         data.comm[i] = 'a';
912     }
913     size_t size = sizeof(PerfRecordCommData) + sizeof(perf_event_header) + 10;
914     uint8_t* p = static_cast<uint8_t*>(malloc(size));
915     ASSERT_EQ(memset_s(p, size, 5, size), 0);
916     ASSERT_EQ(memcpy_s(p, sizeof(perf_event_header),
917         reinterpret_cast<uint8_t*>(&header), sizeof(perf_event_header)), 0);
918     ASSERT_EQ(memcpy_s(p + sizeof(perf_event_header), sizeof(PerfRecordCommData),
919         reinterpret_cast<uint8_t*>(&data), sizeof(PerfRecordCommData)), 0);
920 
921     PerfRecordComm record;
922     record.Init(p);
923     std::string str = record.data_.comm;
924     ASSERT_EQ(str.size(), KILO - 1);
925     for (char c : str) {
926         EXPECT_EQ(c, 'a');
927     }
928     free(p);
929 }
930 
931 HWTEST_F(PerfEventRecordTest, CreatePerfRecordAuxtrace, TestSize.Level1)
932 {
933     perf_event_header header;
934     const char* rawData = "rawData";
935     size_t len = strlen(rawData) + 1;
936     header.size = sizeof(PerfRecordAuxtraceData) + sizeof(perf_event_header);
937     PerfRecordAuxtraceData data;
938     uint8_t* p = static_cast<uint8_t*>(malloc(header.size + len));
939     EXPECT_EQ(memset_s(p, header.size + len, 0, header.size + len), 0);
940     if (memcpy_s(p, sizeof(perf_event_header), reinterpret_cast<const uint8_t *>(&header),
941                  sizeof(perf_event_header)) != 0) {
942         printf("memcpy_s perf_event_header return failed");
943     }
944     if (memcpy_s(p + sizeof(perf_event_header), sizeof(PerfRecordAuxtraceData),
945                  reinterpret_cast<const uint8_t *>(&data), sizeof(PerfRecordAuxtraceData)) != 0) {
946         printf("memcpy_s data return failed");
947     }
948     if (memcpy_s(p + header.size, len, reinterpret_cast<const uint8_t *>(rawData), len) != 0) {
949         printf("memcpy_s rawData return failed");
950     }
951     PerfRecordAuxtrace record;
952     record.Init(p);
953     ASSERT_NE(record.rawData_, nullptr);
954     free(p);
955 }
956 
957 HWTEST_F(PerfEventRecordTest, CreatePerfRecordAuxtrace2, TestSize.Level1)
958 {
959     PerfRecordAuxtrace* record = new PerfRecordAuxtrace();
960     record->Init(nullptr, {});
961 
962     EXPECT_EQ(record->header_.type, PERF_RECORD_MMAP);
963     EXPECT_EQ(record->header_.misc, PERF_RECORD_MISC_USER);
964     EXPECT_EQ(record->header_.size, 0);
965 
966     EXPECT_EQ(record->data_.size, 0);
967     EXPECT_EQ(record->data_.offset, 0);
968     EXPECT_EQ(record->data_.reference, 0);
969     EXPECT_EQ(record->data_.idx, 0);
970     EXPECT_EQ(record->data_.tid, 0);
971     EXPECT_EQ(record->data_.cpu, 0);
972     EXPECT_EQ(record->data_.reserved__, 0);
973 
974     EXPECT_EQ(record->rawData_, nullptr);
975 }
976 
977 HWTEST_F(PerfEventRecordTest, CreatePerfRecordAuxtrace3, TestSize.Level1)
978 {
979     PerfRecordAuxtrace* record = new PerfRecordAuxtrace();
980     record->Init(nullptr, {});
981     record->header_.type = PERF_RECORD_AUXTRACE;
982     record->header_.misc = PERF_RECORD_MISC_KERNEL;
983     record->header_.size = PERF_RECORD_AUXTRACE;
984     record->data_.size = 1;
985     record->data_.offset = 1;
986     record->data_.reference = 1;
987     record->data_.idx = 1;
988     record->data_.tid = 1;
989     record->data_.cpu = 1;
990     record->data_.reserved__ = 1;
991     std::shared_ptr<u8> ptr = std::make_shared<u8>();
992     record->rawData_ = ptr.get();
993 
994     record->Init(nullptr, {});
995     EXPECT_EQ(record->header_.type, PERF_RECORD_MMAP);
996     EXPECT_EQ(record->header_.misc, PERF_RECORD_MISC_USER);
997     EXPECT_EQ(record->header_.size, 0);
998 
999     EXPECT_EQ(record->data_.size, 0);
1000     EXPECT_EQ(record->data_.offset, 0);
1001     EXPECT_EQ(record->data_.reference, 0);
1002     EXPECT_EQ(record->data_.idx, 0);
1003     EXPECT_EQ(record->data_.tid, 0);
1004     EXPECT_EQ(record->data_.cpu, 0);
1005     EXPECT_EQ(record->data_.reserved__, 0);
1006 
1007     EXPECT_EQ(record->rawData_, nullptr);
1008 }
1009 
1010 HWTEST_F(PerfEventRecordTest, CreatePerfRecordSample, TestSize.Level1)
1011 {
1012     pid_t pid = fork();
1013     ASSERT_NE(pid, -1);
1014 
1015     if (pid == 0) {
1016         PerfRecordSample record;
1017         perf_event_attr attr = {};
1018         attr.sample_type = PERF_SAMPLE_CALLCHAIN + PERF_SAMPLE_RAW + PERF_SAMPLE_BRANCH_STACK + PERF_SAMPLE_REGS_USER;
1019         std::vector<uint8_t> data = {};
1020         data.resize(200);
1021         for (auto i = 0; i < 200; i++) {
1022             data[i] = UINT8_MAX;
1023         }
1024         record.Init(data.data(), attr);
1025         _exit(-2);
1026     } else {
1027         int status = 0;
1028         waitpid(pid, &status, 0);
1029         ASSERT_TRUE(WIFEXITED(status));
1030         EXPECT_EQ(WEXITSTATUS(status), static_cast<uint8_t>(-1));
1031     }
1032 }
1033 
1034 HWTEST_F(PerfEventRecordTest, SetDumpRemoveStack, TestSize.Level1)
1035 {
1036     bool dump = PerfRecordSample::IsDumpRemoveStack();
1037     PerfRecordSample::SetDumpRemoveStack(!dump);
1038     EXPECT_EQ(PerfRecordSample::IsDumpRemoveStack(), !dump);
1039     PerfRecordSample::SetDumpRemoveStack(dump);
1040     EXPECT_EQ(PerfRecordSample::IsDumpRemoveStack(), dump);
1041 }
1042 
1043 HWTEST_F(PerfEventRecordTest, GetTime, TestSize.Level1)
1044 {
1045     static constexpr uint64_t time = 1234u;
1046     PerfRecordSample sample;
1047     sample.data_.time = time;
1048     EXPECT_EQ(sample.GetTime(), time);
1049 }
1050 
1051 HWTEST_F(PerfEventRecordTest, AuxTraceInfo, TestSize.Level1)
1052 {
1053     constexpr uint32_t type    = 4;
1054     constexpr uint32_t reserve = 0;
1055     constexpr uint64_t speType = 7;
1056     constexpr uint64_t cpuMmap = 2;
1057     struct PerfRecordAuxTraceInfost {
1058         perf_event_header h;
1059         PerfRecordAuxtraceInfoData d;
1060     };
1061     PerfRecordAuxTraceInfost data = {{PERF_RECORD_AUXTRACE_INFO, PERF_RECORD_MISC_KERNEL,
1062                                      static_cast<uint16_t>(sizeof(PerfRecordAuxTraceInfost))},
1063                                      {type, reserve, {speType, cpuMmap}}};
1064 
1065     PerfRecordAuxTraceInfo record;
1066     record.Init((uint8_t *)&data);
1067     ASSERT_EQ(record.GetType(), PERF_RECORD_AUXTRACE_INFO);
1068     ASSERT_EQ(record.GetName(), PERF_RECORD_TYPE_AUXTRACEINFO);
1069     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
1070     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
1071     ASSERT_EQ(record.GetSize(), sizeof(data));
1072     ASSERT_EQ(record.data_.type, type);
1073     ASSERT_EQ(record.data_.priv[0], speType);
1074     ASSERT_EQ(record.data_.priv[1], cpuMmap);
1075 }
1076 
1077 HWTEST_F(PerfEventRecordTest, TimeConv, TestSize.Level1)
1078 {
1079     constexpr uint64_t timeShift = 21;
1080     constexpr uint64_t timeDefalult = 1;
1081     constexpr uint8_t userTime = 1;
1082     struct PerfRecordTimeConvst {
1083         perf_event_header h;
1084         PerfRecordTtimeConvData d;
1085     };
1086     PerfRecordTimeConvst data = {{PERF_RECORD_TIME_CONV, PERF_RECORD_MISC_KERNEL,
1087                                  static_cast<uint16_t>(sizeof(PerfRecordTimeConvst))},
1088                                  {timeShift, timeDefalult, timeDefalult, timeDefalult, timeDefalult, userTime}};
1089 
1090     PerfRecordTimeConv record;
1091     record.Init((uint8_t *)&data);
1092     ASSERT_EQ(record.GetType(), PERF_RECORD_TIME_CONV);
1093     ASSERT_EQ(record.GetName(), PERF_RECORD_TYPE_TIMECONV);
1094     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
1095     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
1096     ASSERT_EQ(record.GetSize(), sizeof(data));
1097     ASSERT_EQ(record.data_.time_shift, timeShift);
1098     ASSERT_EQ(record.data_.time_mult, timeDefalult);
1099 }
1100 
1101 HWTEST_F(PerfEventRecordTest, CpuMap, TestSize.Level1)
1102 {
1103     constexpr uint16_t type = 0;
1104     constexpr uint16_t cpuNum = 16;
1105     struct PerfRecordCpuMapst {
1106         perf_event_header h;
1107         PerfRecordCpuMapData d;
1108     };
1109     PerfRecordCpuMapst data = {{PERF_RECORD_CPU_MAP, PERF_RECORD_MISC_KERNEL,
1110                                static_cast<uint16_t>(sizeof(PerfRecordCpuMapst))},
1111                                {type, cpuNum}};
1112 
1113     PerfRecordCpuMap record;
1114     record.Init((uint8_t *)&data);
1115     ASSERT_EQ(record.GetType(), PERF_RECORD_CPU_MAP);
1116     ASSERT_EQ(record.GetName(), PERF_RECORD_TYPE_CPUMAP);
1117     ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL);
1118     ASSERT_EQ(record.GetHeaderSize(), HEADER_SIZE);
1119     ASSERT_EQ(record.GetSize(), sizeof(data));
1120     ASSERT_EQ(record.data_.nr, cpuNum);
1121 }
1122 
1123 HWTEST_F(PerfEventRecordTest, AuxtraceInit, TestSize.Level1)
1124 {
1125     const char* rawData = "rawData";
1126     size_t len = strlen(rawData) + 1;
1127     perf_event_header header;
1128     header.size = sizeof(PerfRecordAuxtraceData) + sizeof(perf_event_header);
1129     header.type = PERF_RECORD_AUXTRACE;
1130     header.misc = PERF_RECORD_MISC_USER;
1131     PerfRecordAuxtraceData data;
1132     uint8_t* p = static_cast<uint8_t*>(malloc(header.size + len));
1133     EXPECT_EQ(memset_s(p, header.size + len, 0, header.size + len), 0);
1134     if (memcpy_s(p, sizeof(perf_event_header), reinterpret_cast<const uint8_t *>(&header),
1135                  sizeof(perf_event_header)) != 0) {
1136         printf("memcpy_s perf_event_header return failed");
1137     }
1138     if (memcpy_s(p + sizeof(perf_event_header), sizeof(PerfRecordAuxtraceData),
1139                  reinterpret_cast<const uint8_t *>(&data), sizeof(PerfRecordAuxtraceData)) != 0) {
1140         printf("memcpy_s data return failed");
1141     }
1142     if (memcpy_s(p + header.size, len, reinterpret_cast<const uint8_t *>(rawData), len) != 0) {
1143         printf("memcpy_s rawData return failed");
1144     }
1145     PerfRecordAuxtrace record;
1146     record.Init(p);
1147     ASSERT_NE(record.rawData_, nullptr);
1148     EXPECT_EQ(strcmp(reinterpret_cast<char*>(record.rawData_), "rawData"), 0);
1149     EXPECT_EQ(record.header_.type, PERF_RECORD_AUXTRACE);
1150     EXPECT_EQ(record.header_.misc, PERF_RECORD_MISC_USER);
1151     EXPECT_EQ(record.header_.size, sizeof(PerfRecordAuxtraceData) + sizeof(perf_event_header));
1152     EXPECT_EQ(record.data_.size, 0);
1153     EXPECT_EQ(record.data_.offset, 0);
1154     EXPECT_EQ(record.data_.reference, 0);
1155     EXPECT_EQ(record.data_.idx, 0);
1156     EXPECT_EQ(record.data_.tid, 0);
1157     EXPECT_EQ(record.data_.cpu, 0);
1158     EXPECT_EQ(record.data_.reserved__, 0);
1159     free(p);
1160 }
1161 
1162 HWTEST_F(PerfEventRecordTest, GetBinary1, TestSize.Level1)
1163 {
1164     const char* rawData = "rawData";
1165     size_t len = strlen(rawData) + 1;
1166     perf_event_header header;
1167     header.size = sizeof(PerfRecordAuxtraceData) + sizeof(perf_event_header);
1168     header.type = PERF_RECORD_AUXTRACE;
1169     header.misc = PERF_RECORD_MISC_USER;
1170     PerfRecordAuxtraceData data;
1171     data.cpu = 1;
1172     data.idx = 1;
1173     data.offset = 2;
1174     data.reference = 2;
1175     data.reserved__ = 2;
1176     data.size = 1;
1177     data.tid = 1;
1178     uint8_t* p = static_cast<uint8_t*>(malloc(header.size + len));
1179     EXPECT_EQ(memset_s(p, header.size + len, 0, header.size + len), 0);
1180     EXPECT_EQ(memcpy_s(p, sizeof(perf_event_header), reinterpret_cast<const uint8_t *>(&header),
1181                  sizeof(perf_event_header)), 0);
1182     EXPECT_EQ(memcpy_s(p + sizeof(perf_event_header), sizeof(PerfRecordAuxtraceData),
1183                  reinterpret_cast<const uint8_t *>(&data), sizeof(PerfRecordAuxtraceData)), 0);
1184     EXPECT_EQ(memcpy_s(p + header.size, len, reinterpret_cast<const uint8_t *>(rawData), len), 0);
1185     PerfRecordAuxtrace record;
1186     PerfRecordAuxtrace recordCopy;
1187     record.Init(p);
1188     std::vector<u8> buf;
1189     ASSERT_TRUE(record.GetBinary1(buf));
1190     EXPECT_LT(buf.size(), record.GetSize());
1191     ASSERT_EQ(CompareByteStream(p, buf.data(), buf.size()), 0);
1192     recordCopy.Init(buf.data());
1193     EXPECT_EQ(recordCopy.header_.type, PERF_RECORD_AUXTRACE);
1194     EXPECT_EQ(recordCopy.header_.misc, PERF_RECORD_MISC_USER);
1195     EXPECT_EQ(recordCopy.header_.size, sizeof(PerfRecordAuxtraceData) + sizeof(perf_event_header));
1196     EXPECT_EQ(recordCopy.data_.size, 1);
1197     EXPECT_EQ(recordCopy.data_.offset, 2);
1198     EXPECT_EQ(recordCopy.data_.reference, 2);
1199     EXPECT_EQ(recordCopy.data_.idx, 1);
1200     EXPECT_EQ(recordCopy.data_.tid, 1);
1201     EXPECT_EQ(recordCopy.data_.cpu, 1);
1202     EXPECT_EQ(recordCopy.data_.reserved__, 2);
1203     free(p);
1204 }
1205 
1206 HWTEST_F(PerfEventRecordTest, AuxtraceInitErr, TestSize.Level1)
1207 {
1208     perf_event_header header;
1209     header.size = sizeof(PerfRecordAuxtraceData) + sizeof(perf_event_header) - 1;
1210     header.type = PERF_RECORD_AUXTRACE;
1211     header.misc = PERF_RECORD_MISC_USER;
1212     PerfRecordAuxtraceData data;
1213     uint8_t* p = static_cast<uint8_t*>(malloc(header.size));
1214     EXPECT_EQ(memset_s(p, header.size, 0, header.size), 0);
1215     if (memcpy_s(p, sizeof(perf_event_header), reinterpret_cast<const uint8_t *>(&header),
1216                  sizeof(perf_event_header)) != 0) {
1217         printf("memcpy_s perf_event_header return failed");
1218     }
1219     if (memcpy_s(p + sizeof(perf_event_header), sizeof(PerfRecordAuxtraceData),
1220                  reinterpret_cast<const uint8_t *>(&data), sizeof(PerfRecordAuxtraceData)) != 0) {
1221         printf("memcpy_s data return failed");
1222     }
1223     PerfRecordAuxtrace record;
1224     record.Init(p);
1225     EXPECT_EQ(record.rawData_, nullptr);
1226     EXPECT_NE(record.header_.size, sizeof(PerfRecordAuxtraceData) + sizeof(perf_event_header));
1227     free(p);
1228 }
1229 } // namespace HiPerf
1230 } // namespace Developtools
1231 } // namespace OHOS
1232