• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (c) 2021 Huawei Device Co., Ltd.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <hwext/gtest-ext.h>
17 #include <hwext/gtest-tag.h>
18 #include "bio_latency_data_parser.h"
19 #include "cpu_filter.h"
20 #include "ebpf_data_parser.h"
21 #include "ebpf_stdtype.h"
22 #include "process_filter.h"
23 #include "trace_streamer_selector.h"
24 #include "ts_common.h"
25 using namespace testing::ext;
26 using namespace SysTuning::TraceStreamer;
27 using namespace SysTuning::EbpfStdtype;
28 namespace SysTuning ::TraceStreamer {
29 const std::string COMMAND_LINE = "hiebpf --events ptrace --duration 50";
30 const uint64_t EPBF_ERROR_MAGIC = 0x12345678;
31 const uint32_t EPBF_ERROR_HEAD_SIZE = 0;
32 class EbpfBioParserTest : public ::testing::Test {
33 public:
SetUp()34     void SetUp()
35     {
36         stream_.InitFilter();
37     }
TearDown()38     void TearDown() {}
39 
40 public:
41     TraceStreamerSelector stream_ = {};
42 };
43 const char PROCESS_NAME_01[MAX_PROCESS_NAME_SZIE] = "process01";
44 const uint64_t START_TIME = 1725645867369;
45 const uint64_t END_TIME = 1725645967369;
46 const uint64_t BLKCNT = 7829248;
47 const uint64_t IPS_01 = 548606407208;
48 const uint64_t IPS_02 = 548607407208;
49 const uint64_t EBPF_COMMAND_MAX_SIZE = 1000;
50 const uint32_t DURPER4K = 4096;
51 /**
52  * @tc.name: EbpfBioParserCorrectWithoutCallback
53  * @tc.desc: Test parse BIO data without callback
54  * @tc.type: FUNC
55  */
56 HWTEST_F(EbpfBioParserTest, EbpfBioParserCorrectWithoutCallback, TestSize.Level1)
57 {
58     TS_LOGI("test32-1");
59     EbpfDataHeader ebpfHeader;
60     ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME;
61     ebpfHeader.header.cmdLineLen = COMMAND_LINE.length();
62     strcpy(ebpfHeader.cmdline, COMMAND_LINE.c_str());
63     std::deque<uint8_t> dequeBuffer;
64     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfHeader),
65                        reinterpret_cast<uint8_t*>(&ebpfHeader + 1));
66     EbpfTypeAndLength ebpfTypeAndLength;
67     ebpfTypeAndLength.length = sizeof(BIOFixedHeader);
68     ebpfTypeAndLength.type = ITEM_EVENT_BIO;
69     BIOFixedHeader bioFixedHeader;
70     bioFixedHeader.pid = 32;
71     bioFixedHeader.tid = 32;
72     memcpy_s(bioFixedHeader.processName, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE);
73     bioFixedHeader.startTime = START_TIME;
74     bioFixedHeader.endTime = END_TIME;
75     bioFixedHeader.prio = 0;
76     bioFixedHeader.size = DURPER4K;
77     bioFixedHeader.blkcnt = BLKCNT;
78     bioFixedHeader.nips = 0;
79     bioFixedHeader.type = 2;
80     dequeBuffer.insert(dequeBuffer.end(), &(reinterpret_cast<uint8_t*>(&ebpfTypeAndLength))[0],
81                        &(reinterpret_cast<uint8_t*>(&ebpfTypeAndLength))[sizeof(EbpfTypeAndLength)]);
82     dequeBuffer.insert(dequeBuffer.end(), &(reinterpret_cast<uint8_t*>(&bioFixedHeader))[0],
83                        &(reinterpret_cast<uint8_t*>(&bioFixedHeader))[sizeof(BIOFixedHeader)]);
84     std::unique_ptr<EbpfDataParser> ebpfDataParser =
85         std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get());
86     EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer, dequeBuffer.size()));
87     EXPECT_TRUE(ebpfDataParser->reader_->GetBIOSampleMap().size());
88     ebpfDataParser->ParseBioLatencyEvent();
89     ebpfDataParser->Finish();
90     EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
91     auto callChainId = stream_.traceDataCache_->GetConstBioLatencySampleData().CallChainIds()[0];
92     EXPECT_EQ(callChainId, INVALID_UINT32);
93     auto type = stream_.traceDataCache_->GetConstBioLatencySampleData().Types()[0];
94     EXPECT_EQ(type, 2);
95     auto startTs = stream_.traceDataCache_->GetConstBioLatencySampleData().StartTs()[0];
96     EXPECT_EQ(startTs, START_TIME);
97     auto endTs = stream_.traceDataCache_->GetConstBioLatencySampleData().EndTs()[0];
98     EXPECT_EQ(endTs, END_TIME);
99     auto dur = stream_.traceDataCache_->GetConstBioLatencySampleData().LatencyDurs()[0];
100     EXPECT_EQ(dur, END_TIME - START_TIME);
101     auto tier = stream_.traceDataCache_->GetConstBioLatencySampleData().Tiers()[0];
102     EXPECT_EQ(tier, 0);
103     auto size = stream_.traceDataCache_->GetConstBioLatencySampleData().Sizes()[0];
104     EXPECT_EQ(size, DURPER4K);
105     auto Expectblk = ebpfDataParser->ConvertToHexTextIndex(BLKCNT);
106     auto blk = stream_.traceDataCache_->GetConstBioLatencySampleData().BlockNumbers()[0];
107     EXPECT_EQ(blk, Expectblk);
108     auto durPer4K = stream_.traceDataCache_->GetConstBioLatencySampleData().DurPer4k()[0];
109     EXPECT_EQ(durPer4K, dur / (size / DURPER4K));
110 }
111 
112 /**
113  * @tc.name: EbpfBioParserwrongWithoutCallback
114  * @tc.desc: Test parse BIO data without callback and startTs > endTs
115  * @tc.type: FUNC
116  */
117 HWTEST_F(EbpfBioParserTest, EbpfBioParserwrongWithoutCallback, TestSize.Level1)
118 {
119     TS_LOGI("test32-2");
120     EbpfDataHeader ebpfHeader;
121     ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME;
122     ebpfHeader.header.cmdLineLen = COMMAND_LINE.length();
123     strcpy(ebpfHeader.cmdline, COMMAND_LINE.c_str());
124     std::deque<uint8_t> dequeBuffer;
125     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfHeader),
126                        reinterpret_cast<uint8_t*>(&ebpfHeader + 1));
127     EbpfTypeAndLength ebpfTypeAndLength;
128     ebpfTypeAndLength.length = sizeof(BIOFixedHeader);
129     ebpfTypeAndLength.type = ITEM_EVENT_BIO;
130     BIOFixedHeader bioFixedHeader;
131     bioFixedHeader.pid = 32;
132     bioFixedHeader.tid = 32;
133     memcpy_s(bioFixedHeader.processName, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE);
134     bioFixedHeader.startTime = END_TIME;
135     bioFixedHeader.endTime = START_TIME;
136     bioFixedHeader.prio = 0;
137     bioFixedHeader.size = DURPER4K;
138     bioFixedHeader.blkcnt = BLKCNT;
139     bioFixedHeader.nips = 0;
140     bioFixedHeader.type = 2;
141     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfTypeAndLength),
142                        reinterpret_cast<uint8_t*>(&ebpfTypeAndLength + 1));
143     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&bioFixedHeader),
144                        reinterpret_cast<uint8_t*>(&bioFixedHeader + 1));
145     std::unique_ptr<EbpfDataParser> ebpfDataParser =
146         std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get());
147     EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer, dequeBuffer.size()));
148     EXPECT_TRUE(ebpfDataParser->reader_->GetBIOSampleMap().size());
149     ebpfDataParser->ParseBioLatencyEvent();
150     ebpfDataParser->Finish();
151     EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
152     auto callChainId = stream_.traceDataCache_->GetConstBioLatencySampleData().CallChainIds()[0];
153     EXPECT_FALSE(callChainId == INVALID_UINT64);
154     auto type = stream_.traceDataCache_->GetConstBioLatencySampleData().Types()[0];
155     EXPECT_FALSE(type == 2);
156     auto startTs = stream_.traceDataCache_->GetConstBioLatencySampleData().StartTs()[0];
157     EXPECT_FALSE(startTs == END_TIME);
158     auto endTs = stream_.traceDataCache_->GetConstBioLatencySampleData().EndTs()[0];
159     EXPECT_FALSE(endTs == START_TIME);
160     auto dur = stream_.traceDataCache_->GetConstBioLatencySampleData().LatencyDurs()[0];
161     EXPECT_FALSE(dur == endTs - startTs);
162     auto tier = stream_.traceDataCache_->GetConstBioLatencySampleData().Tiers()[0];
163     EXPECT_FALSE(tier == 0);
164     auto size = stream_.traceDataCache_->GetConstBioLatencySampleData().Sizes()[0];
165     EXPECT_FALSE(size == DURPER4K);
166     auto Expectblk = ebpfDataParser->ConvertToHexTextIndex(BLKCNT);
167     auto blk = stream_.traceDataCache_->GetConstBioLatencySampleData().BlockNumbers()[0];
168     EXPECT_FALSE(blk == Expectblk);
169     auto durPer4K = stream_.traceDataCache_->GetConstBioLatencySampleData().DurPer4k()[0];
170     EXPECT_FALSE(durPer4K == dur / (size / DURPER4K));
171 }
172 
173 /**
174  * @tc.name: EbpfBioParserCorrectWithOneCallback
175  * @tc.desc: Test parse BIO data with one callback
176  * @tc.type: FUNC
177  */
178 HWTEST_F(EbpfBioParserTest, EbpfBioParserCorrectWithOneCallback, TestSize.Level1)
179 {
180     TS_LOGI("test32-3");
181     EbpfDataHeader ebpfHeader;
182     ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME;
183     ebpfHeader.header.cmdLineLen = COMMAND_LINE.length();
184     memcpy_s(ebpfHeader.cmdline, EBPF_COMMAND_MAX_SIZE, COMMAND_LINE.c_str(), COMMAND_LINE.length());
185     std::deque<uint8_t> dequeBuffer;
186     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfHeader),
187                        reinterpret_cast<uint8_t*>(&ebpfHeader + 1));
188     EbpfTypeAndLength ebpfTypeAndLength;
189     ebpfTypeAndLength.length = sizeof(BIOFixedHeader);
190     ebpfTypeAndLength.type = ITEM_EVENT_BIO;
191     BIOFixedHeader bioFixedHeader;
192     bioFixedHeader.pid = 32;
193     bioFixedHeader.tid = 32;
194     memcpy_s(bioFixedHeader.processName, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE);
195     bioFixedHeader.startTime = START_TIME;
196     bioFixedHeader.endTime = END_TIME;
197     bioFixedHeader.prio = 0;
198     bioFixedHeader.size = DURPER4K;
199     bioFixedHeader.blkcnt = BLKCNT;
200     bioFixedHeader.nips = 1;
201     bioFixedHeader.type = 2;
202     const uint64_t ips[1] = {IPS_01};
203     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfTypeAndLength),
204                        reinterpret_cast<uint8_t*>(&ebpfTypeAndLength + 1));
205     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&bioFixedHeader),
206                        reinterpret_cast<uint8_t*>(&bioFixedHeader + 1));
207     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<const uint8_t*>(ips),
208                        reinterpret_cast<const uint8_t*>(&ips + 1));
209     std::unique_ptr<EbpfDataParser> ebpfDataParser =
210         std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get());
211     EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer, dequeBuffer.size()));
212     EXPECT_TRUE(ebpfDataParser->reader_->GetBIOSampleMap().size());
213     ebpfDataParser->ParseBioLatencyEvent();
214     ebpfDataParser->Finish();
215     EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
216     auto callChainId = stream_.traceDataCache_->GetConstBioLatencySampleData().CallChainIds()[0];
217     EXPECT_EQ(callChainId, 0);
218     auto type = stream_.traceDataCache_->GetConstBioLatencySampleData().Types()[0];
219     EXPECT_EQ(type, 2);
220     auto ipid = stream_.traceDataCache_->GetConstBioLatencySampleData().Ipids()[0];
221     EXPECT_EQ(ipid, 1);
222     auto itid = stream_.traceDataCache_->GetConstBioLatencySampleData().Itids()[0];
223     EXPECT_EQ(itid, 1);
224     auto startTs = stream_.traceDataCache_->GetConstBioLatencySampleData().StartTs()[0];
225     EXPECT_EQ(startTs, START_TIME);
226     auto endTs = stream_.traceDataCache_->GetConstBioLatencySampleData().EndTs()[0];
227     EXPECT_EQ(endTs, END_TIME);
228     auto dur = stream_.traceDataCache_->GetConstBioLatencySampleData().LatencyDurs()[0];
229     EXPECT_EQ(dur, END_TIME - START_TIME);
230     auto tier = stream_.traceDataCache_->GetConstBioLatencySampleData().Tiers()[0];
231     EXPECT_EQ(tier, 0);
232     auto size = stream_.traceDataCache_->GetConstBioLatencySampleData().Sizes()[0];
233     EXPECT_EQ(size, DURPER4K);
234     auto Expectblk = ebpfDataParser->ConvertToHexTextIndex(BLKCNT);
235     auto blk = stream_.traceDataCache_->GetConstBioLatencySampleData().BlockNumbers()[0];
236     EXPECT_EQ(blk, Expectblk);
237     auto durPer4K = stream_.traceDataCache_->GetConstBioLatencySampleData().DurPer4k()[0];
238     EXPECT_EQ(durPer4K, dur / (size / DURPER4K));
239     auto ExpectIps0 = ebpfDataParser->ConvertToHexTextIndex(ips[0]);
240     auto ips0 = stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[0];
241     EXPECT_EQ(ips0, ExpectIps0);
242 }
243 
244 /**
245  * @tc.name: EbpfBioParserCorrectWithMultipleCallback
246  * @tc.desc: Test parse BIO data with multiple callback
247  * @tc.type: FUNC
248  */
249 HWTEST_F(EbpfBioParserTest, EbpfBioParserCorrectWithMultipleCallback, TestSize.Level1)
250 {
251     TS_LOGI("test32-4");
252     EbpfDataHeader ebpfHeader;
253     ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME;
254     ebpfHeader.header.cmdLineLen = COMMAND_LINE.length();
255     memcpy_s(ebpfHeader.cmdline, EBPF_COMMAND_MAX_SIZE, COMMAND_LINE.c_str(), COMMAND_LINE.length());
256     std::deque<uint8_t> dequeBuffer;
257     dequeBuffer.insert(dequeBuffer.end(), &(reinterpret_cast<uint8_t*>(&ebpfHeader))[0],
258                        &(reinterpret_cast<uint8_t*>(&ebpfHeader))[EbpfDataHeader::EBPF_DATA_HEADER_SIZE]);
259     EbpfTypeAndLength ebpfTypeAndLength;
260     ebpfTypeAndLength.length = sizeof(BIOFixedHeader) + 2 * sizeof(uint64_t);
261     ebpfTypeAndLength.type = ITEM_EVENT_BIO;
262     BIOFixedHeader bioFixedHeader;
263     bioFixedHeader.pid = 32;
264     bioFixedHeader.tid = 32;
265     memcpy_s(bioFixedHeader.processName, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE);
266     bioFixedHeader.startTime = START_TIME;
267     bioFixedHeader.endTime = END_TIME;
268     bioFixedHeader.prio = 0;
269     bioFixedHeader.size = DURPER4K;
270     bioFixedHeader.blkcnt = BLKCNT;
271     bioFixedHeader.nips = 2;
272     bioFixedHeader.type = 2;
273     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfTypeAndLength),
274                        reinterpret_cast<uint8_t*>(&ebpfTypeAndLength + 1));
275     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&bioFixedHeader),
276                        reinterpret_cast<uint8_t*>(&bioFixedHeader + 1));
277     const uint64_t ips[2] = {IPS_01, IPS_02};
278     dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<const uint8_t*>(ips),
279                        reinterpret_cast<const uint8_t*>(&ips + 1));
280     std::unique_ptr<EbpfDataParser> ebpfDataParser =
281         std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get());
282     EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer, dequeBuffer.size()));
283     EXPECT_TRUE(ebpfDataParser->reader_->GetBIOSampleMap().size());
284     ebpfDataParser->ParseBioLatencyEvent();
285     ebpfDataParser->Finish();
286     EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
287     auto callChainId = stream_.traceDataCache_->GetConstBioLatencySampleData().CallChainIds()[0];
288     EXPECT_EQ(callChainId, 0);
289     auto type = stream_.traceDataCache_->GetConstBioLatencySampleData().Types()[0];
290     EXPECT_EQ(type, 2);
291     auto ipid = stream_.traceDataCache_->GetConstBioLatencySampleData().Ipids()[0];
292     EXPECT_EQ(ipid, 1);
293     auto itid = stream_.traceDataCache_->GetConstBioLatencySampleData().Itids()[0];
294     EXPECT_EQ(itid, 1);
295     auto startTs = stream_.traceDataCache_->GetConstBioLatencySampleData().StartTs()[0];
296     EXPECT_EQ(startTs, START_TIME);
297     auto endTs = stream_.traceDataCache_->GetConstBioLatencySampleData().EndTs()[0];
298     EXPECT_EQ(endTs, END_TIME);
299     auto dur = stream_.traceDataCache_->GetConstBioLatencySampleData().LatencyDurs()[0];
300     EXPECT_EQ(dur, END_TIME - START_TIME);
301     auto tier = stream_.traceDataCache_->GetConstBioLatencySampleData().Tiers()[0];
302     EXPECT_EQ(tier, 0);
303     auto size = stream_.traceDataCache_->GetConstBioLatencySampleData().Sizes()[0];
304     EXPECT_EQ(size, DURPER4K);
305     auto Expectblk = ebpfDataParser->ConvertToHexTextIndex(BLKCNT);
306     auto blk = stream_.traceDataCache_->GetConstBioLatencySampleData().BlockNumbers()[0];
307     EXPECT_EQ(blk, Expectblk);
308     auto durPer4K = stream_.traceDataCache_->GetConstBioLatencySampleData().DurPer4k()[0];
309     EXPECT_EQ(durPer4K, dur / (size / DURPER4K));
310     auto ExpectIps0 = ebpfDataParser->ConvertToHexTextIndex(ips[0]);
311     auto ips0 = stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[1];
312     EXPECT_EQ(ips0, ExpectIps0);
313     auto ExpectIps1 = ebpfDataParser->ConvertToHexTextIndex(ips[1]);
314     auto ips1 = stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[0];
315     EXPECT_EQ(ips1, ExpectIps1);
316 }
317 } // namespace SysTuning::TraceStreamer
318