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