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