• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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 <hwext/gtest-ext.h>
17 #include <hwext/gtest-tag.h>
18 
19 #include "ebpf_data_parser.h"
20 #include "ebpf_stdtype.h"
21 #include "process_filter.h"
22 #include "trace_streamer_selector.h"
23 #include "ts_common.h"
24 
25 using namespace testing::ext;
26 using namespace SysTuning::TraceStreamer;
27 using namespace SysTuning::EbpfStdtype;
28 namespace SysTuning {
29 namespace TraceStreamer {
30 const uint32_t PID_01 = 32;
31 const uint32_t TID_01 = 12;
32 const uint32_t PID_02 = 33;
33 const uint32_t TID_02 = 13;
34 const uint64_t START_TIME_01 = 1725645867369;
35 const uint64_t END_TIME_01 = 1725645967369;
36 const uint64_t START_TIME_02 = 1725645867369;
37 const uint64_t END_TIME_02 = 1725645967369;
38 const int32_t RET_01 = 8;
39 const int32_t RET_02 = -1;
40 const uint16_t IPS_NUM_00 = 0;
41 const uint16_t IPS_NUM_01 = 1;
42 const uint16_t IPS_NUM_02 = 2;
43 const uint64_t ARGS_01[ARGS_MAX] = {101, 102, 103, 104};
44 const uint64_t ARGS_02[ARGS_MAX] = {201, 202, 203, 204};
45 const char PROCESS_NAME_01[MAX_PROCESS_NAME_SZIE] = "process01";
46 const char PROCESS_NAME_02[MAX_PROCESS_NAME_SZIE] = "process02";
47 const uint64_t IPS_01[IPS_NUM_01] = {0x100000000};
48 const uint64_t IPS_02[IPS_NUM_02] = {0x100000000, 0x100000001};
49 
50 class EbpfFileSystemTest : public ::testing::Test {
51 public:
SetUp()52     void SetUp()
53     {
54         stream_.InitFilter();
55         parser_ = std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get());
56 
57         EbpfDataHeader ebpfHeader;
58         ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME;
59 
60         dequeBuffer_.insert(dequeBuffer_.end(), reinterpret_cast<uint8_t *>(&ebpfHeader),
61                             reinterpret_cast<uint8_t *>(&ebpfHeader + 1));
62 
63         ebpfTypeAndLength_.length = sizeof(fsFixedHeader_);
64         ebpfTypeAndLength_.type = ITEM_EVENT_FS;
65     }
66 
TearDown()67     void TearDown() {}
68 
InitData(uint16_t nrUserIPs=IPS_NUM_00)69     void InitData(uint16_t nrUserIPs = IPS_NUM_00)
70     {
71         fsFixedHeader_.pid = PID_01;
72         fsFixedHeader_.tid = TID_01;
73         fsFixedHeader_.startTime = START_TIME_01;
74         fsFixedHeader_.endTime = END_TIME_01;
75         fsFixedHeader_.ret = RET_01;
76         fsFixedHeader_.nrUserIPs = nrUserIPs;
77         for (auto i = 0; i < ARGS_MAX; i++) {
78             fsFixedHeader_.args[i] = ARGS_01[i];
79         }
80         strncpy_s(fsFixedHeader_.processName, MAX_PROCESS_NAME_SZIE, PROCESS_NAME_01, MAX_PROCESS_NAME_SZIE);
81     }
82 
ResetData()83     void ResetData()
84     {
85         fsFixedHeader_.pid = PID_02;
86         fsFixedHeader_.tid = TID_02;
87         fsFixedHeader_.startTime = START_TIME_02;
88         fsFixedHeader_.endTime = END_TIME_02;
89         fsFixedHeader_.ret = RET_02;
90         fsFixedHeader_.nrUserIPs = IPS_NUM_00;
91         for (auto i = 0; i < ARGS_MAX; i++) {
92             fsFixedHeader_.args[i] = ARGS_02[i];
93         }
94         strncpy_s(fsFixedHeader_.processName, MAX_PROCESS_NAME_SZIE, PROCESS_NAME_02, MAX_PROCESS_NAME_SZIE);
95     }
96 
UpdateData()97     void UpdateData()
98     {
99         dequeBuffer_.insert(dequeBuffer_.end(), reinterpret_cast<uint8_t *>(&ebpfTypeAndLength_),
100                             reinterpret_cast<uint8_t *>(&ebpfTypeAndLength_ + 1));
101         dequeBuffer_.insert(dequeBuffer_.end(), reinterpret_cast<uint8_t *>(&fsFixedHeader_),
102                             reinterpret_cast<uint8_t *>(&fsFixedHeader_ + 1));
103     }
104 
105 public:
106     SysTuning::TraceStreamer::TraceStreamerSelector stream_ = {};
107     FsFixedHeader fsFixedHeader_;
108     EbpfTypeAndLength ebpfTypeAndLength_;
109     std::deque<uint8_t> dequeBuffer_ = {};
110     std::unique_ptr<EbpfDataParser> parser_ = nullptr;
111 };
112 
113 /**
114  * @tc.name: ParseFileSystemWithTypeOpen
115  * @tc.desc: Test parse Ebpf data has one file system data with type open and no ips
116  * @tc.type: FUNC
117  */
118 HWTEST_F(EbpfFileSystemTest, ParseFileSystemWithTypeOpen, TestSize.Level1)
119 {
120     TS_LOGI("test30-1");
121 
122     InitData();
123     ebpfTypeAndLength_.length = sizeof(FsFixedHeader);
124     fsFixedHeader_.type = SYS_OPENAT2;
125     UpdateData();
126 
127     EXPECT_TRUE(parser_->Init(dequeBuffer_, dequeBuffer_.size()));
128     EXPECT_TRUE(parser_->reader_->GetFileSystemEventMap().size());
129     parser_->ParseFileSystemEvent();
130     parser_->Finish();
131     EXPECT_TRUE(parser_->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
132     auto fileSystemSample = stream_.traceDataCache_->GetConstFileSystemSample();
133     EXPECT_EQ(fileSystemSample.CallChainIds()[0], INVALID_UINT32);
134     EXPECT_EQ(fileSystemSample.Types()[0], OPEN);
135     EXPECT_EQ(fileSystemSample.StartTs()[0], START_TIME_01);
136     EXPECT_EQ(fileSystemSample.EndTs()[0], END_TIME_01);
137     EXPECT_EQ(fileSystemSample.Durs()[0], END_TIME_01 - START_TIME_01);
138     EXPECT_EQ(parser_->ConvertToHexTextIndex(RET_01), fileSystemSample.ReturnValues()[0]);
139     EXPECT_EQ(fileSystemSample.ErrorCodes()[0], INVALID_UINT64);
140     EXPECT_EQ(fileSystemSample.Fds()[0], RET_01);
141     EXPECT_EQ(fileSystemSample.FileIds()[0], INVALID_UINT64);
142     EXPECT_EQ(fileSystemSample.Sizes()[0], MAX_SIZE_T);
143 
144     auto i = 0;
145     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_01[i++]), fileSystemSample.FirstArguments()[0]);
146     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_01[i++]), fileSystemSample.SecondArguments()[0]);
147     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_01[i++]), fileSystemSample.ThirdArguments()[0]);
148     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_01[i]), fileSystemSample.FourthArguments()[0]);
149 }
150 
151 /**
152  * @tc.name: ParseFileSystemWithTypeClose
153  * @tc.desc: Test parse Ebpf data has one file system data with type close and no ips and return value little to zero
154  * @tc.type: FUNC
155  */
156 HWTEST_F(EbpfFileSystemTest, ParseFileSystemWithTypeClose, TestSize.Level1)
157 {
158     TS_LOGI("test30-2");
159 
160     ResetData();
161     fsFixedHeader_.type = SYS_CLOSE;
162     UpdateData();
163 
164     EXPECT_TRUE(parser_->Init(dequeBuffer_, dequeBuffer_.size()));
165     EXPECT_TRUE(parser_->reader_->GetFileSystemEventMap().size());
166     parser_->ParseFileSystemEvent();
167     parser_->Finish();
168     EXPECT_TRUE(parser_->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
169     auto fileSystemSample = stream_.traceDataCache_->GetConstFileSystemSample();
170     EXPECT_EQ(fileSystemSample.CallChainIds()[0], INVALID_UINT32);
171     EXPECT_EQ(fileSystemSample.Types()[0], CLOSE);
172     EXPECT_EQ(fileSystemSample.StartTs()[0], START_TIME_02);
173     EXPECT_EQ(fileSystemSample.EndTs()[0], END_TIME_02);
174     EXPECT_EQ(fileSystemSample.Durs()[0], END_TIME_02 - START_TIME_02);
175     EXPECT_EQ(parser_->ConvertToHexTextIndex(0), fileSystemSample.ReturnValues()[0]);
176     EXPECT_EQ(fileSystemSample.ErrorCodes()[0], parser_->ConvertToHexTextIndex(-RET_02));
177     EXPECT_EQ(fileSystemSample.Fds()[0], ARGS_02[1]);
178     EXPECT_EQ(fileSystemSample.FileIds()[0], INVALID_UINT64);
179     EXPECT_EQ(fileSystemSample.Sizes()[0], MAX_SIZE_T);
180 
181     auto i = 0;
182     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_02[i++]), fileSystemSample.FirstArguments()[0]);
183     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_02[i++]), fileSystemSample.SecondArguments()[0]);
184     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_02[i++]), fileSystemSample.ThirdArguments()[0]);
185     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_02[i]), fileSystemSample.FourthArguments()[0]);
186 }
187 
188 /**
189  * @tc.name: ParseFileSystemWithTypeRead
190  * @tc.desc: Test parse Ebpf data has one file system data with type read and no ips
191  * @tc.type: FUNC
192  */
193 HWTEST_F(EbpfFileSystemTest, ParseFileSystemWithTypeRead, TestSize.Level1)
194 {
195     TS_LOGI("test30-3");
196 
197     InitData();
198     fsFixedHeader_.type = SYS_READ;
199     UpdateData();
200 
201     EXPECT_TRUE(parser_->Init(dequeBuffer_, dequeBuffer_.size()));
202     EXPECT_TRUE(parser_->reader_->GetFileSystemEventMap().size());
203     parser_->ParseFileSystemEvent();
204     parser_->Finish();
205     EXPECT_TRUE(parser_->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
206     auto fileSystemSample = stream_.traceDataCache_->GetConstFileSystemSample();
207     EXPECT_EQ(fileSystemSample.CallChainIds()[0], INVALID_UINT32);
208     EXPECT_EQ(fileSystemSample.Types()[0], READ);
209     EXPECT_EQ(fileSystemSample.StartTs()[0], START_TIME_01);
210     EXPECT_EQ(fileSystemSample.EndTs()[0], END_TIME_01);
211     EXPECT_EQ(fileSystemSample.Durs()[0], END_TIME_01 - START_TIME_01);
212     EXPECT_EQ(fileSystemSample.ReturnValues()[0], parser_->ConvertToHexTextIndex(RET_01));
213     EXPECT_EQ(fileSystemSample.ErrorCodes()[0], INVALID_UINT64);
214     EXPECT_EQ(fileSystemSample.Fds()[0], ARGS_01[0]);
215     EXPECT_EQ(fileSystemSample.FileIds()[0], INVALID_UINT64);
216     EXPECT_EQ(fileSystemSample.Sizes()[0], RET_01);
217 
218     auto i = 0;
219     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_01[i++]), fileSystemSample.FirstArguments()[0]);
220     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_01[i++]), fileSystemSample.SecondArguments()[0]);
221     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_01[i++]), fileSystemSample.ThirdArguments()[0]);
222     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_01[i]), fileSystemSample.FourthArguments()[0]);
223 }
224 
225 /**
226  * @tc.name: ParseFileSystemWithTypeWrite
227  * @tc.desc: Test parse Ebpf data has one file system data with type read and no ips
228  * @tc.type: FUNC
229  */
230 HWTEST_F(EbpfFileSystemTest, ParseFileSystemWithTypeWrite, TestSize.Level1)
231 {
232     TS_LOGI("test30-4");
233 
234     ResetData();
235     fsFixedHeader_.type = SYS_WRITE;
236     UpdateData();
237 
238     EXPECT_TRUE(parser_->Init(dequeBuffer_, dequeBuffer_.size()));
239     EXPECT_TRUE(parser_->reader_->GetFileSystemEventMap().size());
240     parser_->ParseFileSystemEvent();
241     parser_->Finish();
242     EXPECT_TRUE(parser_->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
243     auto fileSystemSample = stream_.traceDataCache_->GetConstFileSystemSample();
244     EXPECT_EQ(fileSystemSample.CallChainIds()[0], INVALID_UINT32);
245     EXPECT_EQ(fileSystemSample.Types()[0], WRITE);
246     EXPECT_EQ(fileSystemSample.StartTs()[0], START_TIME_02);
247     EXPECT_EQ(fileSystemSample.EndTs()[0], END_TIME_02);
248     EXPECT_EQ(fileSystemSample.Durs()[0], END_TIME_02 - START_TIME_02);
249     EXPECT_EQ(fileSystemSample.ReturnValues()[0], parser_->ConvertToHexTextIndex(0));
250     EXPECT_EQ(fileSystemSample.ErrorCodes()[0], parser_->ConvertToHexTextIndex(-RET_02));
251     EXPECT_EQ(fileSystemSample.Fds()[0], ARGS_02[0]);
252     EXPECT_EQ(fileSystemSample.FileIds()[0], INVALID_UINT64);
253     EXPECT_EQ(fileSystemSample.Sizes()[0], MAX_SIZE_T);
254 
255     auto i = 0;
256     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_02[i++]), fileSystemSample.FirstArguments()[0]);
257     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_02[i++]), fileSystemSample.SecondArguments()[0]);
258     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_02[i++]), fileSystemSample.ThirdArguments()[0]);
259     EXPECT_EQ(parser_->ConvertToHexTextIndex(ARGS_02[i]), fileSystemSample.FourthArguments()[0]);
260 }
261 
262 /**
263  * @tc.name: ParseFileSystemWithErrorType
264  * @tc.desc: Test parse Ebpf data has one file system data with error type and no ips
265  * @tc.type: FUNC
266  */
267 HWTEST_F(EbpfFileSystemTest, ParseFileSystemWithErrorType, TestSize.Level1)
268 {
269     TS_LOGI("test30-5");
270 
271     InitData();
272     fsFixedHeader_.type = 0;
273     UpdateData();
274 
275     EXPECT_TRUE(parser_->Init(dequeBuffer_, dequeBuffer_.size()));
276     EXPECT_TRUE(parser_->reader_->GetFileSystemEventMap().size());
277     parser_->ParseFileSystemEvent();
278     parser_->Finish();
279     EXPECT_TRUE(parser_->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
280     EXPECT_FALSE(stream_.traceDataCache_->GetConstFileSystemSample().Size());
281 }
282 
283 /**
284  * @tc.name: ParseFileSystemWithIPsButNoSymTable
285  * @tc.desc: Test parse Ebpf data has one file system data with ips but no maps
286  * @tc.type: FUNC
287  */
288 HWTEST_F(EbpfFileSystemTest, ParseFileSystemWithIPsButNoMaps, TestSize.Level1)
289 {
290     TS_LOGI("test30-6");
291 
292     InitData(IPS_NUM_02);
293     fsFixedHeader_.type = SYS_OPENAT2;
294     ebpfTypeAndLength_.length = sizeof(fsFixedHeader_) + IPS_NUM_02 * sizeof(uint64_t);
295     UpdateData();
296     dequeBuffer_.insert(dequeBuffer_.end(), reinterpret_cast<const uint8_t *>(IPS_02),
297                         reinterpret_cast<const uint8_t *>(&IPS_02 + 1));
298 
299     EXPECT_TRUE(parser_->Init(dequeBuffer_, dequeBuffer_.size()));
300     EXPECT_TRUE(parser_->reader_->GetFileSystemEventMap().size());
301     parser_->ParseFileSystemEvent();
302     parser_->Finish();
303     EXPECT_TRUE(parser_->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME);
304     EXPECT_EQ(stream_.traceDataCache_->GetConstFileSystemSample().CallChainIds()[0], 0);
305     auto ebpfCallStackData = stream_.traceDataCache_->GetConstEbpfCallStackData();
306     EXPECT_EQ(ebpfCallStackData.CallChainIds()[0], 0);
307     EXPECT_EQ(ebpfCallStackData.CallChainIds()[1], 0);
308     EXPECT_EQ(ebpfCallStackData.Depths()[0], 0);
309     EXPECT_EQ(ebpfCallStackData.Depths()[1], 1);
310     EXPECT_EQ(ebpfCallStackData.Ips()[0], parser_->ConvertToHexTextIndex(IPS_02[1]));
311     EXPECT_EQ(ebpfCallStackData.Ips()[1], parser_->ConvertToHexTextIndex(IPS_02[0]));
312     EXPECT_EQ(ebpfCallStackData.SymbolIds()[0], INVALID_UINT64);
313     EXPECT_EQ(ebpfCallStackData.SymbolIds()[1], INVALID_UINT64);
314     EXPECT_EQ(ebpfCallStackData.FilePathIds()[0], INVALID_UINT64);
315     EXPECT_EQ(ebpfCallStackData.FilePathIds()[1], INVALID_UINT64);
316 }
317 } // namespace TraceStreamer
318 } // namespace SysTuning
319