blob: d0d0985c9f977f94455a6faebf6b628143b7fa0b [file] [log] [blame]
// Copyright 2020 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/local_aggregation_1_1/local_aggregate_storage/immediate_local_aggregate_storage.h"
#include <memory>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "src/lib/statusor/statusor.h"
#include "src/lib/util/testing/test_with_files.h"
#include "src/local_aggregation_1_1/local_aggregate_storage/local_aggregate_storage.h"
#include "src/local_aggregation_1_1/testing/test_registry.cb.h"
#include "src/logger/project_context_factory.h"
#include "src/logging.h"
#include "src/registry/cobalt_registry.pb.h"
namespace cobalt::local_aggregation {
using lib::statusor::StatusOr;
using ::testing::Contains;
using ::testing::Not;
using MetricAggregateRef = LocalAggregateStorage::MetricAggregateRef;
namespace {
std::unique_ptr<CobaltRegistry> GetRegistry() {
std::string bytes;
if (!absl::Base64Unescape(kCobaltRegistryBase64, &bytes)) {
LOG(ERROR) << "Unable to decode Base64 String";
return nullptr;
}
auto registry = std::make_unique<CobaltRegistry>();
if (!registry->ParseFromString(bytes)) {
LOG(ERROR) << "Unable to parse registry from bytes";
return nullptr;
}
return registry;
}
} // namespace
class ImmediateLocalAggregateStorageTest : public util::testing::TestWithFiles {
private:
void SetUp() override {
MakeTestFolder();
ReplaceRegistry();
}
public:
void ReplaceRegistry(std::unique_ptr<CobaltRegistry> registry = GetRegistry()) {
global_project_context_factory_ =
std::make_unique<logger::ProjectContextFactory>(std::move(registry));
storage_ = std::make_unique<ImmediateLocalAggregateStorage>(
test_folder(), fs(), global_project_context_factory_.get());
}
protected:
std::unique_ptr<logger::ProjectContextFactory> global_project_context_factory_;
std::unique_ptr<ImmediateLocalAggregateStorage> storage_;
};
TEST_F(ImmediateLocalAggregateStorageTest, MakesExpectedFiles) {
// Root directory should contain expected customer_id: 123
ASSERT_THAT(fs()->ListFiles(test_folder()).ConsumeValueOrDie(), Contains("123"));
// Customer 123 directory should contain expected project: 100
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123")).ConsumeValueOrDie(),
Contains("100"));
// Customer 123 Project 100 directory should *not* contain the metric file: 1
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123/100")).ConsumeValueOrDie(),
Not(Contains("1")));
StatusOr<MetricAggregateRef> agg_or = storage_->GetMetricAggregate(123, 100, 1);
ASSERT_TRUE(agg_or.ok());
agg_or.ConsumeValueOrDie().Save();
// Customer 123 Project 100 directory should contain the metric file: 1
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123/100")).ConsumeValueOrDie(),
Contains("1"));
}
TEST_F(ImmediateLocalAggregateStorageTest, CanReadAlreadyWrittenFiles) {
{
StatusOr<MetricAggregateRef> agg_or = storage_->GetMetricAggregate(123, 100, 1);
ASSERT_TRUE(agg_or.ok());
MetricAggregateRef agg = agg_or.ConsumeValueOrDie();
agg.aggregate()->set_version(100);
ASSERT_TRUE(agg.Save().ok());
}
ReplaceRegistry();
StatusOr<MetricAggregateRef> agg_or = storage_->GetMetricAggregate(123, 100, 1);
ASSERT_TRUE(agg_or.ok());
ASSERT_TRUE(agg_or.ConsumeValueOrDie().Save().ok());
}
TEST_F(ImmediateLocalAggregateStorageTest, CleansUpOldMetrics) {
StatusOr<MetricAggregateRef> agg_or = storage_->GetMetricAggregate(123, 100, 1);
ASSERT_TRUE(agg_or.ok());
agg_or.ConsumeValueOrDie().Save();
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123/100")).ConsumeValueOrDie(),
Contains("1"));
auto registry = GetRegistry();
google::protobuf::RepeatedPtrField<MetricDefinition>* metrics =
registry->mutable_customers(0)->mutable_projects(0)->mutable_metrics();
metrics->erase(metrics->begin() + kOccurrenceMetricMetricIndex);
ReplaceRegistry(std::move(registry));
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123/100")).ConsumeValueOrDie(),
Not(Contains("1")));
}
TEST_F(ImmediateLocalAggregateStorageTest, CleansUpOldProjects) {
StatusOr<MetricAggregateRef> agg_or = storage_->GetMetricAggregate(123, 100, 1);
ASSERT_TRUE(agg_or.ok());
agg_or.ConsumeValueOrDie().Save();
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123")).ConsumeValueOrDie(),
Contains("100"));
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123/100")).ConsumeValueOrDie(),
Contains("1"));
auto registry = GetRegistry();
registry->mutable_customers(0)->mutable_projects()->RemoveLast();
ReplaceRegistry(std::move(registry));
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123")).ConsumeValueOrDie(),
Not(Contains("100")));
}
TEST_F(ImmediateLocalAggregateStorageTest, DeleteDataWorks) {
StatusOr<MetricAggregateRef> agg_or = storage_->GetMetricAggregate(123, 100, 1);
ASSERT_TRUE(agg_or.ok());
agg_or.ConsumeValueOrDie().Save();
ASSERT_THAT(fs()->ListFiles(test_folder()).ConsumeValueOrDie(), Contains("123"));
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123")).ConsumeValueOrDie(),
Contains("100"));
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_folder(), "/123/100")).ConsumeValueOrDie(),
Contains("1"));
storage_->DeleteData();
ASSERT_THAT(fs()->ListFiles(test_folder()).ConsumeValueOrDie(), Not(Contains("123")));
}
class ImmediateLocalAggregateStorageMissingDirectoryTest : public util::testing::TestWithFiles {
private:
void SetUp() override {
MakeTestFolder();
ReplaceRegistry();
}
public:
void ReplaceRegistry(std::unique_ptr<CobaltRegistry> registry = GetRegistry()) {
global_project_context_factory_ =
std::make_unique<logger::ProjectContextFactory>(std::move(registry));
storage_ = std::make_unique<ImmediateLocalAggregateStorage>(
test_subfolder(), fs(), global_project_context_factory_.get());
}
protected:
std::string test_subfolder() { return absl::StrCat(test_folder(), "/sub"); }
std::unique_ptr<logger::ProjectContextFactory> global_project_context_factory_;
std::unique_ptr<ImmediateLocalAggregateStorage> storage_;
};
TEST_F(ImmediateLocalAggregateStorageMissingDirectoryTest, DontAssumeDirectoryExists) {
// Root directory should contain expected customer_id: 123
ASSERT_THAT(fs()->ListFiles(test_subfolder()).ConsumeValueOrDie(), Contains("123"));
// Customer 123 directory should contain expected project: 100
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_subfolder(), "/123")).ConsumeValueOrDie(),
Contains("100"));
// Customer 123 Project 100 directory should *not* contain the metric file: 1
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_subfolder(), "/123/100")).ConsumeValueOrDie(),
Not(Contains("1")));
StatusOr<MetricAggregateRef> agg_or = storage_->GetMetricAggregate(123, 100, 1);
ASSERT_TRUE(agg_or.ok());
agg_or.ConsumeValueOrDie().Save();
// Customer 123 Project 100 directory should contain the metric file: 1
ASSERT_THAT(fs()->ListFiles(absl::StrCat(test_subfolder(), "/123/100")).ConsumeValueOrDie(),
Contains("1"));
}
} // namespace cobalt::local_aggregation