blob: 4643f140d2b504cfe5066939028d6d1e5f74a55c [file] [log] [blame]
Eric Holkf1a2c0e2020-09-29 11:13:55 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "metrics.h"
18
19#include "gtest/gtest.h"
Eric Holk096bef82020-10-19 12:04:39 -070020#include "metrics_test.h"
Eric Holkf1a2c0e2020-09-29 11:13:55 -070021
22#pragma clang diagnostic push
23#pragma clang diagnostic error "-Wconversion"
24
25namespace art {
26namespace metrics {
27
Eric Holk096bef82020-10-19 12:04:39 -070028using test::CounterValue;
29using test::GetBuckets;
30using test::TestBackendBase;
31
Eric Holkf1a2c0e2020-09-29 11:13:55 -070032class MetricsTest : public testing::Test {};
33
34TEST_F(MetricsTest, SimpleCounter) {
Eric Holk096bef82020-10-19 12:04:39 -070035 MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
Eric Holkf1a2c0e2020-09-29 11:13:55 -070036
Eric Holk096bef82020-10-19 12:04:39 -070037 EXPECT_EQ(0u, CounterValue(test_counter));
Eric Holkf1a2c0e2020-09-29 11:13:55 -070038
39 test_counter.AddOne();
Eric Holk096bef82020-10-19 12:04:39 -070040 EXPECT_EQ(1u, CounterValue(test_counter));
Eric Holkf1a2c0e2020-09-29 11:13:55 -070041
42 test_counter.Add(5);
Eric Holk096bef82020-10-19 12:04:39 -070043 EXPECT_EQ(6u, CounterValue(test_counter));
Eric Holkf1a2c0e2020-09-29 11:13:55 -070044}
45
Eric Holk1cd030f2020-09-30 11:42:34 -070046TEST_F(MetricsTest, CounterTimer) {
Eric Holk096bef82020-10-19 12:04:39 -070047 MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
Eric Holk1cd030f2020-09-30 11:42:34 -070048 {
49 AutoTimer timer{&test_counter};
50 // Sleep for 2µs so the counter will be greater than 0.
51 NanoSleep(2'000);
52 }
Eric Holk096bef82020-10-19 12:04:39 -070053 EXPECT_GT(CounterValue(test_counter), 0u);
Eric Holk1cd030f2020-09-30 11:42:34 -070054}
55
56TEST_F(MetricsTest, CounterTimerExplicitStop) {
Eric Holk096bef82020-10-19 12:04:39 -070057 MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
Eric Holk1cd030f2020-09-30 11:42:34 -070058 AutoTimer timer{&test_counter};
59 // Sleep for 2µs so the counter will be greater than 0.
60 NanoSleep(2'000);
61 timer.Stop();
Eric Holk096bef82020-10-19 12:04:39 -070062 EXPECT_GT(CounterValue(test_counter), 0u);
Eric Holk1cd030f2020-09-30 11:42:34 -070063}
64
65TEST_F(MetricsTest, CounterTimerExplicitStart) {
Eric Holk096bef82020-10-19 12:04:39 -070066 MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
Eric Holk1cd030f2020-09-30 11:42:34 -070067 {
68 AutoTimer timer{&test_counter, /*autostart=*/false};
69 // Sleep for 2µs so the counter will be greater than 0.
70 NanoSleep(2'000);
71 }
Eric Holk096bef82020-10-19 12:04:39 -070072 EXPECT_EQ(CounterValue(test_counter), 0u);
Eric Holk1cd030f2020-09-30 11:42:34 -070073
74 {
75 AutoTimer timer{&test_counter, /*autostart=*/false};
76 timer.Start();
77 // Sleep for 2µs so the counter will be greater than 0.
78 NanoSleep(2'000);
79 }
Eric Holk096bef82020-10-19 12:04:39 -070080 EXPECT_GT(CounterValue(test_counter), 0u);
Eric Holk1cd030f2020-09-30 11:42:34 -070081}
82
83TEST_F(MetricsTest, CounterTimerExplicitStartStop) {
Eric Holk096bef82020-10-19 12:04:39 -070084 MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
Eric Holk1cd030f2020-09-30 11:42:34 -070085 AutoTimer timer{&test_counter, /*autostart=*/false};
86 // Sleep for 2µs so the counter will be greater than 0.
87 timer.Start();
88 NanoSleep(2'000);
89 timer.Stop();
Eric Holk096bef82020-10-19 12:04:39 -070090 EXPECT_GT(CounterValue(test_counter), 0u);
Eric Holk1cd030f2020-09-30 11:42:34 -070091}
92
Eric Holkf1a2c0e2020-09-29 11:13:55 -070093TEST_F(MetricsTest, DatumName) {
94 EXPECT_EQ("ClassVerificationTotalTime", DatumName(DatumId::kClassVerificationTotalTime));
95}
96
Eric Holkd02435d2020-09-29 11:16:24 -070097TEST_F(MetricsTest, SimpleHistogramTest) {
Eric Holk096bef82020-10-19 12:04:39 -070098 MetricsHistogram<DatumId::kJitMethodCompileTime, 5, 0, 100> histogram;
Eric Holkd02435d2020-09-29 11:16:24 -070099
100 // bucket 0: 0-19
101 histogram.Add(10);
102
103 // bucket 1: 20-39
104 histogram.Add(20);
105 histogram.Add(25);
106
107 // bucket 2: 40-59
108 histogram.Add(56);
109 histogram.Add(57);
110 histogram.Add(58);
111 histogram.Add(59);
112
113 // bucket 3: 60-79
114 histogram.Add(70);
115 histogram.Add(70);
116 histogram.Add(70);
117
118 // bucket 4: 80-99
119 // leave this bucket empty
120
Eric Holk096bef82020-10-19 12:04:39 -0700121 std::vector<uint32_t> buckets{GetBuckets(histogram)};
Eric Holkd02435d2020-09-29 11:16:24 -0700122 EXPECT_EQ(1u, buckets[0u]);
123 EXPECT_EQ(2u, buckets[1u]);
124 EXPECT_EQ(4u, buckets[2u]);
125 EXPECT_EQ(3u, buckets[3u]);
126 EXPECT_EQ(0u, buckets[4u]);
127}
128
129// Make sure values added outside the range of the histogram go into the first or last bucket.
130TEST_F(MetricsTest, HistogramOutOfRangeTest) {
Eric Holk096bef82020-10-19 12:04:39 -0700131 MetricsHistogram<DatumId::kJitMethodCompileTime, 2, 0, 100> histogram;
Eric Holkd02435d2020-09-29 11:16:24 -0700132
133 // bucket 0: 0-49
134 histogram.Add(-500);
135
136 // bucket 1: 50-99
137 histogram.Add(250);
138 histogram.Add(1000);
139
Eric Holk096bef82020-10-19 12:04:39 -0700140 std::vector<uint32_t> buckets{GetBuckets(histogram)};
Eric Holkd02435d2020-09-29 11:16:24 -0700141 EXPECT_EQ(1u, buckets[0u]);
142 EXPECT_EQ(2u, buckets[1u]);
143}
144
145// Test adding values to ArtMetrics and reporting them through a test backend.
146TEST_F(MetricsTest, ArtMetricsReport) {
147 ArtMetrics metrics;
148
149 // Collect some data
150 static constexpr uint64_t verification_time = 42;
151 metrics.ClassVerificationTotalTime()->Add(verification_time);
152 // Add a negative value so we are guaranteed that it lands in the first bucket.
153 metrics.JitMethodCompileTime()->Add(-5);
154
155 // Report and check the data
156 class TestBackend : public TestBackendBase {
157 public:
158 ~TestBackend() {
159 EXPECT_TRUE(found_counter_);
160 EXPECT_TRUE(found_histogram_);
161 }
162
163 void ReportCounter(DatumId counter_type, uint64_t value) override {
164 if (counter_type == DatumId::kClassVerificationTotalTime) {
165 EXPECT_EQ(value, verification_time);
166 found_counter_ = true;
167 } else {
168 EXPECT_EQ(value, 0u);
169 }
170 }
171
172 void ReportHistogram(DatumId histogram_type,
173 int64_t,
174 int64_t,
175 const std::vector<uint32_t>& buckets) override {
176 if (histogram_type == DatumId::kJitMethodCompileTime) {
177 EXPECT_EQ(buckets[0], 1u);
178 for (size_t i = 1; i < buckets.size(); ++i) {
179 EXPECT_EQ(buckets[i], 0u);
180 }
181 found_histogram_ = true;
182 } else {
183 for (size_t i = 0; i < buckets.size(); ++i) {
184 EXPECT_EQ(buckets[i], 0u);
185 }
186 }
187 }
188
189 private:
190 bool found_counter_{false};
191 bool found_histogram_{false};
192 } backend;
193
194 metrics.ReportAllMetrics(&backend);
195}
196
Eric Holk1cd030f2020-09-30 11:42:34 -0700197TEST_F(MetricsTest, HistogramTimer) {
Eric Holk096bef82020-10-19 12:04:39 -0700198 MetricsHistogram<DatumId::kJitMethodCompileTime, 1, 0, 100> test_histogram;
Eric Holk1cd030f2020-09-30 11:42:34 -0700199 {
200 AutoTimer timer{&test_histogram};
201 // Sleep for 2µs so the counter will be greater than 0.
202 NanoSleep(2'000);
203 }
204
Eric Holk096bef82020-10-19 12:04:39 -0700205 EXPECT_GT(GetBuckets(test_histogram)[0], 0u);
Eric Holk1cd030f2020-09-30 11:42:34 -0700206}
207
Eric Holk61c71ef2020-10-19 12:04:39 -0700208// Makes sure all defined metrics are included when dumping through StreamBackend.
209TEST_F(MetricsTest, StreamBackendDumpAllMetrics) {
210 ArtMetrics metrics;
Eric Holkc7ac91b2021-02-04 21:44:01 +0000211 StringBackend backend;
Eric Holk61c71ef2020-10-19 12:04:39 -0700212
213 metrics.ReportAllMetrics(&backend);
214
215 // Make sure the resulting string lists all the counters.
Eric Holkc7ac91b2021-02-04 21:44:01 +0000216 const std::string result = backend.GetAndResetBuffer();
Eric Holkde275aa2021-02-01 22:59:11 +0000217#define COUNTER(name) \
Eric Holkc7ac91b2021-02-04 21:44:01 +0000218 EXPECT_NE(result.find(DatumName(DatumId::k##name)), std::string::npos)
Eric Holk61c71ef2020-10-19 12:04:39 -0700219 ART_COUNTERS(COUNTER);
220#undef COUNTER
221
222 // Make sure the resulting string lists all the histograms.
223#define HISTOGRAM(name, num_buckets, minimum_value, maximum_value) \
Eric Holkc7ac91b2021-02-04 21:44:01 +0000224 EXPECT_NE(result.find(DatumName(DatumId::k##name)), std::string::npos)
Eric Holk61c71ef2020-10-19 12:04:39 -0700225 ART_HISTOGRAMS(HISTOGRAM);
226#undef HISTOGRAM
227}
228
Eric Holkf1a2c0e2020-09-29 11:13:55 -0700229} // namespace metrics
230} // namespace art
231
232#pragma clang diagnostic pop // -Wconversion