| // 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/registry/project_configs.h" |
| |
| #include <sstream> |
| |
| #include <gtest/gtest.h> |
| |
| #include "src/logging.h" |
| #include "src/public/lib/registry_identifiers.h" |
| #include "third_party/abseil-cpp/absl/strings/escaping.h" |
| |
| namespace cobalt::config { |
| |
| namespace { |
| |
| constexpr size_t kNumReportsPerMetric = 3; |
| constexpr size_t kNumMetricsPerProject = 5; |
| constexpr size_t kNumCustomers = 2; |
| constexpr uint32_t kNonExistent = 20; |
| |
| std::string NameForId(const std::string& prefix, uint32_t id) { |
| std::ostringstream stream; |
| stream << prefix << "Name" << id; |
| return stream.str(); |
| } |
| |
| std::string CustomerNameForId(uint32_t id) { return NameForId("Customer-", id); } |
| std::string ProjectNameForId(uint32_t id) { return NameForId("Project-", id); } |
| std::string ReportNameForId(uint32_t id) { return NameForId("Report-", id); } |
| std::string MetricNameForId(uint32_t id) { return NameForId("Metric-", id); } |
| |
| // We create 3n projects for customer n. |
| size_t NumProjectsForCustomer(uint32_t customer_id) { return size_t{3} * customer_id; } |
| |
| void SetupReport(uint32_t report_id, ReportDefinition* report) { |
| report->set_id(report_id); |
| report->set_report_name(ReportNameForId(report_id)); |
| } |
| |
| void SetupMetric(uint32_t metric_id, MetricDefinition* metric) { |
| metric->set_id(metric_id); |
| metric->set_metric_name(MetricNameForId(metric_id)); |
| for (size_t i = 1u; i < kNumReportsPerMetric; i++) { |
| SetupReport(i, metric->add_reports()); |
| } |
| } |
| |
| void SetupProject(uint32_t project_id, ProjectConfig* project) { |
| project->set_project_id(project_id); |
| project->set_project_name(ProjectNameForId(project_id)); |
| for (size_t i = 1u; i <= kNumMetricsPerProject; i++) { |
| SetupMetric(i, project->add_metrics()); |
| } |
| } |
| |
| void SetupCustomer(uint32_t customer_id, size_t num_projects, CustomerConfig* customer) { |
| customer->set_customer_id(customer_id); |
| customer->set_customer_name(CustomerNameForId(customer_id)); |
| for (auto i = 1u; i <= num_projects; i++) { |
| SetupProject(i, customer->add_projects()); |
| } |
| } |
| |
| std::unique_ptr<CobaltRegistry> NewTestRegistry( |
| size_t num_customers, const std::function<size_t(uint32_t)>& num_projects_for_customer_fn) { |
| auto cobalt_registry = std::make_unique<CobaltRegistry>(); |
| for (size_t i = 1u; i <= num_customers; i++) { |
| SetupCustomer(i, num_projects_for_customer_fn(i), cobalt_registry->add_customers()); |
| } |
| return cobalt_registry; |
| } |
| |
| std::unique_ptr<CobaltRegistry> NewTestRegistry() { |
| return NewTestRegistry(kNumCustomers, NumProjectsForCustomer); |
| } |
| |
| // Constructs a ProjectConfigs that wraps a CobaltRegistry with the |
| // specified number of customers and projects-per-customer. |
| std::unique_ptr<ProjectConfigs> NewProjectConfigs(size_t num_customers, |
| size_t num_projects_per_customer) { |
| return std::make_unique<ProjectConfigs>(NewTestRegistry( |
| num_customers, |
| [num_projects_per_customer](uint32_t /*unused*/) { return num_projects_per_customer; })); |
| } |
| |
| } // namespace |
| |
| class ProjectConfigsTest : public ::testing::Test { |
| protected: |
| // Checks that |*customer_config| is as expected. |
| static bool CheckCustomer(uint32_t expected_customer_id, const CustomerConfig* customer_config) { |
| EXPECT_NE(nullptr, customer_config); |
| if (customer_config == nullptr) { |
| return false; |
| } |
| |
| auto customer_id = customer_config->customer_id(); |
| EXPECT_EQ(expected_customer_id, customer_id); |
| if (expected_customer_id != customer_id) { |
| return false; |
| } |
| EXPECT_EQ(CustomerNameForId(expected_customer_id), customer_config->customer_name()); |
| if (CustomerNameForId(expected_customer_id) != customer_config->customer_name()) { |
| return false; |
| } |
| size_t expected_num_projects = NumProjectsForCustomer(customer_id); |
| size_t num_projects = customer_config->projects_size(); |
| EXPECT_EQ(expected_num_projects, num_projects); |
| return num_projects == expected_num_projects; |
| } |
| |
| // Checks that |*project_config| is as expected. |
| static bool CheckProject(uint32_t expected_project_id, const ProjectConfig* project_config) { |
| EXPECT_NE(nullptr, project_config); |
| if (project_config == nullptr) { |
| return false; |
| } |
| |
| EXPECT_EQ(expected_project_id, project_config->project_id()); |
| if (expected_project_id != project_config->project_id()) { |
| return false; |
| } |
| EXPECT_EQ(ProjectNameForId(expected_project_id), project_config->project_name()); |
| if (ProjectNameForId(expected_project_id) != project_config->project_name()) { |
| return false; |
| } |
| size_t num_metrics = project_config->metrics_size(); |
| EXPECT_EQ(kNumMetricsPerProject, num_metrics); |
| return num_metrics == kNumMetricsPerProject; |
| } |
| |
| // Checks that |project_configs| is as expected. |
| static bool CheckProjectConfigs(const ProjectConfigs& project_configs) { |
| for (uint32_t customer_id = 1; customer_id <= kNumCustomers; customer_id++) { |
| std::string expected_customer_name = CustomerNameForId(customer_id); |
| size_t expected_num_projects = NumProjectsForCustomer(customer_id); |
| lib::CustomerIdentifier customer_identifier(customer_id); |
| |
| // Check getting the customer by ID. |
| bool success = |
| CheckCustomer(customer_id, project_configs.GetCustomerConfig(customer_identifier)); |
| EXPECT_TRUE(success); |
| if (!success) { |
| return false; |
| } |
| |
| for (uint32_t project_id = 1; project_id <= expected_num_projects; project_id++) { |
| std::string project_name = ProjectNameForId(project_id); |
| |
| // Check getting the project by ID. |
| success = CheckProject(project_id, project_configs.GetProjectConfig( |
| customer_identifier.ForProject(project_id))); |
| EXPECT_TRUE(success); |
| if (!success) { |
| return false; |
| } |
| |
| // Check using an invalid project_id. |
| const ProjectConfig* project = project_configs.GetProjectConfig( |
| customer_identifier.ForProject(expected_num_projects + project_id)); |
| EXPECT_EQ(nullptr, project); |
| if (project != nullptr) { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| }; |
| |
| // Test GetCustomerConfig by id. |
| TEST_F(ProjectConfigsTest, GetCustomerConfigById) { |
| ProjectConfigs project_configs(NewTestRegistry()); |
| const CustomerConfig* customer; |
| |
| customer = project_configs.GetCustomerConfig(lib::CustomerIdentifier(1)); |
| EXPECT_NE(customer, nullptr); |
| EXPECT_EQ(customer->customer_id(), 1u); |
| |
| customer = project_configs.GetCustomerConfig(lib::CustomerIdentifier(2)); |
| EXPECT_NE(customer, nullptr); |
| EXPECT_EQ(customer->customer_id(), 2u); |
| |
| // Customer does not exist. |
| customer = project_configs.GetCustomerConfig(lib::CustomerIdentifier(kNonExistent)); |
| EXPECT_EQ(customer, nullptr); |
| } |
| |
| // Test GetProjectConfig by id. |
| TEST_F(ProjectConfigsTest, GetProjectConfigById) { |
| ProjectConfigs project_configs(NewTestRegistry()); |
| const ProjectConfig* project; |
| |
| project = project_configs.GetProjectConfig(lib::CustomerIdentifier(1).ForProject(1)); |
| EXPECT_NE(project, nullptr); |
| EXPECT_EQ(project->project_id(), 1u); |
| |
| project = project_configs.GetProjectConfig(lib::CustomerIdentifier(1).ForProject(2)); |
| EXPECT_NE(project, nullptr); |
| EXPECT_EQ(project->project_id(), 2u); |
| |
| // Customer does not exist. |
| project = project_configs.GetProjectConfig(lib::CustomerIdentifier(kNonExistent).ForProject(2)); |
| EXPECT_EQ(project, nullptr); |
| |
| // Customer exists, project does not exist. |
| project = project_configs.GetProjectConfig(lib::CustomerIdentifier(1).ForProject(kNonExistent)); |
| EXPECT_EQ(project, nullptr); |
| } |
| |
| // Test GetMetricDefintion. |
| TEST_F(ProjectConfigsTest, GetMetricDefinitionById) { |
| ProjectConfigs project_configs(NewTestRegistry()); |
| const MetricDefinition* metric; |
| |
| metric = |
| project_configs.GetMetricDefinition(lib::CustomerIdentifier(1).ForProject(1).ForMetric(1)); |
| EXPECT_NE(metric, nullptr); |
| EXPECT_EQ(metric->id(), 1u); |
| |
| metric = |
| project_configs.GetMetricDefinition(lib::CustomerIdentifier(1).ForProject(1).ForMetric(2)); |
| EXPECT_NE(metric, nullptr); |
| EXPECT_EQ(metric->id(), 2u); |
| |
| // Customer does not exist. |
| metric = project_configs.GetMetricDefinition( |
| lib::CustomerIdentifier(kNonExistent).ForProject(1).ForMetric(2)); |
| EXPECT_EQ(metric, nullptr); |
| |
| // Customer exists, project does not exist. |
| metric = project_configs.GetMetricDefinition( |
| lib::CustomerIdentifier(1).ForProject(kNonExistent).ForMetric(2)); |
| EXPECT_EQ(metric, nullptr); |
| |
| // Customer exists, project exists, metric does not exist. |
| metric = project_configs.GetMetricDefinition( |
| lib::CustomerIdentifier(1).ForProject(1).ForMetric(kNonExistent)); |
| EXPECT_EQ(metric, nullptr); |
| } |
| |
| // Test GetReportDefinition. |
| TEST_F(ProjectConfigsTest, GetReportDefinitionById) { |
| ProjectConfigs project_configs(NewTestRegistry()); |
| const ReportDefinition* report; |
| |
| report = project_configs.GetReportDefinition( |
| lib::CustomerIdentifier(1).ForProject(1).ForMetric(1).ForReport(1)); |
| EXPECT_NE(report, nullptr); |
| EXPECT_EQ(report->id(), 1u); |
| |
| report = project_configs.GetReportDefinition( |
| lib::CustomerIdentifier(1).ForProject(1).ForMetric(1).ForReport(2)); |
| EXPECT_NE(report, nullptr); |
| EXPECT_EQ(report->id(), 2u); |
| |
| // Customer does not exist. |
| report = project_configs.GetReportDefinition( |
| lib::CustomerIdentifier(kNonExistent).ForProject(1).ForMetric(1).ForReport(2)); |
| EXPECT_EQ(report, nullptr); |
| |
| // Customer exists, project does not exist. |
| report = project_configs.GetReportDefinition( |
| lib::CustomerIdentifier(1).ForProject(kNonExistent).ForMetric(2).ForReport(2)); |
| EXPECT_EQ(report, nullptr); |
| |
| // Customer exists, project exists, metric does not exist. |
| report = project_configs.GetReportDefinition( |
| lib::CustomerIdentifier(1).ForProject(1).ForMetric(kNonExistent).ForReport(2)); |
| EXPECT_EQ(report, nullptr); |
| |
| // Customer exists, project exists, metric exist, report does not exist. |
| report = project_configs.GetReportDefinition( |
| lib::CustomerIdentifier(1).ForProject(1).ForMetric(1).ForReport(kNonExistent)); |
| EXPECT_EQ(report, nullptr); |
| } |
| |
| // Tests using a ProjectConfigs constructed directly from a |
| // CobaltRegistry |
| TEST_F(ProjectConfigsTest, ConstructForCobaltRegistry) { |
| ProjectConfigs project_configs(NewTestRegistry()); |
| EXPECT_TRUE(CheckProjectConfigs(project_configs)); |
| } |
| |
| // Tests using a ProjectConfigs obtained via CreateFromCobaltRegistryBytes(). |
| TEST_F(ProjectConfigsTest, CreateFromCobaltRegistryBytes) { |
| auto cobalt_registry = NewTestRegistry(); |
| std::string bytes; |
| cobalt_registry->SerializeToString(&bytes); |
| auto project_configs = ProjectConfigs::CreateFromCobaltRegistryBytes(bytes); |
| EXPECT_TRUE(CheckProjectConfigs(*project_configs)); |
| } |
| |
| // Tests using a ProjectConfigs obtained via CreateFromCobaltRegistryBase64(). |
| TEST_F(ProjectConfigsTest, CreateFromCobaltRegistryBase64) { |
| auto cobalt_registry = NewTestRegistry(); |
| std::string bytes; |
| cobalt_registry->SerializeToString(&bytes); |
| std::string cobalt_registry_base64; |
| absl::Base64Escape(bytes, &cobalt_registry_base64); |
| auto project_configs = ProjectConfigs::CreateFromCobaltRegistryBase64(cobalt_registry_base64); |
| EXPECT_TRUE(CheckProjectConfigs(*project_configs)); |
| } |
| |
| // Tests the logic that determines whether or not a ProjectConfigs is empty |
| // or contains a single project. |
| TEST_F(ProjectConfigsTest, IsSingleProject) { |
| // An ProjectConfigs constructed from an empty CobaltRegistry is empty but |
| // is not a single project. |
| auto project_configs = NewProjectConfigs(0, 0); |
| EXPECT_FALSE(project_configs->is_single_project()); |
| EXPECT_TRUE(project_configs->is_empty()); |
| EXPECT_TRUE(project_configs->TakeSingleProjectConfig() == nullptr); |
| |
| // A ProjectConfigs constructed from a CobaltRegistry with 1 customer with |
| // no projects is not empty and is not a single project. |
| project_configs = NewProjectConfigs(1, 0); |
| EXPECT_FALSE(project_configs->is_single_project()); |
| EXPECT_FALSE(project_configs->is_empty()); |
| EXPECT_TRUE(project_configs->TakeSingleProjectConfig() == nullptr); |
| |
| // A ProjectConfigs constructed from a CobaltRegistry with 1 customer with 1 |
| // project is not empty and is a single project. |
| project_configs = NewProjectConfigs(1, 1); |
| EXPECT_TRUE(project_configs->is_single_project()); |
| EXPECT_FALSE(project_configs->is_empty()); |
| EXPECT_EQ(1u, project_configs->single_customer_id()); |
| EXPECT_EQ("Customer-Name1", project_configs->single_customer_name()); |
| EXPECT_EQ(1u, project_configs->single_project_id()); |
| EXPECT_EQ("Project-Name1", project_configs->single_project_name()); |
| // Test TakeSingleProjectConfg() in the case that there is a single project. |
| EXPECT_NE(project_configs->GetProjectConfig(lib::CustomerIdentifier(1).ForProject(1)), nullptr); |
| auto project_config = project_configs->TakeSingleProjectConfig(); |
| EXPECT_TRUE(project_config != nullptr); |
| EXPECT_EQ("Project-Name1", project_config->project_name()); |
| EXPECT_FALSE(project_configs->is_single_project()); |
| EXPECT_TRUE(project_configs->is_empty()); |
| EXPECT_EQ(project_configs->GetProjectConfig(lib::CustomerIdentifier(1).ForProject(1)), nullptr); |
| |
| // A ProjectConfigs constructed from a CobaltRegistry with 1 customer with 2 |
| // projects is not empty and is not a single project. |
| project_configs = NewProjectConfigs(1, 2); |
| EXPECT_FALSE(project_configs->is_single_project()); |
| EXPECT_FALSE(project_configs->is_empty()); |
| EXPECT_TRUE(project_configs->TakeSingleProjectConfig() == nullptr); |
| |
| // A ProjectConfigs constructed from a CobaltRegistry with 2 customers with |
| // 1 project each is not empty and is not a single project. |
| project_configs = NewProjectConfigs(2, 1); |
| EXPECT_FALSE(project_configs->is_single_project()); |
| EXPECT_FALSE(project_configs->is_empty()); |
| EXPECT_TRUE(project_configs->TakeSingleProjectConfig() == nullptr); |
| } |
| |
| } // namespace cobalt::config |