From c0e5be9aa6c5b2d36cfdee0bca4c8981367547b5 Mon Sep 17 00:00:00 2001 From: erichsueh3 Date: Thu, 6 Aug 2020 18:19:55 -0700 Subject: [PATCH 1/3] Add PrometheusCollector tests --- .../test/prometheus_collector_test.cc | 752 ++++++++++++++++++ 1 file changed, 752 insertions(+) create mode 100644 exporters/prometheus/test/prometheus_collector_test.cc diff --git a/exporters/prometheus/test/prometheus_collector_test.cc b/exporters/prometheus/test/prometheus_collector_test.cc new file mode 100644 index 0000000000..0efa50139e --- /dev/null +++ b/exporters/prometheus/test/prometheus_collector_test.cc @@ -0,0 +1,752 @@ +#include +#include +#include +#include + +#include "opentelemetry/exporters/prometheus/prometheus_collector.h" +#include "opentelemetry/metrics/instrument.h" +#include "opentelemetry/sdk/metrics/aggregator/aggregator.h" +#include "opentelemetry/sdk/metrics/aggregator/counter_aggregator.h" +#include "opentelemetry/sdk/metrics/aggregator/exact_aggregator.h" +#include "opentelemetry/sdk/metrics/aggregator/gauge_aggregator.h" +#include "opentelemetry/sdk/metrics/aggregator/histogram_aggregator.h" +#include "opentelemetry/sdk/metrics/aggregator/min_max_sum_count_aggregator.h" +#include "opentelemetry/sdk/metrics/aggregator/sketch_aggregator.h" +#include "opentelemetry/sdk/metrics/record.h" +#include "opentelemetry/version.h" + +using opentelemetry::exporter::prometheus::PrometheusCollector; + +OPENTELEMETRY_BEGIN_NAMESPACE + +/** + * CreateAgg() is a helper function that returns a + * nostd::shared_ptr given an AggregatorKind + */ +template +nostd::shared_ptr> CreateAgg(metric_sdk::AggregatorKind kind, + bool exactMode = true) +{ + nostd::shared_ptr> aggregator; + switch (kind) + { + case metric_sdk::AggregatorKind::Counter: { + aggregator = nostd::shared_ptr>( + new metric_sdk::CounterAggregator(opentelemetry::metrics::InstrumentKind::Counter)); + break; + } + case metric_sdk::AggregatorKind::MinMaxSumCount: { + aggregator = + nostd::shared_ptr>(new metric_sdk::MinMaxSumCountAggregator( + opentelemetry::metrics::InstrumentKind::Counter)); + break; + } + case metric_sdk::AggregatorKind::Gauge: { + aggregator = nostd::shared_ptr>( + new metric_sdk::GaugeAggregator(opentelemetry::metrics::InstrumentKind::Counter)); + break; + } + case metric_sdk::AggregatorKind::Sketch: { + aggregator = nostd::shared_ptr>(new metric_sdk::SketchAggregator( + opentelemetry::metrics::InstrumentKind::Counter, 0.000005)); + break; + } + case metric_sdk::AggregatorKind::Histogram: { + std::vector boundaries{10, 20}; + aggregator = + nostd::shared_ptr>(new metric_sdk::HistogramAggregator( + opentelemetry::metrics::InstrumentKind::Counter, boundaries)); + break; + } + case metric_sdk::AggregatorKind::Exact: { + aggregator = nostd::shared_ptr>(new metric_sdk::ExactAggregator( + opentelemetry::metrics::InstrumentKind::Counter, exactMode)); + break; + } + default: + aggregator = nullptr; + } + return aggregator; +} + +/** + * Populate() updates the aggregator with values and checkpoints it based + * on what its AggregatorKind is + */ +template +void Populate(nostd::shared_ptr> &aggregator) +{ + if (aggregator->get_aggregator_kind() == metric_sdk::AggregatorKind::Counter) + { + aggregator->update(10.0); + aggregator->update(5.0); + aggregator->checkpoint(); + } + else if (aggregator->get_aggregator_kind() == metric_sdk::AggregatorKind::MinMaxSumCount) + { + aggregator->update(10); + aggregator->update(2); + aggregator->update(5); + aggregator->checkpoint(); + } + else if (aggregator->get_aggregator_kind() == metric_sdk::AggregatorKind::Gauge) + { + aggregator->update(10); + aggregator->update(5); + aggregator->checkpoint(); + } + else if (aggregator->get_aggregator_kind() == metric_sdk::AggregatorKind::Sketch) + { + for (double i = 0; i < 10.0; i++) + { + aggregator->update(i); + } + aggregator->checkpoint(); + } + else if (aggregator->get_aggregator_kind() == metric_sdk::AggregatorKind::Histogram) + { + for (float i = 0; i < 30.0; i++) + { + aggregator->update(i); + } + aggregator->checkpoint(); + } + else if (aggregator->get_aggregator_kind() == metric_sdk::AggregatorKind::Exact) + { + for (double i = 0; i < 10.0; i++) + { + aggregator->update(i); + } + aggregator->checkpoint(); + } +} + +/** + * Helper function to create a collection of records taken from + * a aggregator of specified AggregatorKind + */ +template +std::vector CreateRecords(int num, + metric_sdk::AggregatorKind kind, + bool exactMode = true) +{ + std::vector records; + + for (int i = 0; i < num; i++) + { + std::string name = "record-" + std::to_string(i); + std::string description = "record " + std::to_string(i) + " for test purpose"; + std::string labels = "{label1:v1,label2:v2,}"; + nostd::shared_ptr> aggregator = CreateAgg(kind, exactMode); + Populate(aggregator); + + metric_sdk::Record r{name, description, labels, aggregator}; + records.push_back(r); + } + return records; +} + +// ==================== Test for addMetricsData() function ====================== + +/** + * AddMetricData() should be able to successfully add a collection + * of Records with Counter Aggregators. It checks that the cumulative + * sum of updates to the aggregator of a record before and after AddMetricData() + * is called are equal. + */ +TEST(PrometheusCollector, AddMetricDataWithCounterRecordsSuccessfully) +{ + PrometheusCollector collector; + + // number of records to create + int num_records = 2; + + // construct a collection of records with CounterAggregators and double + std::vector records = + CreateRecords(num_records, metric_sdk::AggregatorKind::Counter); + + // add records to collection + collector.AddMetricData(records); + + // Collection size should be the same as the size + // of the records collection passed to addMetricData() + ASSERT_EQ(collector.GetCollection().size(), records.size()); + + // check values of records created vs records from metricsToCollect, + // accessed by getCollection() + + for (int i = 0; i < num_records; i++) + { + metric_sdk::Record before = records[i]; + metric_sdk::Record after = collector.GetCollection()[i]; + + ASSERT_EQ(before.GetName(), after.GetName()); + + ASSERT_EQ(before.GetDescription(), after.GetDescription()); + + ASSERT_EQ(before.GetLabels(), after.GetLabels()); + + auto before_agg_var = before.GetAggregator(); + auto before_agg = nostd::get>>(before_agg_var); + + auto after_agg_var = after.GetAggregator(); + auto after_agg = nostd::get>>(after_agg_var); + + ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); + for (int i = 0; i < before_agg->get_checkpoint().size(); i++) + { + ASSERT_EQ(before_agg->get_checkpoint()[i], after_agg->get_checkpoint()[i]); + } + } +} + +/** + * AddMetricData() should be able to successfully add a collection + * of Records with MinMaxSumCount Aggregators. It checks that the min, max, + * sum, and count of updates to the aggregator of a record before and after AddMetricData() + * is called are equal. + */ +TEST(PrometheusCollector, AddMetricDataWithMinMaxSumCountRecordsSuccessfully) +{ + PrometheusCollector collector; + + // number of records to create + int num_records = 2; + + // construct a collection of records with MinMaxSumCountAggregators and short + std::vector records = + CreateRecords(num_records, metric_sdk::AggregatorKind::MinMaxSumCount); + + // add records to collection + collector.AddMetricData(records); + + // Collection size should be the same as the size + // of the records collection passed to addMetricData() + ASSERT_EQ(collector.GetCollection().size(), records.size()); + + // check values of records created vs records from metricsToCollect, + // accessed by getCollection() + + for (int i = 0; i < num_records; i++) + { + metric_sdk::Record before = records[i]; + metric_sdk::Record after = collector.GetCollection()[i]; + + ASSERT_EQ(before.GetName(), after.GetName()); + + ASSERT_EQ(before.GetDescription(), after.GetDescription()); + + ASSERT_EQ(before.GetLabels(), after.GetLabels()); + + auto before_agg_var = before.GetAggregator(); + auto before_agg = nostd::get>>(before_agg_var); + + auto after_agg_var = after.GetAggregator(); + auto after_agg = nostd::get>>(after_agg_var); + + ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); + for (int i = 0; i < before_agg->get_checkpoint().size(); i++) + { + ASSERT_EQ(before_agg->get_checkpoint()[i], after_agg->get_checkpoint()[i]); + } + } +} + +/** + * AddMetricData() should be able to successfully add a collection + * of Records with Gauge Aggregators. It checks that the last update + * to the aggregator of a record before and after AddMetricData() + * is called are equal. + */ +TEST(PrometheusCollector, AddMetricDataWithGaugeRecordsSuccessfully) +{ + PrometheusCollector collector; + + // number of records to create + int num_records = 2; + + // construct a collection of records with GaugeAggregators and int + std::vector records = + CreateRecords(num_records, metric_sdk::AggregatorKind::Gauge); + + // add records to collection + collector.AddMetricData(records); + + // Collection size should be the same as the size + // of the records collection passed to addMetricData() + ASSERT_EQ(collector.GetCollection().size(), records.size()); + + // check values of records created vs records from metricsToCollect, + // accessed by getCollection() + + for (int i = 0; i < num_records; i++) + { + metric_sdk::Record before = records[i]; + metric_sdk::Record after = collector.GetCollection()[i]; + + ASSERT_EQ(before.GetName(), after.GetName()); + + ASSERT_EQ(before.GetDescription(), after.GetDescription()); + + ASSERT_EQ(before.GetLabels(), after.GetLabels()); + + auto before_agg_var = before.GetAggregator(); + auto before_agg = nostd::get>>(before_agg_var); + + auto after_agg_var = after.GetAggregator(); + auto after_agg = nostd::get>>(after_agg_var); + + ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); + for (int i = 0; i < before_agg->get_checkpoint().size(); i++) + { + ASSERT_EQ(before_agg->get_checkpoint()[i], after_agg->get_checkpoint()[i]); + } + } +} + +/** + * AddMetricData() should be able to successfully add a collection + * of Records with Sketch Aggregators. It checks that the sum of updates + * and count of values added for a record before and after being added are + * equal using get_checkpoint(). It also checks the same for buckets, in + * get_boundaries(), and counts for buckets, in get_counts(). + */ +TEST(PrometheusCollector, AddMetricDataWithSketchRecordsSuccessfully) +{ + PrometheusCollector collector; + + // number of records to create + int num_records = 2; + + // construct a collection of records with SketchAggregators and double + std::vector records = + CreateRecords(num_records, metric_sdk::AggregatorKind::Sketch); + + // add records to collection + collector.AddMetricData(records); + + // Collection size should be the same as the size + // of the records collection passed to addMetricData() + ASSERT_EQ(collector.GetCollection().size(), records.size()); + + // check values of records created vs records from metricsToCollect, + // accessed by getCollection() + + for (int i = 0; i < num_records; i++) + { + metric_sdk::Record before = records[i]; + metric_sdk::Record after = collector.GetCollection()[i]; + + ASSERT_EQ(before.GetName(), after.GetName()); + + ASSERT_EQ(before.GetDescription(), after.GetDescription()); + + ASSERT_EQ(before.GetLabels(), after.GetLabels()); + + auto before_agg_var = before.GetAggregator(); + auto before_agg = nostd::get>>(before_agg_var); + + auto after_agg_var = after.GetAggregator(); + auto after_agg = nostd::get>>(after_agg_var); + + ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); + for (int i = 0; i < before_agg->get_checkpoint().size(); i++) + { + ASSERT_EQ(before_agg->get_checkpoint()[i], after_agg->get_checkpoint()[i]); + } + for (int i = 0; i < before_agg->get_boundaries().size(); i++) + { + ASSERT_EQ(before_agg->get_boundaries()[i], after_agg->get_boundaries()[i]); + } + for (int i = 0; i < before_agg->get_counts().size(); i++) + { + ASSERT_EQ(before_agg->get_counts()[i], after_agg->get_counts()[i]); + } + } +} + +/** + * AddMetricData() should be able to successfully add a collection + * of Records with Histogram Aggregators. It checks that the sum of + * updates, number of updates, boundaries, and counts for each bucket + * for the aggregator of a record before and after AddMetricData() + * is called are equal. + */ +TEST(PrometheusCollector, AddMetricDataWithHistogramRecordsSuccessfully) +{ + PrometheusCollector collector; + + // number of records to create + int num_records = 2; + + // construct a collection of records with HistogramAggregators and float + std::vector records = + CreateRecords(num_records, metric_sdk::AggregatorKind::Histogram); + + // add records to collection + collector.AddMetricData(records); + + // Collection size should be the same as the size + // of the records collection passed to addMetricData() + ASSERT_EQ(collector.GetCollection().size(), records.size()); + + // check values of records created vs records from metricsToCollect, + // accessed by getCollection() + + for (int i = 0; i < num_records; i++) + { + metric_sdk::Record before = records[i]; + metric_sdk::Record after = collector.GetCollection()[i]; + + ASSERT_EQ(before.GetName(), after.GetName()); + + ASSERT_EQ(before.GetDescription(), after.GetDescription()); + + ASSERT_EQ(before.GetLabels(), after.GetLabels()); + + auto before_agg_var = before.GetAggregator(); + auto before_agg = nostd::get>>(before_agg_var); + + auto after_agg_var = after.GetAggregator(); + auto after_agg = nostd::get>>(after_agg_var); + + ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); + for (int i = 0; i < before_agg->get_checkpoint().size(); i++) + { + ASSERT_EQ(before_agg->get_checkpoint()[i], after_agg->get_checkpoint()[i]); + } + for (int i = 0; i < before_agg->get_boundaries().size(); i++) + { + ASSERT_EQ(before_agg->get_boundaries()[i], after_agg->get_boundaries()[i]); + } + for (int i = 0; i < before_agg->get_counts().size(); i++) + { + ASSERT_EQ(before_agg->get_counts()[i], after_agg->get_counts()[i]); + } + } +} + +/** + * AddMetricData() should be able to successfully add a collection + * of Records with Exact Aggregators. If the Exact Aggregator is in + * quantile mode, it will check quantiles at selected values of 0, 0.25, + * 0.5, 0.75, and 1. If not, it will check the vector of checkpointed + * values in get_checkpoint(). + */ +TEST(PrometheusCollector, AddMetricDataWithExactRecordsSuccessfully) +{ + PrometheusCollector collector; + + // number of records to create + int num_records = 1; + + // construct a collection of a single record with a quantile + // estimation ExactAggregator and double + std::vector records = + CreateRecords(num_records, metric_sdk::AggregatorKind::Exact, true); + + // add records to collection + collector.AddMetricData(records); + + // construct a collection of a single record with an in-order + // ExactAggregator and double + records = CreateRecords(num_records, metric_sdk::AggregatorKind::Exact, false); + + // add records to collection + collector.AddMetricData(records); + + // Collection size should be the same as the size + // of the records collection passed to addMetricData() + ASSERT_EQ(collector.GetCollection().size(), records.size() * 2); + + // check values of records created vs records from metricsToCollect, + // accessed by getCollection() + + for (int i = 0; i < num_records; i++) + { + metric_sdk::Record before = records[i]; + metric_sdk::Record after = collector.GetCollection()[i]; + + ASSERT_EQ(before.GetName(), after.GetName()); + + ASSERT_EQ(before.GetDescription(), after.GetDescription()); + + ASSERT_EQ(before.GetLabels(), after.GetLabels()); + + auto before_agg_var = before.GetAggregator(); + auto before_agg = nostd::get>>(before_agg_var); + + auto after_agg_var = after.GetAggregator(); + auto after_agg = nostd::get>>(after_agg_var); + + if (before_agg->get_quant_estimation() && after_agg->get_quant_estimation()) + { + for (double i = 0; i <= 1;) + { + ASSERT_EQ(before_agg->get_quantiles(i), after_agg->get_quantiles(i)); + i += 0.25; + } + } + else + { + ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); + for (int i = 0; i < before_agg->get_checkpoint().size(); i++) + { + ASSERT_EQ(before_agg->get_checkpoint()[i], after_agg->get_checkpoint()[i]); + } + } + } +} + +TEST(PrometheusCollector, AddMetricDataDoesNotAddWithInsufficentSpace) +{ + PrometheusCollector collector; + + // number of records to create + int num_records = collector.GetMaxCollectionSize() - 5; + + // construct a collection close to max capacity + std::vector records = + CreateRecords(num_records, metric_sdk::AggregatorKind::Counter); + + collector.AddMetricData(records); + + // Check if all the records have been added + ASSERT_EQ(collector.GetCollection().size(), num_records); + + // Try adding the same collection of records again to + // metricsToCollect. + collector.AddMetricData(records); + + // Check that the number of records in metricsToCollect + // has not changed. + ASSERT_EQ(collector.GetCollection().size(), num_records); +} + +TEST(PrometheusCollector, AddMetricDataDoesNotAddBadIndividualRecords) +{ + PrometheusCollector collector; + + // number of records to create + int num_records = 5; + + // construct a collection with the specified number of records + std::vector records = + CreateRecords(num_records, metric_sdk::AggregatorKind::Counter); + + // add records to collection + collector.AddMetricData(records); + + // Check if all the records have been added + ASSERT_EQ(collector.GetCollection().size(), num_records); + + // Creates a bad record, with a nullptr aggregator and adds + // it to the colelction of records + std::string name = "bad_record"; + std::string description = "nullptr_agg"; + std::string labels = "{label1:v1}"; + nostd::shared_ptr> aggregator; + metric_sdk::Record bad_record{name, description, labels, aggregator}; + + records.push_back(bad_record); + + // add records to collection + collector.AddMetricData(records); + + // Check if all the records except the bad + // record have been added; the number of records added + // should be twice the original number of records + // epecified to be created + ASSERT_EQ(collector.GetCollection().size(), num_records * 2); +} + +// ==================== Test for Constructor ====================== +TEST(PrometheusCollector, ConstructorInitializesCollector) +{ + PrometheusCollector collector; + + // current size should be 0, capacity should be set to default + ASSERT_EQ(collector.GetCollection().size(), 0); +} + +// ==================== Tests for collect() function ====================== + +/** + * When collector is initialized, the collection inside is should also be initialized + */ +TEST(PrometheusCollector, CollectInitializesMetricFamilyCollection) +{ + PrometheusCollector collector; + auto c1 = collector.Collect(); + ASSERT_EQ(c1.size(), 0); +} + +/** + * Collect function should collect all data and clear the intermediate collection + */ +TEST(PrometheusCollector, CollectClearsTheCollection) +{ + PrometheusCollector collector; + + // construct a collection to add metric records + int num_records = 2; + auto records = CreateRecords(num_records, metric_sdk::AggregatorKind::Counter); + collector.AddMetricData(records); + + // the collection should not be empty now + ASSERT_EQ(collector.GetCollection().size(), num_records); + + // don't care the collected result in this test + collector.Collect(); + + // after the collect() call, the collection should be empty + ASSERT_EQ(collector.GetCollection().size(), 0); +} + +/** + * Collected data should be already be parsed to Prometheus Metric format + */ +TEST(PrometheusCollector, CollectParsesDataToMetricFamily) +{ + PrometheusCollector collector; + + // construct a collection to add metric records + int num_records = 1; + auto records = CreateRecords(num_records, metric_sdk::AggregatorKind::Counter); + collector.AddMetricData(records); + + // the collection should not be empty now + ASSERT_EQ(collector.GetCollection().size(), num_records); + auto collected = collector.Collect(); + + ASSERT_EQ(collected.size(), num_records); + + auto metric_family = collected[0]; + + // Collect function really collects a vector of MetricFamily + ASSERT_EQ(metric_family.name, "record_0"); + ASSERT_EQ(metric_family.help, "record 0 for test purpose"); + ASSERT_EQ(metric_family.type, prometheus_client::MetricType::Counter); + ASSERT_EQ(metric_family.metric.size(), 1); + ASSERT_DOUBLE_EQ(metric_family.metric[0].counter.value, 15); +} + +/** + * Concurrency Test 1: After adding data concurrently, the intermediate collection should + * contain all data from all threads. + */ +TEST(PrometheusCollector, ConcurrencyAddingRecords) +{ + PrometheusCollector collector; + + // construct a collection to add metric records + int num_records = 2; + std::vector records1 = + CreateRecords(num_records, metric_sdk::AggregatorKind::Counter); + + std::vector records2 = + CreateRecords(num_records, metric_sdk::AggregatorKind::Gauge); + + std::thread first(&PrometheusCollector::AddMetricData, std::ref(collector), std::ref(records1)); + std::thread second(&PrometheusCollector::AddMetricData, std::ref(collector), std::ref(records2)); + + first.join(); + second.join(); + + ASSERT_EQ(collector.GetCollection().size(), 4); +} + +/** + * Concurrency Test 2: After adding data concurrently and collecting, the intermediate collection + * should be empty, and all data are collected in the result vector. + */ +TEST(PrometheusCollector, ConcurrentlyAddingAndThenCollecting) +{ + PrometheusCollector collector; + + // construct a collection to add metric records + int num_records = 2; + std::vector records1 = + CreateRecords(num_records, metric_sdk::AggregatorKind::Counter); + + std::vector records2 = + CreateRecords(num_records, metric_sdk::AggregatorKind::Gauge); + + std::thread first(&PrometheusCollector::AddMetricData, std::ref(collector), std::ref(records1)); + std::thread second(&PrometheusCollector::AddMetricData, std::ref(collector), std::ref(records2)); + + first.join(); + second.join(); + + auto collect_future = std::async(&PrometheusCollector::Collect, std::ref(collector)); + auto res = collect_future.get(); + + ASSERT_EQ(collector.GetCollection().size(), 0); + ASSERT_EQ(res.size(), 4); +} + +/** + * Concurrency Test 3: Concurrently adding and collecting. We don't know when the collect function is called, + * but all data entries are either collected or left in the collection. + */ +TEST(PrometheusCollector, ConcurrentlyAddingAndCollecting) +{ + PrometheusCollector collector; + + // construct a collection to add metric records + int num_records = 2; + std::vector records1 = + CreateRecords(num_records, metric_sdk::AggregatorKind::Counter); + + std::vector records2 = + CreateRecords(num_records, metric_sdk::AggregatorKind::Gauge); + + std::thread first(&PrometheusCollector::AddMetricData, std::ref(collector), std::ref(records1)); + std::thread second(&PrometheusCollector::AddMetricData, std::ref(collector), std::ref(records2)); + auto collect_future = std::async(&PrometheusCollector::Collect, std::ref(collector)); + + first.join(); + second.join(); + + auto res = collect_future.get(); + + // the size of collection can be 0, 2, 4, because we don't know when the collect() + // is really called. However, we claim that if the data in the collection is collected, + // they must be in the res. So res.size() + collection.size() must be the total number + // of data records we generated. + ASSERT_EQ(res.size() + collector.GetCollection().size(), 4); +} + +/** + * Concurrency Test 4: Concurrently adding then concurrently collecting. We don't know which collecting + * thread fetches all data, but either one should succeed. + */ +TEST(PrometheusCollector, ConcurrentlyAddingAndConcurrentlyCollecting) +{ + PrometheusCollector collector; + + // construct a collection to add metric records + int num_records = 2; + std::vector records1 = + CreateRecords(num_records, metric_sdk::AggregatorKind::Counter); + + std::vector records2 = + CreateRecords(num_records, metric_sdk::AggregatorKind::Gauge); + + // concurrently adding + std::thread first(&PrometheusCollector::AddMetricData, std::ref(collector), std::ref(records1)); + std::thread second(&PrometheusCollector::AddMetricData, std::ref(collector), std::ref(records2)); + first.join(); + second.join(); + + // after adding, then concurrently consuming + auto collect_future1 = std::async(&PrometheusCollector::Collect, std::ref(collector)); + auto collect_future2 = std::async(&PrometheusCollector::Collect, std::ref(collector)); + auto res1 = collect_future1.get(); + auto res2 = collect_future2.get(); + + // all added data must be collected in either res1 or res2 + ASSERT_EQ(res1.size() + res2.size(), 4); +} + +OPENTELEMETRY_END_NAMESPACE From acc2dd0bb54719dc08f5adb3f4b412ff7b6b93ab Mon Sep 17 00:00:00 2001 From: erichsueh3 Date: Fri, 7 Aug 2020 10:47:09 -0700 Subject: [PATCH 2/3] CI formatting, added copyright header --- .../test/prometheus_collector_test.cc | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/exporters/prometheus/test/prometheus_collector_test.cc b/exporters/prometheus/test/prometheus_collector_test.cc index 0efa50139e..4f45da4119 100644 --- a/exporters/prometheus/test/prometheus_collector_test.cc +++ b/exporters/prometheus/test/prometheus_collector_test.cc @@ -1,3 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include #include #include @@ -30,35 +46,41 @@ nostd::shared_ptr> CreateAgg(metric_sdk::AggregatorKin nostd::shared_ptr> aggregator; switch (kind) { - case metric_sdk::AggregatorKind::Counter: { + case metric_sdk::AggregatorKind::Counter: + { aggregator = nostd::shared_ptr>( new metric_sdk::CounterAggregator(opentelemetry::metrics::InstrumentKind::Counter)); break; } - case metric_sdk::AggregatorKind::MinMaxSumCount: { + case metric_sdk::AggregatorKind::MinMaxSumCount: + { aggregator = nostd::shared_ptr>(new metric_sdk::MinMaxSumCountAggregator( opentelemetry::metrics::InstrumentKind::Counter)); break; } - case metric_sdk::AggregatorKind::Gauge: { + case metric_sdk::AggregatorKind::Gauge: + { aggregator = nostd::shared_ptr>( new metric_sdk::GaugeAggregator(opentelemetry::metrics::InstrumentKind::Counter)); break; } - case metric_sdk::AggregatorKind::Sketch: { + case metric_sdk::AggregatorKind::Sketch: + { aggregator = nostd::shared_ptr>(new metric_sdk::SketchAggregator( opentelemetry::metrics::InstrumentKind::Counter, 0.000005)); break; } - case metric_sdk::AggregatorKind::Histogram: { + case metric_sdk::AggregatorKind::Histogram: + { std::vector boundaries{10, 20}; aggregator = nostd::shared_ptr>(new metric_sdk::HistogramAggregator( opentelemetry::metrics::InstrumentKind::Counter, boundaries)); break; } - case metric_sdk::AggregatorKind::Exact: { + case metric_sdk::AggregatorKind::Exact: + { aggregator = nostd::shared_ptr>(new metric_sdk::ExactAggregator( opentelemetry::metrics::InstrumentKind::Counter, exactMode)); break; @@ -686,8 +708,8 @@ TEST(PrometheusCollector, ConcurrentlyAddingAndThenCollecting) } /** - * Concurrency Test 3: Concurrently adding and collecting. We don't know when the collect function is called, - * but all data entries are either collected or left in the collection. + * Concurrency Test 3: Concurrently adding and collecting. We don't know when the collect function + * is called, but all data entries are either collected or left in the collection. */ TEST(PrometheusCollector, ConcurrentlyAddingAndCollecting) { @@ -718,8 +740,8 @@ TEST(PrometheusCollector, ConcurrentlyAddingAndCollecting) } /** - * Concurrency Test 4: Concurrently adding then concurrently collecting. We don't know which collecting - * thread fetches all data, but either one should succeed. + * Concurrency Test 4: Concurrently adding then concurrently collecting. We don't know which + * collecting thread fetches all data, but either one should succeed. */ TEST(PrometheusCollector, ConcurrentlyAddingAndConcurrentlyCollecting) { From bf9b22cc7dc79ace4515b8dc0c1047a06b29f7a1 Mon Sep 17 00:00:00 2001 From: erichsueh3 Date: Fri, 14 Aug 2020 22:27:48 -0700 Subject: [PATCH 3/3] fixed tests to use std::shared_ptrs instead of nostd::shared_ptrs --- .../test/prometheus_collector_test.cc | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/exporters/prometheus/test/prometheus_collector_test.cc b/exporters/prometheus/test/prometheus_collector_test.cc index 4f45da4119..3a1b4c52c3 100644 --- a/exporters/prometheus/test/prometheus_collector_test.cc +++ b/exporters/prometheus/test/prometheus_collector_test.cc @@ -37,37 +37,37 @@ OPENTELEMETRY_BEGIN_NAMESPACE /** * CreateAgg() is a helper function that returns a - * nostd::shared_ptr given an AggregatorKind + * std::shared_ptr given an AggregatorKind */ template -nostd::shared_ptr> CreateAgg(metric_sdk::AggregatorKind kind, +std::shared_ptr> CreateAgg(metric_sdk::AggregatorKind kind, bool exactMode = true) { - nostd::shared_ptr> aggregator; + std::shared_ptr> aggregator; switch (kind) { case metric_sdk::AggregatorKind::Counter: { - aggregator = nostd::shared_ptr>( + aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(opentelemetry::metrics::InstrumentKind::Counter)); break; } case metric_sdk::AggregatorKind::MinMaxSumCount: { aggregator = - nostd::shared_ptr>(new metric_sdk::MinMaxSumCountAggregator( + std::shared_ptr>(new metric_sdk::MinMaxSumCountAggregator( opentelemetry::metrics::InstrumentKind::Counter)); break; } case metric_sdk::AggregatorKind::Gauge: { - aggregator = nostd::shared_ptr>( + aggregator = std::shared_ptr>( new metric_sdk::GaugeAggregator(opentelemetry::metrics::InstrumentKind::Counter)); break; } case metric_sdk::AggregatorKind::Sketch: { - aggregator = nostd::shared_ptr>(new metric_sdk::SketchAggregator( + aggregator = std::shared_ptr>(new metric_sdk::SketchAggregator( opentelemetry::metrics::InstrumentKind::Counter, 0.000005)); break; } @@ -75,13 +75,13 @@ nostd::shared_ptr> CreateAgg(metric_sdk::AggregatorKin { std::vector boundaries{10, 20}; aggregator = - nostd::shared_ptr>(new metric_sdk::HistogramAggregator( + std::shared_ptr>(new metric_sdk::HistogramAggregator( opentelemetry::metrics::InstrumentKind::Counter, boundaries)); break; } case metric_sdk::AggregatorKind::Exact: { - aggregator = nostd::shared_ptr>(new metric_sdk::ExactAggregator( + aggregator = std::shared_ptr>(new metric_sdk::ExactAggregator( opentelemetry::metrics::InstrumentKind::Counter, exactMode)); break; } @@ -96,7 +96,7 @@ nostd::shared_ptr> CreateAgg(metric_sdk::AggregatorKin * on what its AggregatorKind is */ template -void Populate(nostd::shared_ptr> &aggregator) +void Populate(std::shared_ptr> &aggregator) { if (aggregator->get_aggregator_kind() == metric_sdk::AggregatorKind::Counter) { @@ -159,7 +159,7 @@ std::vector CreateRecords(int num, std::string name = "record-" + std::to_string(i); std::string description = "record " + std::to_string(i) + " for test purpose"; std::string labels = "{label1:v1,label2:v2,}"; - nostd::shared_ptr> aggregator = CreateAgg(kind, exactMode); + std::shared_ptr> aggregator = CreateAgg(kind, exactMode); Populate(aggregator); metric_sdk::Record r{name, description, labels, aggregator}; @@ -209,10 +209,10 @@ TEST(PrometheusCollector, AddMetricDataWithCounterRecordsSuccessfully) ASSERT_EQ(before.GetLabels(), after.GetLabels()); auto before_agg_var = before.GetAggregator(); - auto before_agg = nostd::get>>(before_agg_var); + auto before_agg = nostd::get>>(before_agg_var); auto after_agg_var = after.GetAggregator(); - auto after_agg = nostd::get>>(after_agg_var); + auto after_agg = nostd::get>>(after_agg_var); ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); for (int i = 0; i < before_agg->get_checkpoint().size(); i++) @@ -261,10 +261,10 @@ TEST(PrometheusCollector, AddMetricDataWithMinMaxSumCountRecordsSuccessfully) ASSERT_EQ(before.GetLabels(), after.GetLabels()); auto before_agg_var = before.GetAggregator(); - auto before_agg = nostd::get>>(before_agg_var); + auto before_agg = nostd::get>>(before_agg_var); auto after_agg_var = after.GetAggregator(); - auto after_agg = nostd::get>>(after_agg_var); + auto after_agg = nostd::get>>(after_agg_var); ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); for (int i = 0; i < before_agg->get_checkpoint().size(); i++) @@ -313,10 +313,10 @@ TEST(PrometheusCollector, AddMetricDataWithGaugeRecordsSuccessfully) ASSERT_EQ(before.GetLabels(), after.GetLabels()); auto before_agg_var = before.GetAggregator(); - auto before_agg = nostd::get>>(before_agg_var); + auto before_agg = nostd::get>>(before_agg_var); auto after_agg_var = after.GetAggregator(); - auto after_agg = nostd::get>>(after_agg_var); + auto after_agg = nostd::get>>(after_agg_var); ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); for (int i = 0; i < before_agg->get_checkpoint().size(); i++) @@ -366,10 +366,10 @@ TEST(PrometheusCollector, AddMetricDataWithSketchRecordsSuccessfully) ASSERT_EQ(before.GetLabels(), after.GetLabels()); auto before_agg_var = before.GetAggregator(); - auto before_agg = nostd::get>>(before_agg_var); + auto before_agg = nostd::get>>(before_agg_var); auto after_agg_var = after.GetAggregator(); - auto after_agg = nostd::get>>(after_agg_var); + auto after_agg = nostd::get>>(after_agg_var); ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); for (int i = 0; i < before_agg->get_checkpoint().size(); i++) @@ -427,10 +427,10 @@ TEST(PrometheusCollector, AddMetricDataWithHistogramRecordsSuccessfully) ASSERT_EQ(before.GetLabels(), after.GetLabels()); auto before_agg_var = before.GetAggregator(); - auto before_agg = nostd::get>>(before_agg_var); + auto before_agg = nostd::get>>(before_agg_var); auto after_agg_var = after.GetAggregator(); - auto after_agg = nostd::get>>(after_agg_var); + auto after_agg = nostd::get>>(after_agg_var); ASSERT_EQ(before_agg->get_checkpoint().size(), after_agg->get_checkpoint().size()); for (int i = 0; i < before_agg->get_checkpoint().size(); i++) @@ -496,10 +496,10 @@ TEST(PrometheusCollector, AddMetricDataWithExactRecordsSuccessfully) ASSERT_EQ(before.GetLabels(), after.GetLabels()); auto before_agg_var = before.GetAggregator(); - auto before_agg = nostd::get>>(before_agg_var); + auto before_agg = nostd::get>>(before_agg_var); auto after_agg_var = after.GetAggregator(); - auto after_agg = nostd::get>>(after_agg_var); + auto after_agg = nostd::get>>(after_agg_var); if (before_agg->get_quant_estimation() && after_agg->get_quant_estimation()) { @@ -567,7 +567,7 @@ TEST(PrometheusCollector, AddMetricDataDoesNotAddBadIndividualRecords) std::string name = "bad_record"; std::string description = "nullptr_agg"; std::string labels = "{label1:v1}"; - nostd::shared_ptr> aggregator; + std::shared_ptr> aggregator; metric_sdk::Record bad_record{name, description, labels, aggregator}; records.push_back(bad_record);