xref: /aosp_15_r20/art/libartbase/base/metrics/metrics_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "metrics.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
20*795d594fSAndroid Build Coastguard Worker #include "gmock/gmock.h"
21*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
22*795d594fSAndroid Build Coastguard Worker #include "metrics_test.h"
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic push
25*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic error "-Wconversion"
26*795d594fSAndroid Build Coastguard Worker 
27*795d594fSAndroid Build Coastguard Worker namespace art {
28*795d594fSAndroid Build Coastguard Worker namespace metrics {
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker using test::CounterValue;
31*795d594fSAndroid Build Coastguard Worker using test::GetBuckets;
32*795d594fSAndroid Build Coastguard Worker using test::TestBackendBase;
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker class MetricsTest : public testing::Test {};
35*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,SimpleCounter)36*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, SimpleCounter) {
37*795d594fSAndroid Build Coastguard Worker   MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0u, CounterValue(test_counter));
40*795d594fSAndroid Build Coastguard Worker 
41*795d594fSAndroid Build Coastguard Worker   test_counter.AddOne();
42*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, CounterValue(test_counter));
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker   test_counter.Add(5);
45*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(6u, CounterValue(test_counter));
46*795d594fSAndroid Build Coastguard Worker }
47*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,CounterTimer)48*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, CounterTimer) {
49*795d594fSAndroid Build Coastguard Worker   MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
50*795d594fSAndroid Build Coastguard Worker   {
51*795d594fSAndroid Build Coastguard Worker     AutoTimer timer{&test_counter};
52*795d594fSAndroid Build Coastguard Worker     // Sleep for 2µs so the counter will be greater than 0.
53*795d594fSAndroid Build Coastguard Worker     NanoSleep(2'000);
54*795d594fSAndroid Build Coastguard Worker   }
55*795d594fSAndroid Build Coastguard Worker   EXPECT_GT(CounterValue(test_counter), 0u);
56*795d594fSAndroid Build Coastguard Worker }
57*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,CounterTimerExplicitStop)58*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, CounterTimerExplicitStop) {
59*795d594fSAndroid Build Coastguard Worker   MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
60*795d594fSAndroid Build Coastguard Worker   AutoTimer timer{&test_counter};
61*795d594fSAndroid Build Coastguard Worker   // Sleep for 2µs so the counter will be greater than 0.
62*795d594fSAndroid Build Coastguard Worker   NanoSleep(2'000);
63*795d594fSAndroid Build Coastguard Worker   timer.Stop();
64*795d594fSAndroid Build Coastguard Worker   EXPECT_GT(CounterValue(test_counter), 0u);
65*795d594fSAndroid Build Coastguard Worker }
66*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,CounterTimerExplicitStart)67*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, CounterTimerExplicitStart) {
68*795d594fSAndroid Build Coastguard Worker   MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
69*795d594fSAndroid Build Coastguard Worker   {
70*795d594fSAndroid Build Coastguard Worker     AutoTimer timer{&test_counter, /*autostart=*/false};
71*795d594fSAndroid Build Coastguard Worker     // Sleep for 2µs so the counter will be greater than 0.
72*795d594fSAndroid Build Coastguard Worker     NanoSleep(2'000);
73*795d594fSAndroid Build Coastguard Worker   }
74*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(CounterValue(test_counter), 0u);
75*795d594fSAndroid Build Coastguard Worker 
76*795d594fSAndroid Build Coastguard Worker   {
77*795d594fSAndroid Build Coastguard Worker     AutoTimer timer{&test_counter, /*autostart=*/false};
78*795d594fSAndroid Build Coastguard Worker     timer.Start();
79*795d594fSAndroid Build Coastguard Worker     // Sleep for 2µs so the counter will be greater than 0.
80*795d594fSAndroid Build Coastguard Worker     NanoSleep(2'000);
81*795d594fSAndroid Build Coastguard Worker   }
82*795d594fSAndroid Build Coastguard Worker   EXPECT_GT(CounterValue(test_counter), 0u);
83*795d594fSAndroid Build Coastguard Worker }
84*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,CounterTimerExplicitStartStop)85*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, CounterTimerExplicitStartStop) {
86*795d594fSAndroid Build Coastguard Worker   MetricsCounter<DatumId::kClassVerificationTotalTime> test_counter;
87*795d594fSAndroid Build Coastguard Worker   AutoTimer timer{&test_counter, /*autostart=*/false};
88*795d594fSAndroid Build Coastguard Worker   // Sleep for 2µs so the counter will be greater than 0.
89*795d594fSAndroid Build Coastguard Worker   timer.Start();
90*795d594fSAndroid Build Coastguard Worker   NanoSleep(2'000);
91*795d594fSAndroid Build Coastguard Worker   timer.Stop();
92*795d594fSAndroid Build Coastguard Worker   EXPECT_GT(CounterValue(test_counter), 0u);
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,AccumulatorMetric)95*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, AccumulatorMetric) {
96*795d594fSAndroid Build Coastguard Worker   MetricsAccumulator<DatumId::kClassLoadingTotalTime, uint64_t, std::max> accumulator;
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker   std::vector<std::thread> threads;
99*795d594fSAndroid Build Coastguard Worker 
100*795d594fSAndroid Build Coastguard Worker   constexpr uint64_t kMaxValue = 100;
101*795d594fSAndroid Build Coastguard Worker 
102*795d594fSAndroid Build Coastguard Worker   for (uint64_t i = 0; i <= kMaxValue; i++) {
103*795d594fSAndroid Build Coastguard Worker     threads.emplace_back(std::thread{[&accumulator, i]() { accumulator.Add(i); }});
104*795d594fSAndroid Build Coastguard Worker   }
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker   for (auto& thread : threads) {
107*795d594fSAndroid Build Coastguard Worker     thread.join();
108*795d594fSAndroid Build Coastguard Worker   }
109*795d594fSAndroid Build Coastguard Worker 
110*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(CounterValue(accumulator), kMaxValue);
111*795d594fSAndroid Build Coastguard Worker }
112*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,AverageMetric)113*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, AverageMetric) {
114*795d594fSAndroid Build Coastguard Worker   MetricsAverage<DatumId::kClassLoadingTotalTime, uint64_t> avg;
115*795d594fSAndroid Build Coastguard Worker 
116*795d594fSAndroid Build Coastguard Worker   std::vector<std::thread> threads;
117*795d594fSAndroid Build Coastguard Worker 
118*795d594fSAndroid Build Coastguard Worker   constexpr uint64_t kMaxValue = 100;
119*795d594fSAndroid Build Coastguard Worker 
120*795d594fSAndroid Build Coastguard Worker   for (uint64_t i = 0; i <= kMaxValue; i++) {
121*795d594fSAndroid Build Coastguard Worker     threads.emplace_back(std::thread{[&avg, i]() { avg.Add(i); }});
122*795d594fSAndroid Build Coastguard Worker   }
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker   for (auto& thread : threads) {
125*795d594fSAndroid Build Coastguard Worker     thread.join();
126*795d594fSAndroid Build Coastguard Worker   }
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(CounterValue(avg), (kMaxValue + 1) / 2);
129*795d594fSAndroid Build Coastguard Worker }
130*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,DatumName)131*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, DatumName) {
132*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ("ClassVerificationTotalTime", DatumName(DatumId::kClassVerificationTotalTime));
133*795d594fSAndroid Build Coastguard Worker }
134*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,SimpleHistogramTest)135*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, SimpleHistogramTest) {
136*795d594fSAndroid Build Coastguard Worker   MetricsHistogram<DatumId::kYoungGcCollectionTime, 5, 0, 100> histogram;
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   // bucket 0: 0-19
139*795d594fSAndroid Build Coastguard Worker   histogram.Add(10);
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker   // bucket 1: 20-39
142*795d594fSAndroid Build Coastguard Worker   histogram.Add(20);
143*795d594fSAndroid Build Coastguard Worker   histogram.Add(25);
144*795d594fSAndroid Build Coastguard Worker 
145*795d594fSAndroid Build Coastguard Worker   // bucket 2: 40-59
146*795d594fSAndroid Build Coastguard Worker   histogram.Add(56);
147*795d594fSAndroid Build Coastguard Worker   histogram.Add(57);
148*795d594fSAndroid Build Coastguard Worker   histogram.Add(58);
149*795d594fSAndroid Build Coastguard Worker   histogram.Add(59);
150*795d594fSAndroid Build Coastguard Worker 
151*795d594fSAndroid Build Coastguard Worker   // bucket 3: 60-79
152*795d594fSAndroid Build Coastguard Worker   histogram.Add(70);
153*795d594fSAndroid Build Coastguard Worker   histogram.Add(70);
154*795d594fSAndroid Build Coastguard Worker   histogram.Add(70);
155*795d594fSAndroid Build Coastguard Worker 
156*795d594fSAndroid Build Coastguard Worker   // bucket 4: 80-99
157*795d594fSAndroid Build Coastguard Worker   // leave this bucket empty
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   std::vector<uint32_t> buckets{GetBuckets(histogram)};
160*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, buckets[0u]);
161*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(2u, buckets[1u]);
162*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(4u, buckets[2u]);
163*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(3u, buckets[3u]);
164*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0u, buckets[4u]);
165*795d594fSAndroid Build Coastguard Worker }
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker // Make sure values added outside the range of the histogram go into the first or last bucket.
TEST_F(MetricsTest,HistogramOutOfRangeTest)168*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, HistogramOutOfRangeTest) {
169*795d594fSAndroid Build Coastguard Worker   MetricsHistogram<DatumId::kYoungGcCollectionTime, 2, 0, 100> histogram;
170*795d594fSAndroid Build Coastguard Worker 
171*795d594fSAndroid Build Coastguard Worker   // bucket 0: 0-49
172*795d594fSAndroid Build Coastguard Worker   histogram.Add(-500);
173*795d594fSAndroid Build Coastguard Worker 
174*795d594fSAndroid Build Coastguard Worker   // bucket 1: 50-99
175*795d594fSAndroid Build Coastguard Worker   histogram.Add(250);
176*795d594fSAndroid Build Coastguard Worker   histogram.Add(1000);
177*795d594fSAndroid Build Coastguard Worker 
178*795d594fSAndroid Build Coastguard Worker   std::vector<uint32_t> buckets{GetBuckets(histogram)};
179*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, buckets[0u]);
180*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(2u, buckets[1u]);
181*795d594fSAndroid Build Coastguard Worker }
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker // Test adding values to ArtMetrics and reporting them through a test backend.
TEST_F(MetricsTest,ArtMetricsReport)184*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, ArtMetricsReport) {
185*795d594fSAndroid Build Coastguard Worker   ArtMetrics metrics;
186*795d594fSAndroid Build Coastguard Worker 
187*795d594fSAndroid Build Coastguard Worker   // Collect some data
188*795d594fSAndroid Build Coastguard Worker   static constexpr uint64_t verification_time = 42;
189*795d594fSAndroid Build Coastguard Worker   metrics.ClassVerificationTotalTime()->Add(verification_time);
190*795d594fSAndroid Build Coastguard Worker   // Add a negative value so we are guaranteed that it lands in the first bucket.
191*795d594fSAndroid Build Coastguard Worker   metrics.YoungGcCollectionTime()->Add(-5);
192*795d594fSAndroid Build Coastguard Worker 
193*795d594fSAndroid Build Coastguard Worker   // Report and check the data
194*795d594fSAndroid Build Coastguard Worker   class TestBackend : public TestBackendBase {
195*795d594fSAndroid Build Coastguard Worker    public:
196*795d594fSAndroid Build Coastguard Worker     ~TestBackend() {
197*795d594fSAndroid Build Coastguard Worker       EXPECT_TRUE(found_counter_);
198*795d594fSAndroid Build Coastguard Worker       EXPECT_TRUE(found_histogram_);
199*795d594fSAndroid Build Coastguard Worker     }
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker     void ReportCounter(DatumId counter_type, uint64_t value) override {
202*795d594fSAndroid Build Coastguard Worker       switch (counter_type) {
203*795d594fSAndroid Build Coastguard Worker         case DatumId::kClassVerificationTotalTime:
204*795d594fSAndroid Build Coastguard Worker           EXPECT_EQ(value, verification_time)
205*795d594fSAndroid Build Coastguard Worker               << "Unexpected value for counter " << DatumName(counter_type);
206*795d594fSAndroid Build Coastguard Worker           found_counter_ = true;
207*795d594fSAndroid Build Coastguard Worker           break;
208*795d594fSAndroid Build Coastguard Worker         case DatumId::kTimeElapsedDelta:
209*795d594fSAndroid Build Coastguard Worker           // TimeElapsedData can be greater than 0 if the test takes more than 1ms to run
210*795d594fSAndroid Build Coastguard Worker           EXPECT_GE(value, 0u) << "Unexpected value for counter " << DatumName(counter_type);
211*795d594fSAndroid Build Coastguard Worker           break;
212*795d594fSAndroid Build Coastguard Worker         default:
213*795d594fSAndroid Build Coastguard Worker           EXPECT_EQ(value, 0u) << "Unexpected value for counter " << DatumName(counter_type);
214*795d594fSAndroid Build Coastguard Worker       }
215*795d594fSAndroid Build Coastguard Worker     }
216*795d594fSAndroid Build Coastguard Worker 
217*795d594fSAndroid Build Coastguard Worker     void ReportHistogram(DatumId histogram_type,
218*795d594fSAndroid Build Coastguard Worker                          int64_t,
219*795d594fSAndroid Build Coastguard Worker                          int64_t,
220*795d594fSAndroid Build Coastguard Worker                          const std::vector<uint32_t>& buckets) override {
221*795d594fSAndroid Build Coastguard Worker       if (histogram_type == DatumId::kYoungGcCollectionTime) {
222*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(buckets[0], 1u) << "Unexpected value for bucket 0 for histogram "
223*795d594fSAndroid Build Coastguard Worker                                   << DatumName(histogram_type);
224*795d594fSAndroid Build Coastguard Worker         for (size_t i = 1; i < buckets.size(); ++i) {
225*795d594fSAndroid Build Coastguard Worker           EXPECT_EQ(buckets[i], 0u) << "Unexpected value for bucket " << i << " for histogram "
226*795d594fSAndroid Build Coastguard Worker                                     << DatumName(histogram_type);
227*795d594fSAndroid Build Coastguard Worker         }
228*795d594fSAndroid Build Coastguard Worker         found_histogram_ = true;
229*795d594fSAndroid Build Coastguard Worker       } else {
230*795d594fSAndroid Build Coastguard Worker         for (size_t i = 0; i < buckets.size(); ++i) {
231*795d594fSAndroid Build Coastguard Worker           EXPECT_EQ(buckets[i], 0u) << "Unexpected value for bucket " << i << " for histogram "
232*795d594fSAndroid Build Coastguard Worker                                     << DatumName(histogram_type);
233*795d594fSAndroid Build Coastguard Worker         }
234*795d594fSAndroid Build Coastguard Worker       }
235*795d594fSAndroid Build Coastguard Worker     }
236*795d594fSAndroid Build Coastguard Worker 
237*795d594fSAndroid Build Coastguard Worker    private:
238*795d594fSAndroid Build Coastguard Worker     bool found_counter_{false};
239*795d594fSAndroid Build Coastguard Worker     bool found_histogram_{false};
240*795d594fSAndroid Build Coastguard Worker   } backend;
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker   metrics.ReportAllMetricsAndResetValueMetrics({&backend});
243*795d594fSAndroid Build Coastguard Worker }
244*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,HistogramTimer)245*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, HistogramTimer) {
246*795d594fSAndroid Build Coastguard Worker   MetricsHistogram<DatumId::kYoungGcCollectionTime, 1, 0, 100> test_histogram;
247*795d594fSAndroid Build Coastguard Worker   {
248*795d594fSAndroid Build Coastguard Worker     AutoTimer timer{&test_histogram};
249*795d594fSAndroid Build Coastguard Worker     // Sleep for 2µs so the counter will be greater than 0.
250*795d594fSAndroid Build Coastguard Worker     NanoSleep(2'000);
251*795d594fSAndroid Build Coastguard Worker   }
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker   EXPECT_GT(GetBuckets(test_histogram)[0], 0u);
254*795d594fSAndroid Build Coastguard Worker }
255*795d594fSAndroid Build Coastguard Worker 
256*795d594fSAndroid Build Coastguard Worker // Makes sure all defined metrics are included when dumping through StreamBackend.
TEST_F(MetricsTest,StreamBackendDumpAllMetrics)257*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, StreamBackendDumpAllMetrics) {
258*795d594fSAndroid Build Coastguard Worker   ArtMetrics metrics;
259*795d594fSAndroid Build Coastguard Worker   StringBackend backend(std::make_unique<TextFormatter>());
260*795d594fSAndroid Build Coastguard Worker 
261*795d594fSAndroid Build Coastguard Worker   metrics.ReportAllMetricsAndResetValueMetrics({&backend});
262*795d594fSAndroid Build Coastguard Worker 
263*795d594fSAndroid Build Coastguard Worker   // Make sure the resulting string lists all the metrics.
264*795d594fSAndroid Build Coastguard Worker   const std::string result = backend.GetAndResetBuffer();
265*795d594fSAndroid Build Coastguard Worker #define METRIC(name, type, ...) \
266*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(result.find(DatumName(DatumId::k##name)), std::string::npos);
267*795d594fSAndroid Build Coastguard Worker   ART_METRICS(METRIC);
268*795d594fSAndroid Build Coastguard Worker #undef METRIC
269*795d594fSAndroid Build Coastguard Worker }
270*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,ResetMetrics)271*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, ResetMetrics) {
272*795d594fSAndroid Build Coastguard Worker   ArtMetrics metrics;
273*795d594fSAndroid Build Coastguard Worker 
274*795d594fSAndroid Build Coastguard Worker   // Add something to each of the metrics.
275*795d594fSAndroid Build Coastguard Worker #define METRIC(name, type, ...) metrics.name()->Add(42);
276*795d594fSAndroid Build Coastguard Worker   ART_METRICS(METRIC)
277*795d594fSAndroid Build Coastguard Worker #undef METRIC
278*795d594fSAndroid Build Coastguard Worker 
279*795d594fSAndroid Build Coastguard Worker   class NonZeroBackend : public TestBackendBase {
280*795d594fSAndroid Build Coastguard Worker    public:
281*795d594fSAndroid Build Coastguard Worker     void ReportCounter(DatumId counter_type, uint64_t value) override {
282*795d594fSAndroid Build Coastguard Worker       EXPECT_NE(value, 0u) << "Unexpected value for counter " << DatumName(counter_type);
283*795d594fSAndroid Build Coastguard Worker     }
284*795d594fSAndroid Build Coastguard Worker 
285*795d594fSAndroid Build Coastguard Worker     void ReportHistogram(DatumId histogram_type,
286*795d594fSAndroid Build Coastguard Worker                          [[maybe_unused]] int64_t minimum_value,
287*795d594fSAndroid Build Coastguard Worker                          [[maybe_unused]] int64_t maximum_value,
288*795d594fSAndroid Build Coastguard Worker                          const std::vector<uint32_t>& buckets) override {
289*795d594fSAndroid Build Coastguard Worker       bool nonzero = false;
290*795d594fSAndroid Build Coastguard Worker       for (const auto value : buckets) {
291*795d594fSAndroid Build Coastguard Worker         nonzero |= (value != 0u);
292*795d594fSAndroid Build Coastguard Worker       }
293*795d594fSAndroid Build Coastguard Worker       EXPECT_TRUE(nonzero) << "Unexpected value for histogram " << DatumName(histogram_type);
294*795d594fSAndroid Build Coastguard Worker     }
295*795d594fSAndroid Build Coastguard Worker   } non_zero_backend;
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker   // Make sure the metrics all have a nonzero value.
298*795d594fSAndroid Build Coastguard Worker   metrics.ReportAllMetricsAndResetValueMetrics({&non_zero_backend});
299*795d594fSAndroid Build Coastguard Worker 
300*795d594fSAndroid Build Coastguard Worker   // Reset the metrics and make sure they are all zero again
301*795d594fSAndroid Build Coastguard Worker   metrics.Reset();
302*795d594fSAndroid Build Coastguard Worker 
303*795d594fSAndroid Build Coastguard Worker   class ZeroBackend : public TestBackendBase {
304*795d594fSAndroid Build Coastguard Worker    public:
305*795d594fSAndroid Build Coastguard Worker     void ReportCounter(DatumId counter_type, uint64_t value) override {
306*795d594fSAndroid Build Coastguard Worker       if (counter_type == DatumId::kTimeElapsedDelta) {
307*795d594fSAndroid Build Coastguard Worker         // TimeElapsedData can be greater than 0 if the test takes more than 1ms to run
308*795d594fSAndroid Build Coastguard Worker         EXPECT_GE(value, 0u) << "Unexpected value for counter " << DatumName(counter_type);
309*795d594fSAndroid Build Coastguard Worker       } else {
310*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(value, 0u) << "Unexpected value for counter " << DatumName(counter_type);
311*795d594fSAndroid Build Coastguard Worker       }
312*795d594fSAndroid Build Coastguard Worker     }
313*795d594fSAndroid Build Coastguard Worker 
314*795d594fSAndroid Build Coastguard Worker     void ReportHistogram([[maybe_unused]] DatumId histogram_type,
315*795d594fSAndroid Build Coastguard Worker                          [[maybe_unused]] int64_t minimum_value,
316*795d594fSAndroid Build Coastguard Worker                          [[maybe_unused]] int64_t maximum_value,
317*795d594fSAndroid Build Coastguard Worker                          const std::vector<uint32_t>& buckets) override {
318*795d594fSAndroid Build Coastguard Worker       for (const auto value : buckets) {
319*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(value, 0u) << "Unexpected value for histogram " << DatumName(histogram_type);
320*795d594fSAndroid Build Coastguard Worker       }
321*795d594fSAndroid Build Coastguard Worker     }
322*795d594fSAndroid Build Coastguard Worker   } zero_backend;
323*795d594fSAndroid Build Coastguard Worker 
324*795d594fSAndroid Build Coastguard Worker   metrics.ReportAllMetricsAndResetValueMetrics({&zero_backend});
325*795d594fSAndroid Build Coastguard Worker }
326*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsTest,KeepEventMetricsResetValueMetricsAfterReporting)327*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsTest, KeepEventMetricsResetValueMetricsAfterReporting) {
328*795d594fSAndroid Build Coastguard Worker   ArtMetrics metrics;
329*795d594fSAndroid Build Coastguard Worker 
330*795d594fSAndroid Build Coastguard Worker   // Add something to each of the metrics.
331*795d594fSAndroid Build Coastguard Worker #define METRIC(name, type, ...) metrics.name()->Add(42);
332*795d594fSAndroid Build Coastguard Worker   ART_METRICS(METRIC)
333*795d594fSAndroid Build Coastguard Worker #undef METRIC
334*795d594fSAndroid Build Coastguard Worker 
335*795d594fSAndroid Build Coastguard Worker   class FirstBackend : public TestBackendBase {
336*795d594fSAndroid Build Coastguard Worker    public:
337*795d594fSAndroid Build Coastguard Worker     void ReportCounter(DatumId counter_type, uint64_t value) override {
338*795d594fSAndroid Build Coastguard Worker       EXPECT_NE(value, 0u) << "Unexpected value for counter " << DatumName(counter_type);
339*795d594fSAndroid Build Coastguard Worker     }
340*795d594fSAndroid Build Coastguard Worker 
341*795d594fSAndroid Build Coastguard Worker     void ReportHistogram(DatumId histogram_type,
342*795d594fSAndroid Build Coastguard Worker                          [[maybe_unused]] int64_t minimum_value,
343*795d594fSAndroid Build Coastguard Worker                          [[maybe_unused]] int64_t maximum_value,
344*795d594fSAndroid Build Coastguard Worker                          const std::vector<uint32_t>& buckets) override {
345*795d594fSAndroid Build Coastguard Worker       EXPECT_NE(buckets[0], 0u) << "Unexpected value for bucket 0 for histogram "
346*795d594fSAndroid Build Coastguard Worker                                 << DatumName(histogram_type);
347*795d594fSAndroid Build Coastguard Worker       for (size_t i = 1; i < buckets.size(); i++) {
348*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(buckets[i], 0u) << "Unexpected value for bucket " << i << " for histogram "
349*795d594fSAndroid Build Coastguard Worker                                   << DatumName(histogram_type);
350*795d594fSAndroid Build Coastguard Worker       }
351*795d594fSAndroid Build Coastguard Worker     }
352*795d594fSAndroid Build Coastguard Worker   } first_backend;
353*795d594fSAndroid Build Coastguard Worker 
354*795d594fSAndroid Build Coastguard Worker   // Make sure the metrics all have a nonzero value, and they are not reset between backends.
355*795d594fSAndroid Build Coastguard Worker   metrics.ReportAllMetricsAndResetValueMetrics({&first_backend, &first_backend});
356*795d594fSAndroid Build Coastguard Worker 
357*795d594fSAndroid Build Coastguard Worker   // After reporting, the Value Metrics should have been reset.
358*795d594fSAndroid Build Coastguard Worker   class SecondBackend : public TestBackendBase {
359*795d594fSAndroid Build Coastguard Worker    public:
360*795d594fSAndroid Build Coastguard Worker     void ReportCounter(DatumId datum_id, uint64_t value) override {
361*795d594fSAndroid Build Coastguard Worker       switch (datum_id) {
362*795d594fSAndroid Build Coastguard Worker         // Value metrics - expected to have been reset
363*795d594fSAndroid Build Coastguard Worker #define CHECK_METRIC(name, ...) case DatumId::k##name:
364*795d594fSAndroid Build Coastguard Worker         ART_VALUE_METRICS(CHECK_METRIC)
365*795d594fSAndroid Build Coastguard Worker #undef CHECK_METRIC
366*795d594fSAndroid Build Coastguard Worker         if (datum_id == DatumId::kTimeElapsedDelta) {
367*795d594fSAndroid Build Coastguard Worker           // TimeElapsedData can be greater than 0 if the test takes more than 1ms to run
368*795d594fSAndroid Build Coastguard Worker           EXPECT_GE(value, 0u) << "Unexpected value for counter " << DatumName(datum_id);
369*795d594fSAndroid Build Coastguard Worker         } else {
370*795d594fSAndroid Build Coastguard Worker           EXPECT_EQ(value, 0u) << "Unexpected value for counter " << DatumName(datum_id);
371*795d594fSAndroid Build Coastguard Worker         }
372*795d594fSAndroid Build Coastguard Worker         return;
373*795d594fSAndroid Build Coastguard Worker 
374*795d594fSAndroid Build Coastguard Worker         // Event metrics - expected to have retained their previous value
375*795d594fSAndroid Build Coastguard Worker #define CHECK_METRIC(name, ...) case DatumId::k##name:
376*795d594fSAndroid Build Coastguard Worker         ART_EVENT_METRICS(CHECK_METRIC)
377*795d594fSAndroid Build Coastguard Worker #undef CHECK_METRIC
378*795d594fSAndroid Build Coastguard Worker         EXPECT_NE(value, 0u) << "Unexpected value for metric " << DatumName(datum_id);
379*795d594fSAndroid Build Coastguard Worker         return;
380*795d594fSAndroid Build Coastguard Worker 
381*795d594fSAndroid Build Coastguard Worker         default:
382*795d594fSAndroid Build Coastguard Worker           // unknown metric - it should not be possible to reach this path
383*795d594fSAndroid Build Coastguard Worker           FAIL();
384*795d594fSAndroid Build Coastguard Worker           UNREACHABLE();
385*795d594fSAndroid Build Coastguard Worker       }
386*795d594fSAndroid Build Coastguard Worker     }
387*795d594fSAndroid Build Coastguard Worker 
388*795d594fSAndroid Build Coastguard Worker     // All histograms are event metrics.
389*795d594fSAndroid Build Coastguard Worker     void ReportHistogram([[maybe_unused]] DatumId histogram_type,
390*795d594fSAndroid Build Coastguard Worker                          [[maybe_unused]] int64_t minimum_value,
391*795d594fSAndroid Build Coastguard Worker                          [[maybe_unused]] int64_t maximum_value,
392*795d594fSAndroid Build Coastguard Worker                          const std::vector<uint32_t>& buckets) override {
393*795d594fSAndroid Build Coastguard Worker       EXPECT_NE(buckets[0], 0u) << "Unexpected value for bucket 0 for histogram "
394*795d594fSAndroid Build Coastguard Worker                                 << DatumName(histogram_type);
395*795d594fSAndroid Build Coastguard Worker       for (size_t i = 1; i < buckets.size(); i++) {
396*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(buckets[i], 0u) << "Unexpected value for bucket " << i << " for histogram "
397*795d594fSAndroid Build Coastguard Worker                                   << DatumName(histogram_type);
398*795d594fSAndroid Build Coastguard Worker       }
399*795d594fSAndroid Build Coastguard Worker     }
400*795d594fSAndroid Build Coastguard Worker   } second_backend;
401*795d594fSAndroid Build Coastguard Worker 
402*795d594fSAndroid Build Coastguard Worker   metrics.ReportAllMetricsAndResetValueMetrics({&second_backend});
403*795d594fSAndroid Build Coastguard Worker }
404*795d594fSAndroid Build Coastguard Worker 
TEST(TextFormatterTest,ReportMetrics_WithBuckets)405*795d594fSAndroid Build Coastguard Worker TEST(TextFormatterTest, ReportMetrics_WithBuckets) {
406*795d594fSAndroid Build Coastguard Worker   TextFormatter text_formatter;
407*795d594fSAndroid Build Coastguard Worker   SessionData session_data{
408*795d594fSAndroid Build Coastguard Worker       .session_id = 1000,
409*795d594fSAndroid Build Coastguard Worker       .uid = 50,
410*795d594fSAndroid Build Coastguard Worker       .compilation_reason = CompilationReason::kInstall,
411*795d594fSAndroid Build Coastguard Worker       .compiler_filter = CompilerFilterReporting::kSpeed,
412*795d594fSAndroid Build Coastguard Worker   };
413*795d594fSAndroid Build Coastguard Worker 
414*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatBeginReport(200, session_data);
415*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatReportCounter(DatumId::kFullGcCount, 1u);
416*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatReportHistogram(DatumId::kFullGcCollectionTime, 50, 200, {2, 4, 7, 1});
417*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatEndReport();
418*795d594fSAndroid Build Coastguard Worker 
419*795d594fSAndroid Build Coastguard Worker   const std::string result = text_formatter.GetAndResetBuffer();
420*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
421*795d594fSAndroid Build Coastguard Worker             "\n*** ART internal metrics ***\n"
422*795d594fSAndroid Build Coastguard Worker             "  Metadata:\n"
423*795d594fSAndroid Build Coastguard Worker             "    timestamp_since_start_ms: 200\n"
424*795d594fSAndroid Build Coastguard Worker             "    session_id: 1000\n"
425*795d594fSAndroid Build Coastguard Worker             "    uid: 50\n"
426*795d594fSAndroid Build Coastguard Worker             "    compilation_reason: install\n"
427*795d594fSAndroid Build Coastguard Worker             "    compiler_filter: speed\n"
428*795d594fSAndroid Build Coastguard Worker             "  Metrics:\n"
429*795d594fSAndroid Build Coastguard Worker             "    FullGcCount: count = 1\n"
430*795d594fSAndroid Build Coastguard Worker             "    FullGcCollectionTime: range = 50...200, buckets: 2,4,7,1\n"
431*795d594fSAndroid Build Coastguard Worker             "*** Done dumping ART internal metrics ***\n");
432*795d594fSAndroid Build Coastguard Worker }
433*795d594fSAndroid Build Coastguard Worker 
TEST(TextFormatterTest,ReportMetrics_NoBuckets)434*795d594fSAndroid Build Coastguard Worker TEST(TextFormatterTest, ReportMetrics_NoBuckets) {
435*795d594fSAndroid Build Coastguard Worker   TextFormatter text_formatter;
436*795d594fSAndroid Build Coastguard Worker   SessionData session_data{
437*795d594fSAndroid Build Coastguard Worker       .session_id = 500,
438*795d594fSAndroid Build Coastguard Worker       .uid = 15,
439*795d594fSAndroid Build Coastguard Worker       .compilation_reason = CompilationReason::kCmdLine,
440*795d594fSAndroid Build Coastguard Worker       .compiler_filter = CompilerFilterReporting::kExtract,
441*795d594fSAndroid Build Coastguard Worker   };
442*795d594fSAndroid Build Coastguard Worker 
443*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatBeginReport(400, session_data);
444*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatReportHistogram(DatumId::kFullGcCollectionTime, 10, 20, {});
445*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatEndReport();
446*795d594fSAndroid Build Coastguard Worker 
447*795d594fSAndroid Build Coastguard Worker   std::string result = text_formatter.GetAndResetBuffer();
448*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
449*795d594fSAndroid Build Coastguard Worker             "\n*** ART internal metrics ***\n"
450*795d594fSAndroid Build Coastguard Worker             "  Metadata:\n"
451*795d594fSAndroid Build Coastguard Worker             "    timestamp_since_start_ms: 400\n"
452*795d594fSAndroid Build Coastguard Worker             "    session_id: 500\n"
453*795d594fSAndroid Build Coastguard Worker             "    uid: 15\n"
454*795d594fSAndroid Build Coastguard Worker             "    compilation_reason: cmdline\n"
455*795d594fSAndroid Build Coastguard Worker             "    compiler_filter: extract\n"
456*795d594fSAndroid Build Coastguard Worker             "  Metrics:\n"
457*795d594fSAndroid Build Coastguard Worker             "    FullGcCollectionTime: range = 10...20, no buckets\n"
458*795d594fSAndroid Build Coastguard Worker             "*** Done dumping ART internal metrics ***\n");
459*795d594fSAndroid Build Coastguard Worker }
460*795d594fSAndroid Build Coastguard Worker 
TEST(TextFormatterTest,BeginReport_NoSessionData)461*795d594fSAndroid Build Coastguard Worker TEST(TextFormatterTest, BeginReport_NoSessionData) {
462*795d594fSAndroid Build Coastguard Worker   TextFormatter text_formatter;
463*795d594fSAndroid Build Coastguard Worker   std::optional<SessionData> empty_session_data;
464*795d594fSAndroid Build Coastguard Worker 
465*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatBeginReport(100, empty_session_data);
466*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatEndReport();
467*795d594fSAndroid Build Coastguard Worker 
468*795d594fSAndroid Build Coastguard Worker   std::string result = text_formatter.GetAndResetBuffer();
469*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
470*795d594fSAndroid Build Coastguard Worker             "\n*** ART internal metrics ***\n"
471*795d594fSAndroid Build Coastguard Worker             "  Metadata:\n"
472*795d594fSAndroid Build Coastguard Worker             "    timestamp_since_start_ms: 100\n"
473*795d594fSAndroid Build Coastguard Worker             "  Metrics:\n"
474*795d594fSAndroid Build Coastguard Worker             "*** Done dumping ART internal metrics ***\n");
475*795d594fSAndroid Build Coastguard Worker }
476*795d594fSAndroid Build Coastguard Worker 
TEST(TextFormatterTest,GetAndResetBuffer_ActuallyResetsBuffer)477*795d594fSAndroid Build Coastguard Worker TEST(TextFormatterTest, GetAndResetBuffer_ActuallyResetsBuffer) {
478*795d594fSAndroid Build Coastguard Worker   TextFormatter text_formatter;
479*795d594fSAndroid Build Coastguard Worker   std::optional<SessionData> empty_session_data;
480*795d594fSAndroid Build Coastguard Worker 
481*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatBeginReport(200, empty_session_data);
482*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatReportCounter(DatumId::kFullGcCount, 1u);
483*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatEndReport();
484*795d594fSAndroid Build Coastguard Worker 
485*795d594fSAndroid Build Coastguard Worker   std::string result = text_formatter.GetAndResetBuffer();
486*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
487*795d594fSAndroid Build Coastguard Worker             "\n*** ART internal metrics ***\n"
488*795d594fSAndroid Build Coastguard Worker             "  Metadata:\n"
489*795d594fSAndroid Build Coastguard Worker             "    timestamp_since_start_ms: 200\n"
490*795d594fSAndroid Build Coastguard Worker             "  Metrics:\n"
491*795d594fSAndroid Build Coastguard Worker             "    FullGcCount: count = 1\n"
492*795d594fSAndroid Build Coastguard Worker             "*** Done dumping ART internal metrics ***\n");
493*795d594fSAndroid Build Coastguard Worker 
494*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatBeginReport(300, empty_session_data);
495*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatReportCounter(DatumId::kFullGcCount, 5u);
496*795d594fSAndroid Build Coastguard Worker   text_formatter.FormatEndReport();
497*795d594fSAndroid Build Coastguard Worker 
498*795d594fSAndroid Build Coastguard Worker   result = text_formatter.GetAndResetBuffer();
499*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
500*795d594fSAndroid Build Coastguard Worker             "\n*** ART internal metrics ***\n"
501*795d594fSAndroid Build Coastguard Worker             "  Metadata:\n"
502*795d594fSAndroid Build Coastguard Worker             "    timestamp_since_start_ms: 300\n"
503*795d594fSAndroid Build Coastguard Worker             "  Metrics:\n"
504*795d594fSAndroid Build Coastguard Worker             "    FullGcCount: count = 5\n"
505*795d594fSAndroid Build Coastguard Worker             "*** Done dumping ART internal metrics ***\n");
506*795d594fSAndroid Build Coastguard Worker }
507*795d594fSAndroid Build Coastguard Worker 
TEST(XmlFormatterTest,ReportMetrics_WithBuckets)508*795d594fSAndroid Build Coastguard Worker TEST(XmlFormatterTest, ReportMetrics_WithBuckets) {
509*795d594fSAndroid Build Coastguard Worker   XmlFormatter xml_formatter;
510*795d594fSAndroid Build Coastguard Worker   SessionData session_data{
511*795d594fSAndroid Build Coastguard Worker       .session_id = 123,
512*795d594fSAndroid Build Coastguard Worker       .uid = 456,
513*795d594fSAndroid Build Coastguard Worker       .compilation_reason = CompilationReason::kFirstBoot,
514*795d594fSAndroid Build Coastguard Worker       .compiler_filter = CompilerFilterReporting::kSpace,
515*795d594fSAndroid Build Coastguard Worker   };
516*795d594fSAndroid Build Coastguard Worker 
517*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatBeginReport(250, session_data);
518*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatReportCounter(DatumId::kYoungGcCount, 3u);
519*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatReportHistogram(DatumId::kYoungGcCollectionTime, 300, 600, {1, 5, 3});
520*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatEndReport();
521*795d594fSAndroid Build Coastguard Worker 
522*795d594fSAndroid Build Coastguard Worker   const std::string result = xml_formatter.GetAndResetBuffer();
523*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
524*795d594fSAndroid Build Coastguard Worker             "<art_runtime_metrics>"
525*795d594fSAndroid Build Coastguard Worker             "<version>1.0</version>"
526*795d594fSAndroid Build Coastguard Worker             "<metadata>"
527*795d594fSAndroid Build Coastguard Worker             "<timestamp_since_start_ms>250</timestamp_since_start_ms>"
528*795d594fSAndroid Build Coastguard Worker             "<session_id>123</session_id>"
529*795d594fSAndroid Build Coastguard Worker             "<uid>456</uid>"
530*795d594fSAndroid Build Coastguard Worker             "<compilation_reason>first-boot</compilation_reason>"
531*795d594fSAndroid Build Coastguard Worker             "<compiler_filter>space</compiler_filter>"
532*795d594fSAndroid Build Coastguard Worker             "</metadata>"
533*795d594fSAndroid Build Coastguard Worker             "<metrics>"
534*795d594fSAndroid Build Coastguard Worker             "<YoungGcCount>"
535*795d594fSAndroid Build Coastguard Worker             "<counter_type>count</counter_type>"
536*795d594fSAndroid Build Coastguard Worker             "<value>3</value>"
537*795d594fSAndroid Build Coastguard Worker             "</YoungGcCount>"
538*795d594fSAndroid Build Coastguard Worker             "<YoungGcCollectionTime>"
539*795d594fSAndroid Build Coastguard Worker             "<counter_type>histogram</counter_type>"
540*795d594fSAndroid Build Coastguard Worker             "<minimum_value>300</minimum_value>"
541*795d594fSAndroid Build Coastguard Worker             "<maximum_value>600</maximum_value>"
542*795d594fSAndroid Build Coastguard Worker             "<buckets>"
543*795d594fSAndroid Build Coastguard Worker             "<bucket>1</bucket>"
544*795d594fSAndroid Build Coastguard Worker             "<bucket>5</bucket>"
545*795d594fSAndroid Build Coastguard Worker             "<bucket>3</bucket>"
546*795d594fSAndroid Build Coastguard Worker             "</buckets>"
547*795d594fSAndroid Build Coastguard Worker             "</YoungGcCollectionTime>"
548*795d594fSAndroid Build Coastguard Worker             "</metrics>"
549*795d594fSAndroid Build Coastguard Worker             "</art_runtime_metrics>");
550*795d594fSAndroid Build Coastguard Worker }
551*795d594fSAndroid Build Coastguard Worker 
TEST(XmlFormatterTest,ReportMetrics_NoBuckets)552*795d594fSAndroid Build Coastguard Worker TEST(XmlFormatterTest, ReportMetrics_NoBuckets) {
553*795d594fSAndroid Build Coastguard Worker   XmlFormatter xml_formatter;
554*795d594fSAndroid Build Coastguard Worker   SessionData session_data{
555*795d594fSAndroid Build Coastguard Worker       .session_id = 234,
556*795d594fSAndroid Build Coastguard Worker       .uid = 345,
557*795d594fSAndroid Build Coastguard Worker       .compilation_reason = CompilationReason::kFirstBoot,
558*795d594fSAndroid Build Coastguard Worker       .compiler_filter = CompilerFilterReporting::kSpace,
559*795d594fSAndroid Build Coastguard Worker   };
560*795d594fSAndroid Build Coastguard Worker 
561*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatBeginReport(160, session_data);
562*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatReportCounter(DatumId::kYoungGcCount, 4u);
563*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatReportHistogram(DatumId::kYoungGcCollectionTime, 20, 40, {});
564*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatEndReport();
565*795d594fSAndroid Build Coastguard Worker 
566*795d594fSAndroid Build Coastguard Worker   const std::string result = xml_formatter.GetAndResetBuffer();
567*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
568*795d594fSAndroid Build Coastguard Worker             "<art_runtime_metrics>"
569*795d594fSAndroid Build Coastguard Worker             "<version>1.0</version>"
570*795d594fSAndroid Build Coastguard Worker             "<metadata>"
571*795d594fSAndroid Build Coastguard Worker             "<timestamp_since_start_ms>160</timestamp_since_start_ms>"
572*795d594fSAndroid Build Coastguard Worker             "<session_id>234</session_id>"
573*795d594fSAndroid Build Coastguard Worker             "<uid>345</uid>"
574*795d594fSAndroid Build Coastguard Worker             "<compilation_reason>first-boot</compilation_reason>"
575*795d594fSAndroid Build Coastguard Worker             "<compiler_filter>space</compiler_filter>"
576*795d594fSAndroid Build Coastguard Worker             "</metadata>"
577*795d594fSAndroid Build Coastguard Worker             "<metrics>"
578*795d594fSAndroid Build Coastguard Worker             "<YoungGcCount>"
579*795d594fSAndroid Build Coastguard Worker             "<counter_type>count</counter_type>"
580*795d594fSAndroid Build Coastguard Worker             "<value>4</value>"
581*795d594fSAndroid Build Coastguard Worker             "</YoungGcCount>"
582*795d594fSAndroid Build Coastguard Worker             "<YoungGcCollectionTime>"
583*795d594fSAndroid Build Coastguard Worker             "<counter_type>histogram</counter_type>"
584*795d594fSAndroid Build Coastguard Worker             "<minimum_value>20</minimum_value>"
585*795d594fSAndroid Build Coastguard Worker             "<maximum_value>40</maximum_value>"
586*795d594fSAndroid Build Coastguard Worker             "<buckets/>"
587*795d594fSAndroid Build Coastguard Worker             "</YoungGcCollectionTime>"
588*795d594fSAndroid Build Coastguard Worker             "</metrics>"
589*795d594fSAndroid Build Coastguard Worker             "</art_runtime_metrics>");
590*795d594fSAndroid Build Coastguard Worker }
591*795d594fSAndroid Build Coastguard Worker 
TEST(XmlFormatterTest,BeginReport_NoSessionData)592*795d594fSAndroid Build Coastguard Worker TEST(XmlFormatterTest, BeginReport_NoSessionData) {
593*795d594fSAndroid Build Coastguard Worker   XmlFormatter xml_formatter;
594*795d594fSAndroid Build Coastguard Worker   std::optional<SessionData> empty_session_data;
595*795d594fSAndroid Build Coastguard Worker 
596*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatBeginReport(100, empty_session_data);
597*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatReportCounter(DatumId::kYoungGcCount, 3u);
598*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatEndReport();
599*795d594fSAndroid Build Coastguard Worker 
600*795d594fSAndroid Build Coastguard Worker   std::string result = xml_formatter.GetAndResetBuffer();
601*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
602*795d594fSAndroid Build Coastguard Worker             "<art_runtime_metrics>"
603*795d594fSAndroid Build Coastguard Worker             "<version>1.0</version>"
604*795d594fSAndroid Build Coastguard Worker             "<metadata>"
605*795d594fSAndroid Build Coastguard Worker             "<timestamp_since_start_ms>100</timestamp_since_start_ms>"
606*795d594fSAndroid Build Coastguard Worker             "</metadata>"
607*795d594fSAndroid Build Coastguard Worker             "<metrics>"
608*795d594fSAndroid Build Coastguard Worker             "<YoungGcCount>"
609*795d594fSAndroid Build Coastguard Worker             "<counter_type>count</counter_type>"
610*795d594fSAndroid Build Coastguard Worker             "<value>3</value>"
611*795d594fSAndroid Build Coastguard Worker             "</YoungGcCount>"
612*795d594fSAndroid Build Coastguard Worker             "</metrics>"
613*795d594fSAndroid Build Coastguard Worker             "</art_runtime_metrics>");
614*795d594fSAndroid Build Coastguard Worker }
615*795d594fSAndroid Build Coastguard Worker 
TEST(XmlFormatterTest,GetAndResetBuffer_ActuallyResetsBuffer)616*795d594fSAndroid Build Coastguard Worker TEST(XmlFormatterTest, GetAndResetBuffer_ActuallyResetsBuffer) {
617*795d594fSAndroid Build Coastguard Worker   XmlFormatter xml_formatter;
618*795d594fSAndroid Build Coastguard Worker   std::optional<SessionData> empty_session_data;
619*795d594fSAndroid Build Coastguard Worker 
620*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatBeginReport(200, empty_session_data);
621*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatReportCounter(DatumId::kFullGcCount, 1u);
622*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatEndReport();
623*795d594fSAndroid Build Coastguard Worker 
624*795d594fSAndroid Build Coastguard Worker   std::string result = xml_formatter.GetAndResetBuffer();
625*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
626*795d594fSAndroid Build Coastguard Worker             "<art_runtime_metrics>"
627*795d594fSAndroid Build Coastguard Worker             "<version>1.0</version>"
628*795d594fSAndroid Build Coastguard Worker             "<metadata>"
629*795d594fSAndroid Build Coastguard Worker             "<timestamp_since_start_ms>200</timestamp_since_start_ms>"
630*795d594fSAndroid Build Coastguard Worker             "</metadata>"
631*795d594fSAndroid Build Coastguard Worker             "<metrics>"
632*795d594fSAndroid Build Coastguard Worker             "<FullGcCount>"
633*795d594fSAndroid Build Coastguard Worker             "<counter_type>count</counter_type>"
634*795d594fSAndroid Build Coastguard Worker             "<value>1</value>"
635*795d594fSAndroid Build Coastguard Worker             "</FullGcCount>"
636*795d594fSAndroid Build Coastguard Worker             "</metrics>"
637*795d594fSAndroid Build Coastguard Worker             "</art_runtime_metrics>");
638*795d594fSAndroid Build Coastguard Worker 
639*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatBeginReport(300, empty_session_data);
640*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatReportCounter(DatumId::kFullGcCount, 5u);
641*795d594fSAndroid Build Coastguard Worker   xml_formatter.FormatEndReport();
642*795d594fSAndroid Build Coastguard Worker 
643*795d594fSAndroid Build Coastguard Worker   result = xml_formatter.GetAndResetBuffer();
644*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(result,
645*795d594fSAndroid Build Coastguard Worker             "<art_runtime_metrics>"
646*795d594fSAndroid Build Coastguard Worker             "<version>1.0</version>"
647*795d594fSAndroid Build Coastguard Worker             "<metadata>"
648*795d594fSAndroid Build Coastguard Worker             "<timestamp_since_start_ms>300</timestamp_since_start_ms>"
649*795d594fSAndroid Build Coastguard Worker             "</metadata>"
650*795d594fSAndroid Build Coastguard Worker             "<metrics>"
651*795d594fSAndroid Build Coastguard Worker             "<FullGcCount>"
652*795d594fSAndroid Build Coastguard Worker             "<counter_type>count</counter_type>"
653*795d594fSAndroid Build Coastguard Worker             "<value>5</value>"
654*795d594fSAndroid Build Coastguard Worker             "</FullGcCount>"
655*795d594fSAndroid Build Coastguard Worker             "</metrics>"
656*795d594fSAndroid Build Coastguard Worker             "</art_runtime_metrics>");
657*795d594fSAndroid Build Coastguard Worker }
658*795d594fSAndroid Build Coastguard Worker 
TEST(CompilerFilterReportingTest,FromName)659*795d594fSAndroid Build Coastguard Worker TEST(CompilerFilterReportingTest, FromName) {
660*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("error"), CompilerFilterReporting::kError);
661*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("unknown"), CompilerFilterReporting::kUnknown);
662*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("assume-verified"),
663*795d594fSAndroid Build Coastguard Worker             CompilerFilterReporting::kAssumeVerified);
664*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("extract"), CompilerFilterReporting::kExtract);
665*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("verify"), CompilerFilterReporting::kVerify);
666*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("space-profile"),
667*795d594fSAndroid Build Coastguard Worker             CompilerFilterReporting::kSpaceProfile);
668*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("space"), CompilerFilterReporting::kSpace);
669*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("speed-profile"),
670*795d594fSAndroid Build Coastguard Worker             CompilerFilterReporting::kSpeedProfile);
671*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("speed"), CompilerFilterReporting::kSpeed);
672*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("everything-profile"),
673*795d594fSAndroid Build Coastguard Worker             CompilerFilterReporting::kEverythingProfile);
674*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("everything"), CompilerFilterReporting::kEverything);
675*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("run-from-apk"), CompilerFilterReporting::kRunFromApk);
676*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingFromName("run-from-apk-fallback"),
677*795d594fSAndroid Build Coastguard Worker             CompilerFilterReporting::kRunFromApkFallback);
678*795d594fSAndroid Build Coastguard Worker }
679*795d594fSAndroid Build Coastguard Worker 
TEST(CompilerFilterReportingTest,Name)680*795d594fSAndroid Build Coastguard Worker TEST(CompilerFilterReportingTest, Name) {
681*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kError), "error");
682*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kUnknown), "unknown");
683*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kAssumeVerified),
684*795d594fSAndroid Build Coastguard Worker             "assume-verified");
685*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kExtract), "extract");
686*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kVerify), "verify");
687*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kSpaceProfile), "space-profile");
688*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kSpace), "space");
689*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kSpeedProfile), "speed-profile");
690*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kSpeed), "speed");
691*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kEverythingProfile),
692*795d594fSAndroid Build Coastguard Worker             "everything-profile");
693*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kEverything), "everything");
694*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kRunFromApk), "run-from-apk");
695*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilerFilterReportingName(CompilerFilterReporting::kRunFromApkFallback),
696*795d594fSAndroid Build Coastguard Worker             "run-from-apk-fallback");
697*795d594fSAndroid Build Coastguard Worker }
698*795d594fSAndroid Build Coastguard Worker 
TEST(CompilerReason,FromName)699*795d594fSAndroid Build Coastguard Worker TEST(CompilerReason, FromName) {
700*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("unknown"), CompilationReason::kUnknown);
701*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("first-boot"), CompilationReason::kFirstBoot);
702*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("boot-after-ota"), CompilationReason::kBootAfterOTA);
703*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("post-boot"), CompilationReason::kPostBoot);
704*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("install"), CompilationReason::kInstall);
705*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("install-fast"), CompilationReason::kInstallFast);
706*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("install-bulk"), CompilationReason::kInstallBulk);
707*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("install-bulk-secondary"),
708*795d594fSAndroid Build Coastguard Worker             CompilationReason::kInstallBulkSecondary);
709*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("install-bulk-downgraded"),
710*795d594fSAndroid Build Coastguard Worker             CompilationReason::kInstallBulkDowngraded);
711*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("install-bulk-secondary-downgraded"),
712*795d594fSAndroid Build Coastguard Worker             CompilationReason::kInstallBulkSecondaryDowngraded);
713*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("bg-dexopt"), CompilationReason::kBgDexopt);
714*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("ab-ota"), CompilationReason::kABOTA);
715*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("inactive"), CompilationReason::kInactive);
716*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("shared"), CompilationReason::kShared);
717*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("install-with-dex-metadata"),
718*795d594fSAndroid Build Coastguard Worker             CompilationReason::kInstallWithDexMetadata);
719*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("prebuilt"), CompilationReason::kPrebuilt);
720*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("cmdline"), CompilationReason::kCmdLine);
721*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("error"), CompilationReason::kError);
722*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("vdex"), CompilationReason::kVdex);
723*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonFromName("boot-after-mainline-update"),
724*795d594fSAndroid Build Coastguard Worker             CompilationReason::kBootAfterMainlineUpdate);
725*795d594fSAndroid Build Coastguard Worker }
726*795d594fSAndroid Build Coastguard Worker 
TEST(CompilerReason,Name)727*795d594fSAndroid Build Coastguard Worker TEST(CompilerReason, Name) {
728*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kUnknown), "unknown");
729*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kFirstBoot), "first-boot");
730*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kBootAfterOTA), "boot-after-ota");
731*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kPostBoot), "post-boot");
732*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kInstall), "install");
733*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kInstallFast), "install-fast");
734*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kInstallBulk), "install-bulk");
735*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kInstallBulkSecondary),
736*795d594fSAndroid Build Coastguard Worker             "install-bulk-secondary");
737*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kInstallBulkDowngraded),
738*795d594fSAndroid Build Coastguard Worker             "install-bulk-downgraded");
739*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kInstallBulkSecondaryDowngraded),
740*795d594fSAndroid Build Coastguard Worker             "install-bulk-secondary-downgraded");
741*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kBgDexopt), "bg-dexopt");
742*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kABOTA), "ab-ota");
743*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kInactive), "inactive");
744*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kShared), "shared");
745*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kInstallWithDexMetadata),
746*795d594fSAndroid Build Coastguard Worker             "install-with-dex-metadata");
747*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kPrebuilt), "prebuilt");
748*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kCmdLine), "cmdline");
749*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kError), "error");
750*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kVdex), "vdex");
751*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(CompilationReasonName(CompilationReason::kBootAfterMainlineUpdate),
752*795d594fSAndroid Build Coastguard Worker             "boot-after-mainline-update");
753*795d594fSAndroid Build Coastguard Worker }
754*795d594fSAndroid Build Coastguard Worker }  // namespace metrics
755*795d594fSAndroid Build Coastguard Worker }  // namespace art
756*795d594fSAndroid Build Coastguard Worker 
757*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic pop  // -Wconversion
758