blob: f0f2d299fbbcc588815fc9fbbfd2314479fdf815 [file] [log] [blame]
// 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_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_, 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>();
util::PosixFileSystem fs;
MetadataBuilder builder(*system_data, test_clock.get(), "", fs);
}
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