1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "perf_file_format_test.h"
17
18 using namespace testing::ext;
19
20 namespace OHOS {
21 namespace Developtools {
22 namespace HiPerf {
23 class PerfFileFormatTest : public testing::Test {
24 public:
25 static void SetUpTestCase(void);
26 static void TearDownTestCase(void);
27 void SetUp();
28 void TearDown();
29
30 static void CompareVecSymFile(const std::vector<SymbolFileStruct> &a,
31 const std::vector<SymbolFileStruct> &b);
32 static void TestEventDescInit(std::vector<AttrWithId> &eventDesc, size_t &size);
33 static void CompareEventDesc(const std::vector<AttrWithId> &a,
34 const std::vector<AttrWithId> &b);
35
36 static const uint32_t BIGK = 1024;
37 static const uint32_t TESTNUMBER1 = 1;
38 static const uint32_t TESTNUMBER2 = 2;
39 static const uint32_t TESTNUMBER3 = 3;
40 static const uint32_t TESTNUMBER4 = 4;
41 static const uint32_t TESTNUMBER5 = 5;
42 static const int TWO = 2;
43 };
44
SetUpTestCase()45 void PerfFileFormatTest::SetUpTestCase() {}
46
TearDownTestCase()47 void PerfFileFormatTest::TearDownTestCase() {}
48
SetUp()49 void PerfFileFormatTest::SetUp() {}
50
TearDown()51 void PerfFileFormatTest::TearDown() {}
52
53 /**
54 * @tc.name: Test
55 * @tc.desc: push several records of all type into the buffer
56 * @tc.type: FUNC
57 */
58 HWTEST_F(PerfFileFormatTest, GetFeatureName, TestSize.Level1)
59 {
60 const char *unknownFeature = "unknown_feature";
61
62 FEATURE i = FEATURE::FIRST_FEATURE;
63 while (i <= FEATURE::LAST_FEATURE) {
64 std::string name = PerfFileSection::GetFeatureName(i);
65 ASSERT_NE(name, "") << "must return a string";
66 ASSERT_NE(name, unknownFeature) << "should be special name";
67 i = FEATURE(int(i) + 1);
68 }
69 while (i < FEATURE::HIPERF_FIRST_FEATURE) {
70 std::string name = PerfFileSection::GetFeatureName(i);
71 ASSERT_EQ(name, unknownFeature) << "should be unknown";
72 i = FEATURE(int(i) + 1);
73 }
74 while (i <= FEATURE::HIPERF_LAST_FEATURE) {
75 std::string name = PerfFileSection::GetFeatureName(i);
76 ASSERT_NE(name, "") << "must return a string";
77 ASSERT_NE(name, unknownFeature) << "should be special name";
78 i = FEATURE(int(i) + 1);
79 }
80 while (i <= FEATURE::FEATURE_MAX_BITS) {
81 std::string name = PerfFileSection::GetFeatureName(i);
82 ASSERT_EQ(name, unknownFeature) << "should be unknown";
83 i = FEATURE(int(i) + 1);
84 }
85 }
86
87 HWTEST_F(PerfFileFormatTest, PerfFileSectionString, TestSize.Level1)
88 {
89 std::string testString("this is test string");
90 char buff[BIGK] = {0};
91 perf_header_string *p = reinterpret_cast<perf_header_string *>(&buff[0]);
92
93 PerfFileSectionString withString = {FEATURE::RESERVED, testString};
94 ASSERT_EQ(withString.ToString(), testString);
95 ASSERT_EQ(withString.GetSize(), (testString.size() + sizeof(uint32_t) + 1));
96 ASSERT_TRUE(withString.GetBinary(buff, sizeof(buff)));
97 ASSERT_EQ(testString, p->string);
98
99 PerfFileSectionString withBuff(FEATURE::RESERVED, buff, sizeof(buff));
100 ASSERT_EQ(withBuff.ToString(), testString);
101 ASSERT_EQ(withBuff.GetSize(), (testString.size() + sizeof(uint32_t) + 1));
102 ASSERT_TRUE(withBuff.GetBinary(buff, sizeof(buff)));
103 ASSERT_EQ(testString, p->string);
104 }
105
CompareVecSymFile(const std::vector<SymbolFileStruct> & a,const std::vector<SymbolFileStruct> & b)106 void PerfFileFormatTest::CompareVecSymFile(const std::vector<SymbolFileStruct> &a,
107 const std::vector<SymbolFileStruct> &b)
108 {
109 ASSERT_EQ(a.size(), b.size());
110 for (size_t i = 0; i < a.size(); i++) {
111 ASSERT_EQ(a[i].filePath_, b[i].filePath_);
112 ASSERT_EQ(a[i].symbolType_, b[i].symbolType_);
113 ASSERT_EQ(a[i].textExecVaddr_, b[i].textExecVaddr_);
114 ASSERT_EQ(a[i].textExecVaddrFileOffset_, b[i].textExecVaddrFileOffset_);
115 ASSERT_EQ(a[i].buildId_, b[i].buildId_);
116 ASSERT_EQ(a[i].symbolStructs_.size(), b[i].symbolStructs_.size());
117 for (size_t j = 0; j < a[i].symbolStructs_.size(); j++) {
118 ASSERT_EQ(a[i].symbolStructs_[j].vaddr_, b[i].symbolStructs_[j].vaddr_);
119 ASSERT_EQ(a[i].symbolStructs_[j].len_, b[i].symbolStructs_[j].len_);
120 ASSERT_EQ(a[i].symbolStructs_[j].symbolName_, b[i].symbolStructs_[j].symbolName_);
121 }
122 }
123 }
124
125 HWTEST_F(PerfFileFormatTest, PerfFileSectionSymbolsFiles, TestSize.Level1)
126 {
127 std::vector<SymbolFileStruct> testVecSymFile;
128 char buff[BIGK] = {0};
129
130 size_t testSize = sizeof(uint32_t);
131 int count = TWO;
132 while (count--) {
133 auto &symFile = testVecSymFile.emplace_back();
134 symFile.filePath_ = "this is test";
135 testSize += (sizeof(uint32_t) + symFile.filePath_.size() + 1);
136 symFile.symbolType_ = BIGK;
137 testSize += sizeof(symFile.symbolType_);
138 symFile.textExecVaddr_ = BIGK;
139 testSize += sizeof(symFile.textExecVaddr_);
140 symFile.textExecVaddrFileOffset_ = BIGK;
141 testSize += sizeof(symFile.textExecVaddrFileOffset_);
142 symFile.buildId_ = "this is test";
143 testSize += (sizeof(uint32_t) + symFile.buildId_.size() + 1);
144
145 testSize += sizeof(uint32_t);
146 auto &symbol = symFile.symbolStructs_.emplace_back();
147 symbol.vaddr_ = BIGK;
148 testSize += sizeof(symbol.vaddr_);
149 symbol.len_ = BIGK;
150 testSize += sizeof(symbol.len_);
151 symbol.symbolName_ = "this is test";
152 testSize += (sizeof(uint32_t) + symbol.symbolName_.size() + 1);
153 }
154
155 PerfFileSectionSymbolsFiles withVector(FEATURE::RESERVED, testVecSymFile);
156 ASSERT_EQ(withVector.GetSize(), testSize);
157 ASSERT_TRUE(withVector.GetBinary(buff, BIGK));
158
159 PerfFileSectionSymbolsFiles withBUff(FEATURE::RESERVED, buff, BIGK);
160 CompareVecSymFile(withBUff.symbolFileStructs_, testVecSymFile);
161 }
162
163 HWTEST_F(PerfFileFormatTest, PerfFileSectionNrCpus, TestSize.Level1)
164 {
165 uint32_t nr[2] = {TESTNUMBER1, TESTNUMBER2};
166 char buff[BIGK] = {0};
167
168 PerfFileSectionNrCpus nrCpus = {FEATURE::NRCPUS, nr[0], nr[1]};
169 ASSERT_EQ(nrCpus.GetSize(), (sizeof(uint32_t) + sizeof(uint32_t)));
170 ASSERT_TRUE(nrCpus.GetBinary(buff, sizeof(buff)));
171
172 PerfFileSectionNrCpus withBuff(FEATURE::NRCPUS, buff, sizeof(buff));
173 uint32_t nrAvailable = 0;
174 uint32_t nrOnline = 0;
175 withBuff.GetValue(nrAvailable, nrOnline);
176 ASSERT_EQ(nrAvailable, nr[0]);
177 ASSERT_EQ(nrOnline, nr[1]);
178 ASSERT_EQ(withBuff.featureId_, FEATURE::NRCPUS);
179 }
180
181 HWTEST_F(PerfFileFormatTest, PerfFileSectionU64, TestSize.Level1)
182 {
183 uint64_t v = TESTNUMBER1;
184 char buff[BIGK] = {0};
185
186 PerfFileSectionU64 pfsu64 = {FEATURE::RESERVED, v};
187 ASSERT_EQ(pfsu64.GetSize(), sizeof(v));
188 ASSERT_TRUE(pfsu64.GetBinary(buff, sizeof(buff)));
189
190 PerfFileSectionU64 withBuff(FEATURE::RESERVED, buff, sizeof(buff));
191 uint64_t vCheck = 0;
192 withBuff.GetValue(vCheck);
193 ASSERT_EQ(vCheck, v);
194 ASSERT_EQ(withBuff.featureId_, FEATURE::RESERVED);
195 }
196
TestEventDescInit(std::vector<AttrWithId> & eventDesc,size_t & size)197 void PerfFileFormatTest::TestEventDescInit(std::vector<AttrWithId> &eventDesc, size_t &size)
198 {
199 size = sizeof(uint32_t) + sizeof(uint32_t); // nr + attr_size
200 for (uint32_t nr = TESTNUMBER2; nr > 0; nr--) {
201 auto &item = eventDesc.emplace_back();
202 size += sizeof(perf_event_attr);
203 item.attr = {};
204 item.attr.size = 0;
205 item.attr.type = TESTNUMBER1 * nr;
206 item.attr.config = TESTNUMBER2 * nr;
207 item.attr.__reserved_2 = TESTNUMBER3 * nr;
208 item.ids = {TESTNUMBER4 * nr, TESTNUMBER5 * nr};
209 size += sizeof(uint32_t); // nr_ids
210 size += (sizeof(uint64_t) * item.ids.size());
211 item.name = "123456789";
212 size += sizeof(uint32_t) + item.name.size() + 1;
213 }
214 }
215
CompareEventDesc(const std::vector<AttrWithId> & a,const std::vector<AttrWithId> & b)216 void PerfFileFormatTest::CompareEventDesc(const std::vector<AttrWithId> &a,
217 const std::vector<AttrWithId> &b)
218 {
219 ASSERT_EQ(a.size(), b.size());
220 for (size_t i = 0; i < a.size(); i++) {
221 ASSERT_EQ(a[i].name, b[i].name);
222 ASSERT_EQ(a[i].attr.size, b[i].attr.size);
223 ASSERT_EQ(a[i].attr.type, b[i].attr.type);
224 ASSERT_EQ(a[i].attr.config, b[i].attr.config);
225 ASSERT_EQ(a[i].attr.__reserved_2, b[i].attr.__reserved_2);
226 ASSERT_EQ(a[i].ids.size(), b[i].ids.size());
227 for (size_t j = 0; j < a[i].ids.size(); j++) {
228 ASSERT_EQ(a[i].ids[j], b[i].ids[j]);
229 }
230 }
231 }
232
233 HWTEST_F(PerfFileFormatTest, PerfFileSectionEventDesc, TestSize.Level1)
234 {
235 std::vector<AttrWithId> eventDesc;
236 size_t size = 0;
237 TestEventDescInit(eventDesc, size);
238 char buff[BIGK] = {0};
239
240 PerfFileSectionEventDesc pfsEventDesc = {FEATURE::EVENT_DESC, eventDesc};
241 ASSERT_EQ(pfsEventDesc.GetSize(), size);
242 ASSERT_TRUE(pfsEventDesc.GetBinary(buff, sizeof(buff)));
243
244 PerfFileSectionEventDesc withBuff(FEATURE::EVENT_DESC, buff, sizeof(buff));
245 std::vector<AttrWithId> eventDescOut;
246 withBuff.GetValue(eventDescOut);
247 CompareEventDesc(eventDesc, eventDescOut);
248 ASSERT_EQ(withBuff.featureId_, FEATURE::EVENT_DESC);
249 }
250
251 HWTEST_F(PerfFileFormatTest, PerfFileSectionEventDesc2, TestSize.Level1)
252 {
253 pid_t pid = fork();
254 ASSERT_NE(pid, -1);
255
256 if (pid == 0) {
257 char buff[BIGK] = {0};
258 buff[0] = 1;
259 buff[4] = sizeof(perf_event_attr);
260 for (uint32_t i = 8; i < BIGK; i += 4) {
261 buff[i] = 0;
262 }
263 // data for nrId
264 buff[sizeof(perf_event_attr) + 8] = 0x7f;
265 buff[sizeof(perf_event_attr) + 9] = 0x7f;
266 buff[sizeof(perf_event_attr) + 10] = 0x7f;
267 buff[sizeof(perf_event_attr) + 11] = 0x7f;
268
269 // data for size of eventDesc.name
270 buff[sizeof(perf_event_attr) + 12] = 0x02;
271 buff[sizeof(perf_event_attr) + 13] = 0x00;
272 buff[sizeof(perf_event_attr) + 14] = 0x00;
273 buff[sizeof(perf_event_attr) + 15] = 0x00;
274
275 PerfFileSectionEventDesc(FEATURE::EVENT_DESC, buff, sizeof(buff));
276 _exit(-2);
277 } else {
278 int status = 0;
279 waitpid(pid, &status, 0);
280 ASSERT_TRUE(WIFEXITED(status));
281 EXPECT_EQ(WEXITSTATUS(status), static_cast<uint8_t>(-1));
282 }
283 }
284 } // namespace HiPerf
285 } // namespace Developtools
286 } // namespace OHOS
287