| // 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 |