1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/metrics/histogram_macros.h"
6
7 #include "base/test/metrics/histogram_tester.h"
8 #include "base/time/time.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace base {
12
TEST(ScopedHistogramTimer,ThreeTimersOneScope)13 TEST(ScopedHistogramTimer, ThreeTimersOneScope) {
14 SCOPED_UMA_HISTOGRAM_TIMER_MICROS("TestShortTimer0");
15 SCOPED_UMA_HISTOGRAM_TIMER_MICROS("TestShortTimer1");
16 SCOPED_UMA_HISTOGRAM_TIMER("TestTimer0");
17 SCOPED_UMA_HISTOGRAM_TIMER("TestTimer1");
18 SCOPED_UMA_HISTOGRAM_LONG_TIMER("TestLongTimer0");
19 SCOPED_UMA_HISTOGRAM_LONG_TIMER("TestLongTimer1");
20 }
21
22 // Compile tests for UMA_HISTOGRAM_ENUMERATION with the three different types it
23 // accepts:
24 // - integral types
25 // - unscoped enums
26 // - scoped enums
TEST(HistogramMacro,IntegralPseudoEnumeration)27 TEST(HistogramMacro, IntegralPseudoEnumeration) {
28 UMA_HISTOGRAM_ENUMERATION("Test.FauxEnumeration", 1, 1000);
29 }
30
TEST(HistogramMacro,UnscopedEnumeration)31 TEST(HistogramMacro, UnscopedEnumeration) {
32 enum TestEnum : char {
33 FIRST_VALUE,
34 SECOND_VALUE,
35 THIRD_VALUE,
36 MAX_ENTRIES,
37 };
38 UMA_HISTOGRAM_ENUMERATION("Test.UnscopedEnumeration", SECOND_VALUE,
39 MAX_ENTRIES);
40 }
41
TEST(HistogramMacro,ScopedEnumeration)42 TEST(HistogramMacro, ScopedEnumeration) {
43 enum class TestEnum {
44 FIRST_VALUE,
45 SECOND_VALUE,
46 THIRD_VALUE,
47 kMaxValue = THIRD_VALUE,
48 };
49 UMA_HISTOGRAM_ENUMERATION("Test.ScopedEnumeration", TestEnum::FIRST_VALUE);
50
51 enum class TestEnum2 {
52 FIRST_VALUE,
53 SECOND_VALUE,
54 THIRD_VALUE,
55 MAX_ENTRIES,
56 };
57 UMA_HISTOGRAM_ENUMERATION("Test.ScopedEnumeration2", TestEnum2::SECOND_VALUE,
58 TestEnum2::MAX_ENTRIES);
59 }
60
61 // Compile tests for UMA_HISTOGRAM_ENUMERATION when the value type is:
62 // - a const reference to an enum
63 // - a non-const reference to an enum
TEST(HistogramMacro,EnumerationConstRef)64 TEST(HistogramMacro, EnumerationConstRef) {
65 enum class TestEnum { kValue, kMaxValue = kValue };
66 const TestEnum& value_ref = TestEnum::kValue;
67 UMA_HISTOGRAM_ENUMERATION("Test.ScopedEnumeration3", value_ref);
68 }
69
TEST(HistogramMacro,EnumerationNonConstRef)70 TEST(HistogramMacro, EnumerationNonConstRef) {
71 enum class TestEnum { kValue, kMaxValue = kValue };
72 TestEnum value = TestEnum::kValue;
73 TestEnum& value_ref = value;
74 UMA_HISTOGRAM_ENUMERATION("Test.ScopedEnumeration4", value_ref);
75 }
76
TEST(HistogramMacro,SplitByProcessPriorityMacro)77 TEST(HistogramMacro, SplitByProcessPriorityMacro) {
78 TimeTicks mock_now = TimeTicks::Now();
79
80 constexpr TimeDelta kMockIntervalBetweenSamples = Seconds(1);
81
82 {
83 // No BestEffort suffix by default (SetSharedLastForegroundTimeForMetrics
84 // not invoked yet in this process).
85 HistogramTester tester;
86 UMA_HISTOGRAM_SPLIT_BY_PROCESS_PRIORITY(UMA_HISTOGRAM_COUNTS_1000, mock_now,
87 Microseconds(0), "Test.MyCount",
88 123);
89 tester.ExpectUniqueSample("Test.MyCount", 123, 1);
90 tester.ExpectUniqueSample("Test.MyCount.BestEffort", 123, 0);
91 }
92
93 mock_now += kMockIntervalBetweenSamples;
94 std::atomic<base::TimeTicks> shared_last_foreground_time = mock_now;
95 internal::SetSharedLastForegroundTimeForMetrics(&shared_last_foreground_time);
96
97 {
98 // No BestEffort suffix while foreground.
99 HistogramTester tester;
100 UMA_HISTOGRAM_SPLIT_BY_PROCESS_PRIORITY(UMA_HISTOGRAM_COUNTS_1000, mock_now,
101 Microseconds(0), "Test.MyCount",
102 123);
103 tester.ExpectUniqueSample("Test.MyCount", 123, 1);
104 tester.ExpectUniqueSample("Test.MyCount.BestEffort", 123, 0);
105 }
106
107 mock_now += kMockIntervalBetweenSamples;
108 shared_last_foreground_time.store(TimeTicks(), std::memory_order_relaxed);
109
110 {
111 // BestEffort suffix while in BestEffort.
112 HistogramTester tester;
113 UMA_HISTOGRAM_SPLIT_BY_PROCESS_PRIORITY(UMA_HISTOGRAM_COUNTS_1000, mock_now,
114 Microseconds(0), "Test.MyCount",
115 123);
116 tester.ExpectUniqueSample("Test.MyCount", 123, 0);
117 tester.ExpectUniqueSample("Test.MyCount.BestEffort", 123, 1);
118 }
119
120 mock_now += kMockIntervalBetweenSamples;
121 shared_last_foreground_time.store(mock_now, std::memory_order_relaxed);
122
123 {
124 // No BestEffort suffix once back to normal priority.
125 HistogramTester tester;
126 UMA_HISTOGRAM_SPLIT_BY_PROCESS_PRIORITY(UMA_HISTOGRAM_COUNTS_1000, mock_now,
127 Microseconds(0), "Test.MyCount",
128 123);
129 tester.ExpectUniqueSample("Test.MyCount", 123, 1);
130 tester.ExpectUniqueSample("Test.MyCount.BestEffort", 123, 0);
131 }
132 {
133 // BestEffort suffix while normal priority if the sample_interval overlaps
134 // into a BestEffort range.
135 HistogramTester tester;
136 UMA_HISTOGRAM_SPLIT_BY_PROCESS_PRIORITY(UMA_HISTOGRAM_COUNTS_1000, mock_now,
137 kMockIntervalBetweenSamples * 1.5,
138 "Test.MyCount", 123);
139 tester.ExpectUniqueSample("Test.MyCount", 123, 0);
140 tester.ExpectUniqueSample("Test.MyCount.BestEffort", 123, 1);
141 }
142 {
143 HistogramTester tester;
144 // ... and also if the sample was taken at a time before the last foreground
145 // time:
146 UMA_HISTOGRAM_SPLIT_BY_PROCESS_PRIORITY(
147 UMA_HISTOGRAM_COUNTS_1000, mock_now - kMockIntervalBetweenSamples * 1.5,
148 Microseconds(0), "Test.MyCount", 123);
149 tester.ExpectUniqueSample("Test.MyCount", 123, 0);
150 tester.ExpectUniqueSample("Test.MyCount.BestEffort", 123, 1);
151 }
152
153 // Reset the global state at the end of the test.
154 internal::SetSharedLastForegroundTimeForMetrics(nullptr);
155
156 {
157 // No BestEffort suffix by default, again.
158 HistogramTester tester;
159 UMA_HISTOGRAM_SPLIT_BY_PROCESS_PRIORITY(UMA_HISTOGRAM_COUNTS_1000, mock_now,
160 Microseconds(0), "Test.MyCount",
161 123);
162 tester.ExpectUniqueSample("Test.MyCount", 123, 1);
163 tester.ExpectUniqueSample("Test.MyCount.BestEffort", 123, 0);
164 }
165 }
166
167 } // namespace base
168