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