// Helper class to verify the metrics reporter. // The functionality is identical to the MetricsReporter with the exception of // the metrics source. Instead of taking its metrics from the current Runtime, // this class will keep its own copy so that it does not get interference from // other runtime setup logic. class MockMetricsReporter : public MetricsReporter { protected:
MockMetricsReporter(const ReportingConfig& config, Runtime* runtime)
: MetricsReporter(config, runtime), art_metrics_(std::make_unique<ArtMetrics>()) {}
// A test backend which keeps track of all metrics reporting. class TestBackend : public MetricsBackend { public: struct Report {
uint64_t timestamp_millis;
SafeMap<DatumId, uint64_t> data;
};
// The actual metrics test class class MetricsReporterTest : public CommonRuntimeTest { protected: void SetUp() override { // Do the normal setup.
CommonRuntimeTest::SetUp();
// We need to start the runtime in order to run threads.
Thread::Current()->TransitionFromSuspendedToRunnable(); bool started = runtime_->Start();
CHECK(started);
}
// Starts the reporting thread and adds some metrics if necessary. bool MaybeStartBackgroundThread(bool add_metrics) { // TODO: set session_data.compilation_reason and session_data.compiler_filter bool result = reporter_->MaybeStartBackgroundThread(session_data_); if (add_metrics) {
reporter_->art_metrics_->JitMethodCompileCount()->Add(1);
reporter_->art_metrics_->ClassVerificationCount()->Add(2);
} return result;
}
// Right now we either: // 1) don't add metrics (with_metrics = false) // 2) or always add the same metrics (see MaybeStartBackgroundThread) // So we can write a global verify method. void VerifyReports(
uint32_t size, bool with_metrics,
CompilerFilterReporting filter = CompilerFilterReporting::kAbsent,
CompilationReason reason = CompilationReason::kAbsent) { // TODO: we should iterate through all the other metrics to make sure they were not // reported. However, we don't have an easy to use iteration mechanism over metrics yet. // We should add one
ASSERT_EQ(backend_->GetReports().size(), size); for (const TestBackend::Report& report : backend_->GetReports()) {
ASSERT_EQ(report.data.Get(DatumId::kClassVerificationCount), with_metrics ? 2u : 0u);
ASSERT_EQ(report.data.Get(DatumId::kJitMethodCompileCount), with_metrics ? 1u : 0u);
}
// Sleeps until the backend received the give number of reports. void WaitForReport(uint32_t report_count, uint32_t sleep_period_ms) { while (true) { if (backend_->GetReports().size() == report_count) { return;
}
usleep(sleep_period_ms * 1000);
}
}
// We should still not report continuously.
ASSERT_FALSE(ShouldContinueReporting());
}
// LARGE TEST: This test takes 1s to run. // Verifies startup reporting, followed by a fixed, one time only reporting.
TEST_F(MetricsReporterTest, StartupAndPeriod) {
SetupReporter("S,1");
// Start the thread and notify the startup. This will advance the state.
MaybeStartBackgroundThread(/*add_metrics=*/ true);
NotifyStartupCompleted();
// We're waiting for 2 reports: the startup one, and the 1s one.
WaitForReport(/*report_count=*/ 2, /*sleep_period_ms=*/ 500);
VerifyReports(/*size=*/ 2, /*with_metrics*/ true);
// We should no longer report continuously.
ASSERT_FALSE(ShouldContinueReporting());
}
// LARGE TEST: This test take 2s to run. // Verifies startup reporting, followed by continuous reporting.
TEST_F(MetricsReporterTest, StartupAndPeriodContinuous) {
SetupReporter("S,1,*");
// We should no longer report continuously.
ASSERT_FALSE(ShouldContinueReporting());
}
// LARGE TEST: This test takes 5s to run. // Verifies a sequence of reporting, at different interval of times.
TEST_F(MetricsReporterTest, PeriodContinuous) {
SetupReporter("1,2,*");
// Start the thread and notify the startup. This will advance the state.
MaybeStartBackgroundThread(/*add_metrics=*/ true);
NotifyStartupCompleted();
// We're waiting for 2 reports: the startup one, and the 1s one.
WaitForReport(/*report_count=*/ 3, /*sleep_period_ms=*/ 500);
VerifyReports(/*size=*/ 3, /*with_metrics*/ true);
// We should keep reporting continuously.
ASSERT_TRUE(ShouldContinueReporting());
}
// LARGE TEST: This test takes 1s to run. // Verifies reporting when no metrics where recorded.
TEST_F(MetricsReporterTest, NoMetrics) {
SetupReporter("1");
// We should no longer report continuously.
ASSERT_FALSE(ShouldContinueReporting());
}
// Verify we don't start reporting if the sample rate is set to 0.
TEST_F(MetricsReporterTest, SampleRateDisable) {
SetupReporter("1,*", /*session_id=*/ 1, /*reporting_mods=*/ 0);
// The background thread should not start.
ASSERT_FALSE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
// Verify we don't start reporting if the sample rate is low and the session does // not meet conditions.
TEST_F(MetricsReporterTest, SampleRateDisable24) {
SetupReporter("1,*", /*session_id=*/ 125, /*reporting_mods=*/ 24);
// The background thread should not start.
ASSERT_FALSE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
// Verify we start reporting if the sample rate and the session meet // reporting conditions
TEST_F(MetricsReporterTest, SampleRateEnable50) {
SetupReporter("1,*", /*session_id=*/ 125, /*reporting_mods=*/ 50);
// The background thread should start.
ASSERT_TRUE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
// Verify we start reporting if the sample rate and the session meet // reporting conditions
TEST_F(MetricsReporterTest, SampleRateEnableAll) {
SetupReporter("1,*", /*session_id=*/ 1099, /*reporting_mods=*/ 100);
// The background thread should start.
ASSERT_TRUE(MaybeStartBackgroundThread(/*add_metrics=*/ false));
// Test class for period spec parsing class ReportingPeriodSpecTest : public ::testing::Test { public: void VerifyFalse(const std::string& spec_str) {
Verify(spec_str, false, false, false, {});
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.