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