• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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