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 using namespace std;
20 using namespace OHOS::HiviewDFX;
21
22 namespace OHOS {
23 namespace Developtools {
24 namespace HiPerf {
25 class PerfFileFormatTest : public testing::Test {
26 public:
27 static void SetUpTestCase(void);
28 static void TearDownTestCase(void);
29 void SetUp();
30 void TearDown();
31
32 static void CompareVecSymFile(const std::vector<SymbolFileStruct> &a,
33 const std::vector<SymbolFileStruct> &b);
34 static void TestEventDescInit(std::vector<AttrWithId> &eventDesc, size_t &size);
35 static void CompareEventDesc(const std::vector<AttrWithId> &a,
36 const std::vector<AttrWithId> &b);
37
38 static const int BIGK = 1024;
39 static const int TWO = 2;
40 static const int TESTNUMBER1 = 1;
41 static const int TESTNUMBER2 = 2;
42 static const int TESTNUMBER3 = 3;
43 static const int TESTNUMBER4 = 4;
44 static const int TESTNUMBER5 = 5;
45 };
46
SetUpTestCase()47 void PerfFileFormatTest::SetUpTestCase() {}
48
TearDownTestCase()49 void PerfFileFormatTest::TearDownTestCase() {}
50
SetUp()51 void PerfFileFormatTest::SetUp() {}
52
TearDown()53 void PerfFileFormatTest::TearDown() {}
54
55 /**
56 * @tc.name: Test
57 * @tc.desc: push several records of all type into the buffer
58 * @tc.type: FUNC
59 */
60 HWTEST_F(PerfFileFormatTest, GetFeatureName, TestSize.Level1)
61 {
62 const char *unknownFeature = "unknown_feature";
63
64 FEATURE i = FEATURE::FIRST_FEATURE;
65 while (i <= FEATURE::LAST_FEATURE) {
66 std::string name = PerfFileSection::GetFeatureName(i);
67 ASSERT_NE(name, "") << "must return a string";
68 ASSERT_NE(name, unknownFeature) << "should be special name";
69 i = FEATURE(int(i) + 1);
70 }
71 while (i < FEATURE::HIPERF_FIRST_FEATURE) {
72 std::string name = PerfFileSection::GetFeatureName(i);
73 ASSERT_EQ(name, unknownFeature) << "should be unknown";
74 i = FEATURE(int(i) + 1);
75 }
76 while (i <= FEATURE::HIPERF_LAST_FEATURE) {
77 std::string name = PerfFileSection::GetFeatureName(i);
78 ASSERT_NE(name, "") << "must return a string";
79 ASSERT_NE(name, unknownFeature) << "should be special name";
80 i = FEATURE(int(i) + 1);
81 }
82 while (i <= FEATURE::FEATURE_MAX_BITS) {
83 std::string name = PerfFileSection::GetFeatureName(i);
84 ASSERT_EQ(name, unknownFeature) << "should be unknown";
85 i = FEATURE(int(i) + 1);
86 }
87 }
88
89 HWTEST_F(PerfFileFormatTest, PerfFileSectionString, TestSize.Level1)
90 {
91 std::string testString("this is test string");
92 char buff[BIGK] = {0};
93 perf_header_string *p = reinterpret_cast<perf_header_string *>(&buff[0]);
94
95 PerfFileSectionString withString = {FEATURE::RESERVED, testString};
96 ASSERT_EQ(withString.toString(), testString);
97 ASSERT_EQ(withString.GetSize(), (testString.size() + sizeof(uint32_t) + 1));
98 ASSERT_TRUE(withString.GetBinary(buff, sizeof(buff)));
99 ASSERT_EQ(testString, p->string);
100
101 PerfFileSectionString withBuff(FEATURE::RESERVED, buff, sizeof(buff));
102 ASSERT_EQ(withBuff.toString(), testString);
103 ASSERT_EQ(withBuff.GetSize(), (testString.size() + sizeof(uint32_t) + 1));
104 ASSERT_TRUE(withBuff.GetBinary(buff, sizeof(buff)));
105 ASSERT_EQ(testString, p->string);
106 }
107
CompareVecSymFile(const std::vector<SymbolFileStruct> & a,const std::vector<SymbolFileStruct> & b)108 void PerfFileFormatTest::CompareVecSymFile(const std::vector<SymbolFileStruct> &a,
109 const std::vector<SymbolFileStruct> &b)
110 {
111 ASSERT_EQ(a.size(), b.size());
112 for (size_t i = 0; i < a.size(); i++) {
113 ASSERT_EQ(a[i].filePath_, b[i].filePath_);
114 ASSERT_EQ(a[i].symbolType_, b[i].symbolType_);
115 ASSERT_EQ(a[i].textExecVaddr_, b[i].textExecVaddr_);
116 ASSERT_EQ(a[i].textExecVaddrFileOffset_, b[i].textExecVaddrFileOffset_);
117 ASSERT_EQ(a[i].buildId_, b[i].buildId_);
118 ASSERT_EQ(a[i].symbolStructs_.size(), b[i].symbolStructs_.size());
119 for (size_t j = 0; j < a[i].symbolStructs_.size(); j++) {
120 ASSERT_EQ(a[i].symbolStructs_[j].vaddr_, b[i].symbolStructs_[j].vaddr_);
121 ASSERT_EQ(a[i].symbolStructs_[j].len_, b[i].symbolStructs_[j].len_);
122 ASSERT_EQ(a[i].symbolStructs_[j].symbolName_, b[i].symbolStructs_[j].symbolName_);
123 }
124 }
125 }
126
127 HWTEST_F(PerfFileFormatTest, PerfFileSectionSymbolsFiles, TestSize.Level1)
128 {
129 std::vector<SymbolFileStruct> testVecSymFile;
130 char buff[BIGK] = {0};
131
132 size_t testSize = sizeof(uint32_t);
133 int count = TWO;
134 while (count--) {
135 auto &symFile = testVecSymFile.emplace_back();
136 symFile.filePath_ = "this is test";
137 testSize += (sizeof(uint32_t) + symFile.filePath_.size() + 1);
138 symFile.symbolType_ = BIGK;
139 testSize += sizeof(symFile.symbolType_);
140 symFile.textExecVaddr_ = BIGK;
141 testSize += sizeof(symFile.textExecVaddr_);
142 symFile.textExecVaddrFileOffset_ = BIGK;
143 testSize += sizeof(symFile.textExecVaddrFileOffset_);
144 symFile.buildId_ = "this is test";
145 testSize += (sizeof(uint32_t) + symFile.buildId_.size() + 1);
146
147 testSize += sizeof(uint32_t);
148 auto &symbol = symFile.symbolStructs_.emplace_back();
149 symbol.vaddr_ = BIGK;
150 testSize += sizeof(symbol.vaddr_);
151 symbol.len_ = BIGK;
152 testSize += sizeof(symbol.len_);
153 symbol.symbolName_ = "this is test";
154 testSize += (sizeof(uint32_t) + symbol.symbolName_.size() + 1);
155 }
156
157 PerfFileSectionSymbolsFiles withVector(FEATURE::RESERVED, testVecSymFile);
158 ASSERT_EQ(withVector.GetSize(), testSize);
159 ASSERT_TRUE(withVector.GetBinary(buff, BIGK));
160
161 PerfFileSectionSymbolsFiles withBUff(FEATURE::RESERVED, buff, BIGK);
162 CompareVecSymFile(withBUff.symbolFileStructs_, testVecSymFile);
163 }
164
165 HWTEST_F(PerfFileFormatTest, PerfFileSectionNrCpus, TestSize.Level1)
166 {
167 uint32_t nr[2] = {TESTNUMBER1, TESTNUMBER2};
168 char buff[BIGK] = {0};
169
170 PerfFileSectionNrCpus nrCpus = {FEATURE::NRCPUS, nr[0], nr[1]};
171 ASSERT_EQ(nrCpus.GetSize(), (sizeof(uint32_t) + sizeof(uint32_t)));
172 ASSERT_TRUE(nrCpus.GetBinary(buff, sizeof(buff)));
173
174 PerfFileSectionNrCpus withBuff(FEATURE::NRCPUS, buff, sizeof(buff));
175 uint32_t nrAvailable = 0;
176 uint32_t nrOnline = 0;
177 withBuff.GetValue(nrAvailable, nrOnline);
178 ASSERT_EQ(nrAvailable, nr[0]);
179 ASSERT_EQ(nrOnline, nr[1]);
180 ASSERT_EQ(withBuff.featureId_, FEATURE::NRCPUS);
181 }
182
183 HWTEST_F(PerfFileFormatTest, PerfFileSectionU64, TestSize.Level1)
184 {
185 uint64_t v = TESTNUMBER1;
186 char buff[BIGK] = {0};
187
188 PerfFileSectionU64 pfsu64 = {FEATURE::RESERVED, v};
189 ASSERT_EQ(pfsu64.GetSize(), sizeof(v));
190 ASSERT_TRUE(pfsu64.GetBinary(buff, sizeof(buff)));
191
192 PerfFileSectionU64 withBuff(FEATURE::RESERVED, buff, sizeof(buff));
193 uint64_t vCheck = 0;
194 withBuff.GetValue(vCheck);
195 ASSERT_EQ(vCheck, v);
196 ASSERT_EQ(withBuff.featureId_, FEATURE::RESERVED);
197 }
198
TestEventDescInit(std::vector<AttrWithId> & eventDesc,size_t & size)199 void PerfFileFormatTest::TestEventDescInit(std::vector<AttrWithId> &eventDesc, size_t &size)
200 {
201 size = sizeof(uint32_t) + sizeof(uint32_t); // nr + attr_size
202 for (uint32_t nr = TESTNUMBER2; nr > 0; nr--) {
203 auto &item = eventDesc.emplace_back();
204 size += sizeof(perf_event_attr);
205 item.attr = {};
206 item.attr.size = 0;
207 item.attr.type = TESTNUMBER1 * nr;
208 item.attr.config = TESTNUMBER2 * nr;
209 item.attr.__reserved_2 = TESTNUMBER3 * nr;
210 item.ids = {TESTNUMBER4 * nr, TESTNUMBER5 * nr};
211 size += sizeof(uint32_t); // nr_ids
212 size += (sizeof(uint64_t) * item.ids.size());
213 item.name = "123456789";
214 size += sizeof(uint32_t) + item.name.size() + 1;
215 }
216 }
217
CompareEventDesc(const std::vector<AttrWithId> & a,const std::vector<AttrWithId> & b)218 void PerfFileFormatTest::CompareEventDesc(const std::vector<AttrWithId> &a,
219 const std::vector<AttrWithId> &b)
220 {
221 ASSERT_EQ(a.size(), b.size());
222 for (size_t i = 0; i < a.size(); i++) {
223 ASSERT_EQ(a[i].name, b[i].name);
224 ASSERT_EQ(a[i].attr.size, b[i].attr.size);
225 ASSERT_EQ(a[i].attr.type, b[i].attr.type);
226 ASSERT_EQ(a[i].attr.config, b[i].attr.config);
227 ASSERT_EQ(a[i].attr.__reserved_2, b[i].attr.__reserved_2);
228 ASSERT_EQ(a[i].ids.size(), b[i].ids.size());
229 for (size_t j = 0; j < a[i].ids.size(); j++) {
230 ASSERT_EQ(a[i].ids[j], b[i].ids[j]);
231 }
232 }
233 }
234
235 HWTEST_F(PerfFileFormatTest, PerfFileSectionEventDesc, TestSize.Level1)
236 {
237 std::vector<AttrWithId> eventDesc;
238 size_t size = 0;
239 TestEventDescInit(eventDesc, size);
240 char buff[BIGK] = {0};
241
242 PerfFileSectionEventDesc pfsEventDesc = {FEATURE::EVENT_DESC, eventDesc};
243 ASSERT_EQ(pfsEventDesc.GetSize(), size);
244 ASSERT_TRUE(pfsEventDesc.GetBinary(buff, sizeof(buff)));
245
246 PerfFileSectionEventDesc withBuff(FEATURE::EVENT_DESC, buff, sizeof(buff));
247 std::vector<AttrWithId> eventDescOut;
248 withBuff.GetValue(eventDescOut);
249 CompareEventDesc(eventDesc, eventDescOut);
250 ASSERT_EQ(withBuff.featureId_, FEATURE::EVENT_DESC);
251 }
252 } // namespace HiPerf
253 } // namespace Developtools
254 } // namespace OHOS
255