• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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 namespace BioParserUnitTest {
30 const std::string COMMAND_LINE = "hiebpf --events ptrace --duration 50";
31 const uint64_t EPBF_ERROR_MAGIC = 0x12345678;
32 const uint32_t EPBF_ERROR_HEAD_SIZE = 0;
33 const char PROCESS_NAME_01[MAX_PROCESS_NAME_SZIE] = "process01";
34 const uint64_t START_TIME = 1725645867369;
35 const uint64_t END_TIME = 1725645967369;
36 const uint64_t BLKCNT = 7829248;
37 const uint64_t IPS_01 = 548606407208;
38 const uint64_t IPS_02 = 548607407208;
39 const uint64_t EBPF_COMMAND_MAX_SIZE = 1000;
40 const uint32_t DURPER4K = 4096;
41 const uint64_t PID = 32;
42 const uint64_t TID = 32;
43 const uint16_t TYPE = 2;
44 
45 class EbpfBioParserTest : public ::testing::Test {
46 public:
SetUp()47     void SetUp()
48     {
49         stream_.InitFilter();
50     }
51 
TearDown()52     void TearDown()
53     {
54         dequeBuffer_.clear();
55     }
56 
InitData(uint32_t length,uint32_t nips,const uint64_t startTime,const uint64_t endTime,uint32_t prio=0)57     void InitData(uint32_t length, uint32_t nips, const uint64_t startTime, const uint64_t endTime, uint32_t prio = 0)
58     {
59         ebpfHeader_.header.clock = EBPF_CLOCK_BOOTTIME;
60         ebpfHeader_.header.cmdLineLen = COMMAND_LINE.length();
61         strcpy_s(ebpfHeader_.cmdline, EBPF_COMMAND_MAX_SIZE, COMMAND_LINE.c_str());
62         ebpfTypeAndLength_.type = ITEM_EVENT_BIO;
63         ebpfTypeAndLength_.length = length;
64         bioFixedHeader_.pid = PID;
65         bioFixedHeader_.tid = TID;
66         memcpy_s(bioFixedHeader_.processName, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE);
67         bioFixedHeader_.prio = 0;
68         bioFixedHeader_.size = DURPER4K;
69         bioFixedHeader_.blkcnt = BLKCNT;
70         bioFixedHeader_.type = TYPE;
71         bioFixedHeader_.nips = nips;
72         bioFixedHeader_.startTime = startTime;
73         bioFixedHeader_.endTime = endTime;
74 
75         dequeBuffer_.insert(dequeBuffer_.end(), reinterpret_cast<uint8_t *>(&ebpfHeader_),
76                             reinterpret_cast<uint8_t *>(&ebpfHeader_ + 1));
77         dequeBuffer_.insert(dequeBuffer_.end(), &(reinterpret_cast<uint8_t *>(&ebpfTypeAndLength_))[0],
78                             &(reinterpret_cast<uint8_t *>(&ebpfTypeAndLength_))[sizeof(EbpfTypeAndLength)]);
79 
80         dequeBuffer_.insert(dequeBuffer_.end(), &(reinterpret_cast<uint8_t *>(&bioFixedHeader_))[0],
81                             &(reinterpret_cast<uint8_t *>(&bioFixedHeader_))[sizeof(BIOFixedHeader)]);
82     }
83 
84 public:
85     TraceStreamerSelector stream_ = {};
86     EbpfDataHeader ebpfHeader_;
87     EbpfTypeAndLength ebpfTypeAndLength_;
88     BIOFixedHeader bioFixedHeader_;
89     std::deque<uint8_t> dequeBuffer_;
90 };
91 
92 /**
93  * @tc.name: EbpfBioParserCorrectWithoutCallback
94  * @tc.desc: Test parse BIO data without callback
95  * @tc.type: FUNC
96  */
97 HWTEST_F(EbpfBioParserTest, EbpfBioParserCorrectWithoutCallback, TestSize.Level1)
98 {
99     TS_LOGI("test32-01");
100     InitData(sizeof(BIOFixedHeader), 0, START_TIME, END_TIME);
101 
102     std::unique_ptr<EbpfDataParser> ebpfDataParser =
103         std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get());
104     EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer_, dequeBuffer_.size()));
105     EXPECT_TRUE(ebpfDataParser->reader_->GetBIOSampleMap().size());
106     ebpfDataParser->ParseBioLatencyEvent();
107     ebpfDataParser->Finish();
108     EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
109     auto sampleData = stream_.traceDataCache_->GetConstBioLatencySampleData();
110     EXPECT_EQ(sampleData.CallChainIds()[0], INVALID_UINT32);
111     EXPECT_EQ(sampleData.Types()[0], 2);
112     EXPECT_EQ(sampleData.StartTs()[0], START_TIME);
113     EXPECT_EQ(sampleData.EndTs()[0], END_TIME);
114     auto dur = sampleData.LatencyDurs()[0];
115     EXPECT_EQ(dur, END_TIME - START_TIME);
116     EXPECT_EQ(sampleData.Tiers()[0], 0);
117     auto size = sampleData.Sizes()[0];
118     EXPECT_EQ(size, DURPER4K);
119     EXPECT_EQ(sampleData.BlockNumbers()[0], ebpfDataParser->ConvertToHexTextIndex(BLKCNT));
120     EXPECT_EQ(sampleData.DurPer4k()[0], dur / (size / DURPER4K));
121 }
122 
123 /**
124  * @tc.name: EbpfBioParserwrongWithoutCallback
125  * @tc.desc: Test parse BIO data without callback and startTs > endTs
126  * @tc.type: FUNC
127  */
128 HWTEST_F(EbpfBioParserTest, EbpfBioParserwrongWithoutCallback, TestSize.Level1)
129 {
130     TS_LOGI("test32-02");
131     InitData(sizeof(BIOFixedHeader), 0, END_TIME, START_TIME, 1);
132 
133     std::unique_ptr<EbpfDataParser> ebpfDataParser =
134         std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get());
135     EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer_, dequeBuffer_.size()));
136     EXPECT_TRUE(ebpfDataParser->reader_->GetBIOSampleMap().size());
137     ebpfDataParser->ParseBioLatencyEvent();
138     ebpfDataParser->Finish();
139     EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
140     auto sampleData = stream_.traceDataCache_->GetConstBioLatencySampleData();
141     EXPECT_NE(sampleData.CallChainIds()[0], INVALID_UINT64);
142     EXPECT_NE(sampleData.Types()[0], 2);
143     EXPECT_NE(sampleData.StartTs()[0], END_TIME);
144     EXPECT_NE(sampleData.EndTs()[0], START_TIME);
145     auto dur = sampleData.LatencyDurs()[0];
146     EXPECT_NE(dur, START_TIME - END_TIME);
147     EXPECT_NE(sampleData.Tiers()[0], 1);
148     auto size = sampleData.Sizes()[0];
149     EXPECT_NE(size, DURPER4K);
150     EXPECT_NE(sampleData.BlockNumbers()[0], ebpfDataParser->ConvertToHexTextIndex(BLKCNT));
151     if (size > 0) {
152         EXPECT_NE(sampleData.DurPer4k()[0], dur / (size / DURPER4K));
153     }
154 }
155 
156 /**
157  * @tc.name: EbpfBioParserCorrectWithOneCallback
158  * @tc.desc: Test parse BIO data with one callback
159  * @tc.type: FUNC
160  */
161 HWTEST_F(EbpfBioParserTest, EbpfBioParserCorrectWithOneCallback, TestSize.Level1)
162 {
163     TS_LOGI("test32-03");
164     InitData(sizeof(BIOFixedHeader), 1, START_TIME, END_TIME);
165 
166     const uint64_t ips[1] = {IPS_01};
167     dequeBuffer_.insert(dequeBuffer_.end(), reinterpret_cast<const uint8_t *>(ips),
168                         reinterpret_cast<const uint8_t *>(&ips + 1));
169     std::unique_ptr<EbpfDataParser> ebpfDataParser =
170         std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get());
171     EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer_, dequeBuffer_.size()));
172     EXPECT_TRUE(ebpfDataParser->reader_->GetBIOSampleMap().size());
173     ebpfDataParser->ParseBioLatencyEvent();
174     ebpfDataParser->Finish();
175     EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
176     auto sampleData = stream_.traceDataCache_->GetConstBioLatencySampleData();
177     EXPECT_EQ(sampleData.CallChainIds()[0], 0);
178     EXPECT_EQ(sampleData.Types()[0], 2);
179     EXPECT_EQ(sampleData.Ipids()[0], 1);
180     EXPECT_EQ(sampleData.Itids()[0], 1);
181     EXPECT_EQ(sampleData.StartTs()[0], START_TIME);
182     EXPECT_EQ(sampleData.EndTs()[0], END_TIME);
183     auto dur = sampleData.LatencyDurs()[0];
184     EXPECT_EQ(dur, END_TIME - START_TIME);
185     EXPECT_EQ(sampleData.Tiers()[0], 0);
186     auto size = sampleData.Sizes()[0];
187     EXPECT_EQ(size, DURPER4K);
188     EXPECT_EQ(sampleData.BlockNumbers()[0], ebpfDataParser->ConvertToHexTextIndex(BLKCNT));
189     EXPECT_EQ(sampleData.DurPer4k()[0], dur / (size / DURPER4K));
190     auto ExpectIps0 = ebpfDataParser->ConvertToHexTextIndex(ips[0]);
191     auto ips0 = stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[0];
192     EXPECT_EQ(ips0, ExpectIps0);
193 }
194 
195 /**
196  * @tc.name: EbpfBioParserCorrectWithMultipleCallback
197  * @tc.desc: Test parse BIO data with multiple callback
198  * @tc.type: FUNC
199  */
200 HWTEST_F(EbpfBioParserTest, EbpfBioParserCorrectWithMultipleCallback, TestSize.Level1)
201 {
202     TS_LOGI("test32-04");
203     InitData(sizeof(BIOFixedHeader) + 2 * sizeof(uint64_t), 2, START_TIME, END_TIME);
204 
205     const uint64_t ips[2] = {IPS_01, IPS_02};
206     dequeBuffer_.insert(dequeBuffer_.end(), reinterpret_cast<const uint8_t *>(ips),
207                         reinterpret_cast<const uint8_t *>(&ips + 1));
208     std::unique_ptr<EbpfDataParser> ebpfDataParser =
209         std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get());
210     EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer_, dequeBuffer_.size()));
211     EXPECT_TRUE(ebpfDataParser->reader_->GetBIOSampleMap().size());
212     ebpfDataParser->ParseBioLatencyEvent();
213     ebpfDataParser->Finish();
214     EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
215     auto sampleData = stream_.traceDataCache_->GetConstBioLatencySampleData();
216     EXPECT_EQ(sampleData.CallChainIds()[0], 0);
217     EXPECT_EQ(sampleData.Types()[0], 2);
218     EXPECT_EQ(sampleData.Ipids()[0], 1);
219     EXPECT_EQ(sampleData.Itids()[0], 1);
220     EXPECT_EQ(sampleData.StartTs()[0], START_TIME);
221     EXPECT_EQ(sampleData.EndTs()[0], END_TIME);
222     auto dur = sampleData.LatencyDurs()[0];
223     EXPECT_EQ(dur, END_TIME - START_TIME);
224     EXPECT_EQ(sampleData.Tiers()[0], 0);
225     auto size = sampleData.Sizes()[0];
226     EXPECT_EQ(size, DURPER4K);
227     EXPECT_EQ(sampleData.BlockNumbers()[0], ebpfDataParser->ConvertToHexTextIndex(BLKCNT));
228     EXPECT_EQ(sampleData.DurPer4k()[0], dur / (size / DURPER4K));
229     auto ExpectIps0 = ebpfDataParser->ConvertToHexTextIndex(ips[0]);
230     auto ips0 = stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[1];
231     EXPECT_EQ(ips0, ExpectIps0);
232     auto ExpectIps1 = ebpfDataParser->ConvertToHexTextIndex(ips[1]);
233     auto ips1 = stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[0];
234     EXPECT_EQ(ips1, ExpectIps1);
235 }
236 } // namespace BioParserUnitTest
237 } // namespace SysTuning::TraceStreamer
238