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