// Copyright 2017 The Fuchsia Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_ANALYZER_STORE_REPORT_STORE_ABSTRACT_TEST_H_
#define COBALT_ANALYZER_STORE_REPORT_STORE_ABSTRACT_TEST_H_

#include "analyzer/store/report_store.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "analyzer/store/observation_store_internal.h"
#include "analyzer/store/report_store_test_utils.h"
#include "glog/logging.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"

// This file contains type-parameterized tests of the ReportStore.
//
// We use C++ templates along with the macros TYPED_TEST_CASE_P and
// TYPED_TEST_P in order to define test templates that may be instantiated to
// to produce concrete tests that use various implementations of Datastore.
//
// See report_store_test.cc and report_store_emulator_test.cc for the
// concrete instantiations.
//
// NOTE: If you add a new test to this file you must add its name to the
// invocation REGISTER_TYPED_TEST_CASE_P macro at the bottom of this file.

namespace cobalt {
namespace analyzer {
namespace store {

// Test value to use for the std_error field. We choose a power 2 so it can
// be represented exactly.
const float kStandardError = 0.25;

// ReportStoreAbstractTest is templatized on the parameter
// |StoreFactoryClass| which must be the name of a class that contains the
// following method: static DataStore* NewStore()
// See MemoryStoreFactory in memory_store_test.cc and
// BigtableStoreEmulatorFactory in bigtable_store_emulator_test.cc.
template <class StoreFactoryClass>
class ReportStoreAbstractTest : public ::testing::Test {
 protected:
  ReportStoreAbstractTest()
      : data_store_(StoreFactoryClass::NewStore()),
        report_store_(new ReportStore(data_store_)) {}

  void SetUp() {
    EXPECT_EQ(kOK, data_store_->DeleteAllRows(DataStore::kReportMetadata));
    EXPECT_EQ(kOK, data_store_->DeleteAllRows(DataStore::kReportRows));
  }

  static const uint32_t kCustomerId = 11;
  static const uint32_t kProjectId = 222;
  static const uint32_t kReportConfigId = 3333;
  static const uint32_t kFirstDayIndex = 12345;
  static const uint32_t kLastDayIndex = 12347;

  static ReportId MakeReportId(int64_t creation_time_seconds,
                               uint32_t instance_id) {
    ReportId report_id;
    report_id.set_customer_id(kCustomerId);
    report_id.set_project_id(kProjectId);
    report_id.set_report_config_id(kReportConfigId);
    report_id.set_creation_time_seconds(creation_time_seconds);
    report_id.set_instance_id(instance_id);
    return report_id;
  }

  static std::string MakeStringValue(const ReportId& report_id,
                                     size_t row_index, uint8_t variable_index) {
    std::ostringstream stream;
    stream << report_id.creation_time_seconds() << ":"
           << report_id.instance_id() << ":" << report_id.sequence_num() << ":"
           << row_index << ":" << variable_index;
    return stream.str();
  }

  static void FillValuePart(const ReportId& report_id, size_t row_index,
                            uint8_t variable_index, ValuePart* value_part) {
    value_part->set_string_value(
        MakeStringValue(report_id, row_index, variable_index));
  }

  static void CheckValue(const ValuePart& value_part, size_t row_index,
                         const ReportId& report_id, uint8_t variable_index) {
    EXPECT_EQ(MakeStringValue(report_id, row_index, variable_index),
              value_part.string_value());
  }

  static ReportRow MakeHistogramReportRow(const ReportId& report_id,
                                          size_t row_index) {
    ReportRow report_row;
    report_row.mutable_histogram()->set_count_estimate(row_index);
    report_row.mutable_histogram()->set_std_error(kStandardError);
    FillValuePart(report_id, row_index, 1,
                  report_row.mutable_histogram()->mutable_value());
    return report_row;
  }

  static void CheckHistogramReportRow(const ReportRow& row,
                                      const ReportId& report_id) {
    EXPECT_EQ(kStandardError, row.histogram().std_error());
    EXPECT_TRUE(row.histogram().has_value());
    // Note we use the fact that the count_estimate was set to the
    // row_index.
    CheckValue(row.histogram().value(), row.histogram().count_estimate(),
               report_id, 1);
  }

  std::string ToString(const ReportId& report_id) {
    return report_store_->MakeMetadataRowKey(report_id);
  }

  Status StartNewReport(bool one_off, const std::string export_name,
                        bool in_store, ReportType report_type,
                        const std::vector<uint32_t>& variable_indices,
                        ReportId* report_id) {
    return this->report_store_->StartNewReport(
        kFirstDayIndex, kLastDayIndex, one_off, export_name, in_store,
        report_type, variable_indices, report_id);
  }

  // Starts a new report of type HISTOGRAM with variable_indices = {0}
  Status StartNewHistogramReport(bool one_off, ReportId* report_id) {
    return StartNewReport(one_off, "", true, HISTOGRAM, {0}, report_id);
  }

  // Starts a new report with one_off=true, type=HISTOGRAM,
  // the specified |variable_index| as the single variable index,
  // and our global contstant values for all of the numeric IDs.
  ReportId StartNewHistogramReport() {
    // Make a new ReportID without specifying timestamp or instance_id.
    ReportId report_id = MakeReportId(0, 0);
    EXPECT_EQ(0, report_id.creation_time_seconds());
    EXPECT_EQ(0u, report_id.instance_id());

    EXPECT_EQ(kOK, StartNewHistogramReport(true, &report_id));
    return report_id;
  }

  // Inserts |num_timestamps| * 6 rows into the report_metadata table.
  // Starting with timestamp=start_timestamp, for |num_timestamps| increments of
  // |timestamp_delta|, 6 rows are inserted with that timestamp: For three
  // sequence_num=0,1,2, we insert two rows with two different values of
  // instance_id. For each insert we store
  // timestamp + instance_id + sequence_num
  // into the ReportMetadata's start_timestamp_ms field for later verifaction.
  void WriteManyNewReports(int64_t start_timestamp, uint64_t timestamp_delta,
                           size_t num_timestamps) {
    std::vector<ReportId> report_ids;
    std::vector<ReportMetadataLite> metadata_vector;
    int64_t timestamp = start_timestamp;
    for (size_t ts_index = 0; ts_index < num_timestamps; ts_index++) {
      for (size_t instance_id = 0; instance_id <= 1; instance_id++) {
        for (size_t sequence_num = 0; sequence_num < 3; sequence_num++) {
          report_ids.emplace_back(MakeReportId(timestamp, instance_id));
          EXPECT_EQ(report_ids.back().instance_id(), instance_id);
          report_ids.back().set_sequence_num(sequence_num);
          ReportMetadataLite metadata;
          metadata.set_start_time_seconds(timestamp + instance_id +
                                          sequence_num);
          metadata_vector.emplace_back(metadata);
        }
      }
      timestamp += timestamp_delta;
    }
    ReportStoreTestUtils test_utils(report_store_);
    test_utils.WriteBulkMetadata(report_ids, metadata_vector);
  }

  Status AddHistogramReportRows(const ReportId& report_id, size_t num_rows) {
    std::vector<ReportRow> report_rows;
    for (size_t index = 0; index < num_rows; index++) {
      report_rows.emplace_back(MakeHistogramReportRow(report_id, index));
    }
    return report_store_->AddReportRows(report_id, report_rows);
  }

  void GetReportAndCheck(const ReportId& report_id, int expected_num_rows) {
    ReportMetadataLite read_metadata;
    ReportRows rows;
    EXPECT_EQ(kOK, report_store_->GetReport(report_id, &read_metadata, &rows));
    EXPECT_EQ(COMPLETED_SUCCESSFULLY, read_metadata.state());
    EXPECT_EQ(expected_num_rows, rows.rows_size());
    EXPECT_EQ(HISTOGRAM, read_metadata.report_type());
    EXPECT_EQ(1, read_metadata.variable_indices_size());
    auto var_index = read_metadata.variable_indices(0);
    EXPECT_TRUE(var_index == 0 || var_index == 1);
    for (const auto& row : rows.rows()) {
      this->CheckHistogramReportRow(row, report_id);
    }
  }

  Status DeleteAllForReportConfig(uint32_t report_config_id) {
    return report_store_->DeleteAllForReportConfig(kCustomerId, kProjectId,
                                                   report_config_id);
  }

  uint32_t first_day_index() const { return kFirstDayIndex; }

  uint32_t last_day_index() const { return kLastDayIndex; }

  uint32_t customer_id() const { return kCustomerId; }

  uint32_t project_id() const { return kProjectId; }

  uint32_t report_config_id() const { return kReportConfigId; }

  std::shared_ptr<DataStore> data_store_;
  std::shared_ptr<ReportStore> report_store_;
};

TYPED_TEST_CASE_P(ReportStoreAbstractTest);

// Tests the methods StartNewReport(), EndReport() and GetMetadata().
TYPED_TEST_P(ReportStoreAbstractTest, SetAndGetMetadata) {
  bool one_off = true;

  // Make a new ReportID without specifying timestamp or instance_id.
  ReportId report_id = this->MakeReportId(0, 0);
  EXPECT_EQ(0, report_id.creation_time_seconds());
  EXPECT_EQ(0u, report_id.instance_id());

  // Invoke StartNewReport().
  EXPECT_EQ(kOK, this->StartNewHistogramReport(one_off, &report_id));

  // Check that the report_id was completed.
  EXPECT_NE(0, report_id.creation_time_seconds());
  EXPECT_NE(0u, report_id.instance_id());

  // Get the ReportMetatdata for this new ID.
  ReportMetadataLite report_metadata;
  EXPECT_EQ(kOK, this->report_store_->GetMetadata(report_id, &report_metadata));

  // Check its state.
  EXPECT_EQ(IN_PROGRESS, report_metadata.state());
  EXPECT_EQ(this->first_day_index(), report_metadata.first_day_index());
  EXPECT_EQ(this->last_day_index(), report_metadata.last_day_index());
  EXPECT_EQ(one_off, report_metadata.one_off());
  EXPECT_EQ(report_id.creation_time_seconds(),
            report_metadata.start_time_seconds());
  EXPECT_EQ(0, report_metadata.finish_time_seconds());
  EXPECT_EQ(0, report_metadata.info_messages_size());
  EXPECT_EQ("", report_metadata.export_name());

  // Invoke EndReport() with success=true.
  bool success = true;
  EXPECT_EQ(kOK, this->report_store_->EndReport(report_id, success, "hello"));

  // Get the ReportMetatdata again.
  report_metadata.Clear();
  EXPECT_EQ(kOK, this->report_store_->GetMetadata(report_id, &report_metadata));

  // Check its state. It should now be completed and have a finish_timestamp.
  EXPECT_EQ(COMPLETED_SUCCESSFULLY, report_metadata.state());
  EXPECT_EQ(this->first_day_index(), report_metadata.first_day_index());
  EXPECT_EQ(this->last_day_index(), report_metadata.last_day_index());
  EXPECT_EQ(one_off, report_metadata.one_off());
  EXPECT_EQ(report_id.creation_time_seconds(),
            report_metadata.start_time_seconds());
  EXPECT_NE(0, report_metadata.finish_time_seconds());
  EXPECT_EQ(1, report_metadata.info_messages_size());
  EXPECT_EQ("hello", report_metadata.info_messages(0).message());

  // Invoke EndReport() with success=false. Note that we never do this in
  // the real product (i.e. convert from COMPLETED_SUCCESSFULLY to
  // TERMINATED) but it is a convenient shortcut for the test.
  success = false;
  EXPECT_EQ(kOK, this->report_store_->EndReport(report_id, success, "goodbye"));

  // Get the ReportMetatdata again.
  report_metadata.Clear();
  EXPECT_EQ(kOK, this->report_store_->GetMetadata(report_id, &report_metadata));

  // Check its state. It should now be terminated.
  EXPECT_EQ(TERMINATED, report_metadata.state());
  EXPECT_EQ(2, report_metadata.info_messages_size());
  EXPECT_EQ("goodbye", report_metadata.info_messages(1).message());

  // Start another report, this time with one_off = false and with a
  // non-empty export_name.
  one_off = false;
  std::string export_name("an-export-name");
  report_id = this->MakeReportId(1, 1);
  // Invoke StartNewReport().
  EXPECT_EQ(kOK, this->StartNewReport(one_off, export_name, true, HISTOGRAM,
                                      {0}, &report_id));

  // Get the ReportMetatdata.
  report_metadata.Clear();
  EXPECT_EQ(kOK, this->report_store_->GetMetadata(report_id, &report_metadata));

  // Check one_off and export_name
  EXPECT_EQ(IN_PROGRESS, report_metadata.state());
  EXPECT_FALSE(report_metadata.one_off());
  EXPECT_EQ("an-export-name", report_metadata.export_name());
}

// Tests the functions CreateDependentReport() and StartDependentReport.
TYPED_TEST_P(ReportStoreAbstractTest, CreateAndStartDependentReport) {
  bool one_off = false;

  // Make a new ReportID without specifying timestamp or instance_id.
  ReportId report_id1 = this->MakeReportId(0, 0);
  EXPECT_EQ(0u, report_id1.sequence_num());

  // Invoke StartNewReport().
  EXPECT_EQ(kOK, this->StartNewHistogramReport(one_off, &report_id1));

  // Invoke EndReport()
  EXPECT_EQ(kOK, this->report_store_->EndReport(report_id1, true, "hello"));

  // Copy the new report_id
  ReportId report_id2(report_id1);

  // Invoke CreateDependentReport() to create a report with sequence_num=1
  // that analyzes variable 1.
  EXPECT_EQ(kOK, this->report_store_->CreateDependentReport(
                     1, "", true, HISTOGRAM, {1}, &report_id2));

  // Check that report_id2 had its sequence_num set correctly.
  EXPECT_EQ(1u, report_id2.sequence_num());
  // Creation time should be the same as for the initial report.
  EXPECT_EQ(report_id1.creation_time_seconds(),
            report_id2.creation_time_seconds());

  // Get the ReportMetatdata for report_id2.
  ReportMetadataLite report_metadata;
  EXPECT_EQ(kOK,
            this->report_store_->GetMetadata(report_id2, &report_metadata));

  // Check its state.
  EXPECT_EQ(WAITING_TO_START, report_metadata.state());
  EXPECT_EQ(this->first_day_index(), report_metadata.first_day_index());
  EXPECT_EQ(this->last_day_index(), report_metadata.last_day_index());
  EXPECT_EQ(one_off, report_metadata.one_off());
  ASSERT_EQ(1, report_metadata.variable_indices_size());
  EXPECT_EQ(1u, report_metadata.variable_indices(0));
  EXPECT_EQ("", report_metadata.export_name());

  // start_time_seconds, finish_time_seconds and info_message should not have
  // been copied to this ReportMetadataLite.
  EXPECT_EQ(0, report_metadata.start_time_seconds());
  EXPECT_EQ(0, report_metadata.finish_time_seconds());
  EXPECT_EQ(0, report_metadata.info_messages_size());

  // Now start the dependent report.
  EXPECT_EQ(kOK, this->report_store_->StartDependentReport(report_id2));

  // Get the ReportMetatdata for report_id2.
  report_metadata.Clear();
  EXPECT_EQ(kOK,
            this->report_store_->GetMetadata(report_id2, &report_metadata));

  // Check the state state.
  EXPECT_EQ(IN_PROGRESS, report_metadata.state());

  // The report should now be started, but not finished.
  EXPECT_NE(0, report_metadata.start_time_seconds());
  EXPECT_EQ(0, report_metadata.finish_time_seconds());

  // Create another dependent report, this time with a non-empty export_name.
  std::string export_name("another-export-name");
  // Invoke CreateDependentReport() to create a report with sequence_num=2
  // that analyzes variable 2.
  EXPECT_EQ(kOK, this->report_store_->CreateDependentReport(
                     2, export_name, true, HISTOGRAM, {2}, &report_id2));

  // Get the ReportMetatdata.
  report_metadata.Clear();
  EXPECT_EQ(kOK,
            this->report_store_->GetMetadata(report_id2, &report_metadata));

  // Check the export_name
  EXPECT_EQ("another-export-name", report_metadata.export_name());
}

// Tests the functions AddReportRow and GetReport, using HistogramReportRows.
TYPED_TEST_P(ReportStoreAbstractTest, ReportRows) {
  // We start three reports. Two independent reports, report 1 and report 2.
  auto report_id1 = this->StartNewHistogramReport();
  auto report_id2 = this->StartNewHistogramReport();
  // And report 2a which is an associated sub-report with report 2.
  ReportId report_id2a(report_id2);
  std::vector<uint32_t> variable_indices = {1};
  EXPECT_EQ(kOK, this->report_store_->CreateDependentReport(
                     1, "", true, HISTOGRAM, {1}, &report_id2a));
  EXPECT_EQ(kOK, this->report_store_->StartDependentReport(report_id2a));

  // Add rows to all three reports.
  EXPECT_EQ(kOK, this->AddHistogramReportRows(report_id1, 100));
  EXPECT_EQ(kOK, this->AddHistogramReportRows(report_id2, 200));
  EXPECT_EQ(kOK, this->AddHistogramReportRows(report_id2a, 300));

  // Complete all three reports
  this->report_store_->EndReport(report_id1, true, "");
  this->report_store_->EndReport(report_id2, true, "");
  this->report_store_->EndReport(report_id2a, true, "");

  // Fetch report 1 and check it.
  this->GetReportAndCheck(report_id1, 100);

  // Fetch report 2 and check it.
  this->GetReportAndCheck(report_id2, 200);

  // Fetch report 2a and check it.
  this->GetReportAndCheck(report_id2a, 300);
}

// Tests the use of the parameter |in_store|.
TYPED_TEST_P(ReportStoreAbstractTest, InStore) {
  // Start two new reports, one with in_store = true and one with it false.
  ReportId report_id1 = this->MakeReportId(0, 0);
  bool in_store = true;
  this->StartNewReport(true, "", in_store, HISTOGRAM, {0}, &report_id1);

  ReportId report_id2 = this->MakeReportId(0, 0);
  in_store = false;
  this->StartNewReport(true, "", in_store, HISTOGRAM, {0}, &report_id2);

  // Fetch the two metadata and make sure the first one has in_store true
  // and the second one has it false.
  ReportMetadataLite md1;
  EXPECT_EQ(kOK, this->report_store_->GetMetadata(report_id1, &md1));
  EXPECT_TRUE(md1.in_store());

  ReportMetadataLite md2;
  EXPECT_EQ(kOK, this->report_store_->GetMetadata(report_id2, &md2));
  EXPECT_FALSE(md2.in_store());

  // Check that we can add rows to the first report but not the second;
  EXPECT_EQ(kOK, this->AddHistogramReportRows(report_id1, 1));
  EXPECT_EQ(kInvalidArguments, this->AddHistogramReportRows(report_id2, 1));

  // Start two dependent reports, one with in_store = true and one with it
  // false.
  ReportId report_id1d(report_id1);
  in_store = true;
  this->report_store_->CreateDependentReport(1, "", in_store, HISTOGRAM, {1},
                                             &report_id1d);

  ReportId report_id2d(report_id2);
  in_store = false;
  this->report_store_->CreateDependentReport(1, "", in_store, HISTOGRAM, {1},
                                             &report_id2d);

  // Fetch the two metadata and make sure the first one has in_store true
  // and the second one has it false.
  ReportMetadataLite md1d;
  EXPECT_EQ(kOK, this->report_store_->GetMetadata(report_id1d, &md1d));
  EXPECT_TRUE(md1d.in_store());

  ReportMetadataLite md2d;
  EXPECT_EQ(kOK, this->report_store_->GetMetadata(report_id2d, &md2d));
  EXPECT_FALSE(md2d.in_store());
}

// Tests the function QueryReports
TYPED_TEST_P(ReportStoreAbstractTest, QueryReports) {
  static const int64_t kStartTimestamp = 123456789;
  static const uint64_t kTimestampDelta = 10;
  size_t num_timestamps = 50;

  // According to the comments on WriteManyNewReports, we are inserting
  // 6*50 = 300 new report rows: 6 for each of the 50 timestamps specified
  // by kStartTimestamp and kTimestampDelta;
  this->WriteManyNewReports(kStartTimestamp, kTimestampDelta, num_timestamps);

  // Query for 120 of the  300 rows.
  uint64_t interval_start_time_seconds = kStartTimestamp + 5 * kTimestampDelta;
  uint64_t interval_end_time_seconds = kStartTimestamp + 25 * kTimestampDelta;
  auto query_reports_response = this->report_store_->QueryReports(
      this->customer_id(), this->project_id(), this->report_config_id(),
      interval_start_time_seconds, interval_end_time_seconds, INT_MAX, "");

  // Check the results.
  ASSERT_EQ(kOK, query_reports_response.status);
  EXPECT_TRUE(query_reports_response.pagination_token.empty());
  ASSERT_EQ(120u, query_reports_response.results.size());
  for (const auto& report_record : query_reports_response.results) {
    const ReportId& report_id = report_record.report_id;
    EXPECT_EQ(this->customer_id(), report_id.customer_id());
    EXPECT_EQ(this->project_id(), report_id.project_id());
    EXPECT_EQ(this->report_config_id(), report_id.report_config_id());
    uint64_t timestamp = report_id.creation_time_seconds();
    EXPECT_TRUE(interval_start_time_seconds <= timestamp);
    EXPECT_TRUE(timestamp < interval_end_time_seconds);
    // See WriteManyNewReports for how we set
    // report_metadata.start_time_seconds()
    EXPECT_EQ(timestamp + report_id.instance_id() + report_id.sequence_num(),
              (uint64_t)report_record.report_metadata.start_time_seconds());
  }

  // Query again. This time we set limit_start_timestamp = infinity and
  // we query the results in batches of 100.
  std::vector<ReportStore::ReportRecord> full_results;
  interval_start_time_seconds = kStartTimestamp + 5 * kTimestampDelta;
  interval_end_time_seconds = UINT64_MAX;
  std::string pagination_token = "";
  do {
    query_reports_response = this->report_store_->QueryReports(
        this->customer_id(), this->project_id(), this->report_config_id(),
        interval_start_time_seconds, interval_end_time_seconds, 100,
        pagination_token);
    EXPECT_EQ(kOK, query_reports_response.status);
    for (auto& result : query_reports_response.results) {
      full_results.emplace_back(std::move(result));
    }
    pagination_token = std::move(query_reports_response.pagination_token);
  } while (!pagination_token.empty());

  // Check the results.
  ASSERT_EQ(270u, full_results.size());
  for (const auto& report_record : full_results) {
    const ReportId& report_id = report_record.report_id;
    EXPECT_EQ(this->customer_id(), report_id.customer_id());
    EXPECT_EQ(this->project_id(), report_id.project_id());
    EXPECT_EQ(this->report_config_id(), report_id.report_config_id());
    uint64_t timestamp = report_id.creation_time_seconds();
    EXPECT_TRUE(interval_start_time_seconds <= timestamp);
    EXPECT_TRUE(timestamp < interval_end_time_seconds);
    // See WriteManyNewReports for how we set
    // report_metadata.start_time_seconds()
    EXPECT_EQ(timestamp + report_id.instance_id() + report_id.sequence_num(),
              (uint64_t)report_record.report_metadata.start_time_seconds());
  }
}

// Tests the function DeleteAllForReportConfig
TYPED_TEST_P(ReportStoreAbstractTest, TestDeleteAllForReportConfig) {
  // We start four reports: two using our standard report config ID..
  auto report_id_1_a = this->StartNewHistogramReport();
  auto report_id_1_b = this->StartNewHistogramReport();
  // and two using a different report config id.
  auto report_id_2_a = this->MakeReportId(0, 0);
  report_id_2_a.set_report_config_id(this->kReportConfigId + 1);
  EXPECT_EQ(kOK, this->StartNewHistogramReport(true, &report_id_2_a));
  auto report_id_2_b = this->MakeReportId(0, 0);
  report_id_2_b.set_report_config_id(this->kReportConfigId + 1);
  EXPECT_EQ(kOK, this->StartNewHistogramReport(true, &report_id_2_b));

  // Add rows to all four reports.
  EXPECT_EQ(kOK, this->AddHistogramReportRows(report_id_1_a, 100));
  EXPECT_EQ(kOK, this->AddHistogramReportRows(report_id_1_b, 200));
  EXPECT_EQ(kOK, this->AddHistogramReportRows(report_id_2_a, 300));
  EXPECT_EQ(kOK, this->AddHistogramReportRows(report_id_2_b, 400));

  // Complete all four reports
  this->report_store_->EndReport(report_id_1_a, true, "");
  this->report_store_->EndReport(report_id_1_b, true, "");
  this->report_store_->EndReport(report_id_2_a, true, "");
  this->report_store_->EndReport(report_id_2_b, true, "");

  // Now delete everything corresponding to the first report config ID.
  EXPECT_EQ(kOK, this->DeleteAllForReportConfig(this->kReportConfigId));

  // Attempt to get the ReportMetatdata for all four reports.
  // The first two should be not found.
  ReportMetadataLite report_metadata;
  EXPECT_EQ(kNotFound,
            this->report_store_->GetMetadata(report_id_1_a, &report_metadata));
  EXPECT_EQ(kNotFound,
            this->report_store_->GetMetadata(report_id_1_b, &report_metadata));
  // The second two should be ok.
  EXPECT_EQ(kOK,
            this->report_store_->GetMetadata(report_id_2_a, &report_metadata));
  EXPECT_EQ(kOK,
            this->report_store_->GetMetadata(report_id_2_b, &report_metadata));

  // Attempt to get the report rows for all four reports.
  // The first two should be not found.
  cobalt::analyzer::ReportRows rows;
  EXPECT_EQ(kNotFound, this->report_store_->GetReport(report_id_1_a,
                                                      &report_metadata, &rows));
  EXPECT_EQ(kNotFound, this->report_store_->GetReport(report_id_1_b,
                                                      &report_metadata, &rows));
  // The second two should be ok.
  this->GetReportAndCheck(report_id_2_a, 300);
  this->GetReportAndCheck(report_id_2_b, 400);

  // Query for all reports with the first report config id.
  auto query_reports_response = this->report_store_->QueryReports(
      this->customer_id(), this->project_id(), this->report_config_id(), 0,
      INT64_MAX, INT_MAX, "");

  // Check the results. We expect kOK and zero results.
  ASSERT_EQ(kOK, query_reports_response.status);
  EXPECT_TRUE(query_reports_response.pagination_token.empty());
  ASSERT_EQ(0u, query_reports_response.results.size());

  // Query for all reports with the second report config id.
  auto query_reports_response2 = this->report_store_->QueryReports(
      this->customer_id(), this->project_id(), this->report_config_id() + 1, 0,
      INT64_MAX, INT_MAX, "");

  // Check the results. We expect kOK and 2 results.
  ASSERT_EQ(kOK, query_reports_response2.status);
  EXPECT_TRUE(query_reports_response2.pagination_token.empty());
  ASSERT_EQ(2u, query_reports_response2.results.size());
}

REGISTER_TYPED_TEST_CASE_P(ReportStoreAbstractTest, SetAndGetMetadata,
                           CreateAndStartDependentReport, ReportRows, InStore,
                           QueryReports, TestDeleteAllForReportConfig);

}  // namespace store
}  // namespace analyzer
}  // namespace cobalt

#endif  // COBALT_ANALYZER_STORE_REPORT_STORE_ABSTRACT_TEST_H_
