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