blob: e1b9ab7e234692a2a2351c78f49754839773d5b7 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/logger/logger_test_utils.h"
#include <algorithm>
#include <utility>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/message_differencer.h>
#include "src/logger/project_context_factory.h"
#include "src/pb/observation.pb.h"
namespace cobalt::logger::testing {
std::unique_ptr<ProjectContextFactory> GetTestProjectContextFactory(
const std::string& registry_base64) {
auto project_context_factory =
ProjectContextFactory::CreateFromCobaltRegistryBase64(registry_base64);
EXPECT_NE(nullptr, project_context_factory);
return project_context_factory;
}
std::unique_ptr<ProjectContext> GetTestProject(const std::string& registry_base64) {
auto project_context_factory = GetTestProjectContextFactory(registry_base64);
EXPECT_TRUE(project_context_factory->is_single_project());
return project_context_factory->TakeSingleProjectContext();
}
HistogramPtr NewHistogram(std::vector<uint32_t> indices, std::vector<uint32_t> counts) {
CHECK(indices.size() == counts.size());
HistogramPtr histogram = std::make_unique<google::protobuf::RepeatedPtrField<HistogramBucket>>();
for (auto i = 0u; i < indices.size(); i++) {
auto* bucket = histogram->Add();
bucket->set_index(indices[i]);
bucket->set_count(counts[i]);
}
return histogram;
}
bool FetchObservations(std::vector<Observation>* observations,
const std::vector<uint32_t>& expected_report_ids,
FakeObservationStore& observation_store,
TestUpdateRecipient* update_recipient) {
CHECK(observations);
size_t expected_num_received = observations->size();
CHECK(expected_report_ids.size() == expected_num_received);
auto num_received = observation_store.messages_received.size();
EXPECT_EQ(num_received, observation_store.metadata_received.size());
EXPECT_EQ(num_received, observation_store.num_observations_added());
if (num_received != observation_store.metadata_received.size()) {
return false;
}
EXPECT_EQ(num_received, expected_num_received);
if (num_received != expected_num_received) {
return false;
}
num_received = update_recipient->invocation_count;
EXPECT_EQ(num_received, expected_num_received);
if (num_received != expected_num_received) {
return false;
}
for (auto i = 0u; i < expected_num_received; i++) {
bool isNull = (observation_store.metadata_received[i].get() == nullptr);
EXPECT_FALSE(isNull);
if (isNull) {
return false;
}
EXPECT_EQ(observation_store.metadata_received[i]->report_id(), expected_report_ids[i])
<< "i=" << i;
isNull = (observation_store.messages_received[i].get() == nullptr);
EXPECT_FALSE(isNull);
if (isNull) {
return false;
}
const auto& message = *observation_store.messages_received[i];
if (message.has_encrypted()) {
bool successfullyDeserialized =
observations->at(i).ParseFromString(message.encrypted().ciphertext());
EXPECT_TRUE(successfullyDeserialized);
if (!successfullyDeserialized) {
return false;
}
} else if (message.has_unencrypted()) {
observations->at(i) = message.unencrypted();
} else {
// Saw unexpected message type.
return false;
}
bool has_random_id = !(observations->at(i).random_id().empty());
EXPECT_TRUE(has_random_id);
}
return true;
}
bool FetchSingleObservation(Observation* observation, uint32_t expected_report_id,
FakeObservationStore& observation_store,
TestUpdateRecipient* update_recipient) {
std::vector<Observation> observations(1);
std::vector<uint32_t> expected_report_ids;
expected_report_ids.push_back(expected_report_id);
if (!FetchObservations(&observations, expected_report_ids, observation_store, update_recipient)) {
return false;
}
*observation = observations[0];
return true;
}
bool CheckNumericEventObservations(const std::vector<uint32_t>& expected_report_ids,
uint32_t expected_event_code,
const std::string& expected_component_name,
int64_t expected_int_value,
FakeObservationStore& observation_store,
TestUpdateRecipient* update_recipient) {
size_t expected_num_observations = expected_report_ids.size();
std::vector<Observation> observations(expected_num_observations);
if (!FetchObservations(&observations, expected_report_ids, observation_store, update_recipient)) {
return false;
}
for (auto i = 0u; i < expected_num_observations; i++) {
switch (observations[i].observation_type_case()) {
case Observation::ObservationTypeCase::kInteger: {
const auto& integer = observations[i].integer();
EXPECT_EQ(integer.values_size(), 1);
if (integer.values_size() < 1) {
return false;
}
const auto& integer_value = integer.values(0);
if (expected_event_code == 0) {
EXPECT_EQ(integer_value.event_codes_size(), 0);
} else {
EXPECT_EQ(integer_value.event_codes_size(), 1);
EXPECT_EQ(expected_event_code, integer_value.event_codes(0));
if (expected_event_code != integer_value.event_codes(0)) {
return false;
}
}
EXPECT_EQ(expected_int_value, integer_value.value());
if (expected_int_value != integer_value.value()) {
return false;
}
} break;
default:
LOG(ERROR) << "Saw unexpected observation_type_case: "
<< observations[i].observation_type_case();
return false;
}
}
return true;
}
} // namespace cobalt::logger::testing