xref: /aosp_15_r20/art/runtime/metrics/reporter_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2021 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 "reporter.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
20*795d594fSAndroid Build Coastguard Worker 
21*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
22*795d594fSAndroid Build Coastguard Worker #include "base/metrics/metrics.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 HIDDEN {
28*795d594fSAndroid Build Coastguard Worker namespace metrics {
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker // Helper class to verify the metrics reporter.
31*795d594fSAndroid Build Coastguard Worker // The functionality is identical to the MetricsReporter with the exception of
32*795d594fSAndroid Build Coastguard Worker // the metrics source. Instead of taking its metrics from the current Runtime,
33*795d594fSAndroid Build Coastguard Worker // this class will keep its own copy so that it does not get interference from
34*795d594fSAndroid Build Coastguard Worker // other runtime setup logic.
35*795d594fSAndroid Build Coastguard Worker class MockMetricsReporter : public MetricsReporter {
36*795d594fSAndroid Build Coastguard Worker  protected:
MockMetricsReporter(const ReportingConfig & config,Runtime * runtime)37*795d594fSAndroid Build Coastguard Worker   MockMetricsReporter(const ReportingConfig& config, Runtime* runtime)
38*795d594fSAndroid Build Coastguard Worker       : MetricsReporter(config, runtime), art_metrics_(std::make_unique<ArtMetrics>()) {}
39*795d594fSAndroid Build Coastguard Worker 
GetMetrics()40*795d594fSAndroid Build Coastguard Worker   ArtMetrics* GetMetrics() override { return art_metrics_.get(); }
41*795d594fSAndroid Build Coastguard Worker 
42*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<ArtMetrics> art_metrics_;
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker   friend class MetricsReporterTest;
45*795d594fSAndroid Build Coastguard Worker };
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker // A test backend which keeps track of all metrics reporting.
48*795d594fSAndroid Build Coastguard Worker class TestBackend : public MetricsBackend {
49*795d594fSAndroid Build Coastguard Worker  public:
50*795d594fSAndroid Build Coastguard Worker   struct Report {
51*795d594fSAndroid Build Coastguard Worker     uint64_t timestamp_millis;
52*795d594fSAndroid Build Coastguard Worker     SafeMap<DatumId, uint64_t> data;
53*795d594fSAndroid Build Coastguard Worker   };
54*795d594fSAndroid Build Coastguard Worker 
BeginOrUpdateSession(const SessionData & session_data)55*795d594fSAndroid Build Coastguard Worker   void BeginOrUpdateSession(const SessionData& session_data) override {
56*795d594fSAndroid Build Coastguard Worker     session_data_ = session_data;
57*795d594fSAndroid Build Coastguard Worker   }
58*795d594fSAndroid Build Coastguard Worker 
BeginReport(uint64_t timestamp_millis)59*795d594fSAndroid Build Coastguard Worker   void BeginReport(uint64_t timestamp_millis) override {
60*795d594fSAndroid Build Coastguard Worker     current_report_.reset(new Report());
61*795d594fSAndroid Build Coastguard Worker     current_report_->timestamp_millis = timestamp_millis;
62*795d594fSAndroid Build Coastguard Worker   }
63*795d594fSAndroid Build Coastguard Worker 
ReportCounter(DatumId counter_type,uint64_t value)64*795d594fSAndroid Build Coastguard Worker   void ReportCounter(DatumId counter_type, uint64_t value) override {
65*795d594fSAndroid Build Coastguard Worker     current_report_->data.Put(counter_type, value);
66*795d594fSAndroid Build Coastguard Worker   }
67*795d594fSAndroid Build Coastguard Worker 
ReportHistogram(DatumId histogram_type,int64_t low_value,int64_t high_value,const std::vector<uint32_t> & buckets)68*795d594fSAndroid Build Coastguard Worker   void ReportHistogram([[maybe_unused]] DatumId histogram_type,
69*795d594fSAndroid Build Coastguard Worker                        [[maybe_unused]] int64_t low_value,
70*795d594fSAndroid Build Coastguard Worker                        [[maybe_unused]] int64_t high_value,
71*795d594fSAndroid Build Coastguard Worker                        [[maybe_unused]] const std::vector<uint32_t>& buckets) override {
72*795d594fSAndroid Build Coastguard Worker     // TODO: nothing yet. We should implement and test histograms as well.
73*795d594fSAndroid Build Coastguard Worker   }
74*795d594fSAndroid Build Coastguard Worker 
EndReport()75*795d594fSAndroid Build Coastguard Worker   void EndReport() override {
76*795d594fSAndroid Build Coastguard Worker     reports_.push_back(*current_report_);
77*795d594fSAndroid Build Coastguard Worker     current_report_ = nullptr;
78*795d594fSAndroid Build Coastguard Worker   }
79*795d594fSAndroid Build Coastguard Worker 
GetReports()80*795d594fSAndroid Build Coastguard Worker   const std::vector<Report>& GetReports() {
81*795d594fSAndroid Build Coastguard Worker     return reports_;
82*795d594fSAndroid Build Coastguard Worker   }
83*795d594fSAndroid Build Coastguard Worker 
GetSessionData()84*795d594fSAndroid Build Coastguard Worker   const SessionData& GetSessionData() {
85*795d594fSAndroid Build Coastguard Worker     return session_data_;
86*795d594fSAndroid Build Coastguard Worker   }
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker  private:
89*795d594fSAndroid Build Coastguard Worker   SessionData session_data_;
90*795d594fSAndroid Build Coastguard Worker   std::vector<Report> reports_;
91*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<Report> current_report_;
92*795d594fSAndroid Build Coastguard Worker };
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker // The actual metrics test class
95*795d594fSAndroid Build Coastguard Worker class MetricsReporterTest : public CommonRuntimeTest {
96*795d594fSAndroid Build Coastguard Worker  protected:
SetUp()97*795d594fSAndroid Build Coastguard Worker   void SetUp() override {
98*795d594fSAndroid Build Coastguard Worker     // Do the normal setup.
99*795d594fSAndroid Build Coastguard Worker     CommonRuntimeTest::SetUp();
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker     // We need to start the runtime in order to run threads.
102*795d594fSAndroid Build Coastguard Worker     Thread::Current()->TransitionFromSuspendedToRunnable();
103*795d594fSAndroid Build Coastguard Worker     bool started = runtime_->Start();
104*795d594fSAndroid Build Coastguard Worker     CHECK(started);
105*795d594fSAndroid Build Coastguard Worker   }
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker   // Configures the metric reporting.
SetupReporter(const char * period_spec,uint32_t session_id=1,uint32_t reporting_mods=100)108*795d594fSAndroid Build Coastguard Worker   void SetupReporter(const char* period_spec,
109*795d594fSAndroid Build Coastguard Worker                      uint32_t session_id = 1,
110*795d594fSAndroid Build Coastguard Worker                      uint32_t reporting_mods = 100) {
111*795d594fSAndroid Build Coastguard Worker     ReportingConfig config;
112*795d594fSAndroid Build Coastguard Worker     if (period_spec != nullptr) {
113*795d594fSAndroid Build Coastguard Worker       std::string error;
114*795d594fSAndroid Build Coastguard Worker       config.reporting_mods = reporting_mods;
115*795d594fSAndroid Build Coastguard Worker       config.period_spec = ReportingPeriodSpec::Parse(period_spec, &error);
116*795d594fSAndroid Build Coastguard Worker       ASSERT_TRUE(config.period_spec.has_value());
117*795d594fSAndroid Build Coastguard Worker     }
118*795d594fSAndroid Build Coastguard Worker 
119*795d594fSAndroid Build Coastguard Worker     reporter_.reset(new MockMetricsReporter(std::move(config), Runtime::Current()));
120*795d594fSAndroid Build Coastguard Worker     backend_ = new TestBackend();
121*795d594fSAndroid Build Coastguard Worker     reporter_->backends_.emplace_back(backend_);
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker     session_data_ = metrics::SessionData::CreateDefault();
124*795d594fSAndroid Build Coastguard Worker     session_data_.session_id = session_id;
125*795d594fSAndroid Build Coastguard Worker   }
126*795d594fSAndroid Build Coastguard Worker 
TearDown()127*795d594fSAndroid Build Coastguard Worker   void TearDown() override {
128*795d594fSAndroid Build Coastguard Worker     reporter_->MaybeStopBackgroundThread();
129*795d594fSAndroid Build Coastguard Worker     reporter_ = nullptr;
130*795d594fSAndroid Build Coastguard Worker     backend_ = nullptr;
131*795d594fSAndroid Build Coastguard Worker   }
132*795d594fSAndroid Build Coastguard Worker 
ShouldReportAtStartup()133*795d594fSAndroid Build Coastguard Worker   bool ShouldReportAtStartup() {
134*795d594fSAndroid Build Coastguard Worker     return reporter_->ShouldReportAtStartup();
135*795d594fSAndroid Build Coastguard Worker   }
136*795d594fSAndroid Build Coastguard Worker 
ShouldContinueReporting()137*795d594fSAndroid Build Coastguard Worker   bool ShouldContinueReporting() {
138*795d594fSAndroid Build Coastguard Worker     return reporter_->ShouldContinueReporting();
139*795d594fSAndroid Build Coastguard Worker   }
140*795d594fSAndroid Build Coastguard Worker 
GetNextPeriodSeconds()141*795d594fSAndroid Build Coastguard Worker   uint32_t GetNextPeriodSeconds() {
142*795d594fSAndroid Build Coastguard Worker     return reporter_->GetNextPeriodSeconds();
143*795d594fSAndroid Build Coastguard Worker   }
144*795d594fSAndroid Build Coastguard Worker 
ReportMetrics()145*795d594fSAndroid Build Coastguard Worker   void ReportMetrics() {
146*795d594fSAndroid Build Coastguard Worker     reporter_->ReportMetrics();
147*795d594fSAndroid Build Coastguard Worker   }
148*795d594fSAndroid Build Coastguard Worker 
NotifyStartupCompleted()149*795d594fSAndroid Build Coastguard Worker   void NotifyStartupCompleted() {
150*795d594fSAndroid Build Coastguard Worker     reporter_->NotifyStartupCompleted();
151*795d594fSAndroid Build Coastguard Worker   }
152*795d594fSAndroid Build Coastguard Worker 
153*795d594fSAndroid Build Coastguard Worker   // Starts the reporting thread and adds some metrics if necessary.
MaybeStartBackgroundThread(bool add_metrics)154*795d594fSAndroid Build Coastguard Worker   bool MaybeStartBackgroundThread(bool add_metrics) {
155*795d594fSAndroid Build Coastguard Worker     // TODO: set session_data.compilation_reason and session_data.compiler_filter
156*795d594fSAndroid Build Coastguard Worker     bool result = reporter_->MaybeStartBackgroundThread(session_data_);
157*795d594fSAndroid Build Coastguard Worker     if (add_metrics) {
158*795d594fSAndroid Build Coastguard Worker       reporter_->art_metrics_->JitMethodCompileCount()->Add(1);
159*795d594fSAndroid Build Coastguard Worker       reporter_->art_metrics_->ClassVerificationCount()->Add(2);
160*795d594fSAndroid Build Coastguard Worker     }
161*795d594fSAndroid Build Coastguard Worker     return result;
162*795d594fSAndroid Build Coastguard Worker   }
163*795d594fSAndroid Build Coastguard Worker 
164*795d594fSAndroid Build Coastguard Worker   // Right now we either:
165*795d594fSAndroid Build Coastguard Worker   //   1) don't add metrics (with_metrics = false)
166*795d594fSAndroid Build Coastguard Worker   //   2) or always add the same metrics (see MaybeStartBackgroundThread)
167*795d594fSAndroid Build Coastguard Worker   // So we can write a global verify method.
VerifyReports(uint32_t size,bool with_metrics,CompilerFilterReporting filter=CompilerFilterReporting::kUnknown,CompilationReason reason=CompilationReason::kUnknown)168*795d594fSAndroid Build Coastguard Worker   void VerifyReports(
169*795d594fSAndroid Build Coastguard Worker         uint32_t size,
170*795d594fSAndroid Build Coastguard Worker         bool with_metrics,
171*795d594fSAndroid Build Coastguard Worker         CompilerFilterReporting filter = CompilerFilterReporting::kUnknown,
172*795d594fSAndroid Build Coastguard Worker         CompilationReason reason = CompilationReason::kUnknown) {
173*795d594fSAndroid Build Coastguard Worker     // TODO: we should iterate through all the other metrics to make sure they were not
174*795d594fSAndroid Build Coastguard Worker     // reported. However, we don't have an easy to use iteration mechanism over metrics yet.
175*795d594fSAndroid Build Coastguard Worker     // We should add one
176*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(backend_->GetReports().size(), size);
177*795d594fSAndroid Build Coastguard Worker     for (const TestBackend::Report& report : backend_->GetReports()) {
178*795d594fSAndroid Build Coastguard Worker       ASSERT_EQ(report.data.Get(DatumId::kClassVerificationCount), with_metrics ? 2u : 0u);
179*795d594fSAndroid Build Coastguard Worker       ASSERT_EQ(report.data.Get(DatumId::kJitMethodCompileCount), with_metrics ? 1u : 0u);
180*795d594fSAndroid Build Coastguard Worker     }
181*795d594fSAndroid Build Coastguard Worker 
182*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(backend_->GetSessionData().compiler_filter, filter);
183*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(backend_->GetSessionData().compilation_reason, reason);
184*795d594fSAndroid Build Coastguard Worker   }
185*795d594fSAndroid Build Coastguard Worker 
186*795d594fSAndroid Build Coastguard Worker   // Sleeps until the backend received the give number of reports.
WaitForReport(uint32_t report_count,uint32_t sleep_period_ms)187*795d594fSAndroid Build Coastguard Worker   void WaitForReport(uint32_t report_count, uint32_t sleep_period_ms) {
188*795d594fSAndroid Build Coastguard Worker     while (true) {
189*795d594fSAndroid Build Coastguard Worker       if (backend_->GetReports().size() == report_count) {
190*795d594fSAndroid Build Coastguard Worker         return;
191*795d594fSAndroid Build Coastguard Worker       }
192*795d594fSAndroid Build Coastguard Worker       usleep(sleep_period_ms * 1000);
193*795d594fSAndroid Build Coastguard Worker     }
194*795d594fSAndroid Build Coastguard Worker   }
195*795d594fSAndroid Build Coastguard Worker 
NotifyAppInfoUpdated(AppInfo * app_info)196*795d594fSAndroid Build Coastguard Worker   void NotifyAppInfoUpdated(AppInfo* app_info) {
197*795d594fSAndroid Build Coastguard Worker     reporter_->NotifyAppInfoUpdated(app_info);
198*795d594fSAndroid Build Coastguard Worker   }
199*795d594fSAndroid Build Coastguard Worker 
200*795d594fSAndroid Build Coastguard Worker  private:
201*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<MockMetricsReporter> reporter_;
202*795d594fSAndroid Build Coastguard Worker   TestBackend* backend_;
203*795d594fSAndroid Build Coastguard Worker   metrics::SessionData session_data_;
204*795d594fSAndroid Build Coastguard Worker };
205*795d594fSAndroid Build Coastguard Worker 
206*795d594fSAndroid Build Coastguard Worker // Verifies startup reporting.
TEST_F(MetricsReporterTest,StartupOnly)207*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, StartupOnly) {
208*795d594fSAndroid Build Coastguard Worker   SetupReporter("S");
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker   // Verify startup conditions
211*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldReportAtStartup());
212*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldContinueReporting());
213*795d594fSAndroid Build Coastguard Worker 
214*795d594fSAndroid Build Coastguard Worker   // Start the thread and notify the startup. This will advance the state.
215*795d594fSAndroid Build Coastguard Worker   MaybeStartBackgroundThread(/*add_metrics=*/ true);
216*795d594fSAndroid Build Coastguard Worker 
217*795d594fSAndroid Build Coastguard Worker   NotifyStartupCompleted();
218*795d594fSAndroid Build Coastguard Worker   WaitForReport(/*report_count=*/ 1, /*sleep_period_ms=*/ 50);
219*795d594fSAndroid Build Coastguard Worker   VerifyReports(/*size=*/ 1, /*with_metrics*/ true);
220*795d594fSAndroid Build Coastguard Worker 
221*795d594fSAndroid Build Coastguard Worker   // We should still not report continuously.
222*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldContinueReporting());
223*795d594fSAndroid Build Coastguard Worker }
224*795d594fSAndroid Build Coastguard Worker 
225*795d594fSAndroid Build Coastguard Worker // LARGE TEST: This test takes 1s to run.
226*795d594fSAndroid Build Coastguard Worker // Verifies startup reporting, followed by a fixed, one time only reporting.
TEST_F(MetricsReporterTest,StartupAndPeriod)227*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, StartupAndPeriod) {
228*795d594fSAndroid Build Coastguard Worker   SetupReporter("S,1");
229*795d594fSAndroid Build Coastguard Worker 
230*795d594fSAndroid Build Coastguard Worker   // Verify startup conditions
231*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldReportAtStartup());
232*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldContinueReporting());
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker   // Start the thread and notify the startup. This will advance the state.
235*795d594fSAndroid Build Coastguard Worker   MaybeStartBackgroundThread(/*add_metrics=*/ true);
236*795d594fSAndroid Build Coastguard Worker   NotifyStartupCompleted();
237*795d594fSAndroid Build Coastguard Worker 
238*795d594fSAndroid Build Coastguard Worker   // We're waiting for 2 reports: the startup one, and the 1s one.
239*795d594fSAndroid Build Coastguard Worker   WaitForReport(/*report_count=*/ 2, /*sleep_period_ms=*/ 500);
240*795d594fSAndroid Build Coastguard Worker   VerifyReports(/*size=*/ 2, /*with_metrics*/ true);
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker   // We should no longer report continuously.
243*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldContinueReporting());
244*795d594fSAndroid Build Coastguard Worker }
245*795d594fSAndroid Build Coastguard Worker 
246*795d594fSAndroid Build Coastguard Worker // LARGE TEST: This test take 2s to run.
247*795d594fSAndroid Build Coastguard Worker // Verifies startup reporting, followed by continuous reporting.
TEST_F(MetricsReporterTest,StartupAndPeriodContinuous)248*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, StartupAndPeriodContinuous) {
249*795d594fSAndroid Build Coastguard Worker   SetupReporter("S,1,*");
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker   // Verify startup conditions
252*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldReportAtStartup());
253*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldContinueReporting());
254*795d594fSAndroid Build Coastguard Worker 
255*795d594fSAndroid Build Coastguard Worker   // Start the thread and notify the startup. This will advance the state.
256*795d594fSAndroid Build Coastguard Worker   MaybeStartBackgroundThread(/*add_metrics=*/ true);
257*795d594fSAndroid Build Coastguard Worker   NotifyStartupCompleted();
258*795d594fSAndroid Build Coastguard Worker 
259*795d594fSAndroid Build Coastguard Worker   // We're waiting for 3 reports: the startup one, and the 1s one.
260*795d594fSAndroid Build Coastguard Worker   WaitForReport(/*report_count=*/ 3, /*sleep_period_ms=*/ 500);
261*795d594fSAndroid Build Coastguard Worker   VerifyReports(/*size=*/ 3, /*with_metrics*/ true);
262*795d594fSAndroid Build Coastguard Worker 
263*795d594fSAndroid Build Coastguard Worker   // We should keep reporting continuously.
264*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldContinueReporting());
265*795d594fSAndroid Build Coastguard Worker }
266*795d594fSAndroid Build Coastguard Worker 
267*795d594fSAndroid Build Coastguard Worker // LARGE TEST: This test takes 1s to run.
268*795d594fSAndroid Build Coastguard Worker // Verifies a fixed, one time only reporting.
TEST_F(MetricsReporterTest,OneTime)269*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, OneTime) {
270*795d594fSAndroid Build Coastguard Worker   SetupReporter("1");
271*795d594fSAndroid Build Coastguard Worker 
272*795d594fSAndroid Build Coastguard Worker   // Verify startup conditions
273*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldReportAtStartup());
274*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldContinueReporting());
275*795d594fSAndroid Build Coastguard Worker 
276*795d594fSAndroid Build Coastguard Worker   // Start the thread and notify the startup. This will advance the state.
277*795d594fSAndroid Build Coastguard Worker   MaybeStartBackgroundThread(/*add_metrics=*/ true);
278*795d594fSAndroid Build Coastguard Worker 
279*795d594fSAndroid Build Coastguard Worker   // We're waiting for 1 report
280*795d594fSAndroid Build Coastguard Worker   WaitForReport(/*report_count=*/ 1, /*sleep_period_ms=*/ 500);
281*795d594fSAndroid Build Coastguard Worker   VerifyReports(/*size=*/ 1, /*with_metrics*/ true);
282*795d594fSAndroid Build Coastguard Worker 
283*795d594fSAndroid Build Coastguard Worker   // We should no longer report continuously.
284*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldContinueReporting());
285*795d594fSAndroid Build Coastguard Worker }
286*795d594fSAndroid Build Coastguard Worker 
287*795d594fSAndroid Build Coastguard Worker // LARGE TEST: This test takes 5s to run.
288*795d594fSAndroid Build Coastguard Worker // Verifies a sequence of reporting, at different interval of times.
TEST_F(MetricsReporterTest,PeriodContinuous)289*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, PeriodContinuous) {
290*795d594fSAndroid Build Coastguard Worker   SetupReporter("1,2,*");
291*795d594fSAndroid Build Coastguard Worker 
292*795d594fSAndroid Build Coastguard Worker   // Verify startup conditions
293*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldReportAtStartup());
294*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldContinueReporting());
295*795d594fSAndroid Build Coastguard Worker 
296*795d594fSAndroid Build Coastguard Worker   // Start the thread and notify the startup. This will advance the state.
297*795d594fSAndroid Build Coastguard Worker   MaybeStartBackgroundThread(/*add_metrics=*/ true);
298*795d594fSAndroid Build Coastguard Worker   NotifyStartupCompleted();
299*795d594fSAndroid Build Coastguard Worker 
300*795d594fSAndroid Build Coastguard Worker   // We're waiting for 2 reports: the startup one, and the 1s one.
301*795d594fSAndroid Build Coastguard Worker   WaitForReport(/*report_count=*/ 3, /*sleep_period_ms=*/ 500);
302*795d594fSAndroid Build Coastguard Worker   VerifyReports(/*size=*/ 3, /*with_metrics*/ true);
303*795d594fSAndroid Build Coastguard Worker 
304*795d594fSAndroid Build Coastguard Worker   // We should keep reporting continuously.
305*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldContinueReporting());
306*795d594fSAndroid Build Coastguard Worker }
307*795d594fSAndroid Build Coastguard Worker 
308*795d594fSAndroid Build Coastguard Worker // LARGE TEST: This test takes 1s to run.
309*795d594fSAndroid Build Coastguard Worker // Verifies reporting when no metrics where recorded.
TEST_F(MetricsReporterTest,NoMetrics)310*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, NoMetrics) {
311*795d594fSAndroid Build Coastguard Worker   SetupReporter("1");
312*795d594fSAndroid Build Coastguard Worker 
313*795d594fSAndroid Build Coastguard Worker   // Verify startup conditions
314*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldReportAtStartup());
315*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldContinueReporting());
316*795d594fSAndroid Build Coastguard Worker 
317*795d594fSAndroid Build Coastguard Worker   // Start the thread and notify the startup. This will advance the state.
318*795d594fSAndroid Build Coastguard Worker   MaybeStartBackgroundThread(/*add_metrics=*/ false);
319*795d594fSAndroid Build Coastguard Worker 
320*795d594fSAndroid Build Coastguard Worker   // We're waiting for 1 report
321*795d594fSAndroid Build Coastguard Worker   WaitForReport(/*report_count=*/ 1, /*sleep_period_ms=*/ 500);
322*795d594fSAndroid Build Coastguard Worker   VerifyReports(/*size=*/ 1, /*with_metrics*/ false);
323*795d594fSAndroid Build Coastguard Worker 
324*795d594fSAndroid Build Coastguard Worker   // We should no longer report continuously.
325*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldContinueReporting());
326*795d594fSAndroid Build Coastguard Worker }
327*795d594fSAndroid Build Coastguard Worker 
328*795d594fSAndroid Build Coastguard Worker // Verify we don't start reporting if the sample rate is set to 0.
TEST_F(MetricsReporterTest,SampleRateDisable)329*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, SampleRateDisable) {
330*795d594fSAndroid Build Coastguard Worker   SetupReporter("1,*", /*session_id=*/ 1, /*reporting_mods=*/ 0);
331*795d594fSAndroid Build Coastguard Worker 
332*795d594fSAndroid Build Coastguard Worker   // The background thread should not start.
333*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
334*795d594fSAndroid Build Coastguard Worker 
335*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldReportAtStartup());
336*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldContinueReporting());
337*795d594fSAndroid Build Coastguard Worker }
338*795d594fSAndroid Build Coastguard Worker 
339*795d594fSAndroid Build Coastguard Worker // Verify we don't start reporting if the sample rate is low and the session does
340*795d594fSAndroid Build Coastguard Worker // not meet conditions.
TEST_F(MetricsReporterTest,SampleRateDisable24)341*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, SampleRateDisable24) {
342*795d594fSAndroid Build Coastguard Worker   SetupReporter("1,*", /*session_id=*/ 125, /*reporting_mods=*/ 24);
343*795d594fSAndroid Build Coastguard Worker 
344*795d594fSAndroid Build Coastguard Worker   // The background thread should not start.
345*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
346*795d594fSAndroid Build Coastguard Worker 
347*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldReportAtStartup());
348*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldContinueReporting());
349*795d594fSAndroid Build Coastguard Worker }
350*795d594fSAndroid Build Coastguard Worker 
351*795d594fSAndroid Build Coastguard Worker // Verify we start reporting if the sample rate and the session meet
352*795d594fSAndroid Build Coastguard Worker // reporting conditions
TEST_F(MetricsReporterTest,SampleRateEnable50)353*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, SampleRateEnable50) {
354*795d594fSAndroid Build Coastguard Worker   SetupReporter("1,*", /*session_id=*/ 125, /*reporting_mods=*/ 50);
355*795d594fSAndroid Build Coastguard Worker 
356*795d594fSAndroid Build Coastguard Worker   // The background thread should start.
357*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
358*795d594fSAndroid Build Coastguard Worker 
359*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldReportAtStartup());
360*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldContinueReporting());
361*795d594fSAndroid Build Coastguard Worker }
362*795d594fSAndroid Build Coastguard Worker 
363*795d594fSAndroid Build Coastguard Worker // Verify we start reporting if the sample rate and the session meet
364*795d594fSAndroid Build Coastguard Worker // reporting conditions
TEST_F(MetricsReporterTest,SampleRateEnableAll)365*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, SampleRateEnableAll) {
366*795d594fSAndroid Build Coastguard Worker   SetupReporter("1,*", /*session_id=*/ 1099, /*reporting_mods=*/ 100);
367*795d594fSAndroid Build Coastguard Worker 
368*795d594fSAndroid Build Coastguard Worker   // The background thread should start.
369*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
370*795d594fSAndroid Build Coastguard Worker 
371*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(ShouldReportAtStartup());
372*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(ShouldContinueReporting());
373*795d594fSAndroid Build Coastguard Worker }
374*795d594fSAndroid Build Coastguard Worker 
TEST_F(MetricsReporterTest,CompilerFilter)375*795d594fSAndroid Build Coastguard Worker TEST_F(MetricsReporterTest, CompilerFilter) {
376*795d594fSAndroid Build Coastguard Worker   SetupReporter("1", /*session_id=*/ 1099, /*reporting_mods=*/ 100);
377*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(MaybeStartBackgroundThread(/*add_metrics=*/ true));
378*795d594fSAndroid Build Coastguard Worker 
379*795d594fSAndroid Build Coastguard Worker   AppInfo app_info;
380*795d594fSAndroid Build Coastguard Worker   app_info.RegisterOdexStatus(
381*795d594fSAndroid Build Coastguard Worker       "code_location",
382*795d594fSAndroid Build Coastguard Worker       "verify",
383*795d594fSAndroid Build Coastguard Worker       "install",
384*795d594fSAndroid Build Coastguard Worker       "odex_status");
385*795d594fSAndroid Build Coastguard Worker   app_info.RegisterAppInfo(
386*795d594fSAndroid Build Coastguard Worker       "package_name",
387*795d594fSAndroid Build Coastguard Worker       std::vector<std::string>({"code_location"}),
388*795d594fSAndroid Build Coastguard Worker       "",
389*795d594fSAndroid Build Coastguard Worker       "",
390*795d594fSAndroid Build Coastguard Worker       AppInfo::CodeType::kPrimaryApk);
391*795d594fSAndroid Build Coastguard Worker   NotifyAppInfoUpdated(&app_info);
392*795d594fSAndroid Build Coastguard Worker 
393*795d594fSAndroid Build Coastguard Worker   WaitForReport(/*report_count=*/ 1, /*sleep_period_ms=*/ 500);
394*795d594fSAndroid Build Coastguard Worker   VerifyReports(
395*795d594fSAndroid Build Coastguard Worker       /*size=*/ 1,
396*795d594fSAndroid Build Coastguard Worker       /*with_metrics*/ true,
397*795d594fSAndroid Build Coastguard Worker       CompilerFilterReporting::kVerify,
398*795d594fSAndroid Build Coastguard Worker       CompilationReason::kInstall);
399*795d594fSAndroid Build Coastguard Worker }
400*795d594fSAndroid Build Coastguard Worker 
401*795d594fSAndroid Build Coastguard Worker // Test class for period spec parsing
402*795d594fSAndroid Build Coastguard Worker class ReportingPeriodSpecTest : public testing::Test {
403*795d594fSAndroid Build Coastguard Worker  public:
VerifyFalse(const std::string & spec_str)404*795d594fSAndroid Build Coastguard Worker   void VerifyFalse(const std::string& spec_str) {
405*795d594fSAndroid Build Coastguard Worker     Verify(spec_str, false, false, false, {});
406*795d594fSAndroid Build Coastguard Worker   }
407*795d594fSAndroid Build Coastguard Worker 
VerifyTrue(const std::string & spec_str,bool startup_first,bool continuous,const std::vector<uint32_t> & periods)408*795d594fSAndroid Build Coastguard Worker   void VerifyTrue(
409*795d594fSAndroid Build Coastguard Worker       const std::string& spec_str,
410*795d594fSAndroid Build Coastguard Worker       bool startup_first,
411*795d594fSAndroid Build Coastguard Worker       bool continuous,
412*795d594fSAndroid Build Coastguard Worker       const std::vector<uint32_t>& periods) {
413*795d594fSAndroid Build Coastguard Worker     Verify(spec_str, true, startup_first, continuous, periods);
414*795d594fSAndroid Build Coastguard Worker   }
415*795d594fSAndroid Build Coastguard Worker 
Verify(const std::string & spec_str,bool valid,bool startup_first,bool continuous,const std::vector<uint32_t> & periods)416*795d594fSAndroid Build Coastguard Worker   void Verify(
417*795d594fSAndroid Build Coastguard Worker       const std::string& spec_str,
418*795d594fSAndroid Build Coastguard Worker       bool valid,
419*795d594fSAndroid Build Coastguard Worker       bool startup_first,
420*795d594fSAndroid Build Coastguard Worker       bool continuous,
421*795d594fSAndroid Build Coastguard Worker       const std::vector<uint32_t>& periods) {
422*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
423*795d594fSAndroid Build Coastguard Worker     std::optional<ReportingPeriodSpec> spec = ReportingPeriodSpec::Parse(spec_str, &error_msg);
424*795d594fSAndroid Build Coastguard Worker 
425*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(valid, spec.has_value()) << spec_str;
426*795d594fSAndroid Build Coastguard Worker     if (valid) {
427*795d594fSAndroid Build Coastguard Worker         ASSERT_EQ(spec->spec, spec_str) << spec_str;
428*795d594fSAndroid Build Coastguard Worker         ASSERT_EQ(spec->report_startup_first, startup_first) << spec_str;
429*795d594fSAndroid Build Coastguard Worker         ASSERT_EQ(spec->continuous_reporting, continuous) << spec_str;
430*795d594fSAndroid Build Coastguard Worker         ASSERT_EQ(spec->periods_seconds, periods) << spec_str;
431*795d594fSAndroid Build Coastguard Worker     }
432*795d594fSAndroid Build Coastguard Worker   }
433*795d594fSAndroid Build Coastguard Worker };
434*795d594fSAndroid Build Coastguard Worker 
TEST_F(ReportingPeriodSpecTest,ParseTestsInvalid)435*795d594fSAndroid Build Coastguard Worker TEST_F(ReportingPeriodSpecTest, ParseTestsInvalid) {
436*795d594fSAndroid Build Coastguard Worker   VerifyFalse("");
437*795d594fSAndroid Build Coastguard Worker   VerifyFalse("*");
438*795d594fSAndroid Build Coastguard Worker   VerifyFalse("S,*");
439*795d594fSAndroid Build Coastguard Worker   VerifyFalse("foo");
440*795d594fSAndroid Build Coastguard Worker   VerifyFalse("-1");
441*795d594fSAndroid Build Coastguard Worker   VerifyFalse("1,S");
442*795d594fSAndroid Build Coastguard Worker   VerifyFalse("*,1");
443*795d594fSAndroid Build Coastguard Worker   VerifyFalse("1,2,3,-1,3");
444*795d594fSAndroid Build Coastguard Worker   VerifyFalse("1,*,2");
445*795d594fSAndroid Build Coastguard Worker   VerifyFalse("1,S,2");
446*795d594fSAndroid Build Coastguard Worker }
447*795d594fSAndroid Build Coastguard Worker 
TEST_F(ReportingPeriodSpecTest,ParseTestsValid)448*795d594fSAndroid Build Coastguard Worker TEST_F(ReportingPeriodSpecTest, ParseTestsValid) {
449*795d594fSAndroid Build Coastguard Worker   VerifyTrue("S", true, false, {});
450*795d594fSAndroid Build Coastguard Worker   VerifyTrue("S,1", true, false, {1});
451*795d594fSAndroid Build Coastguard Worker   VerifyTrue("S,1,2,3,4", true, false, {1, 2, 3, 4});
452*795d594fSAndroid Build Coastguard Worker   VerifyTrue("S,1,*", true, true, {1});
453*795d594fSAndroid Build Coastguard Worker   VerifyTrue("S,1,2,3,4,*", true, true, {1, 2, 3, 4});
454*795d594fSAndroid Build Coastguard Worker 
455*795d594fSAndroid Build Coastguard Worker   VerifyTrue("1", false, false, {1});
456*795d594fSAndroid Build Coastguard Worker   VerifyTrue("1,2,3,4", false, false, {1, 2, 3, 4});
457*795d594fSAndroid Build Coastguard Worker   VerifyTrue("1,*", false, true, {1});
458*795d594fSAndroid Build Coastguard Worker   VerifyTrue("1,2,3,4,*", false, true, {1, 2, 3, 4});
459*795d594fSAndroid Build Coastguard Worker }
460*795d594fSAndroid Build Coastguard Worker 
461*795d594fSAndroid Build Coastguard Worker }  // namespace metrics
462*795d594fSAndroid Build Coastguard Worker }  // namespace art
463*795d594fSAndroid Build Coastguard Worker 
464*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic pop  // -Wconversion
465