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 "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 const uint64_t START_TIME = 1725645867369; 31 const uint64_t END_TIME = 1725645967369; 32 const uint64_t PAGEED_MEM_ADDR = 46549876; 33 const uint64_t IPS_01 = 548606407208; 34 const uint64_t IPS_02 = 548607407208; 35 const uint64_t EBPF_COMMAND_MAX_SIZE = 1000; 36 const uint64_t PID = 32; 37 const uint64_t TID = 32; 38 const uint16_t TYPE = 2; 39 40 class EbpfPagedMemoryParserTest : public ::testing::Test { 41 public: SetUp()42 void SetUp() 43 { 44 stream_.InitFilter(); 45 46 EbpfDataHeader ebpfHeader; 47 ebpfHeader.header.clock = EBPF_CLOCK_BOOTTIME; 48 ebpfHeader.header.cmdLineLen = COMMAND_LINE.length(); 49 memcpy_s(ebpfHeader.cmdline, EbpfDataHeader::EBPF_COMMAND_MAX_SIZE, COMMAND_LINE.c_str(), 50 COMMAND_LINE.length()); 51 dequeBuffer_.insert(dequeBuffer_.end(), &(reinterpret_cast<uint8_t *>(&ebpfHeader))[0], 52 &(reinterpret_cast<uint8_t *>(&ebpfHeader))[EbpfDataHeader::EBPF_DATA_HEADER_SIZE]); 53 } TearDown()54 void TearDown() {} 55 InitData(uint32_t length,uint16_t nips,uint64_t ts1=START_TIME,uint64_t ts2=END_TIME)56 void InitData(uint32_t length, uint16_t nips, uint64_t ts1 = START_TIME, uint64_t ts2 = END_TIME) 57 { 58 EbpfTypeAndLength ebpfTypeAndLength; 59 ebpfTypeAndLength.length = length; 60 ebpfTypeAndLength.type = ITEM_EVENT_VM; 61 pagedMemoryFixedHeader_.pid = PID; 62 pagedMemoryFixedHeader_.tid = TID; 63 memcpy_s(pagedMemoryFixedHeader_.comm, MAX_PROCESS_NAME_SZIE, "process", MAX_PROCESS_NAME_SZIE); 64 pagedMemoryFixedHeader_.startTime = ts1; 65 pagedMemoryFixedHeader_.endTime = ts2; 66 pagedMemoryFixedHeader_.addr = PAGEED_MEM_ADDR; 67 pagedMemoryFixedHeader_.size = 1; 68 pagedMemoryFixedHeader_.nips = nips; 69 pagedMemoryFixedHeader_.type = TYPE; 70 dequeBuffer_.insert(dequeBuffer_.end(), &(reinterpret_cast<uint8_t *>(&ebpfTypeAndLength))[0], 71 &(reinterpret_cast<uint8_t *>(&ebpfTypeAndLength))[sizeof(EbpfTypeAndLength)]); 72 dequeBuffer_.insert(dequeBuffer_.end(), &(reinterpret_cast<uint8_t *>(&pagedMemoryFixedHeader_))[0], 73 &(reinterpret_cast<uint8_t *>(&pagedMemoryFixedHeader_))[sizeof(PagedMemoryFixedHeader)]); 74 } 75 76 public: 77 TraceStreamerSelector stream_ = {}; 78 std::deque<uint8_t> dequeBuffer_; 79 PagedMemoryFixedHeader pagedMemoryFixedHeader_; 80 }; 81 82 /** 83 * @tc.name: EbpfPagedMemoryParserCorrectWithoutCallback 84 * @tc.desc: Test parse PagedMem data without callback 85 * @tc.type: FUNC 86 */ 87 HWTEST_F(EbpfPagedMemoryParserTest, EbpfPagedMemoryParserCorrectWithoutCallback, TestSize.Level1) 88 { 89 TS_LOGI("test31-1"); 90 91 InitData(sizeof(PagedMemoryFixedHeader), 0); 92 std::unique_ptr<EbpfDataParser> ebpfDataParser = 93 std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 94 EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer_, dequeBuffer_.size())); 95 EXPECT_TRUE(ebpfDataParser->reader_->GetPagedMemoryMap().size()); 96 ebpfDataParser->ParsePagedMemoryEvent(); 97 ebpfDataParser->Finish(); 98 EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME); 99 auto sampleData = stream_.traceDataCache_->GetConstPagedMemorySampleData(); 100 EXPECT_EQ(sampleData.CallChainIds()[0], INVALID_UINT32); 101 EXPECT_EQ(sampleData.Types()[0], 2); 102 EXPECT_EQ(sampleData.StartTs()[0], START_TIME); 103 EXPECT_EQ(sampleData.EndTs()[0], END_TIME); 104 EXPECT_EQ(sampleData.Durs()[0], END_TIME - START_TIME); 105 EXPECT_EQ(sampleData.Sizes()[0], 1); 106 EXPECT_EQ(sampleData.Addr()[0], ebpfDataParser->ConvertToHexTextIndex(pagedMemoryFixedHeader_.addr)); 107 } 108 109 /** 110 * @tc.name: EbpfPagedMemoryParserwrongWithoutCallback 111 * @tc.desc: Test parse pagedMem data without callback and startTs > endTs 112 * @tc.type: FUNC 113 */ 114 HWTEST_F(EbpfPagedMemoryParserTest, EbpfPagedMemoryParserwrongWithoutCallback, TestSize.Level1) 115 { 116 TS_LOGI("test31-2"); 117 118 InitData(sizeof(PagedMemoryFixedHeader), 0, END_TIME, START_TIME); 119 std::unique_ptr<EbpfDataParser> ebpfDataParser = 120 std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 121 EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer_, dequeBuffer_.size())); 122 EXPECT_TRUE(ebpfDataParser->reader_->GetPagedMemoryMap().size()); 123 ebpfDataParser->ParsePagedMemoryEvent(); 124 ebpfDataParser->Finish(); 125 EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME); 126 auto sampleData = stream_.traceDataCache_->GetConstPagedMemorySampleData(); 127 EXPECT_FALSE(sampleData.CallChainIds()[0] == INVALID_UINT32); 128 EXPECT_FALSE(sampleData.Types()[0] == 2); 129 auto startTs = sampleData.StartTs()[0]; 130 auto endTs = sampleData.EndTs()[0]; 131 EXPECT_FALSE(startTs == pagedMemoryFixedHeader_.startTime); 132 EXPECT_FALSE(endTs == pagedMemoryFixedHeader_.endTime); 133 EXPECT_FALSE(sampleData.Durs()[0] == endTs - startTs); 134 EXPECT_FALSE(sampleData.Sizes()[0] == 1); 135 EXPECT_FALSE(sampleData.Addr()[0] == ebpfDataParser->ConvertToHexTextIndex(pagedMemoryFixedHeader_.addr)); 136 } 137 138 /** 139 * @tc.name: EbpfPagedMemoryParserCorrectWithOneCallback 140 * @tc.desc: Test parse PagedMem data with one callback 141 * @tc.type: FUNC 142 */ 143 HWTEST_F(EbpfPagedMemoryParserTest, EbpfPagedMemoryParserCorrectWithOneCallback, TestSize.Level1) 144 { 145 TS_LOGI("test31-3"); 146 147 InitData(sizeof(PagedMemoryFixedHeader), 1); 148 const uint64_t ips[1] = {IPS_01}; 149 dequeBuffer_.insert(dequeBuffer_.end(), reinterpret_cast<const uint8_t *>(ips), 150 reinterpret_cast<const uint8_t *>(&ips + 1)); 151 std::unique_ptr<EbpfDataParser> ebpfDataParser = 152 std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 153 EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer_, dequeBuffer_.size())); 154 EXPECT_TRUE(ebpfDataParser->reader_->GetPagedMemoryMap().size()); 155 ebpfDataParser->ParsePagedMemoryEvent(); 156 ebpfDataParser->Finish(); 157 EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME); 158 auto sampleData = stream_.traceDataCache_->GetConstPagedMemorySampleData(); 159 EXPECT_EQ(sampleData.CallChainIds()[0], 0); 160 EXPECT_EQ(sampleData.Types()[0], 2); 161 EXPECT_EQ(sampleData.StartTs()[0], START_TIME); 162 EXPECT_EQ(sampleData.EndTs()[0], END_TIME); 163 EXPECT_EQ(sampleData.Durs()[0], END_TIME - START_TIME); 164 EXPECT_EQ(sampleData.Sizes()[0], 1); 165 EXPECT_EQ(sampleData.Addr()[0], ebpfDataParser->ConvertToHexTextIndex(pagedMemoryFixedHeader_.addr)); 166 EXPECT_EQ(stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[0], 167 ebpfDataParser->ConvertToHexTextIndex(ips[0])); 168 } 169 170 /** 171 * @tc.name: EbpfPagedMemoryParserCorrectWithMultipleCallback 172 * @tc.desc: Test parse PagedMem data with Multiple callback 173 * @tc.type: FUNC 174 */ 175 HWTEST_F(EbpfPagedMemoryParserTest, EbpfPagedMemoryParserCorrectWithMultipleCallback, TestSize.Level1) 176 { 177 TS_LOGI("test31-4"); 178 179 InitData(sizeof(PagedMemoryFixedHeader) + 2 * sizeof(uint64_t), 2); 180 const uint64_t ips[2] = {IPS_01, IPS_02}; 181 dequeBuffer_.insert(dequeBuffer_.end(), reinterpret_cast<const uint8_t *>(ips), 182 reinterpret_cast<const uint8_t *>(&ips + 1)); 183 std::unique_ptr<EbpfDataParser> ebpfDataParser = 184 std::make_unique<EbpfDataParser>(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 185 EXPECT_TRUE(ebpfDataParser->Init(dequeBuffer_, dequeBuffer_.size())); 186 EXPECT_TRUE(ebpfDataParser->reader_->GetPagedMemoryMap().size()); 187 ebpfDataParser->ParsePagedMemoryEvent(); 188 ebpfDataParser->Finish(); 189 EXPECT_TRUE(ebpfDataParser->reader_->ebpfDataHeader_->header.clock == EBPF_CLOCK_BOOTTIME); 190 auto sampleData = stream_.traceDataCache_->GetConstPagedMemorySampleData(); 191 EXPECT_EQ(sampleData.CallChainIds()[0], 0); 192 EXPECT_EQ(sampleData.Types()[0], 2); 193 EXPECT_EQ(sampleData.StartTs()[0], START_TIME); 194 EXPECT_EQ(sampleData.EndTs()[0], END_TIME); 195 EXPECT_EQ(sampleData.Durs()[0], END_TIME - START_TIME); 196 EXPECT_EQ(sampleData.Sizes()[0], 1); 197 EXPECT_EQ(sampleData.Addr()[0], ebpfDataParser->ConvertToHexTextIndex(pagedMemoryFixedHeader_.addr)); 198 EXPECT_EQ(stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[1], 199 ebpfDataParser->ConvertToHexTextIndex(ips[0])); 200 EXPECT_EQ(stream_.traceDataCache_->GetConstEbpfCallStackData().Ips()[0], 201 ebpfDataParser->ConvertToHexTextIndex(ips[1])); 202 } 203 } // namespace SysTuning::TraceStreamer 204