• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "report_test.h"
17 
18 #include <bitset>
19 #include <sys/ioctl.h>
20 
21 using namespace testing::ext;
22 namespace OHOS {
23 namespace Developtools {
24 namespace HiPerf {
25 template<class T>
CompareNumberTest(T & lowValue,T & midValue,T & highValue,ReportKeyCompareFunction & compareFunction)26 void CompareNumberTest(T &lowValue, T &midValue, T &highValue,
27                        ReportKeyCompareFunction &compareFunction)
28 {
29     EXPECT_EQ(compareFunction(lowValue, midValue) < 0, true);
30     EXPECT_EQ(compareFunction(lowValue, highValue) < 0, true);
31     EXPECT_EQ(compareFunction(highValue, midValue) > 0, true);
32     EXPECT_EQ(compareFunction(highValue, lowValue) > 0, true);
33 }
34 
35 template<class T>
CompareStringTest(T & lowValue,T & midValue,T & highValue,ReportKeyCompareFunction & compareFunction)36 void CompareStringTest(T &lowValue, T &midValue, T &highValue,
37                        ReportKeyCompareFunction &compareFunction)
38 {
39     EXPECT_EQ(compareFunction(lowValue, midValue) < 0, true);
40     EXPECT_EQ(compareFunction(lowValue, highValue) < 0, true);
41     EXPECT_EQ(compareFunction(highValue, midValue) > 0, true);
42     EXPECT_EQ(compareFunction(highValue, lowValue) > 0, true);
43 }
44 class ReportTest : public testing::Test {
45 public:
46     static void SetUpTestCase(void);
47     static void TearDownTestCase(void);
48     void SetUp();
49     void TearDown();
50     std::unique_ptr<Report> report_ = nullptr;
51 };
52 
SetUpTestCase()53 void ReportTest::SetUpTestCase() {}
54 
TearDownTestCase()55 void ReportTest::TearDownTestCase() {}
56 
SetUp()57 void ReportTest::SetUp()
58 {
59     report_ = std::make_unique<Report>();
60     report_->configs_.emplace_back("dummy", 0, 0);
61     report_->configIdIndexMaps_.emplace(0u, 0u); // id 0 as config 0
62 }
63 
TearDown()64 void ReportTest::TearDown() {}
65 
GetNumberTest(const ReportItem & item,ReportKeyGetFunction & getFunction,uint64_t number,size_t len)66 void GetNumberTest(const ReportItem &item, ReportKeyGetFunction &getFunction, uint64_t number,
67                    size_t len)
68 {
69     ASSERT_GE(len, 3u);
70     std::string itemNumber = std::to_string(number);
71     EXPECT_STREQ(getFunction(item, 0, "%*" PRIu64 "").c_str(), itemNumber.c_str());
72     EXPECT_STREQ(getFunction(item, 1, "%*" PRIu64 "").c_str(), itemNumber.c_str());
73     EXPECT_STREQ(getFunction(item, 3, "%*" PRIu64 "").c_str(), itemNumber.c_str());
74     EXPECT_STREQ(getFunction(item, len + 1, "%*" PRIu64 "").c_str(), (" " + itemNumber).c_str());
75     EXPECT_STREQ(getFunction(item, len + 2, "%*" PRIu64 "").c_str(), ("  " + itemNumber).c_str());
76 }
77 
GetNumberTest(const ReportItem & item,ReportKeyGetFunction & getFunction,int number,size_t len)78 void GetNumberTest(const ReportItem &item, ReportKeyGetFunction &getFunction, int number,
79                    size_t len)
80 {
81     ASSERT_GE(len, 3u);
82     std::string itemNumber = std::to_string(number);
83     int num = 3;
84     int num2 = 2;
85     EXPECT_STREQ(getFunction(item, 0, "%*d").c_str(), itemNumber.c_str());
86     EXPECT_STREQ(getFunction(item, 1, "%*d").c_str(), itemNumber.c_str());
87     EXPECT_STREQ(getFunction(item, num, "%*d").c_str(), itemNumber.c_str());
88     EXPECT_STREQ(getFunction(item, len + 1, "%*d").c_str(), (" " + itemNumber).c_str());
89     EXPECT_STREQ(getFunction(item, len + num2, "%*d").c_str(), ("  " + itemNumber).c_str());
90 }
91 
GetStringTest(const ReportItem & item,ReportKeyGetFunction & getFunction,const std::string_view & itemString,size_t len)92 void GetStringTest(const ReportItem &item, ReportKeyGetFunction &getFunction,
93                    const std::string_view &itemString, size_t len)
94 {
95     int num = 3;
96     int num2 = 2;
97     ASSERT_GE(len, 3u);
98     EXPECT_STREQ(getFunction(item, 0, "%-*s").c_str(), itemString.data());
99     EXPECT_STREQ(getFunction(item, 1, "%-*s").c_str(), itemString.data());
100     EXPECT_STREQ(getFunction(item, num, "%-*s").c_str(), itemString.data());
101     EXPECT_STREQ(getFunction(item, len + 1, "%-*s").c_str(),
102                  (std::string(itemString) + " ").c_str());
103     EXPECT_STREQ(getFunction(item, len + num2, "%-*s").c_str(),
104                  (std::string(itemString) + "  ").c_str());
105 }
106 
107 /**
108  * @tc.name: ReportItemCallFrame Same
109  * @tc.desc:
110  * @tc.type: FUNC
111  */
112 HWTEST_F(ReportTest, ReportItemCallFrameSame, TestSize.Level1)
113 {
114     ReportItemCallFrame a("a", 0x0, "aa", 0, 0);
115     ReportItemCallFrame aDuplicated("a", 0x0, "aa", 0, 0);
116     ReportItemCallFrame a2("a2", 0x0, "aa", 0, 0);
117     ReportItemCallFrame aDiffAddr("a", 0x1234, "aa", 0, 0);
118     ReportItemCallFrame aDiffEvent("a", 0, "aa", 1234, 0);
119     ReportItemCallFrame aDiffSelfEvent("a", 0, "aa", 0, 1234);
120     ReportItemCallFrame aDiffDso("a", 0, "aa1234", 0, 1234);
121     ReportItemCallFrame b("b", 0x0, "bb", 0, 0);
122 
123     EXPECT_EQ(a == aDuplicated, true);
124     EXPECT_EQ(a == a2, false);
125     EXPECT_EQ(a == aDiffAddr, false);
126     EXPECT_EQ(a == aDiffEvent, true);
127     EXPECT_EQ(a == aDiffSelfEvent, true);
128     EXPECT_EQ(a == aDiffDso, false);
129     EXPECT_EQ(a == b, false);
130 }
131 
132 /**
133  * @tc.name: CompareSortingEventCount
134  * @tc.desc:
135  * @tc.type: FUNC
136  */
137 HWTEST_F(ReportTest, CompareSortingEventCount, TestSize.Level1)
138 {
139     ReportItemCallFrame a("a", 0x0, "aa", 0, 0);
140     ReportItemCallFrame a2("a", 0x0, "aa", 2, 0);
141     ReportItemCallFrame a200("a", 0x0, "aa", 200, 0);
142 
143     EXPECT_EQ(ReportItemCallFrame::CompareSortingEventCount(a, a), false);
144     EXPECT_EQ(ReportItemCallFrame::CompareSortingEventCount(a, a2), false);
145     EXPECT_EQ(ReportItemCallFrame::CompareSortingEventCount(a, a200), false);
146     EXPECT_EQ(ReportItemCallFrame::CompareSortingEventCount(a2, a200), false);
147     EXPECT_EQ(ReportItemCallFrame::CompareSortingEventCount(a200, a200), false);
148     EXPECT_EQ(ReportItemCallFrame::CompareSortingEventCount(a200, a2), true);
149     EXPECT_EQ(ReportItemCallFrame::CompareSortingEventCount(a200, a), true);
150 }
151 
152 /**
153  * @tc.name: OrderCallFrames
154  * @tc.desc:
155  * @tc.type: FUNC
156  */
157 HWTEST_F(ReportTest, OrderCallFrames, TestSize.Level1)
158 {
159     ReportItemCallFrame a100("a", 0x0, "aa", 100, 0);
160     ReportItemCallFrame a200("a", 0x0, "aa", 200, 0);
161     ReportItemCallFrame a300("a", 0x0, "aa", 300, 0);
162     std::vector<ReportItemCallFrame> callframes;
163 
164     // check empty no error
165     ReportItemCallFrame::OrderCallFrames(callframes);
166 
167     callframes.emplace_back(a100);
168     callframes.emplace_back(a200);
169     callframes.emplace_back(a200);
170     callframes.emplace_back(a300);
171 
172     // check order
173     ReportItemCallFrame::OrderCallFrames(callframes);
174     ASSERT_EQ(callframes.size() == 4u, true);
175     EXPECT_EQ(callframes[0] == a300, true);
176     EXPECT_EQ(callframes[1] == a200, true);
177     EXPECT_EQ(callframes[2] == a200, true);
178     EXPECT_EQ(callframes[3] == a100, true);
179 }
180 
181 /**
182  * @tc.name: ReportItemSame
183  * @tc.desc:
184  * @tc.type: FUNC
185  */
186 HWTEST_F(ReportTest, ReportItemSame, TestSize.Level1)
187 {
188     ReportItem a(1, 2, "comm", "dso", "func", 0x123, 1000);
189     ReportItem aDuplicated(1, 2, "comm", "dso", "func", 0x123, 1000);
190     ReportItem aDiffPid(10, 2, "comm", "dso", "func", 0x123, 1000);
191     ReportItem aDiffTid(1, 20, "comm", "dso", "func", 0x123, 1000);
192     ReportItem aDiffComm(1, 2, "comm0", "dso", "func", 0x123, 1000);
193     ReportItem aDiffDso(1, 2, "comm", "dso0", "func", 0x123, 1000);
194     ReportItem aDiffFunc(1, 2, "comm", "dso", "func0", 0x123, 1000);
195     ReportItem aDiffVaddr(1, 2, "comm", "dso", "func", 0x1230, 1000);
196     ReportItem aDiffEventCount(1, 2, "comm", "dso", "func", 0x123, 10000);
197 
198     EXPECT_EQ(a == aDuplicated, true);
199 
200     EXPECT_EQ(a == aDiffPid, false);
201     EXPECT_EQ(a == aDiffTid, false);
202     EXPECT_EQ(a == aDiffComm, false);
203     EXPECT_EQ(a == aDiffDso, false);
204     EXPECT_EQ(a == aDiffFunc, false);
205     EXPECT_EQ(a == aDiffVaddr, false);
206     EXPECT_EQ(a == aDiffEventCount, true);
207 }
208 
209 /**
210  * @tc.name: ReportItemCompareSortingEventCount
211  * @tc.desc:
212  * @tc.type: FUNC
213  */
214 HWTEST_F(ReportTest, ReportItemCompareSortingEventCount, TestSize.Level1)
215 {
216     ReportItem a123(1, 2, "comm", "dso", "func", 0x123, 123);
217     ReportItem a1234(1, 2, "comm", "dso", "func", 0x1234, 1234);
218     ReportItem a12345(1, 2, "comm", "dso", "func", 0x12345, 12345);
219 
220     EXPECT_EQ(ReportItem::CompareSortingEventCount(a123, a123), false);
221     EXPECT_EQ(ReportItem::CompareSortingEventCount(a123, a1234), false);
222     EXPECT_EQ(ReportItem::CompareSortingEventCount(a123, a12345), false);
223     EXPECT_EQ(ReportItem::CompareSortingEventCount(a1234, a12345), false);
224     EXPECT_EQ(ReportItem::CompareSortingEventCount(a12345, a12345), false);
225     EXPECT_EQ(ReportItem::CompareSortingEventCount(a12345, a1234), true);
226     EXPECT_EQ(ReportItem::CompareSortingEventCount(a1234, a123), true);
227 }
228 
229 /**
230  * @tc.name: CompareEventCount
231  * @tc.desc:
232  * @tc.type: FUNC
233  */
234 HWTEST_F(ReportTest, CompareEventCount, TestSize.Level1)
235 {
236     ReportItem low(1, 4, "comm", "dso", "func", 0x123, 123);
237     ReportItem mid(2, 5, "comm", "dso", "func", 0x1234, 1234);
238     ReportItem high(3, 6, "comm", "dso", "func", 0x12345, 12345);
239     CompareNumberTest(low, mid, high, ReportItem::CompareEventCount);
240 }
241 
242 /**
243  * @tc.name: GetEventCount
244  * @tc.desc:
245  * @tc.type: FUNC
246  */
247 HWTEST_F(ReportTest, GetEventCount, TestSize.Level1)
248 {
249     ReportItem a(123, 4, "comm", "dso", "func", 0x123, 123);
250     GetNumberTest(a, ReportItem::GetEventCount, a.eventCount_,
251                   std::to_string(a.eventCount_).length());
252 }
253 
254 /**
255  * @tc.name: ComparePid
256  * @tc.desc:
257  * @tc.type: FUNC
258  */
259 HWTEST_F(ReportTest, ComparePid, TestSize.Level1)
260 {
261     ReportItem low(1, 4, "comm", "dso", "func", 0x123, 123);
262     ReportItem mid(2, 5, "comm", "dso", "func", 0x1234, 1234);
263     ReportItem high(3, 6, "comm", "dso", "func", 0x12345, 12345);
264     CompareNumberTest(low, mid, high, ReportItem::ComparePid);
265 }
266 
267 /**
268  * @tc.name: GetPid
269  * @tc.desc:
270  * @tc.type: FUNC
271  */
272 HWTEST_F(ReportTest, GetPid, TestSize.Level1)
273 {
274     ReportItem a(123, 456, "comm", "dso", "func", 0x123, 123);
275     GetNumberTest(a, ReportItem::GetPid, a.pid_, std::to_string(a.pid_).length());
276 }
277 
278 /**
279  * @tc.name: CompareTid
280  * @tc.desc:
281  * @tc.type: FUNC
282  */
283 HWTEST_F(ReportTest, CompareTid, TestSize.Level1)
284 {
285     ReportItem low(1, 4, "comm", "dso", "func", 0x123, 123);
286     ReportItem mid(2, 5, "comm", "dso", "func", 0x1234, 1234);
287     ReportItem high(3, 6, "comm", "dso", "func", 0x12345, 12345);
288     CompareNumberTest(low, mid, high, ReportItem::CompareTid);
289 }
290 
291 /**
292  * @tc.name: GetTid
293  * @tc.desc:
294  * @tc.type: FUNC
295  */
296 HWTEST_F(ReportTest, GetTid, TestSize.Level1)
297 {
298     ReportItem a(123, 456, "comm", "dso", "func", 0x123, 123);
299     GetNumberTest(a, ReportItem::GetTid, a.tid_, std::to_string(a.tid_).length());
300 }
301 
302 /**
303  * @tc.name: CompareComm
304  * @tc.desc:
305  * @tc.type: FUNC
306  */
307 HWTEST_F(ReportTest, CompareComm, TestSize.Level1)
308 {
309     ReportItem low(1, 4, "comm", "dso", "func", 0x123, 123);
310     ReportItem mid(2, 5, "domm", "dso", "func", 0x1234, 1234);
311     ReportItem high(3, 6, "eomm", "dso", "func", 0x12345, 12345);
312     CompareStringTest(low, mid, high, ReportItem::CompareComm);
313 }
314 
315 /**
316  * @tc.name: GetComm
317  * @tc.desc:
318  * @tc.type: FUNC
319  */
320 HWTEST_F(ReportTest, GetComm, TestSize.Level1)
321 {
322     ReportItem a(123, 4, "comm", "dso", "func", 0x123, 123);
323     GetStringTest(a, ReportItem::GetComm, a.comm_, a.comm_.length());
324 }
325 
326 /**
327  * @tc.name: CompareFunc
328  * @tc.desc:
329  * @tc.type: FUNC
330  */
331 HWTEST_F(ReportTest, CompareFunc, TestSize.Level1)
332 {
333     ReportItem low(1, 4, "comm", "dso", "func", 0x123, 123);
334     ReportItem mid(2, 5, "comm", "dso", "gunc", 0x1234, 1234);
335     ReportItem high(3, 6, "comm", "dso", "hunc", 0x12345, 12345);
336     CompareStringTest(low, mid, high, ReportItem::CompareFunc);
337 }
338 
339 /**
340  * @tc.name: GetFunc
341  * @tc.desc:
342  * @tc.type: FUNC
343  */
344 HWTEST_F(ReportTest, GetFunc, TestSize.Level1)
345 {
346     ReportItem a(123, 4, "comm", "dso", "func", 0x123, 123);
347     GetStringTest(a, ReportItem::GetFunc, a.func_, a.func_.length());
348 }
349 /**
350  * @tc.name: CompareDso
351  * @tc.desc:
352  * @tc.type: FUNC
353  */
354 HWTEST_F(ReportTest, CompareDso, TestSize.Level1)
355 {
356     ReportItem low(1, 4, "comm", "dso", "func", 0x123, 123);
357     ReportItem mid(2, 5, "comm", "eso", "func", 0x1234, 1234);
358     ReportItem high(3, 6, "comm", "fso", "func", 0x12345, 12345);
359     CompareStringTest(low, mid, high, ReportItem::CompareDso);
360 }
361 
362 /**
363  * @tc.name: GetDso
364  * @tc.desc:
365  * @tc.type: FUNC
366  */
367 HWTEST_F(ReportTest, GetDso, TestSize.Level1)
368 {
369     ReportItem a(123, 4, "comm", "dso", "func", 0x123, 123);
370     GetStringTest(a, ReportItem::GetDso, a.dso_, a.dso_.length());
371 }
372 
373 /**
374  * @tc.name: CompareFromDso
375  * @tc.desc:
376  * @tc.type: FUNC
377  */
378 HWTEST_F(ReportTest, CompareFromDso, TestSize.Level1)
379 {
380     ReportItem low(1, 4, "comm", "dso", "func", 0x123, 123);
381     ReportItem mid(2, 5, "comm", "dso", "func", 0x1234, 1234);
382     ReportItem high(3, 6, "comm", "dso", "func", 0x12345, 12345);
383     low.fromDso_ = "fromDso";
384     mid.fromDso_ = "gromDso";
385     high.fromDso_ = "hromDso";
386     CompareStringTest(low, mid, high, ReportItem::CompareFromDso);
387 }
388 
389 /**
390  * @tc.name: GetFromDso
391  * @tc.desc:
392  * @tc.type: FUNC
393  */
394 HWTEST_F(ReportTest, GetFromDso, TestSize.Level1)
395 {
396     ReportItem a(123, 4, "comm", "dso", "func", 0x123, 123);
397     a.fromDso_ = "fromDso";
398     GetStringTest(a, ReportItem::GetFromDso, a.fromDso_, a.fromDso_.length());
399 }
400 
401 /**
402  * @tc.name: CompareFromFunc
403  * @tc.desc:
404  * @tc.type: FUNC
405  */
406 HWTEST_F(ReportTest, CompareFromFunc, TestSize.Level1)
407 {
408     ReportItem low(1, 4, "comm", "dso", "func", 0x123, 123);
409     ReportItem mid(2, 5, "comm", "dso", "func", 0x1234, 1234);
410     ReportItem high(3, 6, "comm", "dso", "func", 0x12345, 12345);
411     low.fromFunc_ = "fromFunc";
412     mid.fromFunc_ = "gromFunc";
413     high.fromFunc_ = "hromFunc";
414     CompareStringTest(low, mid, high, ReportItem::CompareFromFunc);
415 }
416 
417 /**
418  * @tc.name: GetFromFunc
419  * @tc.desc:
420  * @tc.type: FUNC
421  */
422 HWTEST_F(ReportTest, GetFromFunc, TestSize.Level1)
423 {
424     ReportItem a(123, 4, "comm", "dso", "func", 0x123, 123);
425     a.fromFunc_ = "fromFunc";
426     GetStringTest(a, ReportItem::GetFromFunc, a.fromFunc_, a.fromFunc_.length());
427 }
428 
429 /**
430  * @tc.name: UpdateValueMaxLen
431  * @tc.desc:
432  * @tc.type: FUNC
433  */
434 HWTEST_F(ReportTest, UpdateValueMaxLen, TestSize.Level1)
435 {
436     ReportKey key = {
437         "pid", ReportItem::ComparePid, ReportItem::GetPid, "%*d", std::vector<std::string>(),
438     };
439 
440     key.UpdateValueMaxLen(1);
441     key.UpdateValueMaxLen(11);
442     key.UpdateValueMaxLen(111);
443     key.UpdateValueMaxLen(12345678);
444     key.UpdateValueMaxLen(1);
445     key.UpdateValueMaxLen(111);
446     EXPECT_STREQ(key.maxValue_.c_str(), "12345678");
447     EXPECT_EQ(key.maxLen_, 8u);
448 
449     ReportKey func = {
450         "func", ReportItem::CompareFunc, ReportItem::GetFunc, "%-*s", std::vector<std::string>(),
451     };
452 
453     func.UpdateValueMaxLen("1");
454     func.UpdateValueMaxLen("11");
455     func.UpdateValueMaxLen("111");
456     func.UpdateValueMaxLen("12345678");
457     func.UpdateValueMaxLen("1");
458     func.UpdateValueMaxLen("111");
459     EXPECT_STREQ(func.maxValue_.c_str(), "12345678");
460     EXPECT_EQ(func.maxLen_, 8u);
461 }
462 
463 /**
464  * @tc.name: GetValue
465  * @tc.desc:
466  * @tc.type: FUNC
467  */
468 HWTEST_F(ReportTest, GetValue, TestSize.Level1)
469 {
470     ReportKey key = {
471         "pid", ReportItem::ComparePid, ReportItem::GetPid, "%*d", std::vector<std::string>(),
472     };
473     ReportItem a(123, 4, "comm", "dso", "func", 0x123, 123);
474 
475     EXPECT_STREQ(key.GetValue(a).c_str(), "123");
476     key.maxLen_ = 10u;
477     EXPECT_STREQ(key.GetValue(a).c_str(), "       123");
478 }
479 
480 /**
481  * @tc.name: ShouldDisplay
482  * @tc.desc:
483  * @tc.type: FUNC
484  */
485 HWTEST_F(ReportTest, ShouldDisplay, TestSize.Level1)
486 {
487     ReportOption option;
488     ReportKey pidKey = {
489         "pid", ReportItem::ComparePid, ReportItem::GetPid, "%*d", option.displayPids_,
490     };
491     ReportKey commKey = {
492         "comm", ReportItem::CompareComm, ReportItem::GetComm, "%-*s", option.displayComms_,
493     };
494     ReportItem a(123, 4, "abc", "dso", "func", 0x123, 123);
495     ReportItem b(12, 4, "ab", "dso", "func", 0x123, 123);
496     ReportItem c(1, 4, "a", "dso", "func", 0x123, 123);
497 
498     option.displayPids_ = {"1"};
499     EXPECT_EQ(pidKey.ShouldDisplay(a), false);
500     EXPECT_EQ(pidKey.ShouldDisplay(b), false);
501     EXPECT_EQ(pidKey.ShouldDisplay(c), true);
502     option.displayPids_.clear();
503 
504     option.displayComms_ = {"a", "ab"};
505     EXPECT_EQ(commKey.ShouldDisplay(a), false);
506     EXPECT_EQ(commKey.ShouldDisplay(b), true);
507     EXPECT_EQ(commKey.ShouldDisplay(c), true);
508     option.displayComms_.clear();
509 
510     option.displayComms_ = {"a", "ab", "abc"};
511     EXPECT_EQ(commKey.ShouldDisplay(a), true);
512     EXPECT_EQ(commKey.ShouldDisplay(b), true);
513     EXPECT_EQ(commKey.ShouldDisplay(c), true);
514     option.displayComms_.clear();
515 
516     option.displayComms_ = {"a", "ab", "abc", "d"};
517     EXPECT_EQ(commKey.ShouldDisplay(a), true);
518     EXPECT_EQ(commKey.ShouldDisplay(b), true);
519     EXPECT_EQ(commKey.ShouldDisplay(c), true);
520     option.displayComms_.clear();
521 }
522 
523 /**
524  * @tc.name: MultiLevelSame
525  * @tc.desc:
526  * @tc.type: FUNC
527  */
528 HWTEST_F(ReportTest, MultiLevelSame, TestSize.Level1)
529 {
530     class ReportMock : public Report {
531     public:
532         MOCK_METHOD2(MultiLevelCompare, int(const ReportItem &a, const ReportItem &b));
533     } report;
534     ReportItem dummy(0, 0, "comm", "", "", 0, 0);
535 
536     EXPECT_CALL(report, MultiLevelCompare(testing::_, testing::_)).WillOnce(testing::Return(0));
537     EXPECT_EQ(report.MultiLevelSame(dummy, dummy), true);
538 
539     EXPECT_CALL(report, MultiLevelCompare(testing::_, testing::_)).WillOnce(testing::Return(1));
540     EXPECT_EQ(report.MultiLevelSame(dummy, dummy), false);
541 
542     EXPECT_CALL(report, MultiLevelCompare(testing::_, testing::_)).WillOnce(testing::Return(-1));
543     EXPECT_EQ(report.MultiLevelSame(dummy, dummy), false);
544 }
545 
546 /**
547  * @tc.name: MultiLevelSorting
548  * @tc.desc:
549  * @tc.type: FUNC
550  */
551 HWTEST_F(ReportTest, MultiLevelSorting, TestSize.Level1)
552 {
553     class ReportMock : public Report {
554     public:
555         MOCK_METHOD2(MultiLevelCompare, int(const ReportItem &a, const ReportItem &b));
556     } report;
557     ReportItem dummy(0, 0, "comm", "", "", 0, 0);
558 
559     EXPECT_CALL(report, MultiLevelCompare(testing::_, testing::_))
560         .WillOnce(testing::Return(0))
561         .WillOnce(testing::Return(0))
562         .WillOnce(testing::Return(0));
563     EXPECT_EQ(report.MultiLevelCompare(dummy, dummy), 0);     // 1st
564     EXPECT_EQ(report.MultiLevelSorting(dummy, dummy), false); // 2nd 3rd and > 0?
565 
566     EXPECT_CALL(report, MultiLevelCompare(testing::_, testing::_))
567         .WillOnce(testing::Return(1))
568         .WillOnce(testing::Return(1))
569         .WillOnce(testing::Return(-1));
570     EXPECT_EQ(report.MultiLevelCompare(dummy, dummy), 1);
571     EXPECT_EQ(report.MultiLevelSorting(dummy, dummy), true); // > 0?
572 
573     EXPECT_CALL(report, MultiLevelCompare(testing::_, testing::_))
574         .WillOnce(testing::Return(-1))
575         .WillOnce(testing::Return(-1))
576         .WillOnce(testing::Return(1));
577     EXPECT_EQ(report.MultiLevelCompare(dummy, dummy), -1);
578     EXPECT_EQ(report.MultiLevelSorting(dummy, dummy), false); // > 0?
579 }
580 
581 /**
582  * @tc.name: MultiLevelSameAndUpdateCount
583  * @tc.desc:
584  * @tc.type: FUNC
585  */
586 HWTEST_F(ReportTest, MultiLevelSameAndUpdateCount, TestSize.Level1)
587 {
588     class ReportMock : public Report {
589     public:
590         MOCK_METHOD2(MultiLevelCompare, int(const ReportItem &a, const ReportItem &b));
591     } report;
592     ReportItem dummy100(0, 0, "comm", "", "", 0x0, 100);
593     ReportItem dummy200(0, 0, "comm", "", "", 0x0, 200);
594     ReportItem dummy300(0, 0, "comm", "", "", 0x0, 300);
595 
596     EXPECT_EQ(dummy100.eventCount_, 100u);
597 
598     EXPECT_CALL(report, MultiLevelCompare(testing::_, testing::_)).WillOnce(testing::Return(0));
599     EXPECT_EQ(report.MultiLevelSameAndUpdateCount(dummy100, dummy200), true);
600     // if true , 100 + 200
601     EXPECT_EQ(dummy100.eventCount_, 300u);
602 
603     EXPECT_CALL(report, MultiLevelCompare(testing::_, testing::_)).WillOnce(testing::Return(1));
604     EXPECT_EQ(report.MultiLevelSameAndUpdateCount(dummy200, dummy200), false);
605     EXPECT_EQ(dummy200.eventCount_, 200u);
606     EXPECT_EQ(dummy300.eventCount_, 300u);
607 
608     EXPECT_CALL(report, MultiLevelCompare(testing::_, testing::_)).WillOnce(testing::Return(-1));
609     EXPECT_EQ(report.MultiLevelSameAndUpdateCount(dummy200, dummy200), false);
610     EXPECT_EQ(dummy200.eventCount_, 200u);
611     EXPECT_EQ(dummy300.eventCount_, 300u);
612 }
613 
614 /**
615  * @tc.name: MergeCallFrameCount
616  * @tc.desc:
617  * @tc.type: FUNC
618  */
619 HWTEST_F(ReportTest, MergeCallFrameCount, TestSize.Level1)
620 {
621     class ReportMock : public Report {
622     public:
623         MOCK_METHOD2(MultiLevelCompare, int(const ReportItem &a, const ReportItem &b));
624     } report;
625     ReportItem dummy100(0, 0, "comm", "", "", 0x0, 100);
626     ReportItem dummy200(0, 0, "comm", "", "", 0x0, 200);
627     ReportItem dummy300(0, 0, "comm", "", "", 0x0, 300);
628     EXPECT_EQ(dummy100.eventCount_, 100u);
629     ASSERT_EQ(dummy100.callStacks_.size(), 0u);
630 
631     /*
632     we have a stack like
633     dummy 100
634        funcA 100
635             funcB 100
636                 funcC 100
637     dummy 200
638        funcA 100
639             funcB 100
640     dummy 300
641        funcA 100
642             funcC 100
643 
644     after merge it should be change to
645     dummy 600
646        funcA 300
647             funcB 200
648                 funcC 100
649             funcC 100
650     */
651     {
652         ReportItemCallFrame &child =
653             dummy100.callStacks_.emplace_back("funcA", 0x1234, "dso", 100, 0);
654         ReportItemCallFrame &child2 = child.childs.emplace_back("funcB", 0x1234, "dso", 100, 0);
655         child2.childs.emplace_back("funcC", 0x1234, "dso", 100, 0);
656     }
657 
658     {
659         ReportItemCallFrame &child =
660             dummy200.callStacks_.emplace_back("funcA", 0x1234, "dso", 100, 0);
661         child.childs.emplace_back("funcB", 0x1234, "dso", 100, 0);
662     }
663     {
664         ReportItemCallFrame &child =
665             dummy300.callStacks_.emplace_back("funcA", 0x1234, "dso", 100, 0);
666         child.childs.emplace_back("funcC", 0x1234, "dso", 100, 0);
667     }
668     dummy100.eventCount_ += dummy200.eventCount_;
669     ASSERT_EQ(dummy100.callStacks_.size(), 1u);
670     ASSERT_EQ(dummy200.callStacks_.size(), 1u);
671     ASSERT_STREQ(dummy100.callStacks_[0].func_.data(), "funcA");
672     ASSERT_STREQ(dummy200.callStacks_[0].func_.data(), "funcA");
673     report_->MergeCallFrameCount(dummy100, dummy200);
674 
675     if (dummy100.callStacks_.size() >= 2) {
676         printf("%s\n", dummy100.callStacks_[0].ToDebugString().c_str());
677         printf("%s\n", dummy100.callStacks_[1].ToDebugString().c_str());
678     }
679     ASSERT_EQ(dummy100.callStacks_.size(), 1u);
680 
681     dummy100.eventCount_ += dummy300.eventCount_;
682     report_->MergeCallFrameCount(dummy100, dummy300);
683 
684     ASSERT_EQ(dummy100.callStacks_.size(), 1u);
685     ASSERT_STREQ(dummy100.callStacks_[0].func_.data(), "funcA");
686     EXPECT_EQ(dummy100.callStacks_[0].eventCount_, 300u);
687 
688     ASSERT_STREQ(dummy100.callStacks_[0].childs[0].func_.data(), "funcB");
689     EXPECT_EQ(dummy100.callStacks_[0].childs[0].eventCount_, 200u);
690 
691     ASSERT_STREQ(dummy100.callStacks_[0].childs[1].func_.data(), "funcC");
692     EXPECT_EQ(dummy100.callStacks_[0].childs[1].eventCount_, 100u);
693 
694     ASSERT_EQ(dummy100.callStacks_[0].childs[0].childs.size(), 1u);
695     ASSERT_STREQ(dummy100.callStacks_[0].childs[0].childs[0].func_.data(), "funcC");
696     EXPECT_EQ(dummy100.callStacks_[0].childs[0].childs[0].eventCount_, 100u);
697 }
698 
699 /**
700  * @tc.name: MultiLevelCompare
701  * @tc.desc:
702  * @tc.type: FUNC
703  */
704 HWTEST_F(ReportTest, MultiLevelCompare, TestSize.Level1)
705 {
706     report_->option_.sortKeys_ = {"comm", "pid", "tid", "dso", "func"};
707 
708     ReportItem a(1, 2, "comm", "dso", "funca", 0x1, 4);
709     ReportItem b(2, 3, "comm", "dso", "funcb", 0x2, 3);
710     ReportItem c(3, 4, "comm", "dso", "funcc", 0x3, 2);
711     ReportItem d(4, 5, "comm", "dso", "funcd", 0x4, 1);
712 
713     report_->option_.sortKeys_ = {"comm"};
714     EXPECT_EQ(report_->MultiLevelCompare(a, b), 0);
715 
716     report_->option_.sortKeys_ = {"comm", "pid"};
717     EXPECT_EQ(report_->MultiLevelCompare(a, b), -1);
718 }
719 
720 /**
721  * @tc.name: AddReportItem
722  * @tc.desc:
723  * @tc.type: FUNC
724  */
725 HWTEST_F(ReportTest, AddReportItem, TestSize.Level1)
726 {
727     PerfRecordSample sample(false, 0, 0, 1);
728     sample.callFrames_.emplace_back(0x1, 0x1234, "dummy", "frame1");
729     sample.callFrames_.emplace_back(0x2, 0x1234, "dummy", "frame2");
730     sample.callFrames_.emplace_back(0x3, 0x1234, "dummy", "frame3");
731     sample.callFrames_.emplace_back(0x3, 0x1234, "dummy", "frame4");
732 
733     // caller order should be
734     // 4
735     //  -> 3
736     //       -> 2
737     //            -> 1
738 
739     report_->AddReportItem(sample, false);
740     auto &reportItems = report_->configs_[0].reportItems_;
741     ASSERT_EQ(reportItems.size(), 1u);
742 
743     report_->AddReportItem(sample, true);
744     ASSERT_EQ(reportItems.size(), 2u);
745 
746     // no call frame
747     ASSERT_EQ(reportItems[0].callStacks_.size(), 0u);
748     // have call frame
749     ASSERT_EQ(reportItems[1].callStacks_.size(), 1u);
750 
751     // first on the end caller
752     ASSERT_STREQ(reportItems[1].callStacks_[0].func_.data(), "frame4");
753     ASSERT_EQ(reportItems[1].callStacks_[0].childs.size(), 1u);
754 
755     // next caller
756     ASSERT_STREQ(reportItems[1].callStacks_[0].childs[0].func_.data(), "frame3");
757     ASSERT_EQ(reportItems[1].callStacks_[0].childs[0].childs.size(), 1u);
758 
759     // next caller
760     ASSERT_STREQ(reportItems[1].callStacks_[0].childs[0].childs[0].func_.data(), "frame2");
761     ASSERT_EQ(reportItems[1].callStacks_[0].childs[0].childs.size(), 1u);
762 
763     // top called
764     ASSERT_STREQ(reportItems[1].callStacks_[0].childs[0].childs[0].childs[0].func_.data(),
765                  "frame1");
766     ASSERT_EQ(reportItems[1].callStacks_[0].childs[0].childs[0].childs[0].childs.size(), 0u);
767 
768     report_->AddReportItem(sample, false);
769     EXPECT_EQ(reportItems.size(), 3u);
770 }
771 
772 /**
773  * @tc.name: AddReportItem
774  * @tc.desc:
775  * @tc.type: FUNC
776  */
777 HWTEST_F(ReportTest, AddReportItemBranch, TestSize.Level1)
778 {
779     class PerfRecordSampleMock : public PerfRecordSample {
780     public:
PerfRecordSampleMock(bool inKernel,u32 pid,u32 tid,u64 period)781         PerfRecordSampleMock(bool inKernel, u32 pid, u32 tid, u64 period)
782             : PerfRecordSample(inKernel, pid, tid, period)
783         {
784         }
785     };
786     PerfRecordSampleMock sample(false, 0, 0, 1);
787     sample.data_.bnr = 3;
788     sample.data_.lbr = new PerfBranchEntry[sample.data_.bnr];
789     sample.data_.lbr[0].to = 0x123400;
790     sample.data_.lbr[0].from = 0x432100;
791     sample.data_.lbr[1].to = 0x123401;
792     sample.data_.lbr[1].from = 0x432101;
793     sample.data_.lbr[2].to = 0x123402;
794     sample.data_.lbr[2].from = 0x432102;
795 
796     sample.callFrames_.emplace_back(0x1, 0x1234, "dummy", "frame1");
797     sample.callFrames_.emplace_back(0x2, 0x1234, "dummy", "frame2");
798     sample.callFrames_.emplace_back(0x3, 0x1234, "dummy", "frame3");
799     // vaddr is 0 , will not added
800     sample.callFrames_.emplace_back(0x3, 0, "dummy", "frame4");
801 
802     report_->AddReportItemBranch(sample);
803     // == nbr size
804     ASSERT_EQ(report_->configs_[0].reportItems_.size(), 3u);
805     // no call stack
806     ASSERT_EQ(report_->configs_[0].reportItems_[0].callStacks_.size(), 0u);
807 
808     for (auto &reportItem : report_->configs_[0].reportItems_) {
809         printf("reportItem %s\n", reportItem.ToDebugString().c_str());
810     }
811     EXPECT_STREQ(report_->configs_[0].reportItems_[0].func_.data(), "swapper@0x123400");
812     EXPECT_STREQ(report_->configs_[0].reportItems_[1].func_.data(), "swapper@0x123401");
813     EXPECT_STREQ(report_->configs_[0].reportItems_[2].func_.data(), "swapper@0x123402");
814 }
815 
816 /**
817  * @tc.name: PrepareConsole
818  * @tc.desc:
819  * @tc.type: FUNC
820  */
821 HWTEST_F(ReportTest, PrepareConsole, TestSize.Level1)
822 {
823     struct winsize w = {0, 0, 0, 0};
824     ioctl(fileno(stdout), TIOCGWINSZ, &w);
825     report_->PrepareConsole();
826     if (w.ws_col != 0) {
827         EXPECT_EQ(report_->consoleWidth_, w.ws_col);
828     } else {
829         EXPECT_EQ(report_->consoleWidth_, report_->ConsoleDefaultWidth);
830     }
831 }
832 
833 HWTEST_F(ReportTest, OverConfigIndex, TestSize.Level1)
834 {
835     pid_t pid = fork();
836     ASSERT_NE(pid, -1);
837 
838     if (pid == 0) {
839         report_->configIdIndexMaps_.emplace(1000u, 1000u);
840         report_->GetConfigName(1000);
841         _exit(-2);
842     } else {
843         int status = 0;
844         waitpid(pid, &status, 0);
845         ASSERT_TRUE(WIFEXITED(status));
846         EXPECT_EQ(WEXITSTATUS(status), static_cast<uint8_t>(-1));
847     }
848 }
849 } // namespace HiPerf
850 } // namespace Developtools
851 } // namespace OHOS
852