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