blob: e09229a444773cbeea3e87f718dfa1451c8c1e8b [file] [log] [blame]
// 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_