| // Copyright 2020 The Fuchsia 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 "src/pb/metadata_builder.h" |
| |
| #include <chrono> |
| #include <memory> |
| |
| #include <gtest/gtest.h> |
| |
| #include "absl/strings/str_cat.h" |
| #include "src/lib/util/clock.h" |
| #include "src/lib/util/datetime_util.h" |
| #include "src/lib/util/posix_file_system.h" |
| #include "src/lib/util/testing/test_with_files.h" |
| #include "src/logger/project_context.h" |
| #include "src/logging.h" |
| #include "src/registry/metric_definition.pb.h" |
| #include "src/registry/report_definition.pb.h" |
| #include "src/system_data/fake_system_data.h" |
| |
| namespace cobalt { |
| |
| class MetadataBuilderTest : public util::testing::TestWithFiles { |
| public: |
| void SetUp() override { |
| util::testing::TestWithFiles::SetUp(); |
| |
| system_clock_ = std::make_unique<util::IncrementingSystemClock>(); |
| system_clock_->set_increment(std::chrono::hours(1)); |
| test_clock_ = std::make_unique<util::FakeValidatedClock>(system_clock_.get()); |
| test_clock_->SetAccurate(true); |
| |
| SetupBuilder(); |
| } |
| |
| void SetupBuilder() { |
| system_data_ = std::make_unique<system_data::FakeSystemData>(); |
| builder_ = std::make_unique<MetadataBuilder>(system_data_.get(), test_clock_.get(), |
| system_data_cache_path(), fs()); |
| } |
| |
| std::unique_ptr<ObservationMetadata> BuildForHour(const logger::MetricRef &metric, |
| const ReportDefinition &report, |
| uint32_t hour_id) { |
| return builder_->Build(metric, report, util::TimeInfo::FromHourId(hour_id)); |
| } |
| |
| std::unique_ptr<ObservationMetadata> BuildForDay(const logger::MetricRef &metric, |
| const ReportDefinition &report, |
| uint32_t day_index) { |
| return builder_->Build(metric, report, util::TimeInfo::FromDayIndex(day_index)); |
| } |
| |
| protected: |
| std::unique_ptr<system_data::FakeSystemData> system_data_; |
| std::unique_ptr<util::IncrementingSystemClock> system_clock_; |
| std::unique_ptr<util::FakeValidatedClock> test_clock_; |
| |
| std::unique_ptr<MetadataBuilder> builder_; |
| }; |
| |
| TEST(MetadataBuilder, CanBeConstructedWithEmptySystemDataCachePath) { |
| std::unique_ptr<util::IncrementingSystemClock> system_clock = |
| std::make_unique<util::IncrementingSystemClock>(); |
| system_clock->set_increment(std::chrono::hours(1)); |
| std::unique_ptr<util::FakeValidatedClock> test_clock = |
| std::make_unique<util::FakeValidatedClock>(system_clock.get()); |
| test_clock->SetAccurate(true); |
| std::unique_ptr<system_data::FakeSystemData> system_data = |
| std::make_unique<system_data::FakeSystemData>(); |
| MetadataBuilder builder(system_data.get(), test_clock.get(), "", nullptr); |
| } |
| |
| TEST_F(MetadataBuilderTest, FiltersAsExpected) { |
| const auto kCustomerId = 12; |
| const auto kProjectId = 34; |
| const auto kMetricId = 56; |
| const auto kReportId = 78; |
| |
| Project proj; |
| proj.set_customer_id(kCustomerId); |
| proj.set_project_id(kProjectId); |
| |
| MetricDefinition metric; |
| metric.set_id(kMetricId); |
| metric.set_time_zone_policy(MetricDefinition::UTC); |
| |
| ReportDefinition report; |
| report.set_id(kReportId); |
| report.add_experiment_id(2); |
| report.add_system_profile_field(SystemProfileField::BOARD_NAME); |
| report.add_system_profile_field(SystemProfileField::PRODUCT_NAME); |
| report.add_system_profile_field(SystemProfileField::CHANNEL); |
| report.add_system_profile_field(SystemProfileField::EXPERIMENT_IDS); |
| report.add_system_profile_field(SystemProfileField::EXPERIMENT_TOKENS); |
| |
| logger::MetricRef metric_ref(&proj, &metric); |
| auto metadata = BuildForDay(metric_ref, report, 0); |
| EXPECT_EQ(metadata->customer_id(), kCustomerId); |
| EXPECT_EQ(metadata->project_id(), kProjectId); |
| EXPECT_EQ(metadata->metric_id(), kMetricId); |
| EXPECT_EQ(metadata->report_id(), kReportId); |
| |
| // These fields should match, since they were selected. |
| EXPECT_EQ(metadata->system_profile().board_name(), system_data_->system_profile().board_name()); |
| EXPECT_EQ(metadata->system_profile().product_name(), |
| system_data_->system_profile().product_name()); |
| EXPECT_EQ(metadata->system_profile().channel(), system_data_->channel()); |
| |
| // Only the one experiment ID listed in the report should be included. |
| ASSERT_EQ(metadata->system_profile().experiment_ids_size(), 1); |
| EXPECT_EQ(metadata->system_profile().experiment_ids(0), 2); |
| |
| ASSERT_EQ(metadata->system_profile().experiment_tokens_size(), |
| system_data_->system_profile().experiment_tokens_size()); |
| for (int i = 0; i < metadata->system_profile().experiment_tokens_size(); ++i) { |
| EXPECT_EQ(metadata->system_profile().experiment_tokens(i).ns(), |
| system_data_->system_profile().experiment_tokens(i).ns()); |
| EXPECT_EQ(metadata->system_profile().experiment_tokens(i).token(), |
| system_data_->system_profile().experiment_tokens(i).token()); |
| } |
| |
| // These fields should not match. |
| EXPECT_NE(metadata->system_profile().os(), system_data_->system_profile().os()); |
| EXPECT_NE(metadata->system_profile().arch(), system_data_->system_profile().arch()); |
| EXPECT_NE(metadata->system_profile().realm(), system_data_->system_profile().realm()); |
| } |
| |
| TEST_F(MetadataBuilderTest, CollectsAsExpected) { |
| Project proj; |
| MetricDefinition metric; |
| metric.set_time_zone_policy(MetricDefinition::UTC); |
| ReportDefinition report; |
| report.set_system_profile_selection(SystemProfileSelectionPolicy::SELECT_FIRST); |
| report.set_local_aggregation_period(WindowSize::WINDOW_1_DAY); |
| report.add_system_profile_field(SystemProfileField::SYSTEM_VERSION); |
| for (int i = 0; i < 24 * 7; i++) { |
| system_data_->SetVersion(absl::StrCat("Version ", i + 1)); |
| } |
| |
| logger::MetricRef metric_ref(&proj, &metric); |
| auto metadata = BuildForDay(metric_ref, report, 0); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 1"); |
| |
| metadata = BuildForDay(metric_ref, report, 1); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 24"); |
| |
| metadata = BuildForDay(metric_ref, report, 2); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 48"); |
| |
| report.set_local_aggregation_period(WindowSize::WINDOW_7_DAYS); |
| metadata = BuildForDay(metric_ref, report, 6); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 1"); |
| |
| report.set_system_profile_selection(SystemProfileSelectionPolicy::SELECT_LAST); |
| metadata = BuildForDay(metric_ref, report, 0); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 23"); |
| |
| metadata = BuildForDay(metric_ref, report, 1); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 47"); |
| } |
| |
| TEST_F(MetadataBuilderTest, CleanupWorks) { |
| Project proj; |
| MetricDefinition metric; |
| metric.set_time_zone_policy(MetricDefinition::UTC); |
| ReportDefinition report; |
| report.set_system_profile_selection(SystemProfileSelectionPolicy::SELECT_FIRST); |
| report.set_local_aggregation_period(WindowSize::WINDOW_1_DAY); |
| report.add_system_profile_field(SystemProfileField::SYSTEM_VERSION); |
| for (int i = 0; i < 24 * 7; i++) { |
| system_data_->SetVersion(absl::StrCat("Version ", i + 1)); |
| } |
| |
| system_data_->SetVersion("Default Version"); |
| |
| logger::MetricRef metric_ref(&proj, &metric); |
| auto metadata = BuildForDay(metric_ref, report, 0); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 1"); |
| |
| metadata = BuildForDay(metric_ref, report, 1); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 24"); |
| |
| metadata = BuildForDay(metric_ref, report, 2); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 48"); |
| |
| report.set_local_aggregation_period(WindowSize::WINDOW_7_DAYS); |
| metadata = BuildForDay(metric_ref, report, 6); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 1"); |
| |
| builder_->CleanupBefore(std::chrono::hours(4 * 24)); |
| |
| report.set_local_aggregation_period(WindowSize::WINDOW_1_DAY); |
| metadata = BuildForDay(metric_ref, report, 2); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Default Version"); |
| |
| report.set_local_aggregation_period(WindowSize::WINDOW_7_DAYS); |
| metadata = BuildForDay(metric_ref, report, 6); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Default Version"); |
| |
| report.set_local_aggregation_period(WindowSize::WINDOW_1_DAY); |
| metadata = BuildForDay(metric_ref, report, 6); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 144"); |
| } |
| |
| TEST_F(MetadataBuilderTest, RestoresOnRestart) { |
| Project proj; |
| MetricDefinition metric; |
| metric.set_time_zone_policy(MetricDefinition::UTC); |
| ReportDefinition report; |
| report.set_report_type(ReportDefinition::FLEETWIDE_OCCURRENCE_COUNTS); |
| report.set_system_profile_selection(SystemProfileSelectionPolicy::SELECT_FIRST); |
| report.add_system_profile_field(SystemProfileField::SYSTEM_VERSION); |
| |
| for (int i = 1; i <= 5; i += 2) { |
| system_data_->SetVersion(absl::StrCat("Version ", i)); |
| } |
| |
| SetupBuilder(); |
| system_data_->SetVersion("Default Version"); |
| |
| logger::MetricRef metric_ref(&proj, &metric); |
| auto metadata = BuildForHour(metric_ref, report, 3); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 1"); |
| |
| metadata = BuildForHour(metric_ref, report, 5); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 3"); |
| |
| metadata = BuildForHour(metric_ref, report, 7); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Version 5"); |
| |
| metadata = BuildForHour(metric_ref, report, 9); |
| EXPECT_EQ(metadata->system_profile().system_version(), "Default Version"); |
| } |
| |
| } // namespace cobalt |