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