1 //===-- TimerTest.cpp -----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Utility/StreamString.h"
10 #include "lldb/Utility/Timer.h"
11 #include "gtest/gtest.h"
12 #include <thread>
13 
14 using namespace lldb_private;
15 
TEST(TimerTest,CategoryTimes)16 TEST(TimerTest, CategoryTimes) {
17   Timer::ResetCategoryTimes();
18   {
19     static Timer::Category tcat("CAT1");
20     Timer t(tcat, ".");
21     std::this_thread::sleep_for(std::chrono::milliseconds(10));
22   }
23   StreamString ss;
24   Timer::DumpCategoryTimes(&ss);
25   double seconds;
26   ASSERT_EQ(1, sscanf(ss.GetData(), "%lf sec for CAT1", &seconds));
27   EXPECT_LT(0.001, seconds);
28   EXPECT_GT(0.1, seconds);
29 }
30 
TEST(TimerTest,CategoryTimesNested)31 TEST(TimerTest, CategoryTimesNested) {
32   Timer::ResetCategoryTimes();
33   {
34     static Timer::Category tcat1("CAT1");
35     Timer t1(tcat1, ".");
36     std::this_thread::sleep_for(std::chrono::milliseconds(10));
37     // Explicitly testing the same category as above.
38     Timer t2(tcat1, ".");
39     std::this_thread::sleep_for(std::chrono::milliseconds(10));
40   }
41   StreamString ss;
42   Timer::DumpCategoryTimes(&ss);
43   double seconds;
44   // It should only appear once.
45   ASSERT_EQ(ss.GetString().count("CAT1"), 1U);
46   ASSERT_EQ(1, sscanf(ss.GetData(), "%lf sec for CAT1", &seconds));
47   EXPECT_LT(0.002, seconds);
48   EXPECT_GT(0.2, seconds);
49 }
50 
TEST(TimerTest,CategoryTimes2)51 TEST(TimerTest, CategoryTimes2) {
52   Timer::ResetCategoryTimes();
53   {
54     static Timer::Category tcat1("CAT1");
55     Timer t1(tcat1, ".");
56     std::this_thread::sleep_for(std::chrono::milliseconds(100));
57     static Timer::Category tcat2("CAT2");
58     Timer t2(tcat2, ".");
59     std::this_thread::sleep_for(std::chrono::milliseconds(10));
60   }
61   StreamString ss;
62   Timer::DumpCategoryTimes(&ss);
63   double seconds1, seconds2;
64   ASSERT_EQ(2, sscanf(ss.GetData(),
65                       "%lf sec (total: %*fs; child: %*fs; count: %*d) for "
66                       "CAT1%*[\n ]%lf sec for CAT2",
67                       &seconds1, &seconds2))
68       << "String: " << ss.GetData();
69   EXPECT_LT(0.01, seconds1);
70   EXPECT_GT(1, seconds1);
71   EXPECT_LT(0.001, seconds2);
72   EXPECT_GT(0.1, seconds2);
73 }
74 
TEST(TimerTest,CategoryTimesStats)75 TEST(TimerTest, CategoryTimesStats) {
76   Timer::ResetCategoryTimes();
77   {
78     static Timer::Category tcat1("CAT1");
79     Timer t1(tcat1, ".");
80     std::this_thread::sleep_for(std::chrono::milliseconds(100));
81     static Timer::Category tcat2("CAT2");
82     {
83       Timer t2(tcat2, ".");
84       std::this_thread::sleep_for(std::chrono::milliseconds(10));
85     }
86     {
87       Timer t3(tcat2, ".");
88       std::this_thread::sleep_for(std::chrono::milliseconds(10));
89     }
90   }
91   // Example output:
92   // 0.105202764 sec (total: 0.132s; child: 0.027s; count: 1) for CAT1
93   // 0.026772798 sec (total: 0.027s; child: 0.000s; count: 2) for CAT2
94   StreamString ss;
95   Timer::DumpCategoryTimes(&ss);
96   double seconds1, total1, child1, seconds2;
97   int count1, count2;
98   ASSERT_EQ(
99       6, sscanf(ss.GetData(),
100                 "%lf sec (total: %lfs; child: %lfs; count: %d) for CAT1%*[\n\r ]"
101                 "%lf sec (total: %*fs; child: %*fs; count: %d) for CAT2",
102                 &seconds1, &total1, &child1, &count1, &seconds2, &count2))
103       << "String: " << ss.GetData();
104   EXPECT_NEAR(total1 - child1, seconds1, 0.002);
105   EXPECT_EQ(1, count1);
106   EXPECT_NEAR(child1, seconds2, 0.002);
107   EXPECT_EQ(2, count2);
108 }
109