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