// Copyright 2018 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/logger/event_loggers.h"

#include <chrono>
#include <memory>
#include <string>

#include <google/protobuf/repeated_field.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/message_differencer.h>
#include <gtest/gtest.h>

#include "src/algorithms/rappor/rappor_encoder.h"
#include "src/lib/util/clock.h"
#include "src/lib/util/datetime_util.h"
#include "src/lib/util/encrypted_message_util.h"
#include "src/lib/util/testing/test_with_files.h"
#include "src/local_aggregation/event_aggregator_mgr.h"
#include "src/local_aggregation/local_aggregation.pb.h"
#include "src/local_aggregation/test_utils/test_event_aggregator_mgr.h"
#include "src/local_aggregation_1_1/local_aggregate_storage/immediate_local_aggregate_storage.h"
#include "src/local_aggregation_1_1/local_aggregate_storage/local_aggregate_storage.h"
#include "src/local_aggregation_1_1/local_aggregation.h"
#include "src/local_aggregation_1_1/local_aggregation.pb.h"
#include "src/logger/encoder.h"
#include "src/logger/logger_test_utils.h"
#include "src/logger/project_context.h"
#include "src/logger/test_registries/cobalt1.1_test_registry.cb.h"
#include "src/logger/testing_constants.h"
#include "src/pb/metadata_builder.h"
#include "src/pb/observation.pb.h"
#include "src/public/lib/status.h"
#include "src/registry/packed_event_codes.h"
#include "src/system_data/client_secret.h"
#include "src/system_data/fake_system_data.h"

using ::google::protobuf::RepeatedField;
#ifndef PROTO_LITE
using ::google::protobuf::util::MessageDifferencer;
#endif

namespace cobalt::logger {

using config::PackEventCodes;
using internal::EventLogger;
using local_aggregation::LocalAggregation;
using local_aggregation::TestEventAggregatorManager;
using system_data::ClientSecret;
using testing::CheckNumericEventObservations;
using testing::CheckUniqueActivesObservations;
using testing::ExpectedAggregationParams;
using testing::ExpectedPerDeviceNumericObservations;
using testing::ExpectedReportParticipationObservations;
using testing::ExpectedUniqueActivesObservations;
using testing::FakeObservationStore;
using testing::FetchObservations;
using testing::FetchSingleObservation;
using testing::GetTestProject;
using testing::GetTestProjectContextFactory;
using testing::MakeNullExpectedUniqueActivesObservations;
using testing::TestUpdateRecipient;
using util::EncryptedMessageMaker;
using util::IncrementingSystemClock;
using util::TimeToDayIndex;

namespace {
// Number of seconds in a day
constexpr int kDay = 60 * 60 * 24;
// Number of seconds in an ideal year
constexpr int kYear = kDay * 365;

}  // namespace

template <typename EventLoggerClass = internal::EventLogger>
class EventLoggersTest : public util::testing::TestWithFiles {
 protected:
  static_assert(std::is_base_of<internal::EventLogger, EventLoggerClass>::value,
                "The type argument must be a subclass of EventLogger");

  void SetUp() override {
    SetUpFromMetrics(testing::all_report_types::kCobaltRegistryBase64,
                     testing::all_report_types::kExpectedAggregationParams);
  }

  // Set up LoggerTest using a base64-encoded registry.
  void SetUpFromMetrics(const std::string& registry_base64,
                        const ExpectedAggregationParams& expected_aggregation_params) {
    MakeTestFolder();

    // Create a mock clock which does not increment by default when called.
    // Set the time to 1 year after the start of Unix time so that the start
    // date of any aggregation window falls after the start of time.
    mock_clock_ = std::make_unique<IncrementingSystemClock>(std::chrono::system_clock::duration(0));
    mock_clock_->set_time(std::chrono::system_clock::time_point(std::chrono::seconds(kYear)));
    validated_clock_ = std::make_unique<util::FakeValidatedClock>(mock_clock_.get());
    validated_clock_->SetAccurate(true);
    civil_time_converter_ = std::make_unique<util::UtcTimeConverter>();

    expected_aggregation_params_ = expected_aggregation_params;
    observation_store_ = std::make_unique<FakeObservationStore>();
    update_recipient_ = std::make_unique<TestUpdateRecipient>();
    observation_encrypter_ = EncryptedMessageMaker::MakeUnencrypted();
    observation_writer_ = std::make_unique<ObservationWriter>(
        *observation_store_, update_recipient_.get(), observation_encrypter_.get());
    metadata_builder_ = std::make_unique<MetadataBuilder>(system_data_, validated_clock_.get(),
                                                          system_data_cache_path(), fs());
    metadata_builder_->SnapshotSystemData();
    encoder_ = std::make_unique<Encoder>(ClientSecret::GenerateNewSecret(), *metadata_builder_);
    CobaltConfig cfg = {.client_secret = system_data::ClientSecret::GenerateNewSecret()};

    cfg.local_aggregation_backfill_days = 0;
    cfg.local_aggregate_proto_store_path = aggregate_store_path();
    cfg.obs_history_proto_store_path = obs_history_path();

    project_context_factory_ = GetTestProjectContextFactory(registry_base64);

    event_aggregator_mgr_ = std::make_unique<TestEventAggregatorManager>(
        cfg, fs(), *encoder_, *observation_writer_, *metadata_builder_);
    local_aggregation_ = std::make_unique<LocalAggregation>(
        cfg, project_context_factory_.get(), system_data_, *metadata_builder_, fs(),
        *observation_writer_, *civil_time_converter_);
    project_context_ = GetTestProject(registry_base64);
    event_aggregator_mgr_->GetEventAggregator().UpdateAggregationConfigs(*project_context_);
    logger_ = std::make_unique<EventLoggerClass>(
        *encoder_, event_aggregator_mgr_->GetEventAggregator(), *local_aggregation_,
        *observation_writer_, system_data_, *civil_time_converter_);
  }

  void TearDown() override {
    event_aggregator_mgr_.reset();
    logger_.reset();
  }

  // Returns the day index of the current day according to |mock_clock_|, in
  // |time_zone|, without incrementing the clock.
  uint32_t CurrentDayIndex(MetricDefinition::TimeZonePolicy time_zone) {
    return TimeToDayIndex(std::chrono::system_clock::to_time_t(mock_clock_->peek_now()), time_zone);
  }

  // Advances |mock_clock_| by |num_days| days.
  void AdvanceDay(int num_days) {
    mock_clock_->increment_by(std::chrono::seconds(kDay) * num_days);
  }

  // Clears the FakeObservationStore and resets counts of Observations received
  // by the FakeObservationStore and the TestUpdateRecipient.
  void ResetObservationStore() {
    observation_store_->messages_received.clear();
    observation_store_->metadata_received.clear();
    observation_store_->ResetObservationCounter();
    update_recipient_->invocation_count = 0;
  }

  Status LogEvent(uint32_t metric_id, uint32_t event_code) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    event_record->event()->mutable_event_occurred_event()->set_event_code(event_code);
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::EVENT_OCCURRED,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogEventCount(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                       const std::string& component, int64_t period_duration_micros,
                       uint32_t count) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* event_count_event = event_record->event()->mutable_event_count_event();
    event_count_event->set_component(component);
    event_count_event->set_period_duration_micros(period_duration_micros);
    event_count_event->set_count(count);
    event_count_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::EVENT_COUNT,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogElapsedTime(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                        const std::string& component, int64_t elapsed_micros) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* elapsed_time_event = event_record->event()->mutable_elapsed_time_event();
    elapsed_time_event->set_component(component);
    elapsed_time_event->set_elapsed_micros(elapsed_micros);
    elapsed_time_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::ELAPSED_TIME,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogFrameRate(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                      const std::string& component, int64_t frames_per_1000_seconds) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* frame_rate_event = event_record->event()->mutable_frame_rate_event();
    frame_rate_event->set_component(component);
    frame_rate_event->set_frames_per_1000_seconds(frames_per_1000_seconds);
    frame_rate_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::FRAME_RATE,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogMemoryUsage(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                        const std::string& component, int64_t bytes) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* memory_usage_event = event_record->event()->mutable_memory_usage_event();
    memory_usage_event->set_component(component);
    memory_usage_event->set_bytes(bytes);
    memory_usage_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::MEMORY_USAGE,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogIntHistogram(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                         const std::string& component, const std::vector<uint32_t>& indices,
                         const std::vector<uint32_t>& counts) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* int_histogram_event = event_record->event()->mutable_int_histogram_event();
    int_histogram_event->set_component(component);
    int_histogram_event->mutable_buckets()->Swap(testing::NewHistogram(indices, counts).get());
    int_histogram_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::INT_HISTOGRAM,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogCustomEvent(uint32_t metric_id, const std::vector<std::string>& dimension_names,
                        const std::vector<CustomDimensionValue>& values) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* custom_event = event_record->event()->mutable_custom_event();
    custom_event->mutable_values()->swap(*testing::NewCustomEvent(dimension_names, values));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::CUSTOM,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogSerializedCustomEvent(uint32_t metric_id, const std::string& serialized_proto) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* custom_event = event_record->event()->mutable_custom_event();
    custom_event->set_serialized_proto(serialized_proto);
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::CUSTOM,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  std::chrono::system_clock::time_point start_time_;
  std::unique_ptr<internal::EventLogger> logger_;
  std::unique_ptr<TestEventAggregatorManager> event_aggregator_mgr_;
  std::unique_ptr<LocalAggregation> local_aggregation_;
  std::unique_ptr<ObservationWriter> observation_writer_;
  std::unique_ptr<FakeObservationStore> observation_store_;
  std::unique_ptr<TestUpdateRecipient> update_recipient_;
  ExpectedAggregationParams expected_aggregation_params_;

 private:
  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<Encoder> encoder_;
  std::unique_ptr<EncryptedMessageMaker> observation_encrypter_;
  system_data::FakeSystemData system_data_;
  std::unique_ptr<IncrementingSystemClock> mock_clock_;
  std::unique_ptr<util::FakeValidatedClock> validated_clock_;
  std::unique_ptr<util::UtcTimeConverter> civil_time_converter_;
  std::unique_ptr<ProjectContextFactory> project_context_factory_;
  std::shared_ptr<ProjectContext> project_context_;
};

class EventOccurredEventLoggerTest : public EventLoggersTest<internal::EventOccurredEventLogger> {};

class EventCountEventLoggerTest : public EventLoggersTest<internal::EventCountEventLogger> {};

class ElapsedTimeEventLoggerTest : public EventLoggersTest<internal::ElapsedTimeEventLogger> {};

class FrameRateEventLoggerTest : public EventLoggersTest<internal::FrameRateEventLogger> {};

class MemoryUsageEventLoggerTest : public EventLoggersTest<internal::MemoryUsageEventLogger> {};

class IntHistogramEventLoggerTest : public EventLoggersTest<internal::IntHistogramEventLogger> {};

class CustomEventLoggerTest : public EventLoggersTest<internal::CustomEventLogger> {};

// Creates a Logger whose ProjectContext contains only EVENT_OCCURRED metrics,
// each of which has a report of type UNIQUE_N_DAY_ACTIVES with
// local_privacy_noise_level set to NONE. Used to test the values of
// UniqueActivesObservations generated by the EventAggregator.
class UniqueActivesLoggerTest : public EventOccurredEventLoggerTest {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::unique_actives_noise_free::kCobaltRegistryBase64,
                     testing::unique_actives_noise_free::kExpectedAggregationParams);
  }
};

// Creates a Logger for a ProjectContext where each of the metrics
// has a report of type PER_DEVICE_NUMERIC_STATS.
class PerDeviceNumericEventCountEventLoggerTest
    : public EventLoggersTest<internal::EventCountEventLogger> {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::per_device_numeric_stats::kCobaltRegistryBase64,
                     testing::per_device_numeric_stats::kExpectedAggregationParams);
  }
};

class PerDeviceNumericElapsedTimeEventLoggerTest
    : public EventLoggersTest<internal::ElapsedTimeEventLogger> {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::per_device_numeric_stats::kCobaltRegistryBase64,
                     testing::per_device_numeric_stats::kExpectedAggregationParams);
  }
};

class PerDeviceNumericFrameRateEventLoggerTest
    : public EventLoggersTest<internal::FrameRateEventLogger> {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::per_device_numeric_stats::kCobaltRegistryBase64,
                     testing::per_device_numeric_stats::kExpectedAggregationParams);
  }
};

class PerDeviceNumericMemoryUsageEventLoggerTest
    : public EventLoggersTest<internal::MemoryUsageEventLogger> {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::per_device_numeric_stats::kCobaltRegistryBase64,
                     testing::per_device_numeric_stats::kExpectedAggregationParams);
  }
};

// Tests the EventOccurredEventLogger.
TEST_F(EventOccurredEventLoggerTest, Log) {
  // Attempt to use an event code larger than max_event_code.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogEvent(testing::all_report_types::kErrorOccurredMetricId, 101).error_code());

  // Now use good arguments.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kErrorOccurredMetricId, 42).error_code());
  Observation observation;
  uint32_t expected_report_id = testing::all_report_types::kErrorOccurredErrorCountsByCodeReportId;
  ASSERT_TRUE(FetchSingleObservation(&observation, expected_report_id, *observation_store_,
                                     update_recipient_.get()));
  ASSERT_TRUE(observation.has_basic_rappor());
  EXPECT_FALSE(observation.basic_rappor().data().empty());
}

// Tests the EventCountEventLogger.
TEST_F(EventCountEventLoggerTest, Log) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kReadCacheHitsReadCacheHitCountsReportId,
      testing::all_report_types::kReadCacheHitsReadCacheHitHistogramsReportId,
      testing::all_report_types::kReadCacheHitsReadCacheHitStatsReportId};

  // Attempt to use an event code larger than max_event_code.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {112}, "component2", 1, 303)
          .error_code());

  // All good
  ASSERT_EQ(StatusCode::OK, LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {43},
                                          "component2", 1, 303)
                                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 43u, "component2", 303,
                                            *observation_store_, update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();

  // No problem using event code 0.
  ASSERT_EQ(StatusCode::OK,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {0}, "", 1, 303)
                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0u, "", 303, *observation_store_,
                                            update_recipient_.get()));
}

// Tests the EventCountEventLogger with multiple event codes.
TEST_F(EventCountEventLoggerTest, LogMultiDimension) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kReadCacheHitsReadCacheHitCountsReportId,
      testing::all_report_types::kReadCacheHitsReadCacheHitHistogramsReportId,
      testing::all_report_types::kReadCacheHitsReadCacheHitStatsReportId};

  // Use a metric ID for the wrong type of metric. Expect StatusCode::INVALID_ARGUMENT.
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            LogEventCount(testing::all_report_types::kErrorOccurredMetricId, {43}, "", 0, 303)
                .error_code());

  // Use no event codes when the metric has one dimension. Expect kOK.
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {}, "", 0, 303)
                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0, "", 303, *observation_store_,
                                            update_recipient_.get()));
  ResetObservationStore();

  // Use two event codes when the metric has one dimension. Expect
  // StatusCode::INVALID_ARGUMENT.
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {43, 44}, "", 0, 303)
                .error_code());

  // Use an event code that exceeds the specified max_event_code. Expect
  // StatusCode::INVALID_ARGUMENT.
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {200}, "", 0, 303)
                .error_code());

  // All good, expect OK.
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {43}, "", 0, 303)
                .error_code());

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 43u, "", 303, *observation_store_,
                                            update_recipient_.get()));
}

// Tests the ElapsedTimeEventLogger.
TEST_F(ElapsedTimeEventLoggerTest, Log) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kModuleLoadTimeModuleLoadTimeAggregatedReportId,
      testing::all_report_types::kModuleLoadTimeModuleLoadTimeHistogramReportId};

  // Use a non-zero event code even though the metric does not have any
  // metric dimensions defined. Expect kInvalidArgument.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {44}, "component4", 4004)
          .error_code());

  // Use a zero event code when the metric does not have any metric dimensions
  // set. This is OK by convention. The zero will be ignored.
  ASSERT_EQ(StatusCode::OK, LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {0},
                                           "component4", 4004)
                                .error_code());

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0u, "component4", 4004,
                                            *observation_store_, update_recipient_.get()));
}

// Tests the ElapsedTimeEventLogger with multiple event codes.
TEST_F(ElapsedTimeEventLoggerTest, LogMultiDimension) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kModuleLoadTimeModuleLoadTimeAggregatedReportId,
      testing::all_report_types::kModuleLoadTimeModuleLoadTimeHistogramReportId};

  // Use a non-zero event code even though the metric does not have any
  // metric dimensions defined. Expect kInvalidArgument.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {44}, "component4", 4004)
          .error_code());

  // Use two event codes even though the metric does not have any
  // metric dimensions defined. Expect kInvalidArgument.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {0, 0}, "component4", 4004)
          .error_code());

  // Use no event codes when the metric does not have any metric
  // dimensions set. This is good.
  ASSERT_EQ(StatusCode::OK, LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {},
                                           "component4", 4004)
                                .error_code());

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0u, "component4", 4004,
                                            *observation_store_, update_recipient_.get()));
}

// Tests the FrameRateEventLogger.
TEST_F(FrameRateEventLoggerTest, Log) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kLoginModuleFrameRateLoginModuleFrameRateAggregatedReportId,
      testing::all_report_types::kLoginModuleFrameRateLoginModuleFrameRateHistogramReportId};

  // There is no max_event_code set so only the specified code of 45 is allowed.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {0},
                         "component5", 5123)
                .error_code());

  // All good.
  ASSERT_EQ(StatusCode::OK, LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId,
                                         {45}, "component5", 5123)
                                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 45u, "component5", 5123,
                                            *observation_store_, update_recipient_.get()));
}

// Tests the FrameRateEventLogger with multiple event codes.
TEST_F(FrameRateEventLoggerTest, LogMultiDimension) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kLoginModuleFrameRateLoginModuleFrameRateAggregatedReportId,
      testing::all_report_types::kLoginModuleFrameRateLoginModuleFrameRateHistogramReportId};

  // Use a metric ID for the wrong type of metric. Expect StatusCode::INVALID_ARGUMENT.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogFrameRate(testing::all_report_types::kModuleLoadTimeMetricId, {45}, "", 5123)
                .error_code());

  // Use no event codes when the metric has one dimension. Expect kOK.
  ASSERT_EQ(StatusCode::OK,
            LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {}, "", 5123)
                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0, "", 5123, *observation_store_,
                                            update_recipient_.get()));
  // Clear the FakeObservationStore.
  ResetObservationStore();

  // Use two event codes when the metric has one dimension. Expect
  // StatusCode::INVALID_ARGUMENT.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {45, 46}, "", 5123)
          .error_code());

  // There is no max_event_code set so only the specified code of 45 is allowed.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {44}, "", 5123)
                .error_code());

  // All good
  ASSERT_EQ(StatusCode::OK,
            LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {45}, "", 5123)
                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 45u, "", 5123, *observation_store_,
                                            update_recipient_.get()));
}

// Tests the MemoryUsageEventLogger.
TEST_F(MemoryUsageEventLoggerTest, Log) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kLedgerMemoryUsageLedgerMemoryUsageAggregatedReportId,
      testing::all_report_types::kLedgerMemoryUsageLedgerMemoryUsageHistogramReportId};

  // The simple version of LogMemoryUsage() can be used, even though the metric has two dimensions.
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {46}, "component6", 606)
                                .error_code());

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 46, "component6", 606,
                                            *observation_store_, update_recipient_.get()));
}

// Tests the MemoryUsageEventLogger with multiple event codes.
TEST_F(MemoryUsageEventLoggerTest, LogMultiDimension) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kLedgerMemoryUsageLedgerMemoryUsageAggregatedReportId,
      testing::all_report_types::kLedgerMemoryUsageLedgerMemoryUsageHistogramReportId};

  // Use a metric ID for the wrong type of metric. Expect StatusCode::INVALID_ARGUMENT.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogMemoryUsage(testing::all_report_types::kLoginModuleFrameRateMetricId, {45, 46},
                           "component6", 606)
                .error_code());

  // Use no event codes when the metric has two dimension. Expect kOK.
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {}, "component6", 606)
                                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0, "component6", 606,
                                            *observation_store_, update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();

  // Use one event code when the metric has two dimension. Expect kOK.
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {45}, "component6", 606)
                                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 45u, "component6", 606,
                                            *observation_store_, update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();

  // Use three event codes when the metric has two dimension. Expect
  // StatusCode::INVALID_ARGUMENT.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId, {45, 46, 47},
                           "component6", 606)
                .error_code());

  // There is no max_event_code set for the second dimension so only the
  // specified codes of 1 or 46 are allowed.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId, {1, 45},
                           "component6", 606)
                .error_code());

  // All good
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {1, 46}, "component6", 606)
                                .error_code());
  uint64_t expected_packed_event_code = (1) | (46 << 10);

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, expected_packed_event_code,
                                            "component6", 606, *observation_store_,
                                            update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();

  // No problem with the first event code being zero.
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {0, 46}, "component6", 606)
                                .error_code());
  expected_packed_event_code = (0) | (46 << 10);

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, expected_packed_event_code,
                                            "component6", 606, *observation_store_,
                                            update_recipient_.get()));
}

// Tests the IntHistogramEventLogger.
TEST_F(IntHistogramEventLoggerTest, Log) {
  std::vector<uint32_t> indices = {0, 1, 2, 3};
  std::vector<uint32_t> counts = {100, 101, 102, 103};

  ASSERT_EQ(StatusCode::OK,
            LogIntHistogram(testing::all_report_types::kFileSystemWriteTimesMetricId, {47},
                            "component7", indices, counts)
                .error_code());
  Observation observation;
  uint32_t expected_report_id =
      testing::all_report_types::kFileSystemWriteTimesFileSystemWriteTimesHistogramReportId;
  ASSERT_TRUE(FetchSingleObservation(&observation, expected_report_id, *observation_store_,
                                     update_recipient_.get()));
  ASSERT_TRUE(observation.has_histogram());
  auto histogram_observation = observation.histogram();
  EXPECT_EQ(47u, histogram_observation.event_code());
  EXPECT_EQ(histogram_observation.component_name_hash().size(), 32u);
  EXPECT_EQ(static_cast<size_t>(histogram_observation.buckets_size()), indices.size());
  for (int i = 0; i < indices.size(); i++) {
    const auto& bucket = histogram_observation.buckets(i);
    EXPECT_EQ(bucket.index(), indices[i]);
    EXPECT_EQ(bucket.count(), counts[i]);
  }
}

// Tests the CustomEventLogger.
TEST_F(CustomEventLoggerTest, LogCustomEvent) {
  CustomDimensionValue module_value, number_value;
  module_value.set_string_value("gmail");
  number_value.set_int_value(3);
  std::vector<std::string> dimension_names = {"module", "number"};
  std::vector<CustomDimensionValue> values = {module_value, number_value};
  ASSERT_EQ(StatusCode::OK, LogCustomEvent(testing::all_report_types::kModuleInstallsMetricId,
                                           dimension_names, values)
                                .error_code());
  Observation observation;
  uint32_t expected_report_id =
      testing::all_report_types::kModuleInstallsModuleInstallsDetailedDataReportId;
  ASSERT_TRUE(FetchSingleObservation(&observation, expected_report_id, *observation_store_,
                                     update_recipient_.get()));
  ASSERT_TRUE(observation.has_custom());
  const CustomObservation& custom_observation = observation.custom();
  for (auto i = 0u; i < values.size(); i++) {
    auto obs_dimension = custom_observation.values().at(dimension_names[i]);
#ifdef PROTO_LITE
#else
    EXPECT_TRUE(MessageDifferencer::Equals(obs_dimension, values[i]));
#endif
  }
}

TEST_F(CustomEventLoggerTest, LogSerializedCustomEvent) {
  std::string serialized_proto = "serialized proto";
  ASSERT_EQ(
      StatusCode::OK,
      LogSerializedCustomEvent(testing::all_report_types::kModuleInstallsMetricId, serialized_proto)
          .error_code());
  Observation observation;
  uint32_t expected_report_id =
      testing::all_report_types::kModuleInstallsModuleInstallsDetailedDataReportId;
  ASSERT_TRUE(FetchSingleObservation(&observation, expected_report_id, *observation_store_,
                                     update_recipient_.get()));
  ASSERT_TRUE(observation.has_custom());
  EXPECT_EQ(observation.custom().serialized_proto(), serialized_proto);
}

// Tests that UniqueActivesObservations with the expected values are generated
// when no events have been logged.
TEST_F(UniqueActivesLoggerTest, CheckUniqueActivesObsValuesNoEvents) {
  const auto current_day_index = CurrentDayIndex(MetricDefinition::UTC);
  // Generate locally aggregated Observations without logging any events.
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((current_day_index)).error_code());
  // Check that all generated Observations are of non-activity.
  auto expected_obs =
      MakeNullExpectedUniqueActivesObservations(expected_aggregation_params_, current_day_index);
  EXPECT_TRUE(
      CheckUniqueActivesObservations(expected_obs, *observation_store_, update_recipient_.get()));
}

// Tests that UniqueActivesObservations with the expected values are generated
// when events have been logged for UNIQUE_N_DAY_ACTIVES reports on a single
// day.
TEST_F(UniqueActivesLoggerTest, CheckUniqueActivesObsValuesSingleDay) {
  const auto current_day_index = CurrentDayIndex(MetricDefinition::UTC);
  // Log 2 occurrences of event code 0 for the DeviceBoots metric, which has 1
  // locally aggregated report and no immediate reports.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::unique_actives_noise_free::kDeviceBootsMetricId, 0).error_code());
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::unique_actives_noise_free::kDeviceBootsMetricId, 0).error_code());
  // Log 2 occurrences of different event codes for the SomeFeaturesActive
  // metric, which has 1 locally aggregated report and no immediate reports.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::unique_actives_noise_free::kFeaturesActiveMetricId, 0).error_code());
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::unique_actives_noise_free::kFeaturesActiveMetricId, 1).error_code());
  // Generate locally aggregated observations for the current day index.
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((current_day_index)).error_code());
  // Form the expected observations for the current day index.
  auto expected_obs =
      MakeNullExpectedUniqueActivesObservations(expected_aggregation_params_, current_day_index);
  expected_obs[{testing::unique_actives_noise_free::kDeviceBootsMetricReportId,
                current_day_index}] = {{1, {true, false}}};
  expected_obs[{testing::unique_actives_noise_free::kFeaturesActiveMetricReportId,
                current_day_index}] = {{1, {true, true, false, false, false}},
                                       {7, {true, true, false, false, false}},
                                       {28, {true, true, false, false, false}},
                                       {30, {true, true, false, false, false}}};
  // Check that the expected aggregated observations were generated.
  EXPECT_TRUE(
      CheckUniqueActivesObservations(expected_obs, *observation_store_, update_recipient_.get()));
}

// Tests that UniqueActivesObservations with the expected values are generated
// when events have been logged for a UniqueActives report over multiple days.
//
// Logs events for the EventsOccurred_UniqueDevices report (whose parent metric
// has max_event_code = 5, and whose report ID is 401) for 10 days, according to
// the following pattern:
//
// * Never log event code 0.
// * On the i-th day (0-indexed) of logging, log an event for event code k,
//   1 <= k < 5, if 3*k divides i.
//
// Each day following the first day, generates Observations for the previous
// day index and checks them against the expected set of Observations, then
// garbage-collects the LocalAggregateStore for the current day index.
//
// The EventsOccurred_UniqueDevices report has window sizes 1 and 7, and
// the expected pattern of those Observations' values on the i-th day is:
//
// (i, window size)            active for event codes
// ------------------------------------------------------
// (0, 1)                           1, 2, 3, 4
// (0, 7)                           1, 2, 3, 4
// (1, 1)                          ---
// (1, 7)                           1, 2, 3, 4
// (2, 1)                          ---
// (2, 7)                           1, 2, 3, 4
// (3, 1)                           1
// (3, 7)                           1, 2, 3, 4
// (4, 1)                          ---
// (4, 7)                           1, 2, 3, 4
// (5, 1)                          ---
// (5, 7)                           1, 2, 3, 4
// (6, 1)                           1, 2
// (6, 7)                           1, 2, 3, 4
// (7, 1)                          ---
// (7, 7)                           1, 2
// (8, 1)                          ---
// (8, 7)                           1, 2
// (9, 1)                           1, 3
// (9, 7)                           1, 2, 3
//
// All Observations for all other locally aggregated reports should be
// observations of non-occurrence.
TEST_F(UniqueActivesLoggerTest, CheckUniqueActivesObsValuesMultiDay) {
  const auto& expected_id = testing::unique_actives_noise_free::kEventsOccurredMetricReportId;
  const auto start_day_index = CurrentDayIndex(MetricDefinition::UTC);

  // Form expected Observations for the 10 days of logging.
  std::vector<ExpectedUniqueActivesObservations> expected_obs(10);
  for (uint32_t i = 0; i < expected_obs.size(); i++) {
    expected_obs[i] = MakeNullExpectedUniqueActivesObservations(expected_aggregation_params_,
                                                                start_day_index + i);
  }
  expected_obs[0][{expected_id, start_day_index}] = {{1, {false, true, true, true, true}},
                                                     {7, {false, true, true, true, true}}};
  expected_obs[1][{expected_id, start_day_index + 1}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[2][{expected_id, start_day_index + 2}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[3][{expected_id, start_day_index + 3}] = {{1, {false, true, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[4][{expected_id, start_day_index + 4}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[5][{expected_id, start_day_index + 5}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[6][{expected_id, start_day_index + 6}] = {{1, {false, true, true, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[7][{expected_id, start_day_index + 7}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, false, false}}};
  expected_obs[8][{expected_id, start_day_index + 8}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, false, false}}};
  expected_obs[9][{expected_id, start_day_index + 9}] = {{1, {false, true, false, true, false}},
                                                         {7, {false, true, true, true, false}}};

  for (uint32_t i = 0; i < 10; i++) {
    if (i < 10) {
      for (uint32_t event_code = 1; event_code < 5; event_code++) {
        if (i % (3 * event_code) == 0) {
          ASSERT_EQ(
              StatusCode::OK,
              LogEvent(testing::unique_actives_noise_free::kEventsOccurredMetricId, event_code)
                  .error_code());
        }
      }
    }
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Advance the Logger's clock by 1 day.
    AdvanceDay(1);
    // Generate locally aggregated Observations for the previous day
    // index.
    ASSERT_EQ(
        StatusCode::OK,
        event_aggregator_mgr_->GenerateObservations((CurrentDayIndex(MetricDefinition::UTC) - 1))
            .error_code());
    // Check the generated Observations against the expectation.
    EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[i], *observation_store_,
                                               update_recipient_.get()));
    // Garbage-collect the LocalAggregateStore for the current day index.
    ASSERT_EQ(
        StatusCode::OK,
        event_aggregator_mgr_->GarbageCollect(CurrentDayIndex(MetricDefinition::UTC)).error_code());
  }
}

// Generate Observations without logging any events, and check that the
// resulting Observations are as expected: 1 ReportParticipationObservation for
// each PER_DEVICE_NUMERIC_STATS report in the config, and no
// PerDeviceNumericObservations.
TEST_F(PerDeviceNumericEventCountEventLoggerTest, CheckPerDeviceNumericObsValuesNoEvents) {
  const auto day_index = CurrentDayIndex(MetricDefinition::UTC);
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
  const auto& expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      testing::per_device_numeric_stats::kExpectedAggregationParams, day_index);
  EXPECT_TRUE(CheckPerDeviceNumericObservations({}, expected_report_participation_obs,
                                                *observation_store_, update_recipient_.get()));
}

// Tests that Observations with the expected values are generated when events
// have been logged for EVENT_COUNT metrics with a PER_DEVICE_NUMERIC_STATS
// report, on a single day.
TEST_F(PerDeviceNumericEventCountEventLoggerTest, CheckPerDeviceNumericObsValuesSingleDay) {
  const auto day_index = CurrentDayIndex(MetricDefinition::UTC);

  // Log several events on |day_index|.
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kConnectionFailuresMetricId, {0},
                          "component_A", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kConnectionFailuresMetricId, {0},
                          "component_B", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kConnectionFailuresMetricId, {0},
                          "component_A", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kConnectionFailuresMetricId, {1},
                          "component_A", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kSettingsChangedMetricId, {0},
                          "component_C", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kSettingsChangedMetricId, {0},
                          "component_C", 0, 5)
                .error_code());
  // The ConnectionFailures metric has an immediate report of type
  // EVENT_COMPONENT_OCCURRENCE_COUNT. Check that 4 immediate Observations were
  // generated for that report.
  std::vector<Observation> immediate_observations(4);
  std::vector<uint32_t> expected_immediate_report_ids(
      4,
      testing::per_device_numeric_stats::kConnectionFailuresConnectionFailuresGlobalCountReportId);
  EXPECT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                *observation_store_, update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();
  // Generate locally aggregated Observations for |day_index|.
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
  // Form the expected locally aggregated Observations.
  auto expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      testing::per_device_numeric_stats::kExpectedAggregationParams, day_index);
  ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kConnectionFailuresMetricReportId, day_index}][1] = {
      {"component_A", 0u, 10}, {"component_A", 1u, 5}, {"component_B", 0u, 5}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId, day_index}][7] =
      {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId, day_index}][30] =
      {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId,
      day_index}][7] = {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId,
      day_index}][30] = {{"component_C", 0u, 10}};
  EXPECT_TRUE(CheckPerDeviceNumericObservations(expected_per_device_numeric_obs,
                                                expected_report_participation_obs,
                                                *observation_store_, update_recipient_.get()));
}

// Tests that Observations with the expected values are generated when events
// have been logged for a FRAME_RATE metric with a PER_DEVICE_NUMERIC_STATS
// report, on a single day.
TEST_F(PerDeviceNumericFrameRateEventLoggerTest, CheckPerDeviceNumericObsValuesFrameRateSingleDay) {
  const auto day_index = CurrentDayIndex(MetricDefinition::UTC);
  // Log several events on |day_index|.
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_A", 5000)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_B", 4200)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_A", 3750)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {1},
                         "component_A", 2000)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_C", 7900)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_C", 4000)
                .error_code());
  // The LoginModuleFrameRate metric has an immediate report of type
  // NUMERIC_AGGREGATION. Check that 6 immediate Observations were
  // generated for that report.
  std::vector<Observation> immediate_observations(6);
  std::vector<uint32_t> expected_immediate_report_ids(
      6, testing::per_device_numeric_stats::
             kLoginModuleFrameRateLoginModuleFrameRateAggregatedReportId);
  EXPECT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                *observation_store_, update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();
  // Generate locally aggregated Observations for |day_index|.
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
  // Form the expected locally aggregated Observations.
  auto expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      testing::per_device_numeric_stats::kExpectedAggregationParams, day_index);
  ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kLoginModuleFrameRateMinMetricReportId, day_index}][1] = {
      {"component_A", 0u, 3750},
      {"component_A", 1u, 2000},
      {"component_B", 0u, 4200},
      {"component_C", 0u, 4000}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kLoginModuleFrameRateMinMetricReportId, day_index}][7] = {
      {"component_A", 0u, 3750},
      {"component_A", 1u, 2000},
      {"component_B", 0u, 4200},
      {"component_C", 0u, 4000}};
  EXPECT_TRUE(CheckPerDeviceNumericObservations(expected_per_device_numeric_obs,
                                                expected_report_participation_obs,
                                                *observation_store_, update_recipient_.get()));
}

// Tests that Observations with the expected values are generated when events
// have been logged for a MEMORY_USAGE metric with a PER_DEVICE_NUMERIC_STATS
// report, on a single day.
TEST_F(PerDeviceNumericMemoryUsageEventLoggerTest,
       CheckPerDeviceNumericObsValuesMemoryUsageSingleDay) {
  const auto day_index = CurrentDayIndex(MetricDefinition::UTC);
  // Log several events on |day_index|.
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_A", 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_B", 4)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_A", 3)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{1u, 0u}, "component_A", 2)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_C", 7)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_C", 4)
                .error_code());
  // The LedgerMemoryUsage metric has an immediate report of type
  // NUMERIC_AGGREGATION. Check that 6 immediate Observations were
  // generated for that report.
  std::vector<Observation> immediate_observations(6);
  std::vector<uint32_t> expected_immediate_report_ids(
      6, testing::per_device_numeric_stats::kLedgerMemoryUsageLedgerMemoryUsageAggregatedReportId);
  EXPECT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                *observation_store_, update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();
  // Generate locally aggregated Observations for |day_index|.
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
  // Form the expected locally aggregated Observations.
  auto expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      testing::per_device_numeric_stats::kExpectedAggregationParams, day_index);
  ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kLedgerMemoryUsageMaxMetricReportId, day_index}][1] = {
      {"component_A", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 5},
      {"component_A", PackEventCodes(std::vector<uint32_t>{1u, 0u}), 2},
      {"component_B", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 4},
      {"component_C", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 7}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kLedgerMemoryUsageMaxMetricReportId, day_index}][7] = {
      {"component_A", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 5},
      {"component_A", PackEventCodes(std::vector<uint32_t>{1u, 0u}), 2},
      {"component_B", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 4},
      {"component_C", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 7}};

  EXPECT_TRUE(CheckPerDeviceNumericObservations(expected_per_device_numeric_obs,
                                                expected_report_participation_obs,
                                                *observation_store_, update_recipient_.get()));
}

// Checks that PerDeviceNumericObservations with the expected values are
// generated when some events have been logged for an EVENT_COUNT metric with a
// PER_DEVICE_NUMERIC_STATS report over multiple days and
// GenerateAggregatedObservations(() is called each day).
//
// Logged events for the SettingsChanged_PerDeviceCount metric on the i-th day:
//
//  i            (component, event code, count)
// -----------------------------------------------------------------------
//  0
//  1          ("A", 1, 3)
//  2          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
//  3          ("A", 1, 3)
//  4          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//  5          ("A", 1, 3)
//  6          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
//  7          ("A", 1, 3)
//  8          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//  9          ("A", 1, 3)
//
// Expected PerDeviceNumericObservations for the SettingsChanged_PerDeviceCount
// report on the i-th day:
//
// (i, window size)          (component, event code, count)
// -----------------------------------------------------------------------
// (0, 7)
// (0, 30)
// (1, 7)     ("A", 1,  3)
// (1, 30)    ("A", 1,  3)
// (2, 7)     ("A", 1,  6),  ("A", 2,  3), ("B", 1, 2)
// (2, 30)    ("A", 1,  6),  ("A", 2,  3), ("B", 1, 2)
// (3, 7)     ("A", 1,  9),  ("A", 2,  3), ("B", 1, 2)
// (3, 30)    ("A", 1,  9),  ("A", 2,  3), ("B", 1, 2)
// (4, 7)     ("A", 1, 12),  ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (4, 30)    ("A", 1, 12),  ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (5, 7)     ("A", 1, 15),  ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (5, 30)    ("A", 1, 15),  ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (6, 7)     ("A", 1, 18),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (6, 30)    ("A", 1, 18),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (7, 7)     ("A", 1, 21),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (7, 30)    ("A", 1, 21),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (8, 7)     ("A", 1, 21),  ("A", 2, 12), ("B", 1, 8), ("B", 2, 4)
// (8, 30)    ("A", 1, 24),  ("A", 2, 12), ("B", 1, 8), ("B", 2, 4)
// (9, 7)     ("A", 1, 21),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 4)
// (9, 30)    ("A", 1, 27),  ("A", 2, 12), ("B", 1, 8), ("B", 2, 4)
//
// In addition, expect 1 ReportParticipationObservations for each day, for each
// report in the registry.
TEST_F(PerDeviceNumericEventCountEventLoggerTest, CheckPerDeviceNumericObsValuesMultiDay) {
  const auto start_day_index = CurrentDayIndex(MetricDefinition::UTC);
  std::vector<MetricReportId> expected_ids = {
      testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
      testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId};
  // Form expected Observations for the 10 days of logging.
  uint32_t num_days = 10;
  std::vector<ExpectedPerDeviceNumericObservations> expected_per_device_numeric_obs(num_days);
  std::vector<ExpectedReportParticipationObservations> expected_report_participation_obs(num_days);
  for (uint32_t offset = 0; offset < num_days; offset++) {
    expected_report_participation_obs[offset] = MakeExpectedReportParticipationObservations(
        expected_aggregation_params_, start_day_index + offset);
  }
  expected_per_device_numeric_obs[0] = {};
  for (auto expected_id : expected_ids) {
    expected_per_device_numeric_obs[1][{expected_id, start_day_index + 1}] = {{7, {{"A", 1u, 3}}},
                                                                              {30, {{"A", 1u, 3}}}};
    expected_per_device_numeric_obs[2][{expected_id, start_day_index + 2}] = {
        {7, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}},
        {30, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}}};
    expected_per_device_numeric_obs[3][{expected_id, start_day_index + 3}] = {
        {7, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}},
        {30, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}}};
    expected_per_device_numeric_obs[4][{expected_id, start_day_index + 4}] = {
        {7, {{"A", 1u, 12}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}},
        {30, {{"A", 1u, 12}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}}};
    expected_per_device_numeric_obs[5][{expected_id, start_day_index + 5}] = {
        {7, {{"A", 1u, 15}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}},
        {30, {{"A", 1u, 15}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}}};
    expected_per_device_numeric_obs[6][{expected_id, start_day_index + 6}] = {
        {7, {{"A", 1u, 18}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}},
        {30, {{"A", 1u, 18}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}}};
    expected_per_device_numeric_obs[7][{expected_id, start_day_index + 7}] = {
        {7, {{"A", 1u, 21}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}},
        {30, {{"A", 1u, 21}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}}};
    expected_per_device_numeric_obs[8][{expected_id, start_day_index + 8}] = {
        {7, {{"A", 1u, 21}, {"A", 2u, 12}, {"B", 1u, 8}, {"B", 2u, 4}}},
        {30, {{"A", 1u, 24}, {"A", 2u, 12}, {"B", 1u, 8}, {"B", 2u, 4}}}};
    expected_per_device_numeric_obs[9][{expected_id, start_day_index + 9}] = {
        {7, {{"A", 1u, 21}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 4}}},
        {30, {{"A", 1u, 27}, {"A", 2u, 12}, {"B", 1u, 8}, {"B", 2u, 4}}}};
  }
  for (uint32_t offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex(MetricDefinition::UTC);
    for (uint32_t event_code = 1; event_code < 3; event_code++) {
      if (offset > 0 && offset % event_code == 0) {
        EXPECT_EQ(StatusCode::OK,
                  LogEventCount(testing::per_device_numeric_stats::kSettingsChangedMetricId,
                                {event_code}, "A", 0, 3)
                      .error_code());
      }
      if (offset > 0 && offset % (2 * event_code) == 0) {
        EXPECT_EQ(StatusCode::OK,
                  LogEventCount(testing::per_device_numeric_stats::kSettingsChangedMetricId,
                                {event_code}, "B", 0, 2)
                      .error_code());
      }
    }
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Generate locally aggregated Observations.
    EXPECT_EQ(StatusCode::OK,
              event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
    EXPECT_TRUE(CheckPerDeviceNumericObservations(expected_per_device_numeric_obs[offset],
                                                  expected_report_participation_obs[offset],
                                                  *observation_store_, update_recipient_.get()))
        << "offset = " << offset;
    AdvanceDay(1);
  }
}

// Tests that the expected Observations are generated when events are logged for
// over multiple days for an ELAPSED_TIME metric with PER_DEVICE_NUMERIC_STATS
// reports with multiple aggregation types, when Observations are backfilled for
// some days during that period, and when the LocalAggregatedStore is
// garbage-collected after each call to GenerateObservations().
//
// Logged events for the StreamingTime metric on the i-th day:
//
//  i            (component, event code, count)
// -----------------------------------------------------------------------
//  0
//  1          ("A", 1, 3)
//  2          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
//  3          ("A", 1, 3)
//  4          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//  5          ("A", 1, 3)
//  6          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
//  7          ("A", 1, 3)
//  8          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//
// Expected PerDeviceNumericObservations for the
// StreamingTime_PerDeviceTotal report on the i-th day:
//
// (day, window size)            (event code, component, total)
// ---------------------------------------------------------------------------
// (0, 1)
// (0, 7)
// (1, 1)     ("A", 1,  3)
// (1, 7)     ("A", 1,  3)
// (2, 1)     ("A", 1,  3), ("A", 2,  3), ("B", 1, 2)
// (2, 7)     ("A", 1,  6), ("A", 2,  3), ("B", 1, 2)
// (3, 1)     ("A", 1,  3)
// (3, 7)     ("A", 1,  9), ("A", 2,  3), ("B", 1, 2)
// (4, 1)     ("A", 1,  3), ("A", 2,  3), ("B", 1, 2), ("B", 2, 2)
// (4, 7)     ("A", 1, 12), ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (5, 1)     ("A", 1,  3)
// (5, 7)     ("A", 1, 15), ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (6, 1)     ("A", 1,  3), ("A", 2,  3), ("B", 1, 2)
// (6, 7)     ("A", 1, 18), ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (7, 1)     ("A", 1,  3)
// (7, 7)     ("A", 1, 21), ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (8, 1)     ("A", 1,  3), ("A", 2,  3), ("B", 1, 2), ("B", 2, 2)
// (8, 7)     ("A", 1, 21), ("A", 2, 12), ("B", 1, 8), ("B", 2, 4)
//
//
// Expected PerDeviceNumericObservations for the
// StreamingTime_PerDeviceMin report on the i-th day:
//
// (day, window size)            (event code, component, total)
// ---------------------------------------------------------------------------
// (0, 1)
// (0. 7)
// (1, 1)     ("A", 1, 3)
// (1, 7)     ("A", 1, 3)
// (2, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (2, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (3, 1)     ("A", 1, 3)
// (3, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (4, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (4, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (5, 1)     ("A", 1, 3)
// (5, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (6, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (6, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (7, 1)     ("A", 1, 3)
// (7, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (8, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (8, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//
// Expected PerDeviceNumericObservations for the
// StreamingTime_PerDeviceMax report on the i-th day:
//
// (day, window size)            (event code, component, total)
// ---------------------------------------------------------------------------
// (0, 1)
// (0. 7)
// (1, 1)     ("A", 1, 3)
// (1, 7)     ("A", 1, 3)
// (2, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (2, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (3, 1)     ("A", 1, 3)
// (3, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (4, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (4, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (5, 1)     ("A", 1, 3)
// (5, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (6, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (6, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (7, 1)     ("A", 1, 3)
// (7, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (8, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (8, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//
// In addition, expect 1 ReportParticipationObservation each day for each
// report in the registry.
TEST_F(PerDeviceNumericElapsedTimeEventLoggerTest, ElapsedTimeCheckObservationValues) {
  const auto start_day_index = CurrentDayIndex(MetricDefinition::UTC);
  const auto& total_report_id =
      testing::per_device_numeric_stats::kStreamingTimeTotalMetricReportId;
  const auto& min_report_id = testing::per_device_numeric_stats::kStreamingTimeMinMetricReportId;
  const auto& max_report_id = testing::per_device_numeric_stats::kStreamingTimeMaxMetricReportId;
  // Form expected Observations for the 9 days of logging.
  uint32_t num_days = 9;
  std::vector<ExpectedPerDeviceNumericObservations> expected_per_device_numeric_obs(num_days);
  std::vector<ExpectedReportParticipationObservations> expected_report_participation_obs(num_days);

  for (uint32_t offset = 0; offset < num_days; offset++) {
    expected_report_participation_obs[offset] = MakeExpectedReportParticipationObservations(
        expected_aggregation_params_, start_day_index + offset);
  }
  expected_per_device_numeric_obs[0] = {};
  expected_per_device_numeric_obs[1][{total_report_id, start_day_index + 1}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}}}};
  expected_per_device_numeric_obs[2][{total_report_id, start_day_index + 2}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[3][{total_report_id, start_day_index + 3}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[4][{total_report_id, start_day_index + 4}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 12}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[5][{total_report_id, start_day_index + 5}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 15}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[6][{total_report_id, start_day_index + 6}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 18}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[7][{total_report_id, start_day_index + 7}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 21}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[8][{total_report_id, start_day_index + 8}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 21}, {"A", 2u, 12}, {"B", 1u, 8}, {"B", 2u, 4}}}};

  expected_per_device_numeric_obs[1][{min_report_id, start_day_index + 1}] = {{1, {{"A", 1u, 3}}},
                                                                              {7, {{"A", 1u, 3}}}};
  expected_per_device_numeric_obs[2][{min_report_id, start_day_index + 2}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[3][{min_report_id, start_day_index + 3}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[4][{min_report_id, start_day_index + 4}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[5][{min_report_id, start_day_index + 5}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[6][{min_report_id, start_day_index + 6}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[7][{min_report_id, start_day_index + 7}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[8][{min_report_id, start_day_index + 8}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};

  expected_per_device_numeric_obs[8][{max_report_id, start_day_index + 8}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[1][{max_report_id, start_day_index + 1}] = {{1, {{"A", 1u, 3}}},
                                                                              {7, {{"A", 1u, 3}}}};
  expected_per_device_numeric_obs[2][{max_report_id, start_day_index + 2}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[3][{max_report_id, start_day_index + 3}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[4][{max_report_id, start_day_index + 4}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[5][{max_report_id, start_day_index + 5}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[6][{max_report_id, start_day_index + 6}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[7][{max_report_id, start_day_index + 7}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[8][{max_report_id, start_day_index + 8}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};

  for (uint32_t offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex(MetricDefinition::UTC);
    for (uint32_t event_code = 1; event_code < 3; event_code++) {
      if (offset > 0 && offset % event_code == 0) {
        EXPECT_EQ(StatusCode::OK,
                  LogElapsedTime(testing::per_device_numeric_stats::kStreamingTimeMetricId,
                                 {event_code}, "A", 3)
                      .error_code());
      }
      if (offset > 0 && offset % (2 * event_code) == 0) {
        EXPECT_EQ(StatusCode::OK,
                  LogElapsedTime(testing::per_device_numeric_stats::kStreamingTimeMetricId,
                                 {event_code}, "B", 2)
                      .error_code());
      }
    }
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Generate locally aggregated Observations.
    EXPECT_EQ(StatusCode::OK,
              event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
    EXPECT_TRUE(CheckPerDeviceNumericObservations(expected_per_device_numeric_obs[offset],
                                                  expected_report_participation_obs[offset],
                                                  *observation_store_, update_recipient_.get()))
        << "offset = " << offset;
    AdvanceDay(1);
  }
}

// Tests that the expected number of locally aggregated Observations are
// generated when no events have been logged.
TEST_F(EventOccurredEventLoggerTest, CheckNumAggregatedObsNoEvents) {
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((CurrentDayIndex(MetricDefinition::UTC)))
                .error_code());
  std::vector<Observation> observations(0);
  EXPECT_TRUE(FetchAggregatedObservations(&observations, expected_aggregation_params_,
                                          *observation_store_, update_recipient_.get()));
}

// Tests that the expected number of locally aggregated Observations are
// generated when one Event has been logged for a locally aggregated report.
TEST_F(EventOccurredEventLoggerTest, CheckNumAggregatedObsOneEvent) {
  // Log 1 occurrence of event code 0 for the DeviceBoots metric, which has no
  // immediate reports.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kDeviceBootsMetricId, 0).error_code());
  // Check that no immediate Observation was generated.
  std::vector<Observation> immediate_observations(0);
  std::vector<uint32_t> expected_immediate_report_ids = {};
  ASSERT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                *observation_store_, update_recipient_.get()));
  // Generate locally aggregated observations for the current day index.
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((CurrentDayIndex(MetricDefinition::UTC)))
                .error_code());
  // Check that the expected numbers of aggregated observations were generated.
  std::vector<Observation> aggregated_observations;
  EXPECT_TRUE(FetchAggregatedObservations(&aggregated_observations, expected_aggregation_params_,
                                          *observation_store_, update_recipient_.get()));
}

// Tests that the expected number of locally aggregated Observations are
// generated when multiple Events have been logged for locally aggregated
// and immediate reports.
TEST_F(EventOccurredEventLoggerTest, CheckNumAggregatedObsImmediateAndAggregatedEvents) {
  // Log 3 occurrences of event codes for the EventsOccurred metric, which
  // has 1 locally aggregated report and 1 immediate report.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kEventsOccurredMetricId, 0).error_code());
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kEventsOccurredMetricId, 0).error_code());
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kEventsOccurredMetricId, 2).error_code());
  // Check that each of the 3 logged events resulted in an immediate
  // Observation.
  std::vector<Observation> immediate_observations(3);
  std::vector<uint32_t> expected_immediate_report_ids(
      3, testing::all_report_types::kEventsOccurredEventsOccurredGlobalCountReportId);
  ASSERT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                *observation_store_, update_recipient_.get()));
  // Clear the FakeObservationStore.
  ResetObservationStore();
  // Generate locally aggregated observations for the current day index.
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((CurrentDayIndex(MetricDefinition::UTC)))
                .error_code());
  // Check that the expected aggregated observations were generated.
  std::vector<Observation> observations;
  EXPECT_TRUE(FetchAggregatedObservations(&observations, expected_aggregation_params_,
                                          *observation_store_, update_recipient_.get()));
}

// needed for Friend class status
namespace internal {

class EventLoggersAddEventTest : public util::testing::TestWithFiles {
 public:
  void SetUp() override {
    MakeTestFolder();
    observation_store_ = std::make_unique<FakeObservationStore>();
    update_recipient_ = std::make_unique<TestUpdateRecipient>();
    observation_encrypter_ = EncryptedMessageMaker::MakeUnencrypted();
    observation_writer_ = std::make_unique<ObservationWriter>(
        *observation_store_, update_recipient_.get(), observation_encrypter_.get());
    metadata_builder_ =
        std::make_unique<MetadataBuilder>(system_data_, system_data_cache_path(), fs());
    encoder_ = std::make_unique<Encoder>(ClientSecret::GenerateNewSecret(), *metadata_builder_);
    project_context_factory_ =
        GetTestProjectContextFactory(testing::per_device_histogram::kCobaltRegistryBase64);
    project_context_ = GetTestProject(testing::per_device_histogram::kCobaltRegistryBase64);
    // Create a mock clock which does not increment by default when called.
    // Set the time to 1 year after the start of Unix time so that the start
    // date of any aggregation window falls after the start of time.
    mock_clock_ = std::make_unique<IncrementingSystemClock>(std::chrono::system_clock::duration(0));
    mock_clock_->set_time(std::chrono::system_clock::time_point(std::chrono::seconds(kYear)));
    civil_time_converter_ = std::make_unique<util::UtcTimeConverter>();
    CobaltConfig cfg = {.client_secret = system_data::ClientSecret::GenerateNewSecret()};

    cfg.local_aggregation_backfill_days = 0;
    cfg.local_aggregate_proto_store_path = aggregate_store_path();
    cfg.obs_history_proto_store_path = obs_history_path();

    event_aggregator_mgr_ = std::make_unique<TestEventAggregatorManager>(
        cfg, fs(), *encoder_, *observation_writer_, *metadata_builder_);
    event_aggregator_mgr_->GetEventAggregator().UpdateAggregationConfigs(*project_context_);
    local_aggregation_ = std::make_unique<LocalAggregation>(
        cfg, project_context_factory_.get(), system_data_, *metadata_builder_, fs(),
        *observation_writer_, *civil_time_converter_);
  }

  std::unique_ptr<EventLogger> GetEventLoggerForMetricType(
      MetricDefinition::MetricType metric_type) {
    auto logger = EventLogger::Create(
        metric_type, *encoder_, event_aggregator_mgr_->GetEventAggregator(), *local_aggregation_,
        *observation_writer_, system_data_, *civil_time_converter_);
    return logger;
  }

  std::unique_ptr<EventRecord> GetEventRecordWithMetricType(
      uint32_t metric_id, MetricDefinition::MetricType metric_type) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();

    switch (metric_type) {
      case (MetricDefinition::EVENT_COUNT): {
        EventCountEvent* event = event_record->event()->mutable_event_count_event();
        event->set_component("test");
        event->set_period_duration_micros(10);
        event->set_count(1);
        break;
      }
      case (MetricDefinition::ELAPSED_TIME): {
        ElapsedTimeEvent* event = event_record->event()->mutable_elapsed_time_event();
        event->set_component("test");
        event->set_elapsed_micros(10);
        break;
      }
      case (MetricDefinition::MEMORY_USAGE): {
        MemoryUsageEvent* event = event_record->event()->mutable_memory_usage_event();
        event->set_component("test");
        event->set_bytes(10);
        break;
      }
      case (MetricDefinition::FRAME_RATE): {
        FrameRateEvent* event = event_record->event()->mutable_frame_rate_event();
        event->set_component("test");
        event->set_frames_per_1000_seconds(10);
        break;
      }
      default: {
      }
    }

    return event_record;
  }

  static ReportDefinition ReportDefinitionWithReportType(uint32_t report_id,
                                                         ReportDefinition::ReportType report_type) {
    ReportDefinition report_definition;
    report_definition.set_report_type(report_type);
    report_definition.set_id(report_id);
    return report_definition;
  }

  static Encoder::Result MaybeEncodeImmediateObservation(EventLogger* event_logger,
                                                         const ReportDefinition& report,
                                                         EventRecord* event_record) {
    return event_logger->MaybeEncodeImmediateObservation(report, /*may_invalidate=*/false,
                                                         event_record);
  }

  static Status MaybeUpdateLocalAggregation(EventLogger* event_logger,
                                            const ReportDefinition& report,
                                            const EventRecord& event_record) {
    return event_logger->MaybeUpdateLocalAggregation(report, event_record);
  }

 protected:
  std::unique_ptr<ObservationWriter> observation_writer_;
  std::unique_ptr<FakeObservationStore> observation_store_;
  std::unique_ptr<TestUpdateRecipient> update_recipient_;
  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<Encoder> encoder_;
  std::unique_ptr<EncryptedMessageMaker> observation_encrypter_;
  system_data::FakeSystemData system_data_;
  std::unique_ptr<IncrementingSystemClock> mock_clock_;
  std::unique_ptr<util::UtcTimeConverter> civil_time_converter_;
  std::unique_ptr<ProjectContextFactory> project_context_factory_;
  std::shared_ptr<ProjectContext> project_context_;
  std::unique_ptr<TestEventAggregatorManager> event_aggregator_mgr_;
  std::unique_ptr<LocalAggregation> local_aggregation_;
};

TEST_F(EventLoggersAddEventTest, EventCountPerDeviceHistogramNoImmediateObservation) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kSettingsChangedSettingsChangedPerDeviceHistogramReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kSettingsChangedMetricId, MetricDefinition::EVENT_COUNT);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::EVENT_COUNT);
  auto result = MaybeEncodeImmediateObservation(event_logger.get(), report, event_record.get());

  EXPECT_EQ(StatusCode::OK, result.status.error_code());
  EXPECT_EQ(nullptr, result.observation);
  EXPECT_EQ(nullptr, result.metadata);
  EXPECT_EQ(0, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, EventCountPerDeviceHistogramAddToEventAggregator) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kSettingsChangedSettingsChangedPerDeviceHistogramReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kSettingsChangedMetricId, MetricDefinition::EVENT_COUNT);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::EVENT_COUNT);
  auto status = MaybeUpdateLocalAggregation(event_logger.get(), report, *event_record);

  EXPECT_EQ(StatusCode::OK, status.error_code());
  EXPECT_EQ(1, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, ElapsedTimePerDeviceHistogramNoImmediateObservation) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kStreamingTimeStreamingTimePerDeviceTotalReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kStreamingTimeMetricId, MetricDefinition::ELAPSED_TIME);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::ELAPSED_TIME);
  auto result = MaybeEncodeImmediateObservation(event_logger.get(), report, event_record.get());

  EXPECT_EQ(StatusCode::OK, result.status.error_code());
  EXPECT_EQ(nullptr, result.observation);
  EXPECT_EQ(nullptr, result.metadata);
  EXPECT_EQ(0, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, ElapsedTimePerDeviceHistogramAddToEventAggregator) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kStreamingTimeStreamingTimePerDeviceTotalReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kStreamingTimeMetricId, MetricDefinition::ELAPSED_TIME);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::ELAPSED_TIME);
  auto status = MaybeUpdateLocalAggregation(event_logger.get(), report, *event_record);

  EXPECT_EQ(StatusCode::OK, status.error_code());
  EXPECT_EQ(1, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, FrameRatePerDeviceHistogramNoImmediateObservation) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kLoginModuleFrameRateLoginModuleFrameRatePerDeviceMinReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kLoginModuleFrameRateMetricId, MetricDefinition::FRAME_RATE);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::FRAME_RATE);
  auto result = MaybeEncodeImmediateObservation(event_logger.get(), report, event_record.get());

  EXPECT_EQ(StatusCode::OK, result.status.error_code());
  EXPECT_EQ(nullptr, result.observation);
  EXPECT_EQ(nullptr, result.metadata);
  EXPECT_EQ(0, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, FrameRatePerDeviceHistogramAddToEventAggregator) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kLoginModuleFrameRateLoginModuleFrameRatePerDeviceMinReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kLoginModuleFrameRateMetricId, MetricDefinition::FRAME_RATE);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::FRAME_RATE);
  auto status = MaybeUpdateLocalAggregation(event_logger.get(), report, *event_record);

  EXPECT_EQ(StatusCode::OK, status.error_code());
  EXPECT_EQ(1, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, MemoryUsagePerDeviceHistogramNoImmediateObservation) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kLedgerMemoryUsageLedgerMemoryUsagePerDeviceMaxReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kLedgerMemoryUsageMetricId, MetricDefinition::MEMORY_USAGE);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::MEMORY_USAGE);
  auto result = MaybeEncodeImmediateObservation(event_logger.get(), report, event_record.get());

  EXPECT_EQ(StatusCode::OK, result.status.error_code());
  EXPECT_EQ(nullptr, result.observation);
  EXPECT_EQ(nullptr, result.metadata);
  EXPECT_EQ(0, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, MemoryUsagePerDeviceHistogramAddToEventAggregator) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kLedgerMemoryUsageLedgerMemoryUsagePerDeviceMaxReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kLedgerMemoryUsageMetricId, MetricDefinition::MEMORY_USAGE);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::MEMORY_USAGE);
  auto status = MaybeUpdateLocalAggregation(event_logger.get(), report, *event_record);

  EXPECT_EQ(StatusCode::OK, status.error_code());
  EXPECT_EQ(1, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

class EventLoggersLocalAggregationTest : public util::testing::TestWithFiles {
 public:
  void SetUp() override {
    MakeTestFolder();
    observation_store_ = std::make_unique<FakeObservationStore>();
    update_recipient_ = std::make_unique<TestUpdateRecipient>();
    observation_encrypter_ = EncryptedMessageMaker::MakeUnencrypted();
    observation_writer_ = std::make_unique<ObservationWriter>(
        *observation_store_, update_recipient_.get(), observation_encrypter_.get());
    metadata_builder_ =
        std::make_unique<MetadataBuilder>(system_data_, system_data_cache_path(), fs());
    encoder_ = std::make_unique<Encoder>(ClientSecret::GenerateNewSecret(), *metadata_builder_);
    project_context_factory_ =
        GetTestProjectContextFactory(testing::cobalt_new::kCobaltRegistryBase64);
    project_context_ = GetTestProject(testing::cobalt_new::kCobaltRegistryBase64);
    // Create a mock clock which does not increment by default when called.
    // Set the time to 1 year after the start of Unix time so that the start
    // date of any aggregation window falls after the start of time.
    mock_clock_ = std::make_unique<IncrementingSystemClock>(std::chrono::system_clock::duration(0));
    start_time_ = std::chrono::system_clock::time_point(std::chrono::seconds(kYear));
    mock_clock_->set_time(start_time_);
    // Set the test local time converter to switch time zones 1 hour after `start_time_`.
    // This should only affect metrics with the OTHER_TIME_ZONE TimeZonePolicy.
    civil_time_converter_ = std::make_unique<util::FakeCivilTimeConverter>(
        /*start_utc_offset=*/0, /*start_isdst=*/false, /*end_utc_offset=*/1, /*end_isdst=*/true,
        /*threshold=*/start_time_ + util::kOneHour);

    CobaltConfig cfg = {.client_secret = system_data::ClientSecret::GenerateNewSecret()};

    cfg.local_aggregation_backfill_days = 0;
    cfg.local_aggregate_proto_store_path = aggregate_store_path();
    cfg.obs_history_proto_store_path = obs_history_path();
    cfg.local_aggregate_store_dir = local_aggregation_store_path();

    event_aggregator_mgr_ = std::make_unique<TestEventAggregatorManager>(
        cfg, fs(), *encoder_, *observation_writer_, *metadata_builder_);
    event_aggregator_mgr_->GetEventAggregator().UpdateAggregationConfigs(*project_context_);
    local_aggregation_ = std::make_unique<LocalAggregation>(
        cfg, project_context_factory_.get(), system_data_, *metadata_builder_, fs(),
        *observation_writer_, *civil_time_converter_);
  }

  local_aggregation::ImmediateLocalAggregateStorage GetLocalAggregateStorage() {
    return local_aggregation::ImmediateLocalAggregateStorage(local_aggregation_store_path(), fs(),
                                                             project_context_factory_.get(),
                                                             *metadata_builder_, 0);
  }

  local_aggregation::ReportAggregate GetReportAggregate(
      uint32_t metric_id, MetricDefinition::MetricType metric_type, uint32_t report_id,
      local_aggregation::LocalAggregateStorage* store) {
    std::unique_ptr<EventRecord> event_record =
        GetEventRecordWithMetricType(metric_id, metric_type);
    local_aggregation::LocalAggregateStorage::MetricAggregateRef aggregate =
        store->GetMetricAggregate(event_record->MetricIdentifier()).ConsumeValueOrDie();
    return aggregate.aggregate()->by_report_id().at(report_id);
  }

  std::unique_ptr<EventLogger> GetEventLoggerForMetricType(
      MetricDefinition::MetricType metric_type) {
    auto logger = EventLogger::Create(
        metric_type, *encoder_, event_aggregator_mgr_->GetEventAggregator(), *local_aggregation_,
        *observation_writer_, system_data_, *civil_time_converter_);
    return logger;
  }

  std::unique_ptr<EventRecord> GetEventRecordWithMetricType(
      uint32_t metric_id, MetricDefinition::MetricType metric_type) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();

    switch (metric_type) {
      case (MetricDefinition::OCCURRENCE): {
        OccurrenceEvent* event = event_record->event()->mutable_occurrence_event();
        event->set_count(1);
        break;
      }
      case (MetricDefinition::INTEGER): {
        IntegerEvent* event = event_record->event()->mutable_integer_event();
        event->set_value(10);
        break;
      }
      case (MetricDefinition::INTEGER_HISTOGRAM): {
        IntegerHistogramEvent* event = event_record->event()->mutable_integer_histogram_event();
        event->mutable_buckets()->Swap(
            testing::NewHistogram({0, 1, 2, 3}, {100, 101, 102, 103}).get());
        break;
      }
      case (MetricDefinition::STRING): {
        StringEvent* event = event_record->event()->mutable_string_event();
        event->set_string_value("component4");
        break;
      }
      default: {
      }
    }

    return event_record;
  }

  static ReportDefinition ReportDefinitionWithReportType(uint32_t report_id,
                                                         ReportDefinition::ReportType report_type) {
    ReportDefinition report_definition;
    report_definition.set_report_type(report_type);
    report_definition.set_id(report_id);
    return report_definition;
  }

  static Status MaybeUpdateLocalAggregation(EventLogger* event_logger,
                                            const ReportDefinition& report,
                                            const EventRecord& event_record) {
    return event_logger->MaybeUpdateLocalAggregation(report, event_record);
  }

 protected:
  std::unique_ptr<ObservationWriter> observation_writer_;
  std::unique_ptr<FakeObservationStore> observation_store_;
  std::unique_ptr<TestUpdateRecipient> update_recipient_;
  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<Encoder> encoder_;
  std::unique_ptr<EncryptedMessageMaker> observation_encrypter_;
  system_data::FakeSystemData system_data_;
  std::unique_ptr<IncrementingSystemClock> mock_clock_;
  std::chrono::system_clock::time_point start_time_;
  std::unique_ptr<util::FakeCivilTimeConverter> civil_time_converter_;
  std::unique_ptr<ProjectContextFactory> project_context_factory_;
  std::shared_ptr<ProjectContext> project_context_;
  std::unique_ptr<TestEventAggregatorManager> event_aggregator_mgr_;
  std::unique_ptr<LocalAggregation> local_aggregation_;
};

TEST_F(EventLoggersLocalAggregationTest, OccurrenceUniqueDeviceHistogramsValidation) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kSettingsChangedMetricId,
                                                   MetricDefinition::OCCURRENCE);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::OCCURRENCE);
  EXPECT_EQ(StatusCode::OK,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kSettingsChangedMetricId,
                                          MetricDefinition::OCCURRENCE, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, OccurrenceUniqueDeviceHistogramsValidationWrongType) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kSettingsChangedMetricId,
                                                   MetricDefinition::INTEGER);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::OCCURRENCE);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kSettingsChangedMetricId,
                                          MetricDefinition::OCCURRENCE, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, OccurrenceUniqueDeviceHistograms) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kSettingsChangedSettingsChangedUniqueDeviceHistogramsReportId,
      ReportDefinition::UNIQUE_DEVICE_HISTOGRAMS);
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kSettingsChangedMetricId,
                                                   MetricDefinition::OCCURRENCE);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::OCCURRENCE);
  EXPECT_EQ(
      StatusCode::OK,
      event_logger->Log(std::move(event_record), std::chrono::system_clock::now()).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kSettingsChangedMetricId,
                                              MetricDefinition::OCCURRENCE);
  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate = GetReportAggregate(
      testing::cobalt_new::kSettingsChangedMetricId, MetricDefinition::OCCURRENCE,
      testing::cobalt_new::kSettingsChangedSettingsChangedUniqueDeviceHistogramsReportId, &store);
  ASSERT_TRUE(report_aggregate.has_daily());
  local_aggregation::AggregationPeriodBucket daily_bucket =
      report_aggregate.daily().by_day_index().begin()->second;
  local_aggregation::AggregateData data =
      daily_bucket.system_profile_aggregates(0).by_event_code().at(0).data();
  EXPECT_EQ(data.count(), 1);
}

TEST_F(EventLoggersLocalAggregationTest, IntegerFleetwideMeansValidation) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kStreamingTimeMetricId,
                                                   MetricDefinition::INTEGER);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER);
  EXPECT_EQ(StatusCode::OK,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kStreamingTimeMetricId,
                                          MetricDefinition::INTEGER, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, IntegerFleetwideMeansValidationWrongType) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kStreamingTimeMetricId,
                                                   MetricDefinition::OCCURRENCE);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kStreamingTimeMetricId,
                                          MetricDefinition::INTEGER, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, IntegerFleetwideMeans) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kStreamingTimeStreamingTimeAggregationReportId,
      ReportDefinition::FLEETWIDE_MEANS);
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kStreamingTimeMetricId,
                                                   MetricDefinition::INTEGER);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER);
  EXPECT_EQ(
      StatusCode::OK,
      event_logger->Log(std::move(event_record), std::chrono::system_clock::now()).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kStreamingTimeMetricId,
                                              MetricDefinition::INTEGER);
  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate = GetReportAggregate(
      testing::cobalt_new::kStreamingTimeMetricId, MetricDefinition::INTEGER,
      testing::cobalt_new::kStreamingTimeStreamingTimeAggregationReportId, &store);
  ASSERT_TRUE(report_aggregate.has_hourly());
  local_aggregation::AggregationPeriodBucket hourly_bucket =
      report_aggregate.hourly().by_hour_id().begin()->second;
  local_aggregation::AggregateData data =
      hourly_bucket.system_profile_aggregates(0).by_event_code().at(0).data();
  ASSERT_TRUE(data.has_sum_and_count());
  EXPECT_EQ(data.sum_and_count().sum(), 10);
}

TEST_F(EventLoggersLocalAggregationTest, IntegerHistogramFleetwideHistogramsValidation) {
  auto event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER_HISTOGRAM);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER_HISTOGRAM);
  EXPECT_EQ(StatusCode::OK,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kFileSystemWriteTimesMetricId,
                                          MetricDefinition::INTEGER_HISTOGRAM, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, IntegerHistogramFleetwideHistogramsValidationWrongType) {
  auto event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER_HISTOGRAM);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kFileSystemWriteTimesMetricId,
                                          MetricDefinition::INTEGER_HISTOGRAM, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest,
       IntegerHistogramFleetwideHistogramsValidationWrongBuckets) {
  auto event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER_HISTOGRAM);
  // Replace with a histogram containing an invalid bucket index. The metric FileSystemWriteTimes
  // has a num_buckets = 10, with 0 being the underflow bucket and 10+1=11 being the overflow
  // bucket. So the first invalid bucket index is 12.
  event_record->event()->mutable_integer_histogram_event()->mutable_buckets()->Swap(
      testing::NewHistogram({0, 1, 2, 12}, {100, 101, 102, 103}).get());
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER_HISTOGRAM);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kFileSystemWriteTimesMetricId,
                                          MetricDefinition::INTEGER_HISTOGRAM, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, IntegerHistogramFleetwideHistograms) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kFileSystemWriteTimesFileSystemWriteTimesHistogramReportId,
      ReportDefinition::FLEETWIDE_HISTOGRAMS);
  auto event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER_HISTOGRAM);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER_HISTOGRAM);
  EXPECT_EQ(
      StatusCode::OK,
      event_logger->Log(std::move(event_record), std::chrono::system_clock::now()).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kFileSystemWriteTimesMetricId,
                                              MetricDefinition::INTEGER_HISTOGRAM);
  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate = GetReportAggregate(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER_HISTOGRAM,
      testing::cobalt_new::kFileSystemWriteTimesFileSystemWriteTimesHistogramReportId, &store);
  ASSERT_TRUE(report_aggregate.has_hourly());
  local_aggregation::AggregationPeriodBucket hourly_bucket =
      report_aggregate.hourly().by_hour_id().begin()->second;
  local_aggregation::AggregateData data =
      hourly_bucket.system_profile_aggregates(0).by_event_code().at(0).data();
  ASSERT_TRUE(data.has_integer_histogram());
  const auto& histogram = data.integer_histogram();
  EXPECT_EQ(histogram.histogram().at(0), 100);
  EXPECT_EQ(histogram.histogram().at(1), 101);
  EXPECT_EQ(histogram.histogram().at(2), 102);
  EXPECT_EQ(histogram.histogram().at(3), 103);
}

TEST_F(EventLoggersLocalAggregationTest, StringStringHistogramsValidation) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kComponentMetricId,
                                                   MetricDefinition::STRING);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::STRING);
  EXPECT_EQ(StatusCode::OK,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kComponentMetricId,
                                          MetricDefinition::STRING, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, StringStringHistogramsValidationWrongType) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kComponentMetricId,
                                                   MetricDefinition::INTEGER);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::STRING);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kComponentMetricId,
                                          MetricDefinition::STRING, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, StringStringHistograms) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kComponentComponentHistogramReportId, ReportDefinition::STRING_COUNTS);
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kComponentMetricId,
                                                   MetricDefinition::STRING);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::STRING);
  EXPECT_EQ(
      StatusCode::OK,
      event_logger->Log(std::move(event_record), std::chrono::system_clock::now()).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kComponentMetricId,
                                              MetricDefinition::STRING);
  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate =
      GetReportAggregate(testing::cobalt_new::kComponentMetricId, MetricDefinition::STRING,
                         testing::cobalt_new::kComponentComponentHistogramReportId, &store);
  ASSERT_TRUE(report_aggregate.has_hourly());
  local_aggregation::AggregationPeriodBucket hourly_bucket =
      report_aggregate.hourly().by_hour_id().begin()->second;
  local_aggregation::AggregateData data =
      hourly_bucket.system_profile_aggregates(0).by_event_code().at(0).data();
  ASSERT_TRUE(data.has_string_histogram());
  const auto& histogram = data.string_histogram();
  EXPECT_EQ(histogram.histogram().at(0), 1);
}

TEST_F(EventLoggersLocalAggregationTest, OccurrenceOtherTimeZone) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kOccurrenceOtherTzFleetwideOccurrenceCountsReportId,
      ReportDefinition::FLEETWIDE_OCCURRENCE_COUNTS);
  std::unique_ptr<EventRecord> event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kOccurrenceOtherTzMetricId, MetricDefinition::OCCURRENCE);
  std::unique_ptr<EventLogger> event_logger =
      GetEventLoggerForMetricType(MetricDefinition::OCCURRENCE);

  // Log a count of 1 for start_time_, which has hour ID 17521 in the initial time zone of
  // `civil_time_converter_`.
  EXPECT_EQ(StatusCode::OK, event_logger->Log(std::move(event_record), start_time_).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kOccurrenceOtherTzMetricId,
                                              MetricDefinition::OCCURRENCE);
  event_record->event()->mutable_occurrence_event()->set_count(2);

  // Log a count of 2 for `start_time_ + 1` hour, which has hour ID 17524 in the final time zone of
  // `civil_time_converter_`.
  EXPECT_EQ(StatusCode::OK,
            event_logger->Log(std::move(event_record), start_time_ + util::kOneHour).error_code());

  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate = GetReportAggregate(
      testing::cobalt_new::kOccurrenceOtherTzMetricId, MetricDefinition::OCCURRENCE,
      testing::cobalt_new::kOccurrenceOtherTzFleetwideOccurrenceCountsReportId, &store);

  // Check that the EventLogger recorded the correct hour IDs and event counts.
  ASSERT_TRUE(report_aggregate.has_hourly());
  ASSERT_EQ(report_aggregate.hourly().by_hour_id_size(), 2);

  ASSERT_EQ(report_aggregate.hourly().by_hour_id().count(17521), 1);
  EXPECT_EQ(report_aggregate.hourly()
                .by_hour_id()
                .at(17521)
                .system_profile_aggregates(0)
                .by_event_code()
                .at(0)
                .data()
                .count(),
            1);

  ASSERT_EQ(report_aggregate.hourly().by_hour_id().count(17524), 1);
  EXPECT_EQ(report_aggregate.hourly()
                .by_hour_id()
                .at(17524)
                .system_profile_aggregates(0)
                .by_event_code()
                .at(0)
                .data()
                .count(),
            2);
}

}  // namespace internal
}  // namespace cobalt::logger
