123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/reporting/metrics/metric_data_collector.h"
- #include <memory>
- #include <string>
- #include <vector>
- #include "base/location.h"
- #include "base/run_loop.h"
- #include "base/test/bind.h"
- #include "base/test/task_environment.h"
- #include "base/time/time.h"
- #include "components/reporting/metrics/fake_metric_report_queue.h"
- #include "components/reporting/metrics/fake_reporting_settings.h"
- #include "components/reporting/metrics/fake_sampler.h"
- #include "components/reporting/metrics/metric_report_queue.h"
- #include "components/reporting/proto/synced/metric_data.pb.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace reporting {
- namespace test {
- class FakeEventDetector : public EventDetector {
- public:
- FakeEventDetector() = default;
- FakeEventDetector(const FakeEventDetector& other) = delete;
- FakeEventDetector& operator=(const FakeEventDetector& other) = delete;
- ~FakeEventDetector() override = default;
- absl::optional<MetricEventType> DetectEvent(
- const MetricData& previous_metric_data,
- const MetricData& current_metric_data) override {
- previous_metric_list_.emplace_back(
- std::make_unique<const MetricData>(previous_metric_data));
- if (!has_event_) {
- return absl::nullopt;
- }
- return MetricEventType::NETWORK_HTTPS_LATENCY_CHANGE;
- }
- void SetHasEvent(bool has_event) { has_event_ = has_event; }
- const std::vector<std::unique_ptr<const MetricData>>& GetPreviousMetricList()
- const {
- return previous_metric_list_;
- }
- private:
- bool has_event_ = false;
- std::vector<std::unique_ptr<const MetricData>> previous_metric_list_;
- };
- } // namespace test
- namespace {
- class MetricDataCollectorTest : public ::testing::Test {
- protected:
- void SetUp() override {
- settings_ = std::make_unique<test::FakeReportingSettings>();
- sampler_ = std::make_unique<test::FakeSampler>();
- metric_report_queue_ = std::make_unique<test::FakeMetricReportQueue>();
- }
- void FlushTasks() {
- base::RunLoop run_loop;
- task_environment_.GetMainThreadTaskRunner()->PostTask(
- FROM_HERE, run_loop.QuitClosure());
- run_loop.Run();
- }
- base::test::SingleThreadTaskEnvironment task_environment_{
- base::test::TaskEnvironment::TimeSource::MOCK_TIME};
- const std::string kEnableSettingPath = "enable_path";
- const std::string kRateSettingPath = "rate_path";
- std::unique_ptr<test::FakeReportingSettings> settings_;
- std::unique_ptr<test::FakeSampler> sampler_;
- std::unique_ptr<test::FakeMetricReportQueue> metric_report_queue_;
- };
- TEST_F(MetricDataCollectorTest, OneShotCollector_InitiallyEnabled) {
- settings_->SetBoolean(kEnableSettingPath, true);
- MetricData metric_data;
- metric_data.mutable_info_data();
- sampler_->SetMetricData(std::move(metric_data));
- bool callback_called = false;
- OneShotCollector collector(sampler_.get(), metric_report_queue_.get(),
- settings_.get(), kEnableSettingPath,
- /*setting_enabled_default_value=*/false,
- base::BindLambdaForTesting([&callback_called]() {
- callback_called = true;
- }));
- // Setting is initially enabled, data is being collected.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- settings_->SetBoolean(kEnableSettingPath, false);
- settings_->SetBoolean(kEnableSettingPath, true);
- // No more data should be collected even if the setting was disabled then
- // re-enabled.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- FlushTasks();
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_THAT(metric_data_reported, ::testing::SizeIs(1));
- EXPECT_TRUE(callback_called);
- EXPECT_TRUE(metric_data_reported[0]->has_timestamp_ms());
- EXPECT_TRUE(metric_data_reported[0]->has_info_data());
- }
- TEST_F(MetricDataCollectorTest, OneShotCollector_NoMetricData) {
- settings_->SetBoolean(kEnableSettingPath, true);
- sampler_->SetMetricData(absl::nullopt);
- bool callback_called = false;
- OneShotCollector collector(sampler_.get(), metric_report_queue_.get(),
- settings_.get(), kEnableSettingPath,
- /*setting_enabled_default_value=*/false,
- base::BindLambdaForTesting([&callback_called]() {
- callback_called = true;
- }));
- // Setting is initially enabled, data is being collected.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- FlushTasks();
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_TRUE(metric_data_reported.empty());
- EXPECT_FALSE(callback_called);
- }
- TEST_F(MetricDataCollectorTest, OneShotCollector_InitiallyDisabled) {
- settings_->SetBoolean(kEnableSettingPath, false);
- MetricData metric_data;
- metric_data.mutable_info_data();
- sampler_->SetMetricData(std::move(metric_data));
- OneShotCollector collector(sampler_.get(), metric_report_queue_.get(),
- settings_.get(), kEnableSettingPath,
- /*setting_enabled_default_value=*/false);
- // Setting is initially disabled, no data is collected.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 0);
- settings_->SetBoolean(kEnableSettingPath, true);
- // Setting is enabled, data is being collected.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- settings_->SetBoolean(kEnableSettingPath, false);
- settings_->SetBoolean(kEnableSettingPath, true);
- // No more data should be collected even if the setting was disabled then
- // re-enabled.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- FlushTasks();
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_THAT(metric_data_reported, ::testing::SizeIs(1));
- EXPECT_TRUE(metric_data_reported[0]->has_timestamp_ms());
- EXPECT_TRUE(metric_data_reported[0]->has_info_data());
- }
- TEST_F(MetricDataCollectorTest, OneShotCollector_DefaultEnabled) {
- MetricData metric_data;
- metric_data.mutable_info_data();
- sampler_->SetMetricData(std::move(metric_data));
- bool callback_called = false;
- OneShotCollector collector(sampler_.get(), metric_report_queue_.get(),
- settings_.get(), "invalid/path",
- /*setting_enabled_default_value=*/true,
- base::BindLambdaForTesting([&callback_called]() {
- callback_called = true;
- }));
- // Setting is enabled by default, data is being collected.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- FlushTasks();
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_THAT(metric_data_reported, ::testing::SizeIs(1));
- EXPECT_TRUE(callback_called);
- EXPECT_TRUE(metric_data_reported[0]->has_timestamp_ms());
- EXPECT_TRUE(metric_data_reported[0]->has_info_data());
- }
- TEST_F(MetricDataCollectorTest, OneShotCollector_DefaultDisabled) {
- MetricData metric_data;
- metric_data.mutable_info_data();
- sampler_->SetMetricData(std::move(metric_data));
- OneShotCollector collector(sampler_.get(), metric_report_queue_.get(),
- settings_.get(), kEnableSettingPath,
- /*setting_enabled_default_value=*/false);
- FlushTasks();
- // Setting is disabled by default, no data is collected.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 0);
- EXPECT_TRUE(metric_report_queue_->GetMetricDataReported().empty());
- }
- TEST_F(MetricDataCollectorTest, PeriodicCollector_InitiallyEnabled) {
- constexpr int interval = 10000;
- settings_->SetBoolean(kEnableSettingPath, true);
- settings_->SetInteger(kRateSettingPath, interval);
- MetricData metric_data[5];
- metric_data[0].mutable_telemetry_data();
- metric_data[1].mutable_info_data();
- metric_data[2].mutable_event_data();
- metric_data[3].mutable_telemetry_data();
- metric_data[3].mutable_event_data();
- metric_data[4].mutable_info_data();
- metric_data[4].mutable_event_data();
- sampler_->SetMetricData(metric_data[0]);
- PeriodicCollector collector(
- sampler_.get(), metric_report_queue_.get(), settings_.get(),
- kEnableSettingPath, /*setting_enabled_default_value=*/false,
- kRateSettingPath, base::Milliseconds(interval / 2));
- // One initial collection at startup.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- FlushTasks();
- // Expected calls count initialized to 1 to reflect the initial collection.
- int expected_collect_calls = 1;
- for (int i = 0; i < 2; ++i) {
- sampler_->SetMetricData(metric_data[i + 1]);
- // 5 secs elapsed, no new data collected.
- task_environment_.FastForwardBy(base::Milliseconds(interval / 2));
- EXPECT_EQ(sampler_->GetNumCollectCalls(), expected_collect_calls);
- ++expected_collect_calls;
- // 10 secs elapsed, data should be collected.
- task_environment_.FastForwardBy(base::Milliseconds(interval / 2));
- EXPECT_EQ(sampler_->GetNumCollectCalls(), expected_collect_calls);
- FlushTasks();
- }
- sampler_->SetMetricData(metric_data[3]);
- settings_->SetBoolean(kEnableSettingPath, false);
- // Setting disabled, no data should be collected.
- task_environment_.FastForwardBy(base::Milliseconds(interval));
- EXPECT_EQ(sampler_->GetNumCollectCalls(), expected_collect_calls);
- FlushTasks();
- settings_->SetBoolean(kEnableSettingPath, true);
- // Initial collection at policy enablement.
- ++expected_collect_calls;
- EXPECT_EQ(sampler_->GetNumCollectCalls(), expected_collect_calls);
- FlushTasks();
- sampler_->SetMetricData(metric_data[4]);
- // Setting enabled, data should be collected after interval.
- task_environment_.FastForwardBy(base::Milliseconds(interval / 2));
- EXPECT_EQ(sampler_->GetNumCollectCalls(), expected_collect_calls);
- ++expected_collect_calls;
- task_environment_.FastForwardBy(base::Milliseconds(interval / 2));
- EXPECT_EQ(sampler_->GetNumCollectCalls(), expected_collect_calls);
- FlushTasks();
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_THAT(metric_data_reported, ::testing::SizeIs(5));
- for (int i = 0; i < 5; ++i) {
- EXPECT_TRUE(metric_data_reported[i]->has_timestamp_ms());
- EXPECT_EQ(metric_data_reported[i]->has_telemetry_data(),
- metric_data[i].has_telemetry_data());
- EXPECT_EQ(metric_data_reported[i]->has_info_data(),
- metric_data[i].has_info_data());
- EXPECT_EQ(metric_data_reported[i]->has_event_data(),
- metric_data[i].has_event_data());
- }
- }
- TEST_F(MetricDataCollectorTest, PeriodicCollector_NoMetricData) {
- constexpr int interval = 10000;
- settings_->SetBoolean(kEnableSettingPath, true);
- settings_->SetInteger(kRateSettingPath, interval);
- sampler_->SetMetricData(absl::nullopt);
- PeriodicCollector collector(
- sampler_.get(), metric_report_queue_.get(), settings_.get(),
- kEnableSettingPath, /*setting_enabled_default_value=*/false,
- kRateSettingPath, base::Milliseconds(interval / 2));
- // One initial collection at startup.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- FlushTasks();
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_TRUE(metric_data_reported.empty());
- }
- TEST_F(MetricDataCollectorTest, PeriodicCollector_InitiallyDisabled) {
- constexpr int interval = 10000;
- settings_->SetBoolean(kEnableSettingPath, false);
- settings_->SetInteger(kRateSettingPath, interval);
- MetricData metric_data;
- metric_data.mutable_telemetry_data();
- sampler_->SetMetricData(std::move(metric_data));
- PeriodicCollector collector(
- sampler_.get(), metric_report_queue_.get(), settings_.get(),
- kEnableSettingPath, /*setting_enabled_default_value=*/false,
- kRateSettingPath, base::Milliseconds(interval / 2));
- task_environment_.FastForwardBy(base::Milliseconds(interval));
- // Setting is disabled, no data collected.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 0);
- settings_->SetBoolean(kEnableSettingPath, true);
- // One initial collection at policy enablement.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- FlushTasks();
- task_environment_.FastForwardBy(base::Milliseconds(interval));
- // 1 collection at policy enablement + 1 collection after interval.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 2);
- FlushTasks();
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_THAT(metric_data_reported, ::testing::SizeIs(2));
- EXPECT_TRUE(metric_data_reported[0]->has_timestamp_ms());
- EXPECT_TRUE(metric_data_reported[0]->has_telemetry_data());
- EXPECT_TRUE(metric_data_reported[1]->has_timestamp_ms());
- EXPECT_TRUE(metric_data_reported[1]->has_telemetry_data());
- }
- TEST_F(MetricDataCollectorTest, PeriodicCollector_DefaultEnabled) {
- constexpr int interval = 10000;
- settings_->SetInteger(kRateSettingPath, interval);
- MetricData metric_data;
- metric_data.mutable_telemetry_data();
- sampler_->SetMetricData(std::move(metric_data));
- PeriodicCollector collector(
- sampler_.get(), metric_report_queue_.get(), settings_.get(),
- "invalid/path", /*setting_enabled_default_value=*/true, kRateSettingPath,
- base::Milliseconds(interval / 2));
- // One initial collection at startup.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- FlushTasks();
- metric_data.Clear();
- metric_data.mutable_event_data();
- sampler_->SetMetricData(std::move(metric_data));
- // 10 secs elapsed, data should be collected.
- task_environment_.FastForwardBy(base::Milliseconds(interval));
- // 1 collection at startup + 1 collection after interval.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 2);
- FlushTasks();
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_THAT(metric_data_reported, ::testing::SizeIs(2));
- EXPECT_TRUE(metric_data_reported[0]->has_timestamp_ms());
- EXPECT_TRUE(metric_data_reported[0]->has_telemetry_data());
- EXPECT_TRUE(metric_data_reported[1]->has_timestamp_ms());
- EXPECT_FALSE(metric_data_reported[1]->has_telemetry_data());
- EXPECT_TRUE(metric_data_reported[1]->has_event_data());
- }
- TEST_F(MetricDataCollectorTest, PeriodicCollector_DefaultDisabled) {
- constexpr int interval = 10000;
- settings_->SetInteger(kRateSettingPath, interval);
- MetricData metric_data;
- metric_data.mutable_telemetry_data();
- PeriodicCollector collector(
- sampler_.get(), metric_report_queue_.get(), settings_.get(),
- "invalid/path", /*setting_enabled_default_value=*/false, kRateSettingPath,
- base::Milliseconds(interval / 2));
- sampler_->SetMetricData(std::move(metric_data));
- task_environment_.FastForwardBy(base::Milliseconds(interval));
- FlushTasks();
- // Setting is disabled by default, no data collected.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 0);
- EXPECT_TRUE(metric_report_queue_->GetMetricDataReported().empty());
- }
- TEST_F(MetricDataCollectorTest, PeriodicEventCollector_NoAdditionalSamplers) {
- constexpr int interval = 10000;
- settings_->SetBoolean(kEnableSettingPath, true);
- settings_->SetInteger(kRateSettingPath, interval);
- MetricData metric_data[3];
- metric_data[0].mutable_info_data();
- metric_data[1].mutable_telemetry_data();
- metric_data[2].mutable_info_data();
- auto event_detector = std::make_unique<test::FakeEventDetector>();
- auto* event_detector_ptr = event_detector.get();
- sampler_->SetMetricData(metric_data[0]);
- PeriodicEventCollector collector(sampler_.get(), std::move(event_detector),
- {}, metric_report_queue_.get(),
- settings_.get(), kEnableSettingPath,
- /*setting_enabled_default_value=*/false,
- kRateSettingPath, base::Milliseconds(15000));
- // One initial collection at startup, data collected but not reported.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- FlushTasks();
- sampler_->SetMetricData(std::move(metric_data[1]));
- event_detector_ptr->SetHasEvent(true);
- task_environment_.FastForwardBy(base::Milliseconds(interval));
- // Data collected and reported.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 2);
- FlushTasks();
- sampler_->SetMetricData(std::move(metric_data[2]));
- event_detector_ptr->SetHasEvent(false);
- task_environment_.FastForwardBy(base::Milliseconds(interval));
- // Data collected but not reported.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 3);
- FlushTasks();
- const auto& previous_metric_list =
- event_detector_ptr->GetPreviousMetricList();
- ASSERT_THAT(previous_metric_list, ::testing::SizeIs(3));
- EXPECT_FALSE(previous_metric_list[0]->has_timestamp_ms());
- EXPECT_FALSE(previous_metric_list[0]->has_info_data());
- EXPECT_FALSE(previous_metric_list[0]->has_telemetry_data());
- EXPECT_FALSE(previous_metric_list[0]->has_event_data());
- EXPECT_TRUE(previous_metric_list[1]->has_timestamp_ms());
- EXPECT_TRUE(previous_metric_list[1]->has_info_data());
- EXPECT_FALSE(previous_metric_list[1]->has_telemetry_data());
- EXPECT_FALSE(previous_metric_list[1]->has_event_data());
- EXPECT_TRUE(previous_metric_list[2]->has_timestamp_ms());
- EXPECT_FALSE(previous_metric_list[2]->has_info_data());
- EXPECT_TRUE(previous_metric_list[2]->has_telemetry_data());
- EXPECT_TRUE(previous_metric_list[2]->has_event_data());
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_THAT(metric_data_reported, ::testing::SizeIs(1));
- EXPECT_TRUE(metric_data_reported[0]->has_timestamp_ms());
- EXPECT_FALSE(metric_data_reported[0]->has_info_data());
- EXPECT_TRUE(metric_data_reported[0]->has_telemetry_data());
- EXPECT_TRUE(metric_data_reported[0]->has_event_data());
- }
- TEST_F(MetricDataCollectorTest, PeriodicEventCollector_WithAdditionalSamplers) {
- settings_->SetBoolean(kEnableSettingPath, true);
- MetricData metric_data;
- metric_data.mutable_telemetry_data();
- MetricData additional_metric_data[3];
- additional_metric_data[0]
- .mutable_telemetry_data()
- ->mutable_networks_telemetry()
- ->mutable_https_latency_data()
- ->set_verdict(RoutineVerdict::PROBLEM);
- additional_metric_data[1]
- .mutable_telemetry_data()
- ->mutable_networks_telemetry()
- ->mutable_https_latency_data()
- ->set_problem(HttpsLatencyProblem::HIGH_LATENCY);
- additional_metric_data[2]
- .mutable_telemetry_data()
- ->mutable_networks_telemetry()
- ->mutable_https_latency_data()
- ->set_latency_ms(1500);
- test::FakeSampler additional_samplers[3];
- std::vector<Sampler*> additional_sampler_ptrs;
- for (int i = 0; i < 3; ++i) {
- additional_samplers[i].SetMetricData(additional_metric_data[i]);
- additional_sampler_ptrs.emplace_back(additional_samplers + i);
- }
- test::FakeSampler empty_additional_sampler;
- additional_sampler_ptrs.emplace_back(&empty_additional_sampler);
- auto event_detector = std::make_unique<test::FakeEventDetector>();
- sampler_->SetMetricData(std::move(metric_data));
- event_detector->SetHasEvent(true);
- PeriodicEventCollector collector(sampler_.get(), std::move(event_detector),
- std::move(additional_sampler_ptrs),
- metric_report_queue_.get(), settings_.get(),
- kEnableSettingPath,
- /*setting_enabled_default_value=*/false,
- kRateSettingPath, base::Milliseconds(15000));
- // Data collected and reported.
- EXPECT_EQ(sampler_->GetNumCollectCalls(), 1);
- task_environment_.RunUntilIdle();
- const auto& metric_data_reported =
- metric_report_queue_->GetMetricDataReported();
- ASSERT_THAT(metric_data_reported, ::testing::SizeIs(1));
- EXPECT_TRUE(metric_data_reported[0]->has_timestamp_ms());
- EXPECT_TRUE(metric_data_reported[0]->has_event_data());
- ASSERT_TRUE(metric_data_reported[0]->has_telemetry_data());
- ASSERT_TRUE(
- metric_data_reported[0]->telemetry_data().has_networks_telemetry());
- ASSERT_TRUE(metric_data_reported[0]
- ->telemetry_data()
- .networks_telemetry()
- .has_https_latency_data());
- auto https_latency_data = metric_data_reported[0]
- ->telemetry_data()
- .networks_telemetry()
- .https_latency_data();
- EXPECT_EQ(https_latency_data.verdict(), additional_metric_data[0]
- .telemetry_data()
- .networks_telemetry()
- .https_latency_data()
- .verdict());
- EXPECT_EQ(https_latency_data.problem(), additional_metric_data[1]
- .telemetry_data()
- .networks_telemetry()
- .https_latency_data()
- .problem());
- EXPECT_EQ(https_latency_data.latency_ms(), additional_metric_data[2]
- .telemetry_data()
- .networks_telemetry()
- .https_latency_data()
- .latency_ms());
- }
- } // namespace
- } // namespace reporting
|