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 "paged_memory_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 class EbpfPagedMemoryParserTest : public ::testing::Test { 31 public: SetUp()32 void SetUp() 33 { 34 stream_.InitFilter(); 35 } TearDown()36 void TearDown() {} 37 38 public: 39 TraceStreamerSelector stream_ = {}; 40 }; 41 const uint64_t START_TIME = 1725645867369; 42 const uint64_t END_TIME = 1725645967369; 43 const uint64_t PAGEED_MEM_ADDR = 46549876; 44 const uint64_t IPS_01 = 548606407208; 45 const uint64_t IPS_02 = 548607407208; 46 const uint64_t EBPF_COMMAND_MAX_SIZE = 1000; 47 /** 48 * @tc.name: EbpfPagedMemoryParserCorrectWithoutCallback 49 * @tc.desc: Test parse PagedMem data without callback 50 * @tc.type: FUNC 51 */ 52 HWTEST_F(EbpfPagedMemoryParserTest, EbpfPagedMemoryParserCorrectWithoutCallback, TestSize.Level1) 53 { 54 TS_LOGI("test31-1"); 55 EbpfDataHeader ebpfHeader; 56 ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME; 57 ebpfHeader.header.cmdLineLen = COMMAND_LINE.length(); 58 memcpy_s(ebpfHeader.cmdline, EBPF_COMMAND_MAX_SIZE, COMMAND_LINE.c_str(), COMMAND_LINE.length()); 59 std::deque<uint8_t> dequeBuffer; 60 dequeBuffer.insert(dequeBuffer.end(), &(reinterpret_cast<uint8_t*>(&ebpfHeader))[0], 61 &(reinterpret_cast<uint8_t*>(&ebpfHeader))[EbpfDataHeader::EBPF_DATA_HEADER_SIZE]); 62 EbpfTypeAndLength ebpfTypeAndLength; 63 ebpfTypeAndLength.length = sizeof(PagedMemoryFixedHeader); 64 ebpfTypeAndLength.type = ITEM_EVENT_VM; 65 PagedMemoryFixedHeader pagedMemoryFixedHeader; 66 pagedMemoryFixedHeader.pid = 32; 67 pagedMemoryFixedHeader.tid = 32; 68 memcpy_s(pagedMemoryFixedHeader.comm, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE); 69 pagedMemoryFixedHeader.startTime = START_TIME; 70 pagedMemoryFixedHeader.endTime = END_TIME; 71 pagedMemoryFixedHeader.addr = PAGEED_MEM_ADDR; 72 pagedMemoryFixedHeader.size = 1; 73 pagedMemoryFixedHeader.nips = 0; 74 pagedMemoryFixedHeader.type = 2; 75 dequeBuffer.insert(dequeBuffer.end(), &(reinterpret_cast<uint8_t*>(&ebpfTypeAndLength))[0], 76 &(reinterpret_cast<uint8_t*>(&ebpfTypeAndLength))[sizeof(EbpfTypeAndLength)]); 77 dequeBuffer.insert(dequeBuffer.end(), &(reinterpret_cast<uint8_t*>(&pagedMemoryFixedHeader))[0], 78 &(reinterpret_cast<uint8_t*>(&pagedMemoryFixedHeader))[sizeof(PagedMemoryFixedHeader)]); 79 80 std::unique_ptr<EbpfDataParser> ebpfDataParser = 81 std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 82 EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer, dequeBuffer.size())); 83 EXPECT_TRUE(ebpfDataParser->reader_->GetPagedMemoryMap().size()); 84 ebpfDataParser->ParsePagedMemoryEvent(); 85 ebpfDataParser->Finish(); 86 EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME); 87 auto callChainId = stream_.traceDataCache_->GetConstPagedMemorySampleData().CallChainIds()[0]; 88 EXPECT_EQ(callChainId, INVALID_UINT64); 89 auto type = stream_.traceDataCache_->GetConstPagedMemorySampleData().Types()[0]; 90 EXPECT_EQ(type, 2); 91 92 auto startTs = stream_.traceDataCache_->GetConstPagedMemorySampleData().StartTs()[0]; 93 EXPECT_EQ(startTs, START_TIME); 94 auto endTs = stream_.traceDataCache_->GetConstPagedMemorySampleData().EndTs()[0]; 95 EXPECT_EQ(endTs, END_TIME); 96 auto dur = stream_.traceDataCache_->GetConstPagedMemorySampleData().Durs()[0]; 97 EXPECT_EQ(dur, END_TIME - START_TIME); 98 auto size = stream_.traceDataCache_->GetConstPagedMemorySampleData().Sizes()[0]; 99 EXPECT_EQ(size, 1); 100 auto ExpectAddr = ebpfDataParser->ConvertToHexTextIndex(pagedMemoryFixedHeader.addr); 101 auto addr = stream_.traceDataCache_->GetConstPagedMemorySampleData().Addr()[0]; 102 EXPECT_EQ(addr, ExpectAddr); 103 } 104 105 /** 106 * @tc.name: EbpfPagedMemoryParserwrongWithoutCallback 107 * @tc.desc: Test parse pagedMem data without callback and startTs > endTs 108 * @tc.type: FUNC 109 */ 110 HWTEST_F(EbpfPagedMemoryParserTest, EbpfPagedMemoryParserwrongWithoutCallback, TestSize.Level1) 111 { 112 TS_LOGI("test31-2"); 113 EbpfDataHeader ebpfHeader; 114 ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME; 115 ebpfHeader.header.cmdLineLen = COMMAND_LINE.length(); 116 memcpy_s(ebpfHeader.cmdline, EBPF_COMMAND_MAX_SIZE, COMMAND_LINE.c_str(), COMMAND_LINE.length()); 117 std::deque<uint8_t> dequeBuffer; 118 dequeBuffer.insert(dequeBuffer.end(), &(reinterpret_cast<uint8_t*>(&ebpfHeader))[0], 119 &(reinterpret_cast<uint8_t*>(&ebpfHeader))[EbpfDataHeader::EBPF_DATA_HEADER_SIZE]); 120 EbpfTypeAndLength ebpfTypeAndLength; 121 ebpfTypeAndLength.length = sizeof(PagedMemoryFixedHeader); 122 ebpfTypeAndLength.type = ITEM_EVENT_VM; 123 PagedMemoryFixedHeader pagedMemoryFixedHeader; 124 pagedMemoryFixedHeader.pid = 32; 125 pagedMemoryFixedHeader.tid = 32; 126 memcpy_s(pagedMemoryFixedHeader.comm, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE); 127 pagedMemoryFixedHeader.startTime = END_TIME; 128 pagedMemoryFixedHeader.endTime = START_TIME; 129 pagedMemoryFixedHeader.addr = PAGEED_MEM_ADDR; 130 pagedMemoryFixedHeader.size = 1; 131 pagedMemoryFixedHeader.nips = 0; 132 pagedMemoryFixedHeader.type = 2; 133 dequeBuffer.insert(dequeBuffer.end(), &(reinterpret_cast<uint8_t*>(&ebpfTypeAndLength))[0], 134 &(reinterpret_cast<uint8_t*>(&ebpfTypeAndLength))[sizeof(EbpfTypeAndLength)]); 135 dequeBuffer.insert(dequeBuffer.end(), &(reinterpret_cast<uint8_t*>(&pagedMemoryFixedHeader))[0], 136 &(reinterpret_cast<uint8_t*>(&pagedMemoryFixedHeader))[sizeof(PagedMemoryFixedHeader)]); 137 138 std::unique_ptr<EbpfDataParser> ebpfDataParser = 139 std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 140 EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer, dequeBuffer.size())); 141 EXPECT_TRUE(ebpfDataParser->reader_->GetPagedMemoryMap().size()); 142 ebpfDataParser->ParsePagedMemoryEvent(); 143 ebpfDataParser->Finish(); 144 EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME); 145 auto callChainId = stream_.traceDataCache_->GetConstPagedMemorySampleData().CallChainIds()[0]; 146 EXPECT_FALSE(callChainId == INVALID_UINT64); 147 auto type = stream_.traceDataCache_->GetConstPagedMemorySampleData().Types()[0]; 148 EXPECT_FALSE(type == 2); 149 150 auto startTs = stream_.traceDataCache_->GetConstPagedMemorySampleData().StartTs()[0]; 151 EXPECT_FALSE(startTs == pagedMemoryFixedHeader.startTime); 152 auto endTs = stream_.traceDataCache_->GetConstPagedMemorySampleData().EndTs()[0]; 153 EXPECT_FALSE(endTs == pagedMemoryFixedHeader.endTime); 154 auto dur = stream_.traceDataCache_->GetConstPagedMemorySampleData().Durs()[0]; 155 EXPECT_FALSE(dur == endTs - startTs); 156 auto size = stream_.traceDataCache_->GetConstPagedMemorySampleData().Sizes()[0]; 157 EXPECT_FALSE(size == 1); 158 auto ExpectAddr = ebpfDataParser->ConvertToHexTextIndex(pagedMemoryFixedHeader.addr); 159 auto addr = stream_.traceDataCache_->GetConstPagedMemorySampleData().Addr()[0]; 160 EXPECT_FALSE(addr == ExpectAddr); 161 } 162 163 /** 164 * @tc.name: EbpfPagedMemoryParserCorrectWithOneCallback 165 * @tc.desc: Test parse PagedMem data with one callback 166 * @tc.type: FUNC 167 */ 168 HWTEST_F(EbpfPagedMemoryParserTest, EbpfPagedMemoryParserCorrectWithOneCallback, TestSize.Level1) 169 { 170 TS_LOGI("test31-3"); 171 EbpfDataHeader ebpfHeader; 172 ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME; 173 ebpfHeader.header.cmdLineLen = COMMAND_LINE.length(); 174 memcpy_s(ebpfHeader.cmdline, EBPF_COMMAND_MAX_SIZE, COMMAND_LINE.c_str(), COMMAND_LINE.length()); 175 std::deque<uint8_t> dequeBuffer; 176 dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfHeader), 177 reinterpret_cast<uint8_t*>(&ebpfHeader + 1)); 178 EbpfTypeAndLength ebpfTypeAndLength; 179 ebpfTypeAndLength.length = sizeof(PagedMemoryFixedHeader); 180 ebpfTypeAndLength.type = ITEM_EVENT_VM; 181 PagedMemoryFixedHeader pagedMemoryFixedHeader; 182 pagedMemoryFixedHeader.pid = 32; 183 pagedMemoryFixedHeader.tid = 32; 184 memcpy_s(pagedMemoryFixedHeader.comm, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE); 185 pagedMemoryFixedHeader.startTime = START_TIME; 186 pagedMemoryFixedHeader.endTime = END_TIME; 187 pagedMemoryFixedHeader.addr = PAGEED_MEM_ADDR; 188 pagedMemoryFixedHeader.size = 1; 189 pagedMemoryFixedHeader.nips = 1; 190 pagedMemoryFixedHeader.type = 2; 191 const uint64_t ips[1] = {IPS_01}; 192 dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfTypeAndLength), 193 reinterpret_cast<uint8_t*>(&ebpfTypeAndLength + 1)); 194 dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&pagedMemoryFixedHeader), 195 reinterpret_cast<uint8_t*>(&pagedMemoryFixedHeader + 1)); 196 dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<const uint8_t*>(ips), 197 reinterpret_cast<const uint8_t*>(&ips + 1)); 198 std::unique_ptr<EbpfDataParser> ebpfDataParser = 199 std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 200 EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer, dequeBuffer.size())); 201 EXPECT_TRUE(ebpfDataParser->reader_->GetPagedMemoryMap().size()); 202 ebpfDataParser->ParsePagedMemoryEvent(); 203 ebpfDataParser->Finish(); 204 EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME); 205 auto callChainId = stream_.traceDataCache_->GetConstPagedMemorySampleData().CallChainIds()[0]; 206 EXPECT_EQ(callChainId, 0); 207 auto type = stream_.traceDataCache_->GetConstPagedMemorySampleData().Types()[0]; 208 EXPECT_EQ(type, 2); 209 auto startTs = stream_.traceDataCache_->GetConstPagedMemorySampleData().StartTs()[0]; 210 EXPECT_EQ(startTs, START_TIME); 211 auto endTs = stream_.traceDataCache_->GetConstPagedMemorySampleData().EndTs()[0]; 212 EXPECT_EQ(endTs, END_TIME); 213 auto dur = stream_.traceDataCache_->GetConstPagedMemorySampleData().Durs()[0]; 214 EXPECT_EQ(dur, END_TIME - START_TIME); 215 auto size = stream_.traceDataCache_->GetConstPagedMemorySampleData().Sizes()[0]; 216 EXPECT_EQ(size, 1); 217 auto ExpectAddr = ebpfDataParser->ConvertToHexTextIndex(pagedMemoryFixedHeader.addr); 218 auto addr = stream_.traceDataCache_->GetConstPagedMemorySampleData().Addr()[0]; 219 EXPECT_EQ(addr, ExpectAddr); 220 auto ExpectIps0 = ebpfDataParser->ConvertToHexTextIndex(ips[0]); 221 auto ips0 = stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[0]; 222 EXPECT_EQ(ips0, ExpectIps0); 223 } 224 225 /** 226 * @tc.name: EbpfPagedMemoryParserCorrectWithMultipleCallback 227 * @tc.desc: Test parse PagedMem data with Multiple callback 228 * @tc.type: FUNC 229 */ 230 HWTEST_F(EbpfPagedMemoryParserTest, EbpfPagedMemoryParserCorrectWithMultipleCallback, TestSize.Level1) 231 { 232 TS_LOGI("test31-4"); 233 EbpfDataHeader ebpfHeader; 234 ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME; 235 ebpfHeader.header.cmdLineLen = COMMAND_LINE.length(); 236 memcpy_s(ebpfHeader.cmdline, EBPF_COMMAND_MAX_SIZE, COMMAND_LINE.c_str(), COMMAND_LINE.length()); 237 std::deque<uint8_t> dequeBuffer; 238 dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfHeader), 239 reinterpret_cast<uint8_t*>(&ebpfHeader + 1)); 240 EbpfTypeAndLength ebpfTypeAndLength; 241 ebpfTypeAndLength.length = sizeof(PagedMemoryFixedHeader) + 2 * sizeof(uint64_t); 242 ebpfTypeAndLength.type = ITEM_EVENT_VM; 243 PagedMemoryFixedHeader pagedMemoryFixedHeader; 244 pagedMemoryFixedHeader.pid = 32; 245 pagedMemoryFixedHeader.tid = 32; 246 memcpy_s(pagedMemoryFixedHeader.comm, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE); 247 pagedMemoryFixedHeader.startTime = START_TIME; 248 pagedMemoryFixedHeader.endTime = END_TIME; 249 pagedMemoryFixedHeader.addr = PAGEED_MEM_ADDR; 250 pagedMemoryFixedHeader.size = 1; 251 pagedMemoryFixedHeader.nips = 2; 252 pagedMemoryFixedHeader.type = 2; 253 const uint64_t ips[2] = {IPS_01, IPS_02}; 254 dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&ebpfTypeAndLength), 255 reinterpret_cast<uint8_t*>(&ebpfTypeAndLength + 1)); 256 dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<uint8_t*>(&pagedMemoryFixedHeader), 257 reinterpret_cast<uint8_t*>(&pagedMemoryFixedHeader + 1)); 258 dequeBuffer.insert(dequeBuffer.end(), reinterpret_cast<const uint8_t*>(ips), 259 reinterpret_cast<const uint8_t*>(&ips + 1)); 260 std::unique_ptr<EbpfDataParser> ebpfDataParser = 261 std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 262 EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer, dequeBuffer.size())); 263 EXPECT_TRUE(ebpfDataParser->reader_->GetPagedMemoryMap().size()); 264 ebpfDataParser->ParsePagedMemoryEvent(); 265 ebpfDataParser->Finish(); 266 EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME); 267 auto callChainId = stream_.traceDataCache_->GetConstPagedMemorySampleData().CallChainIds()[0]; 268 EXPECT_EQ(callChainId, 0); 269 auto type = stream_.traceDataCache_->GetConstPagedMemorySampleData().Types()[0]; 270 EXPECT_EQ(type, 2); 271 auto startTs = stream_.traceDataCache_->GetConstPagedMemorySampleData().StartTs()[0]; 272 EXPECT_EQ(startTs, START_TIME); 273 auto endTs = stream_.traceDataCache_->GetConstPagedMemorySampleData().EndTs()[0]; 274 EXPECT_EQ(endTs, END_TIME); 275 auto dur = stream_.traceDataCache_->GetConstPagedMemorySampleData().Durs()[0]; 276 EXPECT_EQ(dur, END_TIME - START_TIME); 277 auto size = stream_.traceDataCache_->GetConstPagedMemorySampleData().Sizes()[0]; 278 EXPECT_EQ(size, 1); 279 auto ExpectAddr = ebpfDataParser->ConvertToHexTextIndex(pagedMemoryFixedHeader.addr); 280 auto addr = stream_.traceDataCache_->GetConstPagedMemorySampleData().Addr()[0]; 281 EXPECT_EQ(addr, ExpectAddr); 282 auto ExpectIps0 = ebpfDataParser->ConvertToHexTextIndex(ips[0]); 283 auto ips0 = stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[1]; 284 EXPECT_EQ(ips0, ExpectIps0); 285 auto ExpectIps1 = ebpfDataParser->ConvertToHexTextIndex(ips[1]); 286 auto ips1 = stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[0]; 287 EXPECT_EQ(ips1, ExpectIps1); 288 } 289 } // namespace SysTuning::TraceStreamer 290