• 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 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