// Copyright 2019 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/local_aggregation/aggregate_store.h"

#include <algorithm>
#include <map>
#include <memory>
#include <set>
#include <utility>
#include <vector>

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <gtest/gtest.h>

#include "src/lib/util/clock.h"
#include "src/lib/util/datetime_util.h"
#include "src/lib/util/proto_util.h"
#include "src/lib/util/testing/test_with_files.h"
#include "src/local_aggregation/aggregation_utils.h"
#include "src/local_aggregation/event_aggregator_mgr.h"
#include "src/local_aggregation/test_utils/test_event_aggregator_mgr.h"
#include "src/logger/logger_test_utils.h"
#include "src/logger/testing_constants.h"
#include "src/pb/event.pb.h"
#include "src/pb/metadata_builder.h"
#include "src/public/lib/registry_identifiers.h"
#include "src/registry/packed_event_codes.h"
#include "src/registry/project_configs.h"
#include "src/system_data/fake_system_data.h"

namespace cobalt {

using config::PackEventCodes;
using encoder::ClientSecret;
using logger::Encoder;
using logger::EventRecord;
using logger::MetricReportId;
using logger::ObservationWriter;
using logger::ProjectContext;
using logger::testing::CheckPerDeviceNumericObservations;
using logger::testing::CheckUniqueActivesObservations;
using logger::testing::ExpectedAggregationParams;
using logger::testing::ExpectedPerDeviceNumericObservations;
using logger::testing::ExpectedReportParticipationObservations;
using logger::testing::ExpectedUniqueActivesObservations;
using logger::testing::FakeObservationStore;
using logger::testing::FetchAggregatedObservations;
using logger::testing::GetTestProject;
using logger::testing::MakeAggregationKey;
using logger::testing::MakeExpectedReportParticipationObservations;
using logger::testing::MakeNullExpectedUniqueActivesObservations;
using logger::testing::TestUpdateRecipient;
using util::EncryptedMessageMaker;
using util::IncrementingSteadyClock;
using util::IncrementingSystemClock;
using util::SerializeToBase64;
using util::TimeToDayIndex;

namespace local_aggregation {

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;

template <typename T>
std::string SerializeAsStringDeterministic(const T& message) {
  std::string s;
  {
    google::protobuf::io::StringOutputStream output(&s);
    google::protobuf::io::CodedOutputStream out(&output);
    out.SetSerializationDeterministic(true);
    message.SerializePartialToCodedStream(&out);
  }
  return s;
}

constexpr uint32_t kTestCustomerId = 34;
constexpr uint32_t kTestProjectId = 123;
constexpr uint32_t kTestMetricId = 1;
constexpr uint32_t kTestReportId = 3;
const lib::ReportIdentifier kTestReportIdentifier = lib::CustomerIdentifier(kTestCustomerId)
                                                        .ForProject(kTestProjectId)
                                                        .ForMetric(kTestMetricId)
                                                        .ForReport(kTestReportId);
constexpr uint64_t kTestEventCode = 1;
constexpr uint32_t kTestDayIndex = 56;
constexpr size_t kTestBackfillDays = 3;

// A map keyed by base64-encoded, serialized ReportAggregationKeys. The value at
// a key is a map of event codes to sets of day indices. Used in tests as
// a record, external to the LocalAggregateStore, of the activity logged for
// UNIQUE_N_DAY_ACTIVES reports.
using LoggedActivity = std::map<std::string, std::map<uint32_t, std::set<uint32_t>>>;

// A map used in tests as a record, external to the LocalAggregateStore, of the
// activity logged for PER_DEVICE_NUMERIC_STATS reports. The keys are, in
// descending order, serialized ReportAggregationKeys, components, event codes,
// and day indices. Each day index maps to a vector of numeric values that were
// logged for that day index..
using LoggedValues =
    std::map<std::string,
             std::map<std::string, std::map<uint32_t, std::map<uint32_t, std::vector<int64_t>>>>>;

std::unique_ptr<ProjectContext> GetProjectContextFor(const MetricDefinition& metric) {
  auto project_config = std::make_unique<ProjectConfig>();
  project_config->set_project_name("test_project");
  project_config->set_project_id(metric.project_id());
  *project_config->add_metrics() = metric;
  return std::make_unique<ProjectContext>(metric.customer_id(), "test_customer",
                                          std::move(project_config));
}

MetricDefinition GetMetricWithId(lib::MetricIdentifier metric) {
  MetricDefinition metric_definition;
  metric_definition.set_metric_name("test_metric");
  metric_definition.set_id(metric.metric_id());
  metric_definition.set_customer_id(metric.customer_id());
  metric_definition.set_project_id(metric.project_id());
  return metric_definition;
}

MetricDefinition GetEventOccurredMetric(lib::MetricIdentifier metric_id) {
  MetricDefinition metric_definition = GetMetricWithId(metric_id);
  metric_definition.set_metric_type(MetricDefinition::EVENT_OCCURRED);
  return metric_definition;
}

MetricDefinition GetEventCountMetric(lib::MetricIdentifier metric_id) {
  MetricDefinition metric_definition = GetMetricWithId(metric_id);
  metric_definition.set_metric_type(MetricDefinition::EVENT_COUNT);
  return metric_definition;
}

std::tuple<MetricDefinition, ReportDefinition> GetUniqueActivesMetricAndReport(
    lib::ReportIdentifier report_id) {
  ReportDefinition report_definition;
  report_definition.set_report_name("test_unique_actives_report");
  report_definition.set_id(report_id.report_id());
  report_definition.set_report_type(ReportDefinition::UNIQUE_N_DAY_ACTIVES);
  *report_definition.add_aggregation_window() = MakeDayWindow(1);

  MetricDefinition metric_definition = GetEventOccurredMetric(report_id.metric());
  *metric_definition.add_reports() = report_definition;

  return std::make_tuple(metric_definition, report_definition);
}

std::tuple<MetricDefinition, ReportDefinition> GetPerDeviceNumericStatsMetricAndReport(
    lib::ReportIdentifier report_id, ReportDefinition::OnDeviceAggregationType aggregation_type) {
  ReportDefinition report_definition;
  report_definition.set_report_name("test_per_device_numeric_stats_report");
  report_definition.set_id(report_id.report_id());
  report_definition.set_report_type(ReportDefinition::PER_DEVICE_NUMERIC_STATS);
  report_definition.set_aggregation_type(aggregation_type);
  *report_definition.add_aggregation_window() = MakeDayWindow(1);

  MetricDefinition metric_definition = GetEventCountMetric(report_id.metric());
  *metric_definition.add_reports() = report_definition;

  return std::make_tuple(metric_definition, report_definition);
}

std::tuple<MetricDefinition, ReportDefinition> GetNotLocallyAggregatedMetricAndReport(
    lib::ReportIdentifier report) {
  ReportDefinition report_definition;
  report_definition.set_report_name("test_report");
  report_definition.set_id(report.report_id());
  report_definition.set_report_type(ReportDefinition::SIMPLE_OCCURRENCE_COUNT);
  *report_definition.add_aggregation_window() = MakeDayWindow(1);

  MetricDefinition metric_definition = GetEventOccurredMetric(report.metric());
  *metric_definition.add_reports() = report_definition;

  return std::make_tuple(metric_definition, report_definition);
}

}  // namespace

// AggregateStoreTest creates an EventAggregator which sends its Observations
// to a FakeObservationStore. The EventAggregator is not pre-populated with
// aggregation configurations.
class AggregateStoreTest : public util::testing::TestWithFiles {
 protected:
  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_.get(), update_recipient_.get(), observation_encrypter_.get());
    ResetEventAggregator();
  }

  void ResetEventAggregator() {
    // Pass this clock to the EventAggregator::Start method, if it is called.
    test_clock_ = std::make_unique<IncrementingSystemClock>(std::chrono::system_clock::duration(0));
    // Some tests generate observations for CurrentDayIndex() - kTestBackfillDays.
    test_clock_->set_time(std::chrono::system_clock::time_point(
        std::chrono::seconds(10ul * kYear - kTestBackfillDays * kDay)));
    // Use this to advance the clock in the tests.
    unowned_test_clock_ = test_clock_.get();
    validated_clock_ = std::make_unique<util::FakeValidatedClock>(test_clock_.get());
    validated_clock_->SetAccurate(true);
    metadata_builder_ = std::make_unique<MetadataBuilder>(&system_data_, validated_clock_.get(),
                                                          system_data_cache_path(), fs());
    metadata_builder_->SnapshotSystemData();
    // Initialize it to 10 years after the beginning of time.
    test_clock_->set_time(std::chrono::system_clock::time_point(std::chrono::seconds(10 * kYear)));
    encoder_ =
        std::make_unique<Encoder>(ClientSecret::GenerateNewSecret(), metadata_builder_.get());

    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_.get(), observation_writer_.get(), metadata_builder_.get());
    day_store_created_ = CurrentDayIndex();
    test_steady_clock_ = new IncrementingSteadyClock(std::chrono::system_clock::duration(0));
    event_aggregator_mgr_->SetSteadyClock(test_steady_clock_);
  }

  // Destruct the EventAggregator (thus calling EventAggregator::ShutDown())
  // before destructing the objects which the EventAggregator points to but does
  // not own.
  void TearDown() override { event_aggregator_mgr_.reset(); }

  // Advances |test_clock_| by |num_seconds| seconds.
  void AdvanceClock(int num_seconds) {
    unowned_test_clock_->increment_by(std::chrono::seconds(num_seconds));
    test_steady_clock_->increment_by(std::chrono::seconds(num_seconds));
  }

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

  size_t GetBackfillDays() { return event_aggregator_mgr_->aggregate_store_->backfill_days_; }

  void SetBackfillDays(size_t num_days) {
    event_aggregator_mgr_->aggregate_store_->backfill_days_ = num_days;
  }

  Status BackUpLocalAggregateStore() {
    return event_aggregator_mgr_->aggregate_store_->BackUpLocalAggregateStore();
  }

  Status BackUpObservationHistory() {
    return event_aggregator_mgr_->aggregate_store_->BackUpObservationHistory();
  }

  LocalAggregateStore MakeNewLocalAggregateStore(
      uint32_t version = kCurrentLocalAggregateStoreVersion) {
    return event_aggregator_mgr_->aggregate_store_->MakeNewLocalAggregateStore(version);
  }

  AggregatedObservationHistoryStore MakeNewObservationHistoryStore(
      uint32_t version = kCurrentObservationHistoryStoreVersion) {
    return event_aggregator_mgr_->aggregate_store_->MakeNewObservationHistoryStore(version);
  }

  Status MaybeUpgradeLocalAggregateStore(LocalAggregateStore* store) {
    return event_aggregator_mgr_->aggregate_store_->MaybeUpgradeLocalAggregateStore(store);
  }

  Status MaybeUpgradeObservationHistoryStore(AggregatedObservationHistoryStore* store) {
    return event_aggregator_mgr_->aggregate_store_->MaybeUpgradeObservationHistoryStore(store);
  }

  LocalAggregateStore CopyLocalAggregateStore() {
    return event_aggregator_mgr_->aggregate_store_->CopyLocalAggregateStore();
  }

  Status GenerateObservations(uint32_t final_day_index_utc, uint32_t final_day_index_local = 0u) {
    return event_aggregator_mgr_->aggregate_store_->GenerateObservations(final_day_index_utc,
                                                                         final_day_index_local);
  }

  bool IsReportInStore(lib::ReportIdentifier report) {
    std::string key;
    ReportAggregationKey key_data;
    key_data.set_customer_id(report.customer_id());
    key_data.set_project_id(report.project_id());
    key_data.set_metric_id(report.metric_id());
    key_data.set_report_id(report.report_id());
    SerializeToBase64(key_data, &key);

    auto locked = event_aggregator_mgr_->aggregate_store_->protected_aggregate_store_.lock();
    return locked->local_aggregate_store.by_report_key().count(key) > 0;
  }

  bool IsActive(lib::ReportIdentifier report, uint64_t event_code, uint32_t day_index) {
    std::string key;
    ReportAggregationKey key_data;
    key_data.set_customer_id(report.customer_id());
    key_data.set_project_id(report.project_id());
    key_data.set_metric_id(report.metric_id());
    key_data.set_report_id(report.report_id());
    SerializeToBase64(key_data, &key);

    auto locked = event_aggregator_mgr_->aggregate_store_->protected_aggregate_store_.lock();

    auto aggregates = locked->local_aggregate_store.by_report_key().find(key);
    if (aggregates == locked->local_aggregate_store.by_report_key().end()) {
      return false;
    }

    auto by_event_code =
        aggregates->second.unique_actives_aggregates().by_event_code().find(event_code);
    if (by_event_code == aggregates->second.unique_actives_aggregates().by_event_code().end()) {
      return false;
    }

    auto by_day_index = by_event_code->second.by_day_index().find(day_index);
    if (by_day_index == by_event_code->second.by_day_index().end()) {
      return false;
    }

    return by_day_index->second.activity_daily_aggregate().activity_indicator();
  }

  std::optional<int64_t> GetValue(lib::ReportIdentifier report, const std::string& component,
                                  uint64_t event_code, uint32_t day_index) {
    std::string key;
    ReportAggregationKey key_data;
    key_data.set_customer_id(report.customer_id());
    key_data.set_project_id(report.project_id());
    key_data.set_metric_id(report.metric_id());
    key_data.set_report_id(report.report_id());
    SerializeToBase64(key_data, &key);

    auto locked = event_aggregator_mgr_->aggregate_store_->protected_aggregate_store_.lock();

    auto aggregates = locked->local_aggregate_store.by_report_key().find(key);
    if (aggregates == locked->local_aggregate_store.by_report_key().end()) {
      return std::nullopt;
    }

    auto by_component = aggregates->second.numeric_aggregates().by_component().find(component);
    if (by_component == aggregates->second.numeric_aggregates().by_component().end()) {
      return std::nullopt;
    }

    auto by_event_code = by_component->second.by_event_code().find(event_code);
    if (by_event_code == by_component->second.by_event_code().end()) {
      return std::nullopt;
    }

    auto by_day_index = by_event_code->second.by_day_index().find(day_index);
    if (by_day_index == by_event_code->second.by_day_index().end()) {
      return std::nullopt;
    }

    return by_day_index->second.numeric_daily_aggregate().value();
  }

  AggregateStore* GetAggregateStore() { return event_aggregator_mgr_->aggregate_store_.get(); }

  Status GarbageCollect(uint32_t day_index_utc, uint32_t day_index_local = 0u) {
    return event_aggregator_mgr_->aggregate_store_->GarbageCollect(day_index_utc, day_index_local);
  }

  void DoScheduledTasksNow() {
    // Steady values don't matter, just tell DoScheduledTasks to run everything.
    auto steady_time = std::chrono::steady_clock::now();
    event_aggregator_mgr_->next_generate_obs_ = steady_time;
    event_aggregator_mgr_->next_gc_ = steady_time;
    event_aggregator_mgr_->DoScheduledTasks(unowned_test_clock_->now(), steady_time);
  }

  // Clears the FakeObservationStore and resets the 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;
  }

  // Given a ProjectContext |project_context| and the MetricReportId of a
  // UNIQUE_N_DAY_ACTIVES report in |project_context|, as well as a day index
  // and an event code, adds an EventOccurredEvent to the EventAggregator for
  // that report, day index, and event code. If a non-null LoggedActivity map is
  // provided, updates the map with information about the logged Event.
  Status AddUniqueActivesEvent(std::shared_ptr<const ProjectContext> project_context,
                               const MetricReportId& metric_report_id, uint32_t day_index,
                               uint32_t event_code, LoggedActivity* logged_activity = nullptr) {
    auto event_record =
        EventRecord::MakeEventRecord(std::move(project_context), metric_report_id.first)
            .ValueOrDie();
    event_record->event()->set_day_index(day_index);
    event_record->event()->mutable_event_occurred_event()->set_event_code(event_code);
    Status status = event_aggregator_mgr_->GetEventAggregator()->AddUniqueActivesEvent(
        metric_report_id.second, *event_record);
    if (logged_activity == nullptr) {
      return status;
    }
    std::string key;
    if (!SerializeToBase64(MakeAggregationKey(*event_record->project_context(), metric_report_id),
                           &key)) {
      return Status(StatusCode::INVALID_ARGUMENT, "Could not serialize");
    }
    (*logged_activity)[key][event_code].insert(day_index);
    return status;
  }

  // Given a ProjectContext |project_context| and the MetricReportId of an
  // EVENT_COUNT metric with a PER_DEVICE_NUMERIC_STATS report in
  // |project_context|, as well as a day index, a component string, and an event
  // code, adds a EventCountEvent to the EventAggregator for that report, day
  // index, component, and event code. If a non-null LoggedValues map is
  // provided, updates the map with information about the logged Event.
  Status AddPerDeviceEventCountEvent(std::shared_ptr<const ProjectContext> project_context,
                                     const MetricReportId& metric_report_id, uint32_t day_index,
                                     const std::string& component, uint32_t event_code,
                                     int64_t count, LoggedValues* logged_values = nullptr) {
    auto event_record =
        EventRecord::MakeEventRecord(std::move(project_context), metric_report_id.first)
            .ValueOrDie();
    event_record->event()->set_day_index(day_index);
    EventCountEvent* event_count_event = event_record->event()->mutable_event_count_event();
    event_count_event->set_component(component);
    event_count_event->add_event_code(event_code);
    event_count_event->set_count(count);
    Status status = event_aggregator_mgr_->GetEventAggregator()->AddEventCountEvent(
        metric_report_id.second, *event_record);
    if (logged_values == nullptr) {
      return status;
    }
    std::string key;
    if (!SerializeToBase64(MakeAggregationKey(*event_record->project_context(), metric_report_id),
                           &key)) {
      return Status(StatusCode::INVALID_ARGUMENT, "Could not serialize");
    }
    (*logged_values)[key][component][event_code][day_index].push_back(count);
    return status;
  }

  // Given a ProjectContext |project_context| and the MetricReportId of an
  // ELAPSED_TIME metric with a PER_DEVICE_NUMERIC_STATS report in
  // |project_context|, as well as a day index, a component string, and an event
  // code, logs an ElapsedTimeEvent to the EventAggregator for that report, day
  // index, component, and event code. If a non-null LoggedValues map is
  // provided, updates the map with information about the logged Event.
  Status AddPerDeviceElapsedTimeEvent(std::shared_ptr<const ProjectContext> project_context,
                                      const MetricReportId& metric_report_id, uint32_t day_index,
                                      const std::string& component, uint32_t event_code,
                                      int64_t micros, LoggedValues* logged_values = nullptr) {
    auto event_record =
        EventRecord::MakeEventRecord(std::move(project_context), metric_report_id.first)
            .ValueOrDie();
    event_record->event()->set_day_index(day_index);
    ElapsedTimeEvent* elapsed_time_event = event_record->event()->mutable_elapsed_time_event();
    elapsed_time_event->set_component(component);
    elapsed_time_event->add_event_code(event_code);
    elapsed_time_event->set_elapsed_micros(micros);
    Status status = event_aggregator_mgr_->GetEventAggregator()->AddElapsedTimeEvent(
        metric_report_id.second, *event_record);
    if (logged_values == nullptr) {
      return status;
    }
    std::string key;
    if (!SerializeToBase64(MakeAggregationKey(*event_record->project_context(), metric_report_id),
                           &key)) {
      return Status(StatusCode::INVALID_ARGUMENT, "Serialize failed");
    }
    (*logged_values)[key][component][event_code][day_index].push_back(micros);
    return status;
  }

  // Given a ProjectContext |project_context| and the MetricReportId of a
  // FRAME_RATE metric with a PER_DEVICE_NUMERIC_STATS report in
  // |project_context|, as well as a day index, a component string, and an event
  // code, logs a FrameRateEvent to the EventAggregator for that report, day
  // index, component, and event code. If a non-null LoggedValues map is
  // provided, updates the map with information about the logged Event.
  Status AddPerDeviceFrameRateEvent(std::shared_ptr<const ProjectContext> project_context,
                                    const MetricReportId& metric_report_id, uint32_t day_index,
                                    const std::string& component, uint32_t event_code, float fps,
                                    LoggedValues* logged_values = nullptr) {
    auto event_record =
        EventRecord::MakeEventRecord(std::move(project_context), metric_report_id.first)
            .ValueOrDie();
    event_record->event()->set_day_index(day_index);
    FrameRateEvent* frame_rate_event = event_record->event()->mutable_frame_rate_event();
    frame_rate_event->set_component(component);
    frame_rate_event->add_event_code(event_code);
    int64_t frames_per_1000_seconds = std::lround(fps * 1000.0);
    frame_rate_event->set_frames_per_1000_seconds(frames_per_1000_seconds);
    Status status = event_aggregator_mgr_->GetEventAggregator()->AddFrameRateEvent(
        metric_report_id.second, *event_record);
    if (logged_values == nullptr) {
      return status;
    }
    std::string key;
    if (!SerializeToBase64(MakeAggregationKey(*event_record->project_context(), metric_report_id),
                           &key)) {
      return Status(StatusCode::INVALID_ARGUMENT, "Serialize failed");
    }
    (*logged_values)[key][component][event_code][day_index].push_back(frames_per_1000_seconds);
    return status;
  }

  // Given a ProjectContext |project_context| and the MetricReportId of a
  // MEMORY_USAGE metric with a PER_DEVICE_NUMERIC_STATS report in
  // |project_context|, as well as a day index, a component string, and an event
  // code, logs a MemoryUsageEvent to the EventAggregator for that report, day
  // index, component, and event code. If a non-null LoggedValues map is
  // provided, updates the map with information about the logged Event.
  Status AddPerDeviceMemoryUsageEvent(std::shared_ptr<const ProjectContext> project_context,
                                      const MetricReportId& metric_report_id, uint32_t day_index,
                                      const std::string& component,
                                      const std::vector<uint32_t>& event_codes, int64_t bytes,
                                      LoggedValues* logged_values = nullptr) {
    auto event_record =
        EventRecord::MakeEventRecord(std::move(project_context), metric_report_id.first)
            .ValueOrDie();
    event_record->event()->set_day_index(day_index);
    MemoryUsageEvent* memory_usage_event = event_record->event()->mutable_memory_usage_event();
    memory_usage_event->set_component(component);
    for (auto event_code : event_codes) {
      memory_usage_event->add_event_code(event_code);
    }
    memory_usage_event->set_bytes(bytes);
    Status status = event_aggregator_mgr_->GetEventAggregator()->AddMemoryUsageEvent(
        metric_report_id.second, *event_record);
    if (logged_values == nullptr) {
      return status;
    }
    std::string key;
    if (!SerializeToBase64(MakeAggregationKey(*event_record->project_context(), metric_report_id),
                           &key)) {
      return Status(StatusCode::INVALID_ARGUMENT, "Serialize failed");
    }

    (*logged_values)[key][component][PackEventCodes(event_codes)][day_index].push_back(bytes);
    return status;
  }

  // Given a LoggedActivity map describing the events that have been logged
  // to the EventAggregator, checks whether the contents of the
  // LocalAggregateStore are as expected, accounting for any garbage
  // collection.
  //
  // logged_activity: a LoggedActivity representing event occurrences
  // since the LocalAggregateStore was created. All day indices should be
  // greater than or equal to |day_store_created_| and less than or equal to
  // |current_day_index|.
  //
  // current_day_index: The day index of the current day in the test's frame
  // of reference.
  bool CheckUniqueActivesAggregates(const LoggedActivity& logged_activity,
                                    uint32_t /*current_day_index*/) {
    auto local_aggregate_store = event_aggregator_mgr_->aggregate_store_->CopyLocalAggregateStore();
    // Check that the LocalAggregateStore contains no more UniqueActives
    // aggregates than |logged_activity| and |day_last_garbage_collected_|
    // should imply.
    for (const auto& report_pair : local_aggregate_store.by_report_key()) {
      const auto& aggregates = report_pair.second;
      if (aggregates.type_case() != ReportAggregates::kUniqueActivesAggregates) {
        continue;
      }
      const auto& report_key = report_pair.first;
      // Check whether this ReportAggregationKey is in |logged_activity|. If
      // not, expect that its by_event_code map is empty.
      auto report_activity = logged_activity.find(report_key);
      if (report_activity == logged_activity.end()) {
        EXPECT_TRUE(aggregates.unique_actives_aggregates().by_event_code().empty());
        if (!aggregates.unique_actives_aggregates().by_event_code().empty()) {
          return false;
        }
        break;
      }
      auto expected_events = report_activity->second;
      for (const auto& event_pair : aggregates.unique_actives_aggregates().by_event_code()) {
        // Check that this event code is in |logged_activity| under this
        // ReportAggregationKey.
        auto event_code = event_pair.first;
        auto event_activity = expected_events.find(event_code);
        EXPECT_NE(event_activity, expected_events.end());
        if (event_activity == expected_events.end()) {
          return false;
        }
        const auto& expected_days = event_activity->second;
        for (const auto& day_pair : event_pair.second.by_day_index()) {
          // Check that this day index is in |logged_activity| under this
          // ReportAggregationKey and event code.
          const auto& day_index = day_pair.first;
          auto day_activity = expected_days.find(day_index);
          EXPECT_NE(day_activity, expected_days.end());
          if (day_activity == expected_days.end()) {
            return false;
          }
          // Check that the day index is no earlier than is implied by the
          // dates of store creation and garbage collection.
          EXPECT_GE(day_index, EarliestAllowedDayIndex(aggregates.aggregation_config()));
          if (day_index < EarliestAllowedDayIndex(aggregates.aggregation_config())) {
            return false;
          }
        }
      }
    }

    // Check that the LocalAggregateStore contains aggregates for all events in
    // |logged_activity|, as long as they are recent enough to have survived any
    // garbage collection.
    for (const auto& logged_pair : logged_activity) {
      const auto& logged_key = logged_pair.first;
      const auto& logged_event_map = logged_pair.second;
      // Check that this ReportAggregationKey is in the LocalAggregateStore, and
      // that the aggregates are of the expected type.
      auto report_aggregates = local_aggregate_store.by_report_key().find(logged_key);
      EXPECT_NE(report_aggregates, local_aggregate_store.by_report_key().end());
      if (report_aggregates == local_aggregate_store.by_report_key().end()) {
        return false;
      }
      if (report_aggregates->second.type_case() != ReportAggregates::kUniqueActivesAggregates) {
        return false;
      }
      // Compute the earliest day index that should appear among the aggregates
      // for this report.
      auto earliest_allowed =
          EarliestAllowedDayIndex(report_aggregates->second.aggregation_config());
      for (const auto& logged_event_pair : logged_event_map) {
        const auto& logged_event_code = logged_event_pair.first;
        const auto& logged_days = logged_event_pair.second;
        // Check whether this event code is in the LocalAggregateStore
        // under this ReportAggregationKey. If not, check that all day indices
        // for this event code are smaller than the day index of the earliest
        // allowed aggregate.
        auto event_code_aggregates =
            report_aggregates->second.unique_actives_aggregates().by_event_code().find(
                logged_event_code);
        if (event_code_aggregates ==
            report_aggregates->second.unique_actives_aggregates().by_event_code().end()) {
          for (auto day_index : logged_days) {
            EXPECT_LT(day_index, earliest_allowed);
            if (day_index >= earliest_allowed) {
              return false;
            }
          }
          break;
        }
        // Check that all of the day indices in |logged_activity| under this
        // ReportAggregationKey and event code are in the
        // LocalAggregateStore, as long as they are recent enough to have
        // survived any garbage collection. Check that each aggregate has its
        // activity field set to true.
        for (const auto& logged_day_index : logged_days) {
          auto day_aggregate = event_code_aggregates->second.by_day_index().find(logged_day_index);
          if (logged_day_index >= earliest_allowed) {
            EXPECT_NE(day_aggregate, event_code_aggregates->second.by_day_index().end());
            if (day_aggregate == event_code_aggregates->second.by_day_index().end()) {
              return false;
            }
            EXPECT_TRUE(day_aggregate->second.activity_daily_aggregate().activity_indicator());
            if (!day_aggregate->second.activity_daily_aggregate().activity_indicator()) {
              return false;
            }
          }
        }
      }
    }
    return true;
  }

  bool CheckPerDeviceNumericAggregates(const LoggedValues& logged_values,
                                       uint32_t /*current_day_index*/) {
    auto local_aggregate_store = event_aggregator_mgr_->aggregate_store_->CopyLocalAggregateStore();
    // Check that the LocalAggregateStore contains no more PerDeviceNumeric
    // aggregates than |logged_values| and |day_last_garbage_collected_| should
    // imply.
    for (const auto& report_pair : local_aggregate_store.by_report_key()) {
      const auto& aggregates = report_pair.second;
      if (aggregates.type_case() != ReportAggregates::kNumericAggregates) {
        continue;
      }
      const auto& report_key = report_pair.first;
      // Check whether this ReportAggregationKey is in |logged_values|. If not,
      // expect that its by_component map is empty.
      auto report_values = logged_values.find(report_key);
      if (report_values == logged_values.end()) {
        EXPECT_TRUE(aggregates.numeric_aggregates().by_component().empty());
        if (!aggregates.numeric_aggregates().by_component().empty()) {
          return false;
        }
        break;
      }
      auto expected_components = report_values->second;
      for (const auto& component_pair : aggregates.numeric_aggregates().by_component()) {
        // Check that this component is in |logged_values| under this
        // ReportAggregationKey.
        auto component = component_pair.first;
        auto component_values = expected_components.find(component);
        EXPECT_NE(component_values, expected_components.end());
        if (component_values == expected_components.end()) {
          return false;
        }
        const auto& expected_events = component_values->second;
        for (const auto& event_pair : component_pair.second.by_event_code()) {
          // Check that this event code is in |logged_values| under this
          // ReportAggregationKey and component.
          const auto& event_code = event_pair.first;
          auto event_values = expected_events.find(event_code);
          EXPECT_NE(event_values, expected_events.end());
          if (event_values == expected_events.end()) {
            return false;
          }
          const auto& expected_days = event_values->second;
          for (const auto& day_pair : event_pair.second.by_day_index()) {
            // Check that this day index is in |logged_values| under this
            // ReportAggregationKey, component, and event code.
            const auto& day_index = day_pair.first;
            auto day_value = expected_days.find(day_index);
            EXPECT_NE(day_value, expected_days.end());
            if (day_value == expected_days.end()) {
              return false;
            }
            // Check that the day index is no earlier than is implied by the
            // dates of store creation and garbage collection.
            EXPECT_GE(day_index, EarliestAllowedDayIndex(aggregates.aggregation_config()));
            if (day_index < EarliestAllowedDayIndex(aggregates.aggregation_config())) {
              return false;
            }
          }
        }
      }
    }

    // Check that the LocalAggregateStore contains aggregates for all values in
    // |logged_values|, as long as they are recent enough to have survived any
    // garbage collection.
    for (const auto& logged_pair : logged_values) {
      const auto& logged_key = logged_pair.first;
      const auto& logged_component_map = logged_pair.second;
      // Check that this ReportAggregationKey is in the LocalAggregateStore, and
      // that the aggregates are of the expected type.
      auto report_aggregates = local_aggregate_store.by_report_key().find(logged_key);
      EXPECT_NE(report_aggregates, local_aggregate_store.by_report_key().end());
      if (report_aggregates == local_aggregate_store.by_report_key().end()) {
        return false;
      }
      if (report_aggregates->second.type_case() != ReportAggregates::kNumericAggregates) {
        return false;
      }
      const auto& aggregation_type =
          report_aggregates->second.aggregation_config().report().aggregation_type();
      // Compute the earliest day index that should appear among the aggregates
      // for this report.
      auto earliest_allowed =
          EarliestAllowedDayIndex(report_aggregates->second.aggregation_config());
      for (const auto& logged_component_pair : logged_component_map) {
        const auto& logged_component = logged_component_pair.first;
        const auto& logged_event_code_map = logged_component_pair.second;
        // Check whether this component is in the LocalAggregateStore under this
        // ReportAggregationKey. If not, check that all day indices for all
        // entries in |logged_values| under this component are smaller than the
        // day index of the earliest allowed aggregate.
        bool component_found = false;
        auto component_aggregates =
            report_aggregates->second.numeric_aggregates().by_component().find(logged_component);
        if (component_aggregates !=
            report_aggregates->second.numeric_aggregates().by_component().end()) {
          component_found = true;
        }
        for (const auto& logged_event_pair : logged_event_code_map) {
          const auto& logged_event_code = logged_event_pair.first;
          const auto& logged_day_map = logged_event_pair.second;
          // Check whether this event code is in the LocalAggregateStore under
          // this ReportAggregationKey. If not, check that all day indices in
          // |logged_values| under this component are smaller than the day index
          // of the earliest allowed aggregate.
          bool event_code_found = false;
          if (component_found) {
            auto event_code_aggregates =
                component_aggregates->second.by_event_code().find(logged_event_code);
            if (event_code_aggregates != component_aggregates->second.by_event_code().end()) {
              event_code_found = true;
            }
            if (event_code_found) {
              // Check that all of the day indices in |logged_values| under this
              // ReportAggregationKey, component, and event code are in the
              // LocalAggregateStore, as long as they are recent enough to have
              // survived any garbage collection. Check that each aggregate has
              // the expected value.
              for (const auto& logged_day_pair : logged_day_map) {
                auto logged_day_index = logged_day_pair.first;
                auto logged_values = logged_day_pair.second;
                auto day_aggregate =
                    event_code_aggregates->second.by_day_index().find(logged_day_index);
                if (logged_day_index >= earliest_allowed) {
                  EXPECT_NE(day_aggregate, event_code_aggregates->second.by_day_index().end());
                  if (day_aggregate == event_code_aggregates->second.by_day_index().end()) {
                    return false;
                  }
                  int64_t aggregate_from_logged_values = 0;
                  for (size_t index = 0; index < logged_values.size(); index++) {
                    switch (aggregation_type) {
                      case ReportDefinition::SUM:
                        aggregate_from_logged_values += logged_values[index];
                        break;
                      case ReportDefinition::MAX:
                        aggregate_from_logged_values =
                            std::max(aggregate_from_logged_values, logged_values[index]);
                        break;
                      case ReportDefinition::MIN:
                        if (index == 0) {
                          aggregate_from_logged_values = logged_values[0];
                        }
                        aggregate_from_logged_values =
                            std::min(aggregate_from_logged_values, logged_values[index]);
                        break;
                      default:
                        return false;
                    }
                  }
                  EXPECT_EQ(day_aggregate->second.numeric_daily_aggregate().value(),
                            aggregate_from_logged_values);
                  if (day_aggregate->second.numeric_daily_aggregate().value() !=
                      aggregate_from_logged_values) {
                    return false;
                  }
                }
              }
            }
          }
          if (!component_found | !event_code_found) {
            for (const auto& logged_day_pair : logged_day_map) {
              auto logged_day_index = logged_day_pair.first;
              EXPECT_LT(logged_day_index, earliest_allowed);
              if (logged_day_index >= earliest_allowed) {
                return false;
              }
            }
            break;
          }
        }
      }
    }

    return true;
  }

  // Given the AggregationConfig of a locally aggregated report, returns the
  // earliest (smallest) day index for which an aggregate may exist in the
  // LocalAggregateStore for that report, accounting for garbage
  // collection and the number of backfill days.
  uint32_t EarliestAllowedDayIndex(const AggregationConfig& config) {
    // If the LocalAggregateStore has never been garbage-collected, then the
    // earliest allowed day index is just the day when the store was created,
    // minus the number of backfill days.
    auto backfill_days = GetBackfillDays();
    EXPECT_GE(day_store_created_, backfill_days)
        << "The day index of store creation must be larger than the number "
           "of backfill days.";
    if (day_last_garbage_collected_ == 0u) {
      return day_store_created_ - backfill_days;
    }
    uint32_t max_aggregation_days = 1;
    for (const auto& window : config.aggregation_window()) {
      if (window.units_case() == OnDeviceAggregationWindow::kDays &&
          window.days() > max_aggregation_days) {
        max_aggregation_days = window.days();
      }
    }
    // Otherwise, it is the later of:
    // (a) The day index on which the store was created minus the number
    // of backfill days.
    // (b) The day index for which the store was last garbage-collected
    // minus the number of backfill days, minus the largest window size in
    // the report associated to |config|, plus 1.
    EXPECT_GE(day_last_garbage_collected_, backfill_days)
        << "The day index of last garbage collection must be larger than "
           "the number of backfill days.";

    if (day_last_garbage_collected_ - backfill_days < (max_aggregation_days + 1)) {
      return day_store_created_ - backfill_days;
    }
    return (day_store_created_ < (day_last_garbage_collected_ - max_aggregation_days + 1))
               ? (day_last_garbage_collected_ - backfill_days - max_aggregation_days + 1)
               : day_store_created_ - backfill_days;
  }

  std::unique_ptr<TestEventAggregatorManager> event_aggregator_mgr_;
  std::unique_ptr<ObservationWriter> observation_writer_;
  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<Encoder> encoder_;
  std::unique_ptr<EncryptedMessageMaker> observation_encrypter_;
  std::unique_ptr<TestUpdateRecipient> update_recipient_;
  std::unique_ptr<FakeObservationStore> observation_store_;
  std::unique_ptr<IncrementingSystemClock> test_clock_;
  IncrementingSystemClock* unowned_test_clock_;
  std::unique_ptr<util::FakeValidatedClock> validated_clock_;
  IncrementingSteadyClock* test_steady_clock_;
  // The day index on which the LocalAggregateStore was last
  // garbage-collected. A value of 0 indicates that the store has never been
  // garbage-collected.
  uint32_t day_last_garbage_collected_ = 0u;
  // The day index on which the LocalAggregateStore was created.
  uint32_t day_store_created_ = 0u;

 private:
  system_data::FakeSystemData system_data_;
};

// Creates an EventAggregator and provides it with a ProjectContext generated
// from a registry.
class AggregateStoreTestWithProjectContext : public AggregateStoreTest {
 protected:
  explicit AggregateStoreTestWithProjectContext(const std::string& registry_var_name) {
    project_context_ = GetTestProject(registry_var_name);
  }

  void SetUp() override {
    AggregateStoreTest::SetUp();
    event_aggregator_mgr_->GetEventAggregator()->UpdateAggregationConfigs(*project_context_);
  }

  // Adds an EventOccurredEvent to the local aggregations for the MetricReportId of a locally
  // aggregated report of the ProjectContext. Overrides the method
  // AggregateStoreTest::AddUniqueActivesEvent.
  Status AddUniqueActivesEvent(const MetricReportId& metric_report_id, uint32_t day_index,
                               uint32_t event_code, LoggedActivity* logged_activity = nullptr) {
    return AggregateStoreTest::AddUniqueActivesEvent(project_context_, metric_report_id, day_index,
                                                     event_code, logged_activity);
  }

  // Logs a EventCountEvent for the MetricReportId of a locally
  // aggregated report of the ProjectContext. Overrides the method
  // AggregateStoreTest::AddPerDeviceEventCountEvent.
  Status AddPerDeviceEventCountEvent(const MetricReportId& metric_report_id, uint32_t day_index,
                                     const std::string& component, uint32_t event_code,
                                     int64_t count, LoggedValues* logged_values = nullptr) {
    return AggregateStoreTest::AddPerDeviceEventCountEvent(
        project_context_, metric_report_id, day_index, component, event_code, count, logged_values);
  }

  // Adds an ElapsedTimeEvent to the local aggregations for the MetricReportId of a locally
  // aggregated report of the ProjectContext. Overrides the method
  // AggregateStoreTest::AddPerDeviceElapsedTimeEvent.
  Status AddPerDeviceElapsedTimeEvent(const MetricReportId& metric_report_id, uint32_t day_index,
                                      const std::string& component, uint32_t event_code,
                                      int64_t micros, LoggedValues* logged_values = nullptr) {
    return AggregateStoreTest::AddPerDeviceElapsedTimeEvent(project_context_, metric_report_id,
                                                            day_index, component, event_code,
                                                            micros, logged_values);
  }

  // Logs a FrameRateEvent for the MetricReportId of a locally
  // aggregated report of the ProjectContext. Overrides the method
  // AggregateStoreTest::AddPerDeviceFrameRateEvent.
  Status AddPerDeviceFrameRateEvent(const MetricReportId& metric_report_id, uint32_t day_index,
                                    const std::string& component, uint32_t event_code, float fps,
                                    LoggedValues* logged_values = nullptr) {
    return AggregateStoreTest::AddPerDeviceFrameRateEvent(
        project_context_, metric_report_id, day_index, component, event_code, fps, logged_values);
  }

  // Adds a MemoryUsageEvent to the local aggregations for the MetricReportId of a locally
  // aggregated report of the ProjectContext. Overrides the method
  // AggregateStoreTest::AddPerDeviceMemoryUsageEvent.
  Status AddPerDeviceMemoryUsageEvent(const MetricReportId& metric_report_id, uint32_t day_index,
                                      const std::string& component,
                                      const std::vector<uint32_t>& event_codes, int64_t bytes,
                                      LoggedValues* logged_values = nullptr) {
    return AggregateStoreTest::AddPerDeviceMemoryUsageEvent(project_context_, metric_report_id,
                                                            day_index, component, event_codes,
                                                            bytes, logged_values);
  }

 private:
  // A ProjectContext wrapping the MetricDefinitions passed to the
  // constructor in |metric_string|.
  std::shared_ptr<ProjectContext> project_context_;
};

// Creates an EventAggregator and provides it with a ProjectContext generated
// from test_registries/unique_actives_test_registry.yaml. All metrics in this
// registry are of type EVENT_OCCURRED and have a UNIQUE_N_DAY_ACTIVES report.
class UniqueActivesAggregateStoreTest : public AggregateStoreTestWithProjectContext {
 protected:
  UniqueActivesAggregateStoreTest()
      : AggregateStoreTestWithProjectContext(
            logger::testing::unique_actives::kCobaltRegistryBase64) {}
};

// Creates an EventAggregator and provides it with a ProjectContext generated
// from test_registries/unique_actives_noise_free_test_registry.yaml. All
// metrics in this registry are of type EVENT_OCCURRED and have a
// UNIQUE_N_DAY_ACTIVES report with local_privacy_noise_level NONE.
class UniqueActivesNoiseFreeAggregateStoreTest : public AggregateStoreTestWithProjectContext {
 protected:
  UniqueActivesNoiseFreeAggregateStoreTest()
      : AggregateStoreTestWithProjectContext(
            logger::testing::unique_actives_noise_free::kCobaltRegistryBase64) {}
};

// Creates an EventAggregator and provides it with a ProjectContext generated
// from test_registries/per_device_numeric_stats_test_registry.yaml. All metrics
// in this registry are of type EVENT_COUNT and have a PER_DEVICE_NUMERIC_STATS
// report.
class PerDeviceNumericAggregateStoreTest : public AggregateStoreTestWithProjectContext {
 protected:
  PerDeviceNumericAggregateStoreTest()
      : AggregateStoreTestWithProjectContext(
            logger::testing::per_device_numeric_stats::kCobaltRegistryBase64) {}
};

// Creates an EventAggregator and provides it with a ProjectContext generated
// from test_registries/mixed_time_zone_test_registry.yaml. This registry
// contains multiple MetricDefinitions with different time zone policies.
class NoiseFreeMixedTimeZoneAggregateStoreTest : public AggregateStoreTestWithProjectContext {
 protected:
  NoiseFreeMixedTimeZoneAggregateStoreTest()
      : AggregateStoreTestWithProjectContext(
            logger::testing::mixed_time_zone::kCobaltRegistryBase64) {}
};

class PerDeviceHistogramAggregateStoreTest : public AggregateStoreTestWithProjectContext {
 protected:
  PerDeviceHistogramAggregateStoreTest()
      : AggregateStoreTestWithProjectContext(
            logger::testing::per_device_histogram::kCobaltRegistryBase64) {}
};

class AggregateStoreWorkerTest : public AggregateStoreTest {
 protected:
  void SetUp() override { AggregateStoreTest::SetUp(); }

  void ShutDownWorkerThread() { event_aggregator_mgr_->ShutDown(); }

  bool in_shutdown_state() { return (shutdown_flag_set() && !worker_joinable()); }

  bool in_run_state() { return (!shutdown_flag_set() && worker_joinable()); }

  bool shutdown_flag_set() {
    return event_aggregator_mgr_->protected_worker_thread_controller_.const_lock()->shut_down;
  }

  bool worker_joinable() { return event_aggregator_mgr_->worker_thread_.joinable(); }
};

// Tests that the Read() method of each ConsistentProtoStore is called once
// during construction of the EventAggregator.
TEST_F(AggregateStoreTest, ReadProtosFromFiles) {
  EXPECT_EQ(1, fs()->TimesRead(aggregate_store_path()));
  EXPECT_EQ(1, fs()->TimesRead(obs_history_path()));
}

// Tests that the BackUp*() methods return a positive status, and checks that
// the Write() method of a ConsistentProtoStore is called once when its
// respective BackUp*() method is called.
TEST_F(AggregateStoreTest, BackUpProtos) {
  EXPECT_EQ(StatusCode::OK, BackUpLocalAggregateStore().error_code());
  EXPECT_EQ(StatusCode::OK, BackUpObservationHistory().error_code());
  EXPECT_EQ(1, fs()->TimesWritten(aggregate_store_path()));
  EXPECT_EQ(1, fs()->TimesWritten(obs_history_path()));
}

// MaybeUpgradeLocalAggregateStore should return an OK status if the version is current. The store
// should not change.
TEST_F(AggregateStoreTest, MaybeUpgradeLocalAggregateStoreCurrent) {
  auto store = MakeNewLocalAggregateStore();
  std::string store_before = SerializeAsStringDeterministic(store);
  ASSERT_EQ(kCurrentLocalAggregateStoreVersion, store.version());
  EXPECT_EQ(StatusCode::OK, MaybeUpgradeLocalAggregateStore(&store).error_code());
  EXPECT_EQ(store_before, SerializeAsStringDeterministic(store));
}

// MaybeUpgradeLocalAggregateStore should return StatusCode::INVALID_ARGUMENT if it is not
// possible to upgrade to the current version.
TEST_F(AggregateStoreTest, MaybeUpgradeLocalAggregateStoreUnsupported) {
  const uint32_t kFutureVersion = kCurrentLocalAggregateStoreVersion + 1;
  auto store = MakeNewLocalAggregateStore(kFutureVersion);
  ASSERT_EQ(kFutureVersion, store.version());
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT, MaybeUpgradeLocalAggregateStore(&store).error_code());
}

// It should be possible to upgrade the LocalAggregateStore from v0 to the current version. The
// version number should be updated and the contents of window_size in each AggregationConfigs
// should be moved to aggregation_window, preserving their order.
TEST_F(AggregateStoreTest, MaybeUpgradeLocalAggregateStoreFromV0) {
  const uint32_t kVersionZero = 0;
  const std::vector<int32_t> kWindowSizes = {1, 7, 30};
  const std::string kKey = "some_report_key";

  // Make a v0 LocalAggregateStore with one report.
  auto store = MakeNewLocalAggregateStore(kVersionZero);
  ReportAggregates report_aggregates;
  for (auto window_size : kWindowSizes) {
    report_aggregates.mutable_aggregation_config()->add_window_size(window_size);
  }
  (*store.mutable_by_report_key())[kKey] = report_aggregates;

  // Make the expected upgraded store.
  auto expected_store = MakeNewLocalAggregateStore(kCurrentLocalAggregateStoreVersion);
  ReportAggregates expected_report_aggregates;
  for (int32_t window_size : kWindowSizes) {
    *expected_report_aggregates.mutable_aggregation_config()->add_aggregation_window() =
        MakeDayWindow(window_size);
  }
  (*expected_store.mutable_by_report_key())[kKey] = expected_report_aggregates;

  // Upgrade and check that the upgraded store is as expected.
  EXPECT_EQ(StatusCode::OK, MaybeUpgradeLocalAggregateStore(&store).error_code());
  EXPECT_EQ(SerializeAsStringDeterministic(expected_store), SerializeAsStringDeterministic(store));
}

// MaybeUpgradeObservationHistoryStore should return an OK status if the version is current. The
// store should not change.
TEST_F(AggregateStoreTest, MaybeUpgradeObservationHistoryStoreCurrent) {
  auto store = MakeNewObservationHistoryStore();
  std::string store_before = SerializeAsStringDeterministic(store);
  ASSERT_EQ(kCurrentObservationHistoryStoreVersion, store.version());
  EXPECT_EQ(StatusCode::OK, MaybeUpgradeObservationHistoryStore(&store).error_code());
  EXPECT_EQ(store_before, SerializeAsStringDeterministic(store));
}

// MaybeUpgradeObservationHistoryStore should return logger::kInvalidArguments if it is not
// possible to upgrade to the current version.
TEST_F(AggregateStoreTest, MaybeUpgradeObservationHistoryStoreUnsupported) {
  const uint32_t kFutureVersion = kCurrentObservationHistoryStoreVersion + 1;
  auto store = MakeNewObservationHistoryStore(kFutureVersion);
  ASSERT_EQ(kFutureVersion, store.version());
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT, MaybeUpgradeObservationHistoryStore(&store).error_code());
}

// MaybeInsertReportConfig successfully updates the store.
TEST_F(AggregateStoreTest, MaybeInsertReportConfig) {
  auto [metric, report] = GetUniqueActivesMetricAndReport(kTestReportIdentifier);
  auto project_context = GetProjectContextFor(metric);

  EXPECT_FALSE(IsReportInStore(kTestReportIdentifier));
  ASSERT_EQ(
      StatusCode::OK,
      GetAggregateStore()->MaybeInsertReportConfig(*project_context, metric, report).error_code());
  EXPECT_TRUE(IsReportInStore(kTestReportIdentifier));
}

// MaybeInsertReportConfig returns kOK when the same config is inserted twice.
TEST_F(AggregateStoreTest, MaybeInsertReportConfigTwice) {
  auto [metric, report] = GetUniqueActivesMetricAndReport(kTestReportIdentifier);
  auto project_context = GetProjectContextFor(metric);

  EXPECT_FALSE(IsReportInStore(kTestReportIdentifier));
  ASSERT_EQ(
      StatusCode::OK,
      GetAggregateStore()->MaybeInsertReportConfig(*project_context, metric, report).error_code());
  ASSERT_EQ(
      StatusCode::OK,
      GetAggregateStore()->MaybeInsertReportConfig(*project_context, metric, report).error_code());
  EXPECT_TRUE(IsReportInStore(kTestReportIdentifier));
}

// MaybeInsertReportConfig fails due to the fact that the given report does not have an
// aggregation window.
TEST_F(AggregateStoreTest, MaybeInsertReportConfigFail) {
  auto [metric, report] = GetNotLocallyAggregatedMetricAndReport(kTestReportIdentifier);
  auto project_context = GetProjectContextFor(metric);

  EXPECT_FALSE(IsReportInStore(kTestReportIdentifier));
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      GetAggregateStore()->MaybeInsertReportConfig(*project_context, metric, report).error_code());
}

// The Aggregate store sets the record for an event to active using SetActive.
TEST_F(AggregateStoreTest, SetActive) {
  auto [metric, report] = GetUniqueActivesMetricAndReport(kTestReportIdentifier);
  auto project_context = GetProjectContextFor(metric);

  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GetEventAggregator()
                                ->UpdateAggregationConfigs(*project_context)
                                .error_code());

  EXPECT_FALSE(IsActive(kTestReportIdentifier, kTestEventCode, kTestDayIndex));
  ASSERT_EQ(StatusCode::OK, GetAggregateStore()
                                ->SetActive(kTestReportIdentifier, kTestEventCode, kTestDayIndex)
                                .error_code());
  EXPECT_TRUE(IsActive(kTestReportIdentifier, kTestEventCode, kTestDayIndex));
}

// SetActive returns kOK when the same config is inserted twice.
TEST_F(AggregateStoreTest, SetActiveTwice) {
  auto [metric, report] = GetUniqueActivesMetricAndReport(kTestReportIdentifier);
  auto project_context = GetProjectContextFor(metric);

  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GetEventAggregator()
                                ->UpdateAggregationConfigs(*project_context)
                                .error_code());
  EXPECT_FALSE(IsActive(kTestReportIdentifier, kTestEventCode, kTestDayIndex));

  ASSERT_EQ(StatusCode::OK, GetAggregateStore()
                                ->SetActive(kTestReportIdentifier, kTestEventCode, kTestDayIndex)
                                .error_code());
  ASSERT_EQ(StatusCode::OK, GetAggregateStore()
                                ->SetActive(kTestReportIdentifier, kTestEventCode, kTestDayIndex)
                                .error_code());
  EXPECT_TRUE(IsActive(kTestReportIdentifier, kTestEventCode, kTestDayIndex));
}

// SetActive fails due to the fact that UpdateAggregationConfigs was not called for the given
// report does not have an aggregation.
TEST_F(AggregateStoreTest, SetActiveFail) {
  auto [metric, report] = GetNotLocallyAggregatedMetricAndReport(kTestReportIdentifier);
  auto project_context = GetProjectContextFor(metric);

  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GetEventAggregator()
                                ->UpdateAggregationConfigs(*project_context)
                                .error_code());
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            GetAggregateStore()
                ->SetActive(kTestReportIdentifier, kTestEventCode, kTestDayIndex)
                .error_code());
}

// The Aggregate store updates the local store with the sum of two values when the aggregation is
// of type SUM.
TEST_F(AggregateStoreTest, UpdateAggregationSUM) {
  auto [metric, report] =
      GetPerDeviceNumericStatsMetricAndReport(kTestReportIdentifier, ReportDefinition::SUM);
  auto project_context = GetProjectContextFor(metric);

  const int64_t kFirstValue = 3;
  const int64_t kSecondValue = 7;

  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GetEventAggregator()
                                ->UpdateAggregationConfigs(*project_context)
                                .error_code());

  EXPECT_EQ(StatusCode::OK, GetAggregateStore()
                                ->UpdateNumericAggregate(kTestReportIdentifier, "", kTestEventCode,
                                                         kTestDayIndex, kFirstValue)
                                .error_code());
  EXPECT_EQ(kFirstValue, GetValue(kTestReportIdentifier, "", kTestEventCode, kTestDayIndex));
  EXPECT_EQ(StatusCode::OK, GetAggregateStore()
                                ->UpdateNumericAggregate(kTestReportIdentifier, "", kTestEventCode,
                                                         kTestDayIndex, kSecondValue)
                                .error_code());
  EXPECT_EQ(kSecondValue + kFirstValue,
            GetValue(kTestReportIdentifier, "", kTestEventCode, kTestDayIndex));
}

// The Aggregate store updates the local store with the sum of two values when the aggregation is
// of type MAX.
TEST_F(AggregateStoreTest, UpdateAggregationMAX) {
  auto [metric, report] =
      GetPerDeviceNumericStatsMetricAndReport(kTestReportIdentifier, ReportDefinition::MAX);
  auto project_context = GetProjectContextFor(metric);

  const int64_t kFirstValue = 3;
  const int64_t kSecondValue = 7;

  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GetEventAggregator()
                                ->UpdateAggregationConfigs(*project_context)
                                .error_code());

  EXPECT_EQ(StatusCode::OK, GetAggregateStore()
                                ->UpdateNumericAggregate(kTestReportIdentifier, "", kTestEventCode,
                                                         kTestDayIndex, kFirstValue)
                                .error_code());
  EXPECT_EQ(kFirstValue, GetValue(kTestReportIdentifier, "", kTestEventCode, kTestDayIndex));
  EXPECT_EQ(StatusCode::OK, GetAggregateStore()
                                ->UpdateNumericAggregate(kTestReportIdentifier, "", kTestEventCode,
                                                         kTestDayIndex, kSecondValue)
                                .error_code());
  EXPECT_EQ(kSecondValue, GetValue(kTestReportIdentifier, "", kTestEventCode, kTestDayIndex));
}
// The Aggregate store updates the local store with the sum of two values when the aggregation is
// of type MIN.
TEST_F(AggregateStoreTest, UpdateAggregationMIN) {
  auto [metric, report] =
      GetPerDeviceNumericStatsMetricAndReport(kTestReportIdentifier, ReportDefinition::MIN);
  auto project_context = GetProjectContextFor(metric);

  const int64_t kFirstValue = 3;
  const int64_t kSecondValue = 7;

  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GetEventAggregator()
                                ->UpdateAggregationConfigs(*project_context)
                                .error_code());

  EXPECT_EQ(StatusCode::OK, GetAggregateStore()
                                ->UpdateNumericAggregate(kTestReportIdentifier, "", kTestEventCode,
                                                         kTestDayIndex, kFirstValue)
                                .error_code());
  EXPECT_EQ(kFirstValue, GetValue(kTestReportIdentifier, "", kTestEventCode, kTestDayIndex));
  EXPECT_EQ(StatusCode::OK, GetAggregateStore()
                                ->UpdateNumericAggregate(kTestReportIdentifier, "", kTestEventCode,
                                                         kTestDayIndex, kSecondValue)
                                .error_code());
  EXPECT_EQ(kFirstValue, GetValue(kTestReportIdentifier, "", kTestEventCode, kTestDayIndex));
}

// UpdateAggregationConfigs fails due to the fact that UpdateAggregationConfigs was not called for
// the given report.
TEST_F(AggregateStoreTest, UpdateAggregationFail) {
  auto [metric, report] =
      GetPerDeviceNumericStatsMetricAndReport(kTestReportIdentifier, ReportDefinition::SUM);
  auto project_context = GetProjectContextFor(metric);

  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            GetAggregateStore()
                ->UpdateNumericAggregate(kTestReportIdentifier, "", kTestEventCode, kTestDayIndex,
                                         /*value*/ 4)
                .error_code());
}

TEST_F(AggregateStoreTest, SetUniqueActivesLastGeneratedDayIndex) {
  const std::string kReportKey = "test_key";
  const int64_t kFirstValue = 3;

  EXPECT_EQ(0u,
            GetAggregateStore()->GetUniqueActivesLastGeneratedDayIndex(kReportKey, kTestEventCode,
                                                                       /*aggregation_days*/ 1));
  GetAggregateStore()->SetUniqueActivesLastGeneratedDayIndex(kReportKey, kTestEventCode,
                                                             /*aggregation_days*/ 1, kFirstValue);
  EXPECT_EQ(kFirstValue,
            GetAggregateStore()->GetUniqueActivesLastGeneratedDayIndex(kReportKey, kTestEventCode,
                                                                       /*aggregation_days*/ 1));
}
TEST_F(AggregateStoreTest, SetPerDeviceNumericLastGeneratedDayIndex) {
  const std::string kReportKey = "test_key";
  const int64_t kFirstValue = 3;

  EXPECT_EQ(0u, GetAggregateStore()->GetPerDeviceNumericLastGeneratedDayIndex(
                    kReportKey, "", kTestEventCode,
                    /*aggregation_days*/ 1));
  GetAggregateStore()->SetPerDeviceNumericLastGeneratedDayIndex(kReportKey, "", kTestEventCode,
                                                                /*aggregation_days*/ 1,
                                                                kFirstValue);
  EXPECT_EQ(kFirstValue, GetAggregateStore()->GetPerDeviceNumericLastGeneratedDayIndex(
                             kReportKey, "", kTestEventCode,
                             /*aggregation_days*/ 1));
}
TEST_F(AggregateStoreTest, SetReportParticipationLastGeneratedDayIndex) {
  const std::string kReportKey = "test_key";
  const int64_t kFirstValue = 3;

  EXPECT_EQ(0u, GetAggregateStore()->GetReportParticipationLastGeneratedDayIndex(kReportKey));
  GetAggregateStore()->SetReportParticipationLastGeneratedDayIndex(kReportKey, kFirstValue);
  EXPECT_EQ(kFirstValue,
            GetAggregateStore()->GetReportParticipationLastGeneratedDayIndex(kReportKey));
}

// Tests that EventAggregator::GenerateObservations() returns a positive
// status and that the expected number of Observations is generated when no
// Events have been logged to the EventAggregator.
TEST_F(AggregateStoreTest, GenerateObservationsNoEvents) {
  // Provide the all_report_types test registry to the EventAggregator.
  auto project_context = GetTestProject(logger::testing::all_report_types::kCobaltRegistryBase64);
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GetEventAggregator()
                                ->UpdateAggregationConfigs(*project_context)
                                .error_code());
  // Generate locally aggregated Observations for the current day index.
  EXPECT_EQ(StatusCode::OK, GenerateObservations(CurrentDayIndex()).error_code());
  std::vector<Observation> observations(0);
  EXPECT_TRUE(FetchAggregatedObservations(
      &observations, logger::testing::all_report_types::kExpectedAggregationParams,
      observation_store_.get(), update_recipient_.get()));
}

// Tests that EventAggregator::GenerateObservations() only generates
// Observations the first time it is called for a given day index.
TEST_F(AggregateStoreTest, GenerateObservationsTwice) {
  // Provide the all_report_types test registry to the EventAggregator.
  auto project_context = GetTestProject(logger::testing::all_report_types::kCobaltRegistryBase64);
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GetEventAggregator()
                                ->UpdateAggregationConfigs(*project_context)
                                .error_code());
  // Check that Observations are generated when GenerateObservations is called
  // for the current day index for the first time.
  auto current_day_index = CurrentDayIndex();
  EXPECT_EQ(StatusCode::OK, GenerateObservations(current_day_index).error_code());
  std::vector<Observation> observations(0);
  EXPECT_TRUE(FetchAggregatedObservations(
      &observations, logger::testing::all_report_types::kExpectedAggregationParams,
      observation_store_.get(), update_recipient_.get()));
  // Check that no Observations are generated when GenerateObservations is
  // called for the currentday index for the second time.
  ResetObservationStore();
  EXPECT_EQ(StatusCode::OK, GenerateObservations(current_day_index).error_code());
  EXPECT_EQ(0u, observation_store_->messages_received.size());
}

// When the LocalAggregateStore contains one ReportAggregates proto and that
// proto is empty, GenerateObservations should return success but generate no
// observations.
TEST_F(AggregateStoreTest, GenerateObservationsFromBadStore) {
  auto bad_store = std::make_unique<LocalAggregateStore>();
  (*bad_store->mutable_by_report_key())["some_key"] = ReportAggregates();
  auto stream = fs()->NewProtoOutputStream(aggregate_store_path()).ConsumeValueOrDie();
  EXPECT_TRUE(bad_store->SerializeToZeroCopyStream(stream.get()));
  // Read the bad store in to the EventAggregator.
  ResetEventAggregator();
  EXPECT_EQ(StatusCode::OK, GenerateObservations(CurrentDayIndex()).error_code());
  EXPECT_EQ(0u, observation_store_->messages_received.size());
}

// When the LocalAggregateStore contains one empty ReportAggregates proto and
// some valid ReportAggregates, GenerateObservations should produce observations
// for the valid ReportAggregates.
TEST_F(AggregateStoreTest, GenerateObservationsFromBadStoreMultiReport) {
  auto bad_store = std::make_unique<LocalAggregateStore>();
  (*bad_store->mutable_by_report_key())["some_key"] = ReportAggregates();
  auto stream = fs()->NewProtoOutputStream(aggregate_store_path()).ConsumeValueOrDie();
  EXPECT_TRUE(bad_store->SerializeToZeroCopyStream(stream.get()));
  // Read the bad store in to the EventAggregator.
  ResetEventAggregator();
  // Provide the all_report_types test registry to the EventAggregator.
  auto project_context = GetTestProject(logger::testing::all_report_types::kCobaltRegistryBase64);
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GetEventAggregator()
                                ->UpdateAggregationConfigs(*project_context)
                                .error_code());
  EXPECT_EQ(StatusCode::OK, GenerateObservations(CurrentDayIndex()).error_code());
  std::vector<Observation> observations(0);
  EXPECT_TRUE(FetchAggregatedObservations(
      &observations, logger::testing::all_report_types::kExpectedAggregationParams,
      observation_store_.get(), update_recipient_.get()));
}

// When the LocalAggregateStore contains one ReportAggregates proto and that
// proto is empty, GarbageCollect should return success.
TEST_F(AggregateStoreTest, GarbageCollectBadStore) {
  auto bad_store = std::make_unique<LocalAggregateStore>();
  (*bad_store->mutable_by_report_key())["some_key"] = ReportAggregates();
  auto stream = fs()->NewProtoOutputStream(aggregate_store_path()).ConsumeValueOrDie();
  EXPECT_TRUE(bad_store->SerializeToZeroCopyStream(stream.get()));
  // Read the bad store in to the EventAggregator.
  ResetEventAggregator();
  EXPECT_EQ(StatusCode::OK, GarbageCollect(CurrentDayIndex()).error_code());
}

// Tests GarbageCollect() for UniqueActivesReportAggregates.
//
// For each value of N in the range [0, 34], logs some UniqueActivesEvents
// each day for N consecutive days and then garbage-collects the
// LocalAggregateStore. After garbage collection, verifies the contents of
// the LocalAggregateStore.
TEST_F(UniqueActivesAggregateStoreTest, GarbageCollect) {
  uint32_t max_days_before_gc = 35;
  for (uint32_t days_before_gc = 0; days_before_gc < max_days_before_gc; days_before_gc++) {
    SetUp();
    day_last_garbage_collected_ = 0u;
    LoggedActivity logged_activity;
    for (uint32_t offset = 0; offset < days_before_gc; offset++) {
      auto day_index = CurrentDayIndex();
      for (const auto& metric_report_id :
           logger::testing::unique_actives::kExpectedAggregationParams.metric_report_ids) {
        // Add 2 events to the local aggregations with event code 0.
        EXPECT_EQ(
            StatusCode::OK,
            AddUniqueActivesEvent(metric_report_id, day_index, 0u, &logged_activity).error_code());
        EXPECT_EQ(
            StatusCode::OK,
            AddUniqueActivesEvent(metric_report_id, day_index, 0u, &logged_activity).error_code());
        if (offset < 3) {
          // Add 1 event to the local aggregations with event code 1.
          EXPECT_EQ(StatusCode::OK,
                    AddUniqueActivesEvent(metric_report_id, day_index, 1u, &logged_activity)
                        .error_code());
        }
      }
      AdvanceClock(kDay);
    }
    auto end_day_index = CurrentDayIndex();
    EXPECT_EQ(StatusCode::OK, GarbageCollect(end_day_index).error_code());
    day_last_garbage_collected_ = end_day_index;
    EXPECT_TRUE(CheckUniqueActivesAggregates(logged_activity, end_day_index));
    TearDown();
  }
}

// Tests that EventAggregator::GenerateObservations() returns a positive
// status and that the expected number of Observations is generated after
// some UniqueActivesEvents have been logged, without any garbage
// collection.
//
// For 35 days, logs 2 events each day for the NetworkActivity_UniqueDevices
// reports and 2 events for the FeaturesActive_UniqueDevices report, all
// with event code 0.
//
// Each day, calls GenerateObservations() with the day index of the previous
// day. Checks that a positive status is returned and that the
// FakeObservationStore has received the expected number of new observations
// for each locally aggregated report ID in the unique_actives registry.
TEST_F(UniqueActivesAggregateStoreTest, GenerateObservations) {
  int num_days = 35;
  std::vector<Observation> observations(0);
  for (int offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    observations.clear();
    ResetObservationStore();
    EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index - 1).error_code());
    EXPECT_TRUE(FetchAggregatedObservations(
        &observations, logger::testing::unique_actives::kExpectedAggregationParams,
        observation_store_.get(), update_recipient_.get()));
    for (int i = 0; i < 2; i++) {
      EXPECT_EQ(StatusCode::OK,
                AddUniqueActivesEvent(
                    logger::testing::unique_actives::kNetworkActivityWindowSizeMetricReportId,
                    day_index, 0u)
                    .error_code());
      EXPECT_EQ(
          StatusCode::OK,
          AddUniqueActivesEvent(
              logger::testing::unique_actives::kNetworkActivityAggregationWindowMetricReportId,
              day_index, 0u)
              .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddUniqueActivesEvent(
                    logger::testing::unique_actives::kFeaturesActiveMetricReportId, day_index, 0u)
                    .error_code());
    }
    AdvanceClock(kDay);
  }
  observations.clear();
  ResetObservationStore();
  EXPECT_EQ(StatusCode::OK, GenerateObservations(CurrentDayIndex() - 1).error_code());
  EXPECT_TRUE(FetchAggregatedObservations(
      &observations, logger::testing::unique_actives::kExpectedAggregationParams,
      observation_store_.get(), update_recipient_.get()));
}

// Tests that GenerateObservations() returns a positive status and that the
// expected number of Observations is generated each day when Events are
// logged for UNIQUE_N_DAY_ACTIVES reports over multiple days, and when the
// LocalAggregateStore is garbage-collected each day.
//
// For 35 days, logs 2 events each day for the NetworkActivity_UniqueDevices
// reports and 2 events for the FeaturesActive_UniqueDevices report, all
// with event code 0.
//
// Each day following the first day, calls GenerateObservations() and then
// GarbageCollect() with the day index of the current day. Checks that
// positive statuses are returned and that the FakeObservationStore has
// received the expected number of new observations for each locally
// aggregated report ID in the unique_actives registry.
TEST_F(UniqueActivesAggregateStoreTest, GenerateObservationsWithGc) {
  int num_days = 35;
  std::vector<Observation> observations(0);
  for (int offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    observations.clear();
    ResetObservationStore();
    EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index - 1).error_code());
    EXPECT_TRUE(FetchAggregatedObservations(
        &observations, logger::testing::unique_actives::kExpectedAggregationParams,
        observation_store_.get(), update_recipient_.get()));
    EXPECT_EQ(StatusCode::OK, GarbageCollect(day_index).error_code());
    for (int i = 0; i < 2; i++) {
      EXPECT_EQ(StatusCode::OK,
                AddUniqueActivesEvent(
                    logger::testing::unique_actives::kNetworkActivityWindowSizeMetricReportId,
                    day_index, 0u)
                    .error_code());
      EXPECT_EQ(
          StatusCode::OK,
          AddUniqueActivesEvent(
              logger::testing::unique_actives::kNetworkActivityAggregationWindowMetricReportId,
              day_index, 0u)
              .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddUniqueActivesEvent(
                    logger::testing::unique_actives::kFeaturesActiveMetricReportId, day_index, 0u)
                    .error_code());
    }
    AdvanceClock(kDay);
  }
  observations.clear();
  ResetObservationStore();
  auto day_index = CurrentDayIndex();
  EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index - 1).error_code());
  EXPECT_TRUE(FetchAggregatedObservations(
      &observations, logger::testing::unique_actives::kExpectedAggregationParams,
      observation_store_.get(), update_recipient_.get()));
  EXPECT_EQ(StatusCode::OK, GarbageCollect(day_index).error_code());
}

// Tests that GenerateObservations() returns a positive status and that the
// expected number of Observations is generated when events are logged over
// multiple days and some of those days' Observations are backfilled, without
// any garbage collection of the LocalAggregateStore.
//
// Sets the |backfill_days_| field of the EventAggregator to 3.
//
// Logging pattern:
// For 35 days, logs 2 events each day for the
// NetworkActivity_UniqueDevices reports and 2 events for the
// FeaturesActive_UniqueDevices report, all with event code 0.
//
// Observation generation pattern:
// Calls GenerateObservations() on the 1st through 5th and the 7th out of
// every 10 days, for 35 days.
//
// Expected numbers of Observations:
// It is expected that 4 days' worth of Observations are generated on
// the first day of every 10 (the day index for which GenerateObservations()
// was called, plus 3 days of backfill), that 1 day's worth of Observations
// are generated on the 2nd through 5th day of every 10, that 2 days'
// worth of Observations are generated on the 7th day of every 10 (the
// day index for which GenerateObservations() was called, plus 1 day of
// backfill), and that no Observations are generated on the remaining days.
TEST_F(UniqueActivesAggregateStoreTest, GenerateObservationsWithBackfill) {
  // Set |backfill_days_| to 3.
  SetBackfillDays(kTestBackfillDays);
  // Adds 2 events to the local aggregations each day for 35 days. Call GenerateObservations() on
  // the first 5 day indices, and the 7th, out of every 10.
  for (int offset = 0; offset < 35; offset++) {
    auto day_index = CurrentDayIndex();
    for (int i = 0; i < 2; i++) {
      EXPECT_EQ(StatusCode::OK,
                AddUniqueActivesEvent(
                    logger::testing::unique_actives::kNetworkActivityWindowSizeMetricReportId,
                    day_index, 0u)
                    .error_code());
      EXPECT_EQ(
          StatusCode::OK,
          AddUniqueActivesEvent(
              logger::testing::unique_actives::kNetworkActivityAggregationWindowMetricReportId,
              day_index, 0u)
              .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddUniqueActivesEvent(
                    logger::testing::unique_actives::kFeaturesActiveMetricReportId, day_index, 0u)
                    .error_code());
    }
    observation_store_->ResetObservationCounter();
    if (offset % 10 < 5 || offset % 10 == 6) {
      EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());
    }
    auto num_new_obs = observation_store_->num_observations_added();
    EXPECT_GE(num_new_obs, 0u);
    // Check that the expected daily number of Observations was generated.
    switch (offset % 10) {
      case 0:
        EXPECT_EQ(logger::testing::unique_actives::kExpectedAggregationParams.daily_num_obs *
                      (kTestBackfillDays + 1),
                  num_new_obs);
        break;
      case 1:
      case 2:
      case 3:
      case 4:
        EXPECT_EQ(logger::testing::unique_actives::kExpectedAggregationParams.daily_num_obs,
                  num_new_obs);
        break;
      case 6:
        EXPECT_EQ(logger::testing::unique_actives::kExpectedAggregationParams.daily_num_obs * 2,
                  num_new_obs);
        break;
      default:
        EXPECT_EQ(0u, num_new_obs);
    }
    AdvanceClock(kDay);
  }
}

// Tests that GenerateObservations() returns a positive status and that the
// expected number of Observations is generated when events are logged over
// multiple days and some of those days' Observations are backfilled, and when
// the LocalAggregateStore is garbage-collected after each call to
// GenerateObservations().
//
// Sets the |backfill_days_| field of the EventAggregator to 3.
//
// Logging pattern:
// For 35 days, logs 2 events each day for the
// NetworkActivity_UniqueDevices reports and 2 events for the
// FeaturesActive_Unique_Devices report, all with event code 0.
//
// Observation generation pattern:
// Calls GenerateObservations() on the 1st through 5th and the 7th out of
// every 10 days, for 35 days. Garbage-collects the LocalAggregateStore after
// each call.
//
// Expected numbers of Observations:
// It is expected that 4 days' worth of Observations are generated on
// the first day of every 10 (the day index for which GenerateObservations()
// was called, plus 3 days of backfill), that 1 day's worth of Observations
// are generated on the 2nd through 5th day of every 10, that 2 days'
// worth of Observations are generated on the 7th day of every 10 (the
// day index for which GenerateObservations() was called, plus 1 day of
// backfill), and that no Observations are generated on the remaining days.
TEST_F(UniqueActivesAggregateStoreTest, GenerateObservationsWithBackfillAndGc) {
  int num_days = 35;
  // Set |backfill_days_| to 3.
  SetBackfillDays(kTestBackfillDays);
  // Adds 2 events to the local aggregations each day for 35 days. Call GenerateObservations() on
  // the first 5 day indices, and the 7th, out of every 10.
  for (int offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    for (int i = 0; i < 2; i++) {
      EXPECT_EQ(StatusCode::OK,
                AddUniqueActivesEvent(
                    logger::testing::unique_actives::kNetworkActivityWindowSizeMetricReportId,
                    day_index, 0u)
                    .error_code());
      EXPECT_EQ(
          StatusCode::OK,
          AddUniqueActivesEvent(
              logger::testing::unique_actives::kNetworkActivityAggregationWindowMetricReportId,
              day_index, 0u)
              .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddUniqueActivesEvent(
                    logger::testing::unique_actives::kFeaturesActiveMetricReportId, day_index, 0u)
                    .error_code());
    }
    observation_store_->ResetObservationCounter();
    if (offset % 10 < 5 || offset % 10 == 6) {
      EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());
      EXPECT_EQ(StatusCode::OK, GarbageCollect(day_index).error_code());
    }
    auto num_new_obs = observation_store_->num_observations_added();
    EXPECT_GE(num_new_obs, 0u);
    // Check that the expected daily number of Observations was generated.
    // This expected number is some multiple of the daily_num_obs field of
    // |kUniqueActivesExpectedParams|, depending on the number of days which
    // should have been backfilled when GenerateObservations() was called.
    switch (offset % 10) {
      case 0:
        EXPECT_EQ(logger::testing::unique_actives::kExpectedAggregationParams.daily_num_obs *
                      (kTestBackfillDays + 1),
                  num_new_obs);
        break;
      case 1:
      case 2:
      case 3:
      case 4:
        EXPECT_EQ(logger::testing::unique_actives::kExpectedAggregationParams.daily_num_obs,
                  num_new_obs);
        break;
      case 6:
        EXPECT_EQ(logger::testing::unique_actives::kExpectedAggregationParams.daily_num_obs * 2,
                  num_new_obs);
        break;
      default:
        EXPECT_EQ(0u, num_new_obs);
    }
    AdvanceClock(kDay);
  }
}

// Checks that UniqueActivesObservations with the expected values (i.e.,
// non-active for all UNIQUE_N_DAY_ACTIVES reports, for all window sizes and
// event codes) are generated when no Events have been logged to the
// EventAggregator.
TEST_F(UniqueActivesNoiseFreeAggregateStoreTest, CheckObservationValuesNoEvents) {
  auto current_day_index = CurrentDayIndex();
  EXPECT_EQ(StatusCode::OK, GenerateObservations(current_day_index).error_code());
  auto expected_obs = MakeNullExpectedUniqueActivesObservations(
      logger::testing::unique_actives_noise_free::kExpectedAggregationParams, current_day_index);
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                             update_recipient_.get()));
}

// Checks that UniqueActivesObservations with the expected values are
// generated when GenerateObservations() is called for a single day index
// after logging some events for UNIQUE_N_DAY_ACTIVES reports for that day
// index, without any garbage collection or backfill.
//
// Logging pattern:
// Logs 2 occurrences of event code 0 for the FeaturesActives_UniqueDevices
// report, and 1 occurrence of event code 1 for the
// EventsOccurred_UniqueDevices report, all on the same day.
//
// Observation generation pattern:
// Calls GenerateObservations() after logging all events.
//
// Expected numbers of Observations:
// The expected number of Observations is the daily_num_obs field of
// |logger::testing::unique_actives_noise_free::kExpectedAggregationParams|.
//
// Expected Observation values:
// All Observations should be labeled with the day index on which the events
// were logged.
//
// For the FeaturesActive_UniqueDevices report, expect activity indicators:
//
// window size        active for event codes
// ------------------------------------------
// 1                           0
// 7                           0
// 30                          0
//
// For the EventsOccurred_UniqueDevices report, expected activity indicators:
// window size        active for event codes
// ------------------------------------------
// 1                           1
// 7                           1
//
// All other Observations should be of inactivity.
TEST_F(UniqueActivesNoiseFreeAggregateStoreTest, CheckObservationValuesSingleDay) {
  auto day_index = CurrentDayIndex();
  // Adds several events to the local aggregations on |day_index|.
  EXPECT_EQ(
      StatusCode::OK,
      AddUniqueActivesEvent(
          logger::testing::unique_actives_noise_free::kFeaturesActiveMetricReportId, day_index, 0u)
          .error_code());
  EXPECT_EQ(
      StatusCode::OK,
      AddUniqueActivesEvent(
          logger::testing::unique_actives_noise_free::kFeaturesActiveMetricReportId, day_index, 0u)
          .error_code());
  EXPECT_EQ(
      StatusCode::OK,
      AddUniqueActivesEvent(
          logger::testing::unique_actives_noise_free::kEventsOccurredMetricReportId, day_index, 1u)
          .error_code());
  // Generate locally aggregated Observations for |day_index|.
  EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());

  // Form the expected observations.
  auto expected_obs = MakeNullExpectedUniqueActivesObservations(
      logger::testing::unique_actives_noise_free::kExpectedAggregationParams, day_index);
  expected_obs[{logger::testing::unique_actives_noise_free::kFeaturesActiveMetricReportId,
                day_index}] = {{1, {true, false, false, false, false}},
                               {7, {true, false, false, false, false}},
                               {28, {true, false, false, false, false}},
                               {30, {true, false, false, false, false}}};
  expected_obs[{logger::testing::unique_actives_noise_free::kEventsOccurredMetricReportId,
                day_index}] = {{1, {false, true, false, false, false}},
                               {7, {false, true, false, false, false}}};

  // Check the contents of the FakeObservationStore.
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                             update_recipient_.get()));
}

// Checks that UniqueActivesObservations with the expected values are
// generated when some events have been logged for a UNIQUE_N_DAY_ACTIVES
// report over multiple days and GenerateObservations() is called each
// day, without garbage collection or backfill.
//
// Logging pattern:
// Logs events for the EventsOccurred_UniqueDevices report (whose parent
// metric has max_event_code = 4) 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.
//
// Observation generation pattern:
// Each day following the first day, generates Observations for the previous
// day index.
//
// Expected number of Observations:
// Each call to GenerateObservations should generate a number of Observations
// equal to the daily_num_obs field of
// |testing::unique_actives_noise_free::kExpectedAggregationParams|.
//
// Expected Observation values:
// The EventsOccurred_UniqueDevices report has window sizes 1 and 7, and
// the expected activity indicators of Observations for that report on the
// i-th day are:
//
// (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(UniqueActivesNoiseFreeAggregateStoreTest, CheckObservationValuesMultiDay) {
  auto start_day_index = CurrentDayIndex();
  // Form expected Obsevations for the 10 days of logging.
  uint32_t num_days = 10;
  std::vector<ExpectedUniqueActivesObservations> expected_obs(num_days);
  const auto& expected_id =
      logger::testing::unique_actives_noise_free::kEventsOccurredMetricReportId;
  for (uint32_t offset = 0; offset < num_days; offset++) {
    expected_obs[offset] = MakeNullExpectedUniqueActivesObservations(
        logger::testing::unique_actives_noise_free::kExpectedAggregationParams,
        start_day_index + offset);
  }
  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 offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    for (uint32_t event_code = 1;
         event_code <
         logger::testing::unique_actives_noise_free::kExpectedAggregationParams.num_event_codes.at(
             expected_id);
         event_code++) {
      if (offset % (3 * event_code) == 0) {
        EXPECT_EQ(StatusCode::OK,
                  AddUniqueActivesEvent(expected_id, day_index, event_code).error_code());
      }
    }
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Generate locally aggregated Observations.
    EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());
    // Check the generated Observations against the expectation.
    EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[offset], observation_store_.get(),
                                               update_recipient_.get()));
    AdvanceClock(kDay);
  }
}

// Checks that UniqueActivesObservations with the expected values are
// generated when some events have been logged for a UNIQUE_N_DAY_ACTIVES
// report over multiple days and GenerateObservations() is called each
// day, and when the LocalAggregateStore is garbage-collected after each call
// to GenerateObservations().
//
// Logging pattern:
// Logs events for the EventsOccurred_UniqueDevices report (whose parent
// metric has max_event_code = 4) 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.
//
// Observation generation pattern:
// Each day following the first day, generates Observations for the previous
// day index.
//
// Expected number of Observations:
// Each call to GenerateObservations should generate a number of Observations
// equal to the daily_num_obs field of
// |logger::testing::unique_actives_noise_free::kExpectedAggregationParams|.
//
// Expected Observation values:
// The EventsOccurred_UniqueDevices report has window sizes 1 and 7, and
// the expected activity indicators of Observations for that report on the
// i-th day are:
//
// (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(UniqueActivesNoiseFreeAggregateStoreTest,
       CheckObservationValuesMultiDayWithGarbageCollection) {
  auto start_day_index = CurrentDayIndex();
  // Form expected Observations for the 10 days of logging.
  uint32_t num_days = 10;
  std::vector<ExpectedUniqueActivesObservations> expected_obs(num_days);
  const auto& expected_id =
      logger::testing::unique_actives_noise_free::kEventsOccurredMetricReportId;

  for (uint32_t offset = 0; offset < num_days; offset++) {
    expected_obs[offset] = MakeNullExpectedUniqueActivesObservations(
        logger::testing::unique_actives_noise_free::kExpectedAggregationParams,
        start_day_index + offset);
  }
  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 offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    for (uint32_t event_code = 1;
         event_code <
         logger::testing::unique_actives_noise_free::kExpectedAggregationParams.num_event_codes.at(
             expected_id);
         event_code++) {
      if (offset % (3 * event_code) == 0) {
        EXPECT_EQ(StatusCode::OK,
                  AddUniqueActivesEvent(expected_id, day_index, event_code).error_code());
      }
    }
    // Advance |test_clock_| by 1 day.
    AdvanceClock(kDay);
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Generate locally aggregated Observations and garbage-collect the
    // LocalAggregateStore, both for the previous day as measured by
    // |test_clock_|. Back up the LocalAggregateStore and
    // AggregatedObservationHistoryStore.
    DoScheduledTasksNow();
    // Check the generated Observations against the expectation.
    EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[offset], observation_store_.get(),
                                               update_recipient_.get()));
  }
}

// Tests that the expected UniqueActivesObservations are generated when events
// are logged over multiple days and when Observations are backfilled for some
// days during that period, without any garbage-collection of the
// LocalAggregateStore.
//
// The test sets the number of backfill days to 3.
//
// Logging pattern:
// Events for the EventsOccurred_UniqueDevices report are logged over the days
// |start_day_index| to |start_day_index + 8| according to the following
// pattern:
//
// * For i = 0 to i = 4, log an event with event code i on day
// |start_day_index + i| and |start_day_index + 2*i|.
//
// Observation generation pattern:
// The test calls GenerateObservations() on day |start_day_index + i| for i =
// 0 through i = 5 and for i = 8, skipping the days |start_day_index + 6| and
// |start_day_index + 7|.
//
// Expected numbers of Observations:
// It is expected that 4 days' worth of Observations are generated on the
// first day (the day index for which GenerateObservations() was called, plus
// 3 days of backfill), that 1 day's worth of Observations is generated on the
// 2nd through 6th day, that 3 days' worth of Observations are generated on
// the 9th day (the day index for which GenerateObservations() was called,
// plus 2 days of backfill), and that no Observations are generated on the
// remaining days.
//
// Expected Observation values:
// The expected activity indicators of Observations for the
// EventsOccurred_UniqueDevices report for the i-th day of logging are:
//
// (i, window size)           active for event codes
// -------------------------------------------------------------------------
// (0, 1)                           0
// (0, 7)                           0
// (1, 1)                           1
// (1, 7)                           0, 1
// (2, 1)                           1, 2
// (2, 7)                           0, 1, 2
// (3, 1)                           3
// (3, 7)                           0, 1, 2, 3
// (4, 1)                           2, 4
// (4, 7)                           0, 1, 2, 3, 4
// (5, 1)                          ---
// (5, 7)                           0, 1, 2, 3, 4
// (6, 1)                           3
// (6, 7)                           0, 1, 2, 3, 4
// (7, 1)                          ---
// (7, 7)                           1, 2, 3, 4
// (8, 1)                           4
// (8, 7)                           1, 2, 3, 4
//
// All other Observations should be of non-activity.
TEST_F(UniqueActivesNoiseFreeAggregateStoreTest, CheckObservationValuesWithBackfill) {
  auto start_day_index = CurrentDayIndex();
  // Set |backfill_days_| to 3.
  SetBackfillDays(kTestBackfillDays);
  const auto& expected_id =
      logger::testing::unique_actives_noise_free::kEventsOccurredMetricReportId;
  const auto& expected_params =
      logger::testing::unique_actives_noise_free::kExpectedAggregationParams;
  // Add eventsto the local aggregations for 9 days. Call GenerateObservations() on the first 6
  // day indices, and the 9th.
  for (uint32_t offset = 0; offset < 9; offset++) {
    auto day_index = CurrentDayIndex();
    ResetObservationStore();
    for (uint32_t event_code = 0; event_code < expected_params.num_event_codes.at(expected_id);
         event_code++) {
      if (event_code == offset || (2 * event_code) == offset) {
        EXPECT_EQ(StatusCode::OK,
                  AddUniqueActivesEvent(expected_id, day_index, event_code).error_code());
      }
    }
    if (offset < 6 || offset == 8) {
      EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());
    }
    // Make the set of Observations which are expected to be generated on
    // |start_day_index + offset| and check it against the contents of the
    // FakeObservationStore.
    ExpectedUniqueActivesObservations expected_obs;
    switch (offset) {
      case 0: {
        for (uint32_t day_index = start_day_index - kTestBackfillDays; day_index <= start_day_index;
             day_index++) {
          for (const auto& pair :
               MakeNullExpectedUniqueActivesObservations(expected_params, day_index)) {
            expected_obs.insert(pair);
          }
        }
        expected_obs[{expected_id, start_day_index}] = {{1, {true, false, false, false, false}},
                                                        {7, {true, false, false, false, false}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 1: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 1);
        expected_obs[{expected_id, start_day_index + 1}] = {{1, {false, true, false, false, false}},
                                                            {7, {true, true, false, false, false}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 2: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 2);
        expected_obs[{expected_id, start_day_index + 2}] = {{1, {false, true, true, false, false}},
                                                            {7, {true, true, true, false, false}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 3: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 3);
        expected_obs[{expected_id, start_day_index + 3}] = {{1, {false, false, false, true, false}},
                                                            {7, {true, true, true, true, false}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 4: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 4);
        expected_obs[{expected_id, start_day_index + 4}] = {{1, {false, false, true, false, true}},
                                                            {7, {true, true, true, true, true}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 5: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 5);
        expected_obs[{expected_id, start_day_index + 5}] = {
            {1, {false, false, false, false, false}}, {7, {true, true, true, true, true}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 8: {
        for (uint32_t day_index = start_day_index + 6; day_index <= start_day_index + 8;
             day_index++) {
          for (const auto& pair :
               MakeNullExpectedUniqueActivesObservations(expected_params, day_index)) {
            expected_obs.insert(pair);
          }
        }
        expected_obs[{expected_id, start_day_index + 6}] = {{1, {false, false, false, true, false}},
                                                            {7, {true, true, true, true, true}}};
        expected_obs[{expected_id, start_day_index + 7}] = {
            {1, {false, false, false, false, false}}, {7, {false, true, true, true, true}}};
        expected_obs[{expected_id, start_day_index + 8}] = {{1, {false, false, false, false, true}},
                                                            {7, {false, true, true, true, true}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      default:
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
    }
    AdvanceClock(kDay);
  }
}

// Tests that the expected UniqueActivesObservations are generated when events
// are logged over multiple days and when Observations are backfilled for some
// days during that period, and when the LocalAggregateStore is
// garbage-collected after each call to GenerateObservations().
//
// The test sets the number of backfill days to 3.
//
// Logging pattern:
// Events for the EventsOccurred_UniqueDevices report are logged over the days
// |start_day_index| to |start_day_index + 8| according to the following
// pattern:
//
// * For i = 0 to i = 4, log an event with event code i on day
// |start_day_index + i| and |start_day_index + 2*i|.
//
// Observation generation pattern:
// The test calls GenerateObservations() on day |start_day_index + i| for i =
// 0 through i = 5 and for i = 8, skipping the days |start_day_index + 6| and
// |start_day_index + 7|.
//
// Expected numbers of Observations:
// It is expected that 4 days' worth of Observations are generated on the
// first day (the day index for which GenerateObservations() was called, plus
// 3 days of backfill), that 1 day's worth of Observations is generated on the
// 2nd through 6th day, that 3 days' worth of Observations are generated on
// the 9th day (the day index for which GenerateObservations() was called,
// plus 2 days of backfill), and that no Observations are generated on the
// remaining days.
//
// Expected Observation values:
// The expected activity indicators of Observations for the
// EventsOccurred_UniqueDevices report for the i-th day of logging are:
//
// (i, window size)           active for event codes
// -------------------------------------------------------------------------
// (0, 1)                           0
// (0, 7)                           0
// (1, 1)                           1
// (1, 7)                           0, 1
// (2, 1)                           1, 2
// (2, 7)                           0, 1, 2
// (3, 1)                           3
// (3, 7)                           0, 1, 2, 3
// (4, 1)                           2, 4
// (4, 7)                           0, 1, 2, 3, 4
// (5, 1)                          ---
// (5, 7)                           0, 1, 2, 3, 4
// (6, 1)                           3
// (6, 7)                           0, 1, 2, 3, 4
// (7, 1)                          ---
// (7, 7)                           1, 2, 3, 4
// (8, 1)                           4
// (8, 7)                           1, 2, 3, 4
//
// All other Observations should be of non-activity.
TEST_F(UniqueActivesNoiseFreeAggregateStoreTest, CheckObservationValuesWithBackfillAndGc) {
  auto start_day_index = CurrentDayIndex();
  // Set |backfill_days_| to 3.
  SetBackfillDays(kTestBackfillDays);

  const auto& expected_id =
      logger::testing::unique_actives_noise_free::kEventsOccurredMetricReportId;
  const auto& expected_params =
      logger::testing::unique_actives_noise_free::kExpectedAggregationParams;

  // Add events to the local aggregations for 9 days. Call GenerateObservations() on the first 6
  // day indices, and the 9th.
  for (uint32_t offset = 0; offset < 8; offset++) {
    auto day_index = CurrentDayIndex();
    ResetObservationStore();
    for (uint32_t event_code = 0; event_code < expected_params.num_event_codes.at(expected_id);
         event_code++) {
      if (event_code == offset || (2 * event_code) == offset) {
        EXPECT_EQ(StatusCode::OK,
                  AddUniqueActivesEvent(expected_id, day_index, event_code).error_code());
      }
    }
    // Advance |test_clock_| by 1 day.
    AdvanceClock(kDay);
    if (offset < 6 || offset == 9) {
      // Generate Observations and garbage-collect, both for the previous day
      // index according to |test_clock_|. Back up the LocalAggregateStore and
      // the AggregatedObservationHistoryStore.
      DoScheduledTasksNow();
    }
    // Make the set of Observations which are expected to be generated on
    // |start_day_index + offset| and check it against the contents of the
    // FakeObservationStore.
    ExpectedUniqueActivesObservations expected_obs;
    switch (offset) {
      case 0: {
        for (uint32_t day_index = start_day_index - kTestBackfillDays; day_index <= start_day_index;
             day_index++) {
          for (const auto& pair :
               MakeNullExpectedUniqueActivesObservations(expected_params, day_index)) {
            expected_obs.insert(pair);
          }
        }
        expected_obs[{expected_id, start_day_index}] = {{1, {true, false, false, false, false}},
                                                        {7, {true, false, false, false, false}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 1: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 1);
        expected_obs[{expected_id, start_day_index + 1}] = {{1, {false, true, false, false, false}},
                                                            {7, {true, true, false, false, false}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 2: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 2);
        expected_obs[{expected_id, start_day_index + 2}] = {{1, {false, true, true, false, false}},
                                                            {7, {true, true, true, false, false}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 3: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 3);
        expected_obs[{expected_id, start_day_index + 3}] = {{1, {false, false, false, true, false}},
                                                            {7, {true, true, true, true, false}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 4: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 4);
        expected_obs[{expected_id, start_day_index + 4}] = {{1, {false, false, true, false, true}},
                                                            {7, {true, true, true, true, true}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 5: {
        expected_obs =
            MakeNullExpectedUniqueActivesObservations(expected_params, start_day_index + 5);
        expected_obs[{expected_id, start_day_index + 5}] = {
            {1, {false, false, false, false, false}}, {7, {true, true, true, true, true}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      case 8: {
        for (uint32_t day_index = start_day_index + 6; day_index <= start_day_index + 8;
             day_index++) {
          for (const auto& pair :
               MakeNullExpectedUniqueActivesObservations(expected_params, day_index)) {
            expected_obs.insert(pair);
          }
        }
        expected_obs[{expected_id, start_day_index + 6}] = {{1, {false, false, false, true, false}},
                                                            {7, {true, true, true, true, true}}};
        expected_obs[{expected_id, start_day_index + 7}] = {
            {1, {false, false, false, false, false}}, {7, {false, true, true, true, true}}};
        expected_obs[{expected_id, start_day_index + 8}] = {{1, {false, false, false, false, true}},
                                                            {7, {false, true, true, true, true}}};
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
        break;
      }
      default:
        EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                                   update_recipient_.get()));
    }
  }
}

// Tests GarbageCollect() for PerDeviceNumericReportAggregates.
//
// For each value of N in the range [0, 34], logs some events for
// PerDeviceNumeric reports each day for N consecutive days, and then
// garbage-collects the LocalAggregateStore. After garbage collection, verifies
// the contents of the LocalAggregateStore.
TEST_F(PerDeviceNumericAggregateStoreTest, GarbageCollect) {
  uint32_t max_days_before_gc = 35;
  for (uint32_t days_before_gc = 0; days_before_gc < max_days_before_gc; days_before_gc++) {
    SetUp();
    day_last_garbage_collected_ = 0u;
    LoggedValues logged_values;
    std::vector<MetricReportId> count_metric_report_ids = {
        logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
        logger::testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId,
        logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId};
    std::vector<MetricReportId> elapsed_time_metric_report_ids = {
        logger::testing::per_device_numeric_stats::kStreamingTimeTotalMetricReportId,
        logger::testing::per_device_numeric_stats::kStreamingTimeMinMetricReportId,
        logger::testing::per_device_numeric_stats::kStreamingTimeMaxMetricReportId};
    MetricReportId frame_rate_metric_report_id =
        logger::testing::per_device_numeric_stats::kLoginModuleFrameRateMinMetricReportId;
    MetricReportId memory_usage_metric_report_id =
        logger::testing::per_device_numeric_stats::kLedgerMemoryUsageMaxMetricReportId;
    for (uint32_t offset = 0; offset < days_before_gc; offset++) {
      auto day_index = CurrentDayIndex();
      for (const auto& id : count_metric_report_ids) {
        for (const auto& component : {"component_A", "component_B", "component_C"}) {
          // Adds 2 events to the local aggregations with event code 0, for each component A, B,
          // C.
          EXPECT_EQ(StatusCode::OK,
                    AddPerDeviceEventCountEvent(id, day_index, component, 0u, 2, &logged_values)
                        .error_code());
          EXPECT_EQ(StatusCode::OK,
                    AddPerDeviceEventCountEvent(id, day_index, component, 0u, 3, &logged_values)
                        .error_code());
        }
        if (offset < 3) {
          // Adds 1 event to the local aggregations for component D and event code 1.
          EXPECT_EQ(StatusCode::OK,
                    AddPerDeviceEventCountEvent(id, day_index, "component_D", 1u, 4, &logged_values)
                        .error_code());
        }
      }
      for (const auto& id : elapsed_time_metric_report_ids) {
        for (const auto& component : {"component_A", "component_B", "component_C"}) {
          // Add 2 events to the local aggregations with event code 0, for each component A, B, C.
          EXPECT_EQ(StatusCode::OK,
                    AddPerDeviceElapsedTimeEvent(id, day_index, component, 0u, 2, &logged_values)
                        .error_code());
          EXPECT_EQ(StatusCode::OK,
                    AddPerDeviceElapsedTimeEvent(id, day_index, component, 0u, 3, &logged_values)
                        .error_code());
        }
        if (offset < 3) {
          // Add 1 event to the local aggregations for component D and event code 1.
          EXPECT_EQ(StatusCode::OK, AddPerDeviceElapsedTimeEvent(id, day_index, "component_D", 1u,
                                                                 4, &logged_values)
                                        .error_code());
        }
      }
      for (const auto& component : {"component_A", "component_B"}) {
        EXPECT_EQ(StatusCode::OK, AddPerDeviceFrameRateEvent(frame_rate_metric_report_id, day_index,
                                                             component, 0u, 2.25, &logged_values)
                                      .error_code());
        EXPECT_EQ(StatusCode::OK, AddPerDeviceFrameRateEvent(frame_rate_metric_report_id, day_index,
                                                             component, 0u, 1.75, &logged_values)
                                      .error_code());
        EXPECT_EQ(StatusCode::OK,
                  AddPerDeviceMemoryUsageEvent(memory_usage_metric_report_id, day_index, component,
                                               std::vector<uint32_t>{0u, 0u}, 300, &logged_values)
                      .error_code());
        EXPECT_EQ(StatusCode::OK,
                  AddPerDeviceMemoryUsageEvent(memory_usage_metric_report_id, day_index, component,
                                               std::vector<uint32_t>{1u, 0u}, 300, &logged_values)
                      .error_code());
      }
      AdvanceClock(kDay);
    }
    auto end_day_index = CurrentDayIndex();
    EXPECT_EQ(StatusCode::OK, GarbageCollect(end_day_index).error_code());
    day_last_garbage_collected_ = end_day_index;
    EXPECT_TRUE(CheckPerDeviceNumericAggregates(logged_values, end_day_index));
    TearDown();
  }
}

// Tests that EventAggregator::GenerateObservations() returns a positive
// status and that the expected number of Observations is generated after
// some EventCountEvents have been logged for PerDeviceNumericStats reports, without
// any garbage collection.
//
// For 35 days, logs a positive number of events each day for the
// ConnectionFailures_PerDeviceNumericStats report with "component_A" and for
// the SettingsChanged_PerDeviceNumericStats reports with "component_B", all with
// event code 0.
//
// Each day, calls GenerateObservations() with the day index of the previous
// day. Checks that a positive status is returned and that the
// FakeObservationStore has received the expected number of new observations
// for each locally aggregated report ID in the per_device_numeric_stats test
// registry.
TEST_F(PerDeviceNumericAggregateStoreTest, GenerateObservations) {
  int num_days = 1;
  std::vector<Observation> observations(0);
  ExpectedAggregationParams expected_params =
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams;
  for (int offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    observations.clear();
    ResetObservationStore();
    EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index - 1).error_code());
    EXPECT_TRUE(FetchAggregatedObservations(&observations, expected_params,
                                            observation_store_.get(), update_recipient_.get()));
    for (int i = 0; i < 2; i++) {
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(
                    logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                    day_index, "component_A", 0u, 1)
                    .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(
                    logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                    day_index, "component_A", 0u, 1)
                    .error_code());
      EXPECT_EQ(
          StatusCode::OK,
          AddPerDeviceEventCountEvent(
              logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
              day_index, "component_B", 0u, 5)
              .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(logger::testing::per_device_numeric_stats::
                                                kSettingsChangedAggregationWindowMetricReportId,
                                            day_index, "component_B", 0u, 5)
                    .error_code());
    }
    // If this is the first time we're logging events, update the expected
    // numbers of generated Observations to account for the logged events.
    // For each report, for each aggregation window, expect 1 Observation more than if
    // no events had been logged.
    if (offset == 0) {
      expected_params.daily_num_obs += 5;
      expected_params.num_obs_per_report
          [logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId] += 1;
      expected_params.num_obs_per_report
          [logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId] +=
          2;
      expected_params.num_obs_per_report[logger::testing::per_device_numeric_stats::
                                             kSettingsChangedAggregationWindowMetricReportId] += 2;
    }
    AdvanceClock(kDay);
  }
  observations.clear();
  ResetObservationStore();
  EXPECT_EQ(StatusCode::OK, GenerateObservations(CurrentDayIndex() - 1).error_code());
  EXPECT_TRUE(FetchAggregatedObservations(&observations, expected_params, observation_store_.get(),
                                          update_recipient_.get()));
}

// Tests that EventAggregator::GenerateObservations() returns a positive
// status and that the expected number of Observations is generated after
// some EventCountEvents have been logged for PerDeviceNumeric reports over multiple
// days, and when the LocalAggregateStore is garbage-collected each day.
//
// For 35 days, logs a positive number of events each day for the
// ConnectionFailures_PerDeviceNumeric report with "component_A" and for
// the SettingsChanged_PerDeviceNumeric report with "component_B", all with
// event code 0.
//
// Each day, calls GenerateObservations() with the day index of the previous
// day. Checks that a positive status is returned and that the
// FakeObservationStore has received the expected number of new observations
// for each locally aggregated report ID in the per_device_numeric_stats test
// registry.
TEST_F(PerDeviceNumericAggregateStoreTest, GenerateObservationsWithGc) {
  int num_days = 35;
  std::vector<Observation> observations(0);
  ExpectedAggregationParams expected_params =
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams;
  for (int offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    observations.clear();
    ResetObservationStore();
    EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index - 1).error_code());
    EXPECT_TRUE(FetchAggregatedObservations(&observations, expected_params,
                                            observation_store_.get(), update_recipient_.get()));
    EXPECT_EQ(StatusCode::OK, GarbageCollect(day_index).error_code());
    for (int i = 0; i < 2; i++) {
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(
                    logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                    day_index, "component_A", 0u, 1)
                    .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(
                    logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                    day_index, "component_A", 0u, 1)
                    .error_code());
      EXPECT_EQ(
          StatusCode::OK,
          AddPerDeviceEventCountEvent(
              logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
              day_index, "component_B", 0u, 5)
              .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(logger::testing::per_device_numeric_stats::
                                                kSettingsChangedAggregationWindowMetricReportId,
                                            day_index, "component_B", 0u, 5)
                    .error_code());
    }
    // If this is the first time we're logging events, update the expected
    // numbers of generated Observations to account for the logged events.
    // For each report, for each window size, expect 1 Observation more than if
    // no events had been logged.
    if (offset == 0) {
      expected_params.daily_num_obs += 5;
      expected_params.num_obs_per_report
          [logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId] += 1;
      expected_params.num_obs_per_report
          [logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId] +=
          2;
      expected_params.num_obs_per_report[logger::testing::per_device_numeric_stats::
                                             kSettingsChangedAggregationWindowMetricReportId] += 2;
    }
    AdvanceClock(kDay);
  }
  observations.clear();
  ResetObservationStore();
  auto day_index = CurrentDayIndex();
  EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index - 1).error_code());
  EXPECT_TRUE(FetchAggregatedObservations(&observations, expected_params, observation_store_.get(),
                                          update_recipient_.get()));
  EXPECT_EQ(StatusCode::OK, GarbageCollect(day_index).error_code());
}

// Tests that GenerateObservations() returns a positive status and that the
// expected number of Observations is generated when events are logged over
// multiple days and some of those days' Observations are backfilled, without
// any garbage collection of the LocalAggregateStore.
//
// Sets the |backfill_days_| field of the EventAggregator to 3.
//
// Logging pattern:
// For 35 days, logs 2 events each day for the
// ConnectionFailures_PerDeviceCount report and 2 events for the
// SettingsChanged_PerDeviceCount report, all with event code 0.
//
// Observation generation pattern:
// Calls GenerateObservations() on the 1st through 5th and the 7th out of
// every 10 days, for 35 days.
//
// Expected numbers of Observations:
// It is expected that 4 days' worth of Observations are generated on
// the first day of every 10 (the day index for which GenerateObservations()
// was called, plus 3 days of backfill), that 1 day's worth of Observations
// are generated on the 2nd through 5th day of every 10, that 2 days'
// worth of Observations are generated on the 7th day of every 10 (the
// day index for which GenerateObservations() was called, plus 1 day of
// backfill), and that no Observations are generated on the remaining days.
TEST_F(PerDeviceNumericAggregateStoreTest, GenerateObservationsWithBackfill) {
  const auto& expected_params =
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams;
  // Set |backfill_days_| to 3.
  SetBackfillDays(kTestBackfillDays);
  // Add 2 events to the local aggregations each day for 35 days. Call GenerateObservations() on
  // the first 5 day indices, and the 7th, out of every 10.
  for (int offset = 0; offset < 35; offset++) {
    auto day_index = CurrentDayIndex();
    for (int i = 0; i < 2; i++) {
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(
                    logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                    day_index, "component_A", 0u, 1)
                    .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(
                    logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                    day_index, "component_A", 0u, 1)
                    .error_code());
      EXPECT_EQ(
          StatusCode::OK,
          AddPerDeviceEventCountEvent(
              logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
              day_index, "component_B", 0u, 5)
              .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(logger::testing::per_device_numeric_stats::
                                                kSettingsChangedAggregationWindowMetricReportId,
                                            day_index, "component_B", 0u, 5)
                    .error_code());
    }
    auto num_obs_before = observation_store_->messages_received.size();
    if (offset % 10 < 5 || offset % 10 == 6) {
      EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());
    }
    auto num_obs_after = observation_store_->messages_received.size();
    EXPECT_GE(num_obs_after, num_obs_before);
    // Check that the expected daily number of Observations was generated.
    switch (offset % 10) {
      case 0:
        // If this is the first day of logging, expect 3 Observations for each
        // day in the backfill period and 8 Observations for the current day.
        if (offset == 0) {
          EXPECT_EQ((expected_params.daily_num_obs * kTestBackfillDays) +
                        expected_params.daily_num_obs + 5,
                    num_obs_after - num_obs_before);
        } else {
          // If this is another day whose offset is a multiple of 10, expect 8
          // Observations for each day in the backfill period as well as the
          // current day.
          EXPECT_EQ((expected_params.daily_num_obs + 5) * (kTestBackfillDays + 1),
                    num_obs_after - num_obs_before);
        }
        break;
      case 1:
      case 2:
      case 3:
      case 4:
        // Expect 8 Observations for this day.
        EXPECT_EQ(expected_params.daily_num_obs + 5, num_obs_after - num_obs_before);
        break;
      case 6:
        // Expect 8 Observations for each of today and yesterday.
        EXPECT_EQ((expected_params.daily_num_obs + 5) * 2, num_obs_after - num_obs_before);
        break;
      default:
        EXPECT_EQ(num_obs_after, num_obs_before);
    }
    AdvanceClock(kDay);
  }
}

// Tests that GenerateObservations() returns a positive status and that the
// expected number of Observations is generated when events are logged over
// multiple days and some of those days' Observations are backfilled, and when
// the LocalAggregateStore is garbage-collected after each call to
// GenerateObservations().
//
// Sets the |backfill_days_| field of the EventAggregator to 3.
//
// Logging pattern:
// For 35 days, logs 2 events each day for the
// ConnectionFailures_PerDeviceNumeric report with "component_A" and 2 events
// for the SettingsChanged_PerDeviceNumeric reports with "component_B", all with
// event code 0.
//
// Observation generation pattern:
// Calls GenerateObservations() on the 1st through 5th and the 7th out of
// every 10 days, for 35 days. Garbage-collects the LocalAggregateStore after
// each call.
//
// Expected numbers of Observations:
// It is expected that 4 days' worth of Observations are generated on
// the first day of every 10 (the day index for which GenerateObservations()
// was called, plus 3 days of backfill), that 1 day's worth of Observations
// are generated on the 2nd through 5th day of every 10, that 2 days'
// worth of Observations are generated on the 7th day of every 10 (the
// day index for which GenerateObservations() was called, plus 1 day of
// backfill), and that no Observations are generated on the remaining days.
TEST_F(PerDeviceNumericAggregateStoreTest, GenerateObservationsWithBackfillAndGc) {
  int num_days = 35;
  const auto& expected_params =
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams;
  // Set |backfill_days_| to 3.
  SetBackfillDays(kTestBackfillDays);
  // Add 2 events to the local aggregations each day for 35 days. Call GenerateObservations() on
  // the first 5 day indices, and the 7th, out of every 10.
  for (int offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    for (int i = 0; i < 2; i++) {
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(
                    logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                    day_index, "component_A", 0u, 1)
                    .error_code());
      EXPECT_EQ(
          StatusCode::OK,
          AddPerDeviceEventCountEvent(
              logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
              day_index, "component_B", 0u, 5)
              .error_code());
      EXPECT_EQ(StatusCode::OK,
                AddPerDeviceEventCountEvent(logger::testing::per_device_numeric_stats::
                                                kSettingsChangedAggregationWindowMetricReportId,
                                            day_index, "component_B", 0u, 5)
                    .error_code());
    }
    auto num_obs_before = observation_store_->messages_received.size();
    if (offset % 10 < 5 || offset % 10 == 6) {
      EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());
      EXPECT_EQ(StatusCode::OK, GarbageCollect(day_index).error_code());
    }
    auto num_obs_after = observation_store_->messages_received.size();
    EXPECT_GE(num_obs_after, num_obs_before);
    // Check that the expected daily number of Observations was generated.
    switch (offset % 10) {
      case 0:
        // If this is the first day of logging, expect 3 Observations for each
        // day in the backfill period and 8 Observations for the current day.
        if (offset == 0) {
          EXPECT_EQ((expected_params.daily_num_obs * kTestBackfillDays) +
                        expected_params.daily_num_obs + 5,
                    num_obs_after - num_obs_before);
        } else {
          // If this is another day whose offset is a multiple of 10, expect 8
          // Observations for each day in the backfill period as well as the
          // current day.
          EXPECT_EQ((expected_params.daily_num_obs + 5) * (kTestBackfillDays + 1),
                    num_obs_after - num_obs_before);
        }
        break;
      case 1:
      case 2:
      case 3:
      case 4:
        // Expect 8 Observations for this day.
        EXPECT_EQ(expected_params.daily_num_obs + 5, num_obs_after - num_obs_before);
        break;
      case 6:
        // Expect 6 Observations for each of today and yesterday.
        EXPECT_EQ((expected_params.daily_num_obs + 5) * 2, num_obs_after - num_obs_before);
        break;
      default:
        EXPECT_EQ(num_obs_after, num_obs_before);
    }
    AdvanceClock(kDay);
  }
}

// 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(PerDeviceNumericAggregateStoreTest, CheckObservationValuesNoEvents) {
  const auto current_day_index = CurrentDayIndex();
  EXPECT_EQ(StatusCode::OK, GenerateObservations(current_day_index).error_code());
  const auto& expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams, current_day_index);
  EXPECT_TRUE(CheckPerDeviceNumericObservations({}, expected_report_participation_obs,
                                                observation_store_.get(), update_recipient_.get()));
}

// Check that the expected PerDeviceNumericObservations and
// ReportParticipationObservations are generated when GenerateObservations() is
// called after logging some EventCountEvents and ElapsedTimeEvents for
// PER_DEVICE_NUMERIC_STATS reports over a single day index.
TEST_F(PerDeviceNumericAggregateStoreTest, CheckObservationValuesSingleDay) {
  const auto day_index = CurrentDayIndex();
  // Add several events to the local aggregations on |day_index|.
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(
                logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                day_index, "component_A", 0u, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(
                logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                day_index, "component_B", 0u, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(
                logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                day_index, "component_A", 0u, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(
                logger::testing::per_device_numeric_stats::kConnectionFailuresMetricReportId,
                day_index, "component_A", 1u, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(
                logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
                day_index, "component_C", 0u, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(
                logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
                day_index, "component_C", 0u, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(logger::testing::per_device_numeric_stats::
                                            kSettingsChangedAggregationWindowMetricReportId,
                                        day_index, "component_C", 0u, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(logger::testing::per_device_numeric_stats::
                                            kSettingsChangedAggregationWindowMetricReportId,
                                        day_index, "component_C", 0u, 5)
                .error_code());

  std::vector<MetricReportId> streaming_time_ids = {
      logger::testing::per_device_numeric_stats::kStreamingTimeTotalMetricReportId,
      logger::testing::per_device_numeric_stats::kStreamingTimeMinMetricReportId,
      logger::testing::per_device_numeric_stats::kStreamingTimeMaxMetricReportId};
  for (const auto& id : streaming_time_ids) {
    EXPECT_EQ(StatusCode::OK,
              AddPerDeviceElapsedTimeEvent(id, day_index, "component_D", 0u, 15).error_code());
    EXPECT_EQ(StatusCode::OK,
              AddPerDeviceElapsedTimeEvent(id, day_index, "component_D", 1u, 5).error_code());
    EXPECT_EQ(StatusCode::OK,
              AddPerDeviceElapsedTimeEvent(id, day_index, "component_D", 0u, 10).error_code());
  }
  // Generate locally aggregated Observations for |day_index|.
  EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());

  // Form the expected Observations.
  auto expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams, day_index);
  ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
  expected_per_device_numeric_obs[{
      logger::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[{
      logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
      day_index}][7] = {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      logger::testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
      day_index}][30] = {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      logger::testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId,
      day_index}][7] = {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      logger::testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId,
      day_index}][30] = {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      logger::testing::per_device_numeric_stats::kStreamingTimeTotalMetricReportId, day_index}][1] =
      {{"component_D", 0u, 25}, {"component_D", 1u, 5}};
  expected_per_device_numeric_obs[{
      logger::testing::per_device_numeric_stats::kStreamingTimeTotalMetricReportId, day_index}][7] =
      {{"component_D", 0u, 25}, {"component_D", 1u, 5}};
  // The 7-day minimum value for the StreamingTime metric is 0 for all event
  // codes and components, so we don't expect a PerDeviceNumericObservation with
  // a 7-day window for the StreamingTime_PerDeviceMin report.
  expected_per_device_numeric_obs[{
      logger::testing::per_device_numeric_stats::kStreamingTimeMinMetricReportId, day_index}][1] = {
      {"component_D", 0u, 10}, {"component_D", 1u, 5}};
  expected_per_device_numeric_obs[{
      logger::testing::per_device_numeric_stats::kStreamingTimeMinMetricReportId, day_index}][7] = {
      {"component_D", 0u, 10}, {"component_D", 1u, 5}};
  expected_per_device_numeric_obs[{
      logger::testing::per_device_numeric_stats::kStreamingTimeMaxMetricReportId, day_index}][1] = {
      {"component_D", 0u, 15}, {"component_D", 1u, 5}};
  expected_per_device_numeric_obs[{
      logger::testing::per_device_numeric_stats::kStreamingTimeMaxMetricReportId, day_index}][7] = {
      {"component_D", 0u, 15}, {"component_D", 1u, 5}};

  EXPECT_TRUE(CheckPerDeviceNumericObservations(expected_per_device_numeric_obs,
                                                expected_report_participation_obs,
                                                observation_store_.get(), 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
// GenerateObservations() is called each day, without garbage collection or
// backfill.
//
// Logged events for the SettingsChanged_PerDeviceCount report 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_PerDeviceNumeric 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 ReportParticipationObservation each day for each of
// the reports in the registry.
TEST_F(PerDeviceNumericAggregateStoreTest, CheckObservationValuesMultiDay) {
  auto start_day_index = CurrentDayIndex();
  const auto& expected_id =
      logger::testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId;
  const auto& expected_params =
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams;
  // 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_params, start_day_index + offset);
  }
  expected_per_device_numeric_obs[0] = {};
  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 < 1; offset++) {
    auto day_index = CurrentDayIndex();
    for (uint32_t event_code = 1; event_code < 3; event_code++) {
      if (offset > 0 && offset % event_code == 0) {
        EXPECT_EQ(
            StatusCode::OK,
            AddPerDeviceEventCountEvent(expected_id, day_index, "A", event_code, 3).error_code());
      }
      if (offset > 0 && offset % (2 * event_code) == 0) {
        EXPECT_EQ(
            StatusCode::OK,
            AddPerDeviceEventCountEvent(expected_id, day_index, "B", event_code, 2).error_code());
      }
    }
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Generate locally aggregated Observations.
    EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());
    EXPECT_TRUE(CheckPerDeviceNumericObservations(
        expected_per_device_numeric_obs[offset], expected_report_participation_obs[offset],
        observation_store_.get(), update_recipient_.get()))
        << "offset = " << offset;
    AdvanceClock(kDay);
  }
}

// Repeat the CheckObservationValuesMultiDay test, this time calling
// GarbageCollect() after each call to GenerateObservations.
//
// The logging pattern and set of Observations for each day index is the same
// as in PerDeviceNumericAggregateStoreTest::CheckObservationValuesMultiDay.
// See that test for documentation.
TEST_F(PerDeviceNumericAggregateStoreTest, CheckObservationValuesMultiDayWithGarbageCollection) {
  auto start_day_index = CurrentDayIndex();
  const auto& expected_id =
      logger::testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId;
  const auto& expected_params =
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams;
  // 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_params, start_day_index + offset);
  }
  expected_per_device_numeric_obs[0] = {};
  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 < 10; offset++) {
    auto day_index = CurrentDayIndex();
    for (uint32_t event_code = 1; event_code < 3; event_code++) {
      if (offset > 0 && offset % event_code == 0) {
        EXPECT_EQ(
            StatusCode::OK,
            AddPerDeviceEventCountEvent(expected_id, day_index, "A", event_code, 3).error_code());
      }
      if (offset > 0 && offset % (2 * event_code) == 0) {
        EXPECT_EQ(
            StatusCode::OK,
            AddPerDeviceEventCountEvent(expected_id, day_index, "B", event_code, 2).error_code());
      }
    }
    // Advance |test_clock_| by 1 day.
    AdvanceClock(kDay);
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Generate locally aggregated Observations and garbage-collect the
    // LocalAggregateStore, both for the previous day as measured by
    // |test_clock_|. Back up the LocalAggregateStore and
    // AggregatedObservationHistoryStore.
    DoScheduledTasksNow();
    EXPECT_TRUE(CheckPerDeviceNumericObservations(
        expected_per_device_numeric_obs[offset], expected_report_participation_obs[offset],
        observation_store_.get(), update_recipient_.get()));
  }
}

// Tests that the expected PerDeviceNumericObservations are generated when
// events are logged over multiple days for an EVENT_COUNT
// metric with a PER_DEVICE_NUMERIC_STATS report, when Observations are
// backfilled for some days during that period, without any garbage-collection
// of the LocalAggregateStore.
//
// The logging pattern and set of Observations for each day index is the same
// as in PerDeviceNumericAggregateStoreTest::CheckObservationValuesMultiDay.
// See that test for documentation.
TEST_F(PerDeviceNumericAggregateStoreTest, CheckObservationValuesWithBackfill) {
  auto start_day_index = CurrentDayIndex();
  const auto& expected_id =
      logger::testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId;
  const auto& expected_params =
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams;
  // Set |backfill_days_| to 3.
  SetBackfillDays(kTestBackfillDays);
  // Add events to the local aggregations for 9 days. Call GenerateObservations() on the first 6
  // day indices, and the 9th.
  uint32_t num_days = 9;
  for (uint32_t offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    ResetObservationStore();
    for (uint32_t event_code = 1; event_code < 3; event_code++) {
      if (offset > 0 && (offset % event_code == 0)) {
        EXPECT_EQ(
            StatusCode::OK,
            AddPerDeviceEventCountEvent(expected_id, day_index, "A", event_code, 3).error_code());
      }
      if (offset > 0 && offset % (2 * event_code) == 0) {
        EXPECT_EQ(
            StatusCode::OK,
            AddPerDeviceEventCountEvent(expected_id, day_index, "B", event_code, 2).error_code());
      }
    }
    if (offset < 6 || offset == 8) {
      EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());
    }
    // Make the set of Observations which are expected to be generated on
    // |start_day_index + offset| and check it against the contents of the
    // FakeObservationStore.
    ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
    ExpectedReportParticipationObservations expected_report_participation_obs;
    switch (offset) {
      case 0: {
        for (uint32_t day_index = start_day_index - kTestBackfillDays; day_index <= start_day_index;
             day_index++) {
          for (const auto& pair :
               MakeExpectedReportParticipationObservations(expected_params, day_index)) {
            expected_report_participation_obs.insert(pair);
          }
        }
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 1: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {{7, {{"A", 1u, 3}}},
                                                                     {30, {{"A", 1u, 3}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 2: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {
            {7, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}},
            {30, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 3: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {
            {7, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}},
            {30, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 4: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {
            {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_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 5: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {
            {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_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 8: {
        expected_per_device_numeric_obs[{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[{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[{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}}}};
        for (uint32_t day_index = start_day_index + 6; day_index <= start_day_index + 8;
             day_index++) {
          for (const auto& pair :
               MakeExpectedReportParticipationObservations(expected_params, day_index)) {
            expected_report_participation_obs.insert(pair);
          }
        }
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      default:
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
    }
    AdvanceClock(kDay);
  }
}

// Tests that the expected Observations are generated for
// PerDeviceNumericStats reports when events are logged for over multiple days
// for an EVENT_COUNT metric with a PER_DEVICE_NUMERIC_STATS report, when
// Observations are backfilled for some days during that period, and when the
// LocalAggregatedStore is garbage-collected after each call to
// GenerateObservations().
//
// The logging pattern and set of Observations for each day index is the same
// as in PerDeviceNumericAggregateStoreTest::CheckObservationValuesMultiDay.
// See that test for documentation.
TEST_F(PerDeviceNumericAggregateStoreTest, EventCountCheckObservationValuesWithBackfillAndGc) {
  auto start_day_index = CurrentDayIndex();
  const auto& expected_id =
      logger::testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId;
  const auto& expected_params =
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams;
  // Set |backfill_days_| to 3.
  SetBackfillDays(kTestBackfillDays);
  // Add events to the local aggregations for 9 days. Call GenerateObservations() on the first 6
  // day indices, and the 9th.
  uint32_t num_days = 9;
  for (uint32_t offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    ResetObservationStore();
    for (uint32_t event_code = 1; event_code < 3; event_code++) {
      if (offset > 0 && (offset % event_code == 0)) {
        EXPECT_EQ(
            StatusCode::OK,
            AddPerDeviceEventCountEvent(expected_id, day_index, "A", event_code, 3).error_code());
      }
      if (offset > 0 && offset % (2 * event_code) == 0) {
        EXPECT_EQ(
            StatusCode::OK,
            AddPerDeviceEventCountEvent(expected_id, day_index, "B", event_code, 2).error_code());
      }
    }
    // Advance |test_clock_| by 1 day.
    AdvanceClock(kDay);
    if (offset < 6 || offset == 8) {
      // Generate Observations and garbage-collect, both for the previous day
      // index according to |test_clock_|. Back up the LocalAggregateStore and
      // the AggregatedObservationHistoryStore.
      DoScheduledTasksNow();
    }
    // Make the set of Observations which are expected to be generated on
    // |start_day_index + offset| and check it against the contents of the
    // FakeObservationStore.
    ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
    ExpectedReportParticipationObservations expected_report_participation_obs;
    switch (offset) {
      case 0: {
        for (uint32_t day_index = start_day_index - kTestBackfillDays; day_index <= start_day_index;
             day_index++) {
          for (const auto& pair :
               MakeExpectedReportParticipationObservations(expected_params, day_index)) {
            expected_report_participation_obs.insert(pair);
          }
        }
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 1: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {{7, {{"A", 1u, 3}}},
                                                                     {30, {{"A", 1u, 3}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 2: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {
            {7, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}},
            {30, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 3: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {
            {7, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}},
            {30, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 4: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {
            {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_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 5: {
        expected_per_device_numeric_obs[{expected_id, day_index}] = {
            {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_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 8: {
        expected_per_device_numeric_obs[{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[{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[{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}}}};
        for (uint32_t day_index = start_day_index + 6; day_index <= start_day_index + 8;
             day_index++) {
          for (const auto& pair :
               MakeExpectedReportParticipationObservations(expected_params, day_index)) {
            expected_report_participation_obs.insert(pair);
          }
        }
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      default:
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
    }
  }
}

// Tests that the expected Observations are generated for
// PerDeviceNumericStats reports 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_PerDevice{Total, Min, Max} reports 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(PerDeviceNumericAggregateStoreTest, ElapsedTimeCheckObservationValuesWithBackfillAndGc) {
  auto start_day_index = CurrentDayIndex();
  const auto& total_report_id =
      logger::testing::per_device_numeric_stats::kStreamingTimeTotalMetricReportId;
  const auto& min_report_id =
      logger::testing::per_device_numeric_stats::kStreamingTimeMinMetricReportId;
  const auto& max_report_id =
      logger::testing::per_device_numeric_stats::kStreamingTimeMaxMetricReportId;
  std::vector<MetricReportId> streaming_time_ids = {total_report_id, min_report_id, max_report_id};
  const auto& expected_params =
      logger::testing::per_device_numeric_stats::kExpectedAggregationParams;
  // Set |backfill_days_| to 3.
  SetBackfillDays(kTestBackfillDays);
  // Add events to the local aggregations for 9 days. Call GenerateObservations() on the first 6
  // day indices, and the 9th.
  uint32_t num_days = 9;
  for (uint32_t offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex();
    ResetObservationStore();
    for (uint32_t event_code = 1; event_code < 3; event_code++) {
      for (const auto& report_id : streaming_time_ids) {
        if (offset > 0 && (offset % event_code == 0)) {
          EXPECT_EQ(
              StatusCode::OK,
              AddPerDeviceElapsedTimeEvent(report_id, day_index, "A", event_code, 3).error_code());
        }
        if (offset > 0 && offset % (2 * event_code) == 0) {
          EXPECT_EQ(
              StatusCode::OK,
              AddPerDeviceElapsedTimeEvent(report_id, day_index, "B", event_code, 2).error_code());
        }
      }
    }

    // Advance |test_clock_| by 1 day.
    AdvanceClock(kDay);
    if (offset < 6 || offset == 8) {
      // Generate Observations and garbage-collect, both for the previous day
      // index according to |test_clock_|. Back up the LocalAggregateStore and
      // the AggregatedObservationHistoryStore.
      DoScheduledTasksNow();
    }
    // Make the set of Observations which are expected to be generated on
    // |start_day_index + offset| and check it against the contents of the
    // FakeObservationStore.
    ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
    ExpectedReportParticipationObservations expected_report_participation_obs;
    switch (offset) {
      case 0: {
        for (uint32_t day_index = start_day_index - kTestBackfillDays; day_index <= start_day_index;
             day_index++) {
          for (const auto& pair :
               MakeExpectedReportParticipationObservations(expected_params, day_index)) {
            expected_report_participation_obs.insert(pair);
          }
        }
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 1: {
        expected_per_device_numeric_obs[{total_report_id, day_index}] = {{1, {{"A", 1u, 3}}},
                                                                         {7, {{"A", 1u, 3}}}};
        expected_per_device_numeric_obs[{min_report_id, day_index}] = {{1, {{"A", 1u, 3}}},
                                                                       {7, {{"A", 1u, 3}}}};
        expected_per_device_numeric_obs[{max_report_id, day_index}] = {{1, {{"A", 1u, 3}}},
                                                                       {7, {{"A", 1u, 3}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()))
            << "day 1";
        break;
      }
      case 2: {
        expected_per_device_numeric_obs[{total_report_id, day_index}] = {
            {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[{min_report_id, day_index}] = {
            {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[{max_report_id, day_index}] = {
            {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
            {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 3: {
        expected_per_device_numeric_obs[{total_report_id, day_index}] = {
            {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}}};
        expected_per_device_numeric_obs[{min_report_id, day_index}] = {
            {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
        expected_per_device_numeric_obs[{max_report_id, day_index}] = {
            {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 4: {
        expected_per_device_numeric_obs[{total_report_id, day_index}] = {
            {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[{min_report_id, day_index}] = {
            {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[{max_report_id, day_index}] = {
            {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_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 5: {
        expected_per_device_numeric_obs[{total_report_id, day_index}] = {
            {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 15}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}}};
        expected_per_device_numeric_obs[{min_report_id, day_index}] = {
            {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
        expected_per_device_numeric_obs[{max_report_id, day_index}] = {
            {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
        expected_report_participation_obs =
            MakeExpectedReportParticipationObservations(expected_params, day_index);
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      case 8: {
        expected_per_device_numeric_obs[{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[{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[{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[{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[{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[{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[{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[{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[{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 day_index = start_day_index + 6; day_index <= start_day_index + 8;
             day_index++) {
          for (const auto& pair :
               MakeExpectedReportParticipationObservations(expected_params, day_index)) {
            expected_report_participation_obs.insert(pair);
          }
        }
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
        break;
      }
      default:
        EXPECT_TRUE(CheckPerDeviceNumericObservations(
            expected_per_device_numeric_obs, expected_report_participation_obs,
            observation_store_.get(), update_recipient_.get()));
    }
  }
}

// Check that GenerateObservations returns an OK status after some events have been logged for a
// PerDeviceHistogram report.
TEST_F(PerDeviceHistogramAggregateStoreTest, GenerateObservations) {
  const auto day_index = CurrentDayIndex();
  // Add several events to the local aggregations on |day_index|.
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(
                logger::testing::per_device_histogram::kSettingsChangedMetricReportId, day_index,
                "component_C", 0u, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            AddPerDeviceEventCountEvent(
                logger::testing::per_device_histogram::kSettingsChangedMetricReportId, day_index,
                "component_C", 0u, 5)
                .error_code());

  // Generate locally aggregated Observations for |day_index|.
  EXPECT_EQ(StatusCode::OK, GenerateObservations(day_index).error_code());
}

// Tests GenerateObservations() and GarbageCollect() in the case where the
// LocalAggregateStore contains aggregates for metrics with both UTC and LOCAL
// time zone policies, and where the day index in local time may be less than
// the day index in UTC.
TEST_F(NoiseFreeMixedTimeZoneAggregateStoreTest, LocalBeforeUTC) {
  std::vector<ExpectedUniqueActivesObservations> expected_obs(3);
  // Begin at a time when the current day index is the same in both UTC and local time. Add 1
  // event to the local aggregations for event code 0 for each of the 2 reports, then generate
  // Observations and garbage-collect for the previous day index in each of UTC and local time.
  auto start_day_index = CurrentDayIndex();
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kDeviceBootsMetricReportId,
                        start_day_index, 0u);
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kFeaturesActiveMetricReportId,
                        start_day_index, 0u);
  GenerateObservations(start_day_index - 1, start_day_index - 1);
  GarbageCollect(start_day_index - 1, start_day_index - 1);
  // Form the expected contents of the FakeObservationStore.
  // Since no events were logged on the previous day and no Observations have
  // been generated for that day yet, expect Observations of non-activity for
  // all event codes, for both reports.
  expected_obs[0] = MakeNullExpectedUniqueActivesObservations(
      logger::testing::mixed_time_zone::kExpectedAggregationParams, start_day_index - 1);
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[0], observation_store_.get(),
                                             update_recipient_.get()));
  ResetObservationStore();
  // Advance the day index in UTC, but not in local time, and log 1 event for
  // event code 1 for each of the 2 reports. Generate Observations and
  // garbage-collect for the previous day in each of UTC and local time.
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kDeviceBootsMetricReportId,
                        start_day_index, 1u);
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kFeaturesActiveMetricReportId,
                        start_day_index + 1, 1u);
  GenerateObservations(start_day_index, start_day_index - 1);
  GarbageCollect(start_day_index, start_day_index - 1);
  // Form the expected contents of the FakeObservationStore. Since
  // Observations have already been generated for the
  // DeviceBoots_UniqueDevices report for |start_day_index - 1|, expect no
  // Observations for that report.
  expected_obs[1][{logger::testing::mixed_time_zone::kFeaturesActiveMetricReportId,
                   start_day_index}] = {{1, {true, false, false}}};
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[1], observation_store_.get(),
                                             update_recipient_.get()));
  ResetObservationStore();
  // Advance the day index in local time so that it is equal to the day index in UTC. Add 1 event
  // to the local aggregations for event code 2 for each of the 2 reports, then generate
  // Observations and garbage-collect for the previous day in each of UTC and local time.
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kDeviceBootsMetricReportId,
                        start_day_index + 1, 2u);
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kFeaturesActiveMetricReportId,
                        start_day_index + 1, 2u);
  GenerateObservations(start_day_index, start_day_index);
  GarbageCollect(start_day_index, start_day_index);
  // Form the expected contents of the FakeObservationStore. Since
  // Observations have already been generated for the
  // FeaturesActive_UniqueDevices report for day |start_day_index|, expect no
  // Observations for that report.
  expected_obs[2][{logger::testing::mixed_time_zone::kDeviceBootsMetricReportId, start_day_index}] =
      {{1, {true, true, false}}};
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[2], observation_store_.get(),
                                             update_recipient_.get()));
}

// Tests GenerateObservations() and GarbageCollect() in the case where the
// LocalAggregateStore contains aggregates for metrics with both UTC and LOCAL
// time zone policies, and where the day index in UTC may be less than
// the day index in local time.
TEST_F(NoiseFreeMixedTimeZoneAggregateStoreTest, LocalAfterUTC) {
  std::vector<ExpectedUniqueActivesObservations> expected_obs(3);
  // Begin at a time when the current day index is the same in both UTC and local time. Add 1
  // event to the local aggregations for event code 0 for each of the 2 reports, then generate
  // Observations and garbage-collect for the previous day index in each of UTC and local time.
  auto start_day_index = CurrentDayIndex();
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kDeviceBootsMetricReportId,
                        start_day_index, 0u);
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kFeaturesActiveMetricReportId,
                        start_day_index, 0u);
  GenerateObservations(start_day_index - 1, start_day_index - 1);
  GarbageCollect(start_day_index - 1, start_day_index - 1);
  // Form the expected contents of the FakeObservationStore.
  // Since no events were logged on the previous day and no Observations have
  // been generated for that day yet, expect Observations of non-activity for
  // all event codes, for both reports.
  expected_obs[0] = MakeNullExpectedUniqueActivesObservations(
      logger::testing::mixed_time_zone::kExpectedAggregationParams, start_day_index - 1);
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[0], observation_store_.get(),
                                             update_recipient_.get()));
  ResetObservationStore();
  // Advance the day index in local time, but not in UTC, and log 1 event for
  // event code 1 for each of the 2 reports. Generate Observations and
  // garbage-collect for the previous day in each of UTC and local time.
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kDeviceBootsMetricReportId,
                        start_day_index + 1, 1u);
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kFeaturesActiveMetricReportId,
                        start_day_index, 1u);
  GenerateObservations(start_day_index - 1, start_day_index);
  GarbageCollect(start_day_index - 1, start_day_index);
  // Form the expected contents of the FakeObservationStore. Since
  // Observations have already been generated for the
  // FeaturesActive_UniqueDevices report for |start_day_index - 1|, expect no
  // Observations for that report.
  expected_obs[1][{logger::testing::mixed_time_zone::kDeviceBootsMetricReportId, start_day_index}] =
      {{1, {true, false, false}}};
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[1], observation_store_.get(),
                                             update_recipient_.get()));
  ResetObservationStore();
  // Advance the day index in UTC so that it is equal to the day index in local time. Add 1 event
  // to the local aggregations for event code 2 for each of the 2 reports, then generate
  // Observations and garbage-collect for the previous day in each of UTC and local time.
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kDeviceBootsMetricReportId,
                        start_day_index + 1, 2u);
  AddUniqueActivesEvent(logger::testing::mixed_time_zone::kFeaturesActiveMetricReportId,
                        start_day_index + 1, 2u);
  GenerateObservations(start_day_index, start_day_index);
  GarbageCollect(start_day_index, start_day_index);
  // Form the expected contents of the FakeObservationStore. Since
  // Observations have already been generated for the
  // DeviceBoots_UniqueDevices report for day |start_day_index|, expect no
  // Observations for that report.
  expected_obs[2][{logger::testing::mixed_time_zone::kFeaturesActiveMetricReportId,
                   start_day_index}] = {{1, {true, true, false}}};
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[2], observation_store_.get(),
                                             update_recipient_.get()));
}
}  // namespace local_aggregation
}  // namespace cobalt
