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