blob: b925f1d1a318a275618de98f336a72a22f8c1510 [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.
#ifndef COBALT_SRC_LOGGER_LOGGER_TEST_UTILS_H_
#define COBALT_SRC_LOGGER_LOGGER_TEST_UTILS_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include <gtest/gtest.h>
#include "src/lib/util/consistent_proto_store.h"
#include "src/lib/util/posix_file_system.h"
#include "src/logger/project_context.h"
#include "src/logger/project_context_factory.h"
#include "src/observation_store/observation_store.h"
#include "src/observation_store/observation_store_update_recipient.h"
#include "src/public/lib/status.h"
namespace cobalt::logger::testing {
// A representation of a set of expected ReportParticipationObservations. Used
// to check the values of ReportParticipationObservations generated by the
// EventAggregator. The first element of each pair is the MetricReportId of a
// report, and the second element represents the day index of an expected
// Observation for that report. a pair is a a set of window sizes.
using ExpectedReportParticipationObservations = std::set<std::pair<MetricReportId, uint32_t>>;
// A mock ObservationStore.
// TODO(https://fxbug.dev/278925674): Move this to a more appropriate location (Perhaps in
// src/observation_store)
class FakeObservationStore : public ::cobalt::observation_store::ObservationStoreWriterInterface {
public:
using ::cobalt::observation_store::ObservationStoreWriterInterface::StoreObservation;
Status StoreObservation(std::unique_ptr<::cobalt::observation_store::StoredObservation> message,
std::unique_ptr<ObservationMetadata> metadata) override {
if (fail_calls_) {
return ::cobalt::Status(StatusCode::FAILED_PRECONDITION, "fail_calls was set");
}
messages_received.emplace_back(std::move(message));
metadata_received.emplace_back(std::move(metadata));
num_observations_added_++;
return Status::OkStatus();
}
std::vector<std::unique_ptr<::cobalt::observation_store::StoredObservation>>
messages_received; // NOLINT
std::vector<std::unique_ptr<ObservationMetadata>> metadata_received; // NOLINT
size_t num_observations_added() const { return num_observations_added_; }
void ResetObservationCounter() { num_observations_added_ = 0; }
void SetFailCalls(bool fail_calls) { fail_calls_ = fail_calls; }
private:
size_t num_observations_added_ = 0;
bool fail_calls_ = false;
};
// A mock ObservationStoreUpdateRecipient.
class TestUpdateRecipient : public ::cobalt::observation_store::ObservationStoreUpdateRecipient {
public:
void NotifyObservationsAdded() override { invocation_count++; }
int invocation_count = 0;
};
// A mock ConsistentProtoStore. Its Read() and Write() methods increment
// counts of their invocations.
class MockConsistentProtoStore : public ::cobalt::util::ConsistentProtoStore {
public:
explicit MockConsistentProtoStore(std::string filename)
: ::cobalt::util::ConsistentProtoStore(std::move(filename), fs_) {
read_count_ = 0;
write_count_ = 0;
}
~MockConsistentProtoStore() override = default;
// To set the stored proto in a test, use |set_stored_proto| instead of Write.
Status Write(const google::protobuf::MessageLite& /*proto*/) override {
write_count_++;
return Status::OkStatus();
}
Status Read(google::protobuf::MessageLite* proto) override {
if (stored_proto_) {
proto->Clear();
proto->CheckTypeAndMergeFrom(*stored_proto_);
}
read_count_++;
return Status::OkStatus();
}
void ResetCounts() {
read_count_ = 0;
write_count_ = 0;
}
int read_count_; // NOLINT
int write_count_; // NOLINT
void set_stored_proto(std::unique_ptr<google::protobuf::MessageLite> proto) {
stored_proto_ = std::move(proto);
}
private:
::cobalt::util::PosixFileSystem fs_;
std::unique_ptr<google::protobuf::MessageLite> stored_proto_;
};
// Creates and returns a ProjectContextFactory from a serialized, base64-encoded Cobalt
// registry.
std::unique_ptr<ProjectContextFactory> GetTestProjectContextFactory(
const std::string& registry_base64);
// Creates and returns a ProjectContext from a serialized, base64-encoded Cobalt
// registry.
std::unique_ptr<ProjectContext> GetTestProject(const std::string& registry_base64);
// Construct a histogram to log from the indices for buckets, and the counts in that bucket.
HistogramPtr NewHistogram(std::vector<uint32_t> indices, std::vector<uint32_t> counts);
// Populates |observations| with the contents of a FakeObservationStore.
// |observations| should be a vector whose size is equal to the number
// of expected observations. Checks the the ObservationStore contains
// the expected number of Observations and that the report_ids of the
// Observations are equal to |expected_report_ids|. Returns true iff all checks
// pass.
bool FetchObservations(std::vector<Observation>* observations,
const std::vector<uint32_t>& expected_report_ids,
FakeObservationStore& observation_store,
TestUpdateRecipient* update_recipient);
// Populates |observation| with the contents of a FakeObservationStore,
// which is expected to contain a single Observation with a report_id
// of |expected_report_id|. Returns true iff all checks pass.
bool FetchSingleObservation(Observation* observation, uint32_t expected_report_id,
FakeObservationStore& observation_store,
TestUpdateRecipient* update_recipient);
// Checks that the contents of a FakeObservationStore is a sequence of
// IntegerEventObservations specified by the various parameters. Returns
// true if all checks pass.
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);
} // namespace cobalt::logger::testing
#endif // COBALT_SRC_LOGGER_LOGGER_TEST_UTILS_H_