diff options
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/sdk/test/metrics')
22 files changed, 1706 insertions, 0 deletions
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/BUILD b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/BUILD new file mode 100644 index 000000000..819a8d225 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/BUILD @@ -0,0 +1,203 @@ +load("//bazel:otel_cc_benchmark.bzl", "otel_cc_benchmark") + +cc_test( + name = "meter_provider_sdk_test", + srcs = [ + "meter_provider_sdk_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "metric_reader_test", + srcs = [ + "metric_reader_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "view_registry_test", + srcs = [ + "view_registry_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "aggregation_test", + srcs = [ + "aggregation_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "sync_metric_storage_test", + srcs = [ + "sync_metric_storage_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "sync_instruments_test", + srcs = [ + "sync_instruments_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "async_metric_storage_test", + srcs = [ + "async_metric_storage_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "observer_result_test", + srcs = [ + "observer_result_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "multi_metric_storage_test", + srcs = [ + "multi_metric_storage_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "attributes_processor_test", + srcs = [ + "attributes_processor_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "attributes_hashmap_test", + srcs = [ + "attributes_hashmap_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "@com_google_googletest//:gtest_main", + ], +) + +otel_cc_benchmark( + name = "attributes_processor_benchmark", + srcs = [ + "attributes_processor_benchmark.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + ], +) + +otel_cc_benchmark( + name = "attributes_hashmap_benchmark", + srcs = [ + "attributes_hashmap_benchmark.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + ], +) diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/CMakeLists.txt new file mode 100644 index 000000000..faf2f2b49 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/CMakeLists.txt @@ -0,0 +1,34 @@ +foreach( + testname + meter_provider_sdk_test + view_registry_test + aggregation_test + attributes_processor_test + attributes_hashmap_test + sync_metric_storage_test + async_metric_storage_test + multi_metric_storage_test + observer_result_test + sync_instruments_test + async_instruments_test + metric_reader_test + periodic_exporting_metric_reader_test) + add_executable(${testname} "${testname}.cc") + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} + opentelemetry_resources opentelemetry_metrics) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX metrics. + TEST_LIST ${testname}) +endforeach() + +add_executable(attributes_processor_benchmark attributes_processor_benchmark.cc) +target_link_libraries(attributes_processor_benchmark benchmark::benchmark + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common) + +add_executable(attributes_hashmap_benchmark attributes_hashmap_benchmark.cc) +target_link_libraries(attributes_hashmap_benchmark benchmark::benchmark + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common) + +add_subdirectory(exemplar) diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/aggregation_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/aggregation_test.cc new file mode 100644 index 000000000..f8051776d --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/aggregation_test.cc @@ -0,0 +1,182 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include <gtest/gtest.h> +# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/sum_aggregation.h" + +# include "opentelemetry/nostd/variant.h" + +using namespace opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; +TEST(Aggregation, LongSumAggregation) +{ + LongSumAggregation aggr; + auto data = aggr.ToPoint(); + ASSERT_TRUE(nostd::holds_alternative<SumPointData>(data)); + auto sum_data = nostd::get<SumPointData>(data); + ASSERT_TRUE(nostd::holds_alternative<long>(sum_data.value_)); + EXPECT_EQ(nostd::get<long>(sum_data.value_), 0l); + EXPECT_NO_THROW(aggr.Aggregate(12l, {})); + EXPECT_NO_THROW(aggr.Aggregate(0l, {})); + sum_data = nostd::get<SumPointData>(aggr.ToPoint()); + EXPECT_EQ(nostd::get<long>(sum_data.value_), 12l); +} + +TEST(Aggregation, DoubleSumAggregation) +{ + DoubleSumAggregation aggr; + auto data = aggr.ToPoint(); + ASSERT_TRUE(nostd::holds_alternative<SumPointData>(data)); + auto sum_data = nostd::get<SumPointData>(data); + ASSERT_TRUE(nostd::holds_alternative<double>(sum_data.value_)); + EXPECT_EQ(nostd::get<double>(sum_data.value_), 0); + EXPECT_NO_THROW(aggr.Aggregate(12.0, {})); + EXPECT_NO_THROW(aggr.Aggregate(1.0, {})); + sum_data = nostd::get<SumPointData>(aggr.ToPoint()); + EXPECT_EQ(nostd::get<double>(sum_data.value_), 13.0); +} + +TEST(Aggregation, LongLastValueAggregation) +{ + LongLastValueAggregation aggr; + auto data = aggr.ToPoint(); + ASSERT_TRUE(nostd::holds_alternative<LastValuePointData>(data)); + auto lastvalue_data = nostd::get<LastValuePointData>(data); + ASSERT_TRUE(nostd::holds_alternative<long>(lastvalue_data.value_)); + EXPECT_EQ(lastvalue_data.is_lastvalue_valid_, false); + EXPECT_NO_THROW(aggr.Aggregate(12l, {})); + EXPECT_NO_THROW(aggr.Aggregate(1l, {})); + lastvalue_data = nostd::get<LastValuePointData>(aggr.ToPoint()); + EXPECT_EQ(nostd::get<long>(lastvalue_data.value_), 1.0); +} + +TEST(Aggregation, DoubleLastValueAggregation) +{ + DoubleLastValueAggregation aggr; + auto data = aggr.ToPoint(); + ASSERT_TRUE(nostd::holds_alternative<LastValuePointData>(data)); + auto lastvalue_data = nostd::get<LastValuePointData>(data); + ASSERT_TRUE(nostd::holds_alternative<double>(lastvalue_data.value_)); + EXPECT_EQ(lastvalue_data.is_lastvalue_valid_, false); + EXPECT_NO_THROW(aggr.Aggregate(12.0, {})); + EXPECT_NO_THROW(aggr.Aggregate(1.0, {})); + lastvalue_data = nostd::get<LastValuePointData>(aggr.ToPoint()); + EXPECT_EQ(nostd::get<double>(lastvalue_data.value_), 1.0); +} + +TEST(Aggregation, LongHistogramAggregation) +{ + LongHistogramAggregation aggr; + auto data = aggr.ToPoint(); + ASSERT_TRUE(nostd::holds_alternative<HistogramPointData>(data)); + auto histogram_data = nostd::get<HistogramPointData>(data); + ASSERT_TRUE(nostd::holds_alternative<long>(histogram_data.sum_)); + ASSERT_TRUE(nostd::holds_alternative<std::list<long>>(histogram_data.boundaries_)); + EXPECT_EQ(nostd::get<long>(histogram_data.sum_), 0); + EXPECT_EQ(histogram_data.count_, 0); + EXPECT_NO_THROW(aggr.Aggregate(12l, {})); // lies in fourth bucket + EXPECT_NO_THROW(aggr.Aggregate(100l, {})); // lies in eight bucket + histogram_data = nostd::get<HistogramPointData>(aggr.ToPoint()); + EXPECT_EQ(nostd::get<long>(histogram_data.sum_), 112); + EXPECT_EQ(histogram_data.count_, 2); + EXPECT_EQ(histogram_data.counts_[3], 1); + EXPECT_EQ(histogram_data.counts_[7], 1); + EXPECT_NO_THROW(aggr.Aggregate(13l, {})); // lies in fourth bucket + EXPECT_NO_THROW(aggr.Aggregate(252l, {})); // lies in ninth bucket + histogram_data = nostd::get<HistogramPointData>(aggr.ToPoint()); + EXPECT_EQ(histogram_data.count_, 4); + EXPECT_EQ(histogram_data.counts_[3], 2); + EXPECT_EQ(histogram_data.counts_[8], 1); + + // Merge + LongHistogramAggregation aggr1; + aggr1.Aggregate(1l, {}); + aggr1.Aggregate(11l, {}); + aggr1.Aggregate(26l, {}); + + LongHistogramAggregation aggr2; + aggr2.Aggregate(2l, {}); + aggr2.Aggregate(3l, {}); + aggr2.Aggregate(13l, {}); + aggr2.Aggregate(28l, {}); + aggr2.Aggregate(105l, {}); + + auto aggr3 = aggr1.Merge(aggr2); + histogram_data = nostd::get<HistogramPointData>(aggr3->ToPoint()); + + EXPECT_EQ(histogram_data.count_, 8); // 3 each from aggr1 and aggr2 + EXPECT_EQ(histogram_data.counts_[1], 3); // 1, 2, 3 + EXPECT_EQ(histogram_data.counts_[3], 2); // 11, 13 + EXPECT_EQ(histogram_data.counts_[4], 2); // 25, 28 + EXPECT_EQ(histogram_data.counts_[7], 1); // 105 + + // Diff + auto aggr4 = aggr1.Diff(aggr2); + histogram_data = nostd::get<HistogramPointData>(aggr4->ToPoint()); + EXPECT_EQ(histogram_data.count_, 2); // aggr2:5 - aggr1:3 + EXPECT_EQ(histogram_data.counts_[1], 1); // aggr2(2, 3) - aggr1(1) + EXPECT_EQ(histogram_data.counts_[3], 0); // aggr2(13) - aggr1(11) + EXPECT_EQ(histogram_data.counts_[4], 0); // aggr2(28) - aggr1(25) + EXPECT_EQ(histogram_data.counts_[7], 1); // aggr2(105) - aggr1(0) +} + +TEST(Aggregation, DoubleHistogramAggregation) +{ + DoubleHistogramAggregation aggr; + auto data = aggr.ToPoint(); + ASSERT_TRUE(nostd::holds_alternative<HistogramPointData>(data)); + auto histogram_data = nostd::get<HistogramPointData>(data); + ASSERT_TRUE(nostd::holds_alternative<double>(histogram_data.sum_)); + ASSERT_TRUE(nostd::holds_alternative<std::list<double>>(histogram_data.boundaries_)); + EXPECT_EQ(nostd::get<double>(histogram_data.sum_), 0); + EXPECT_EQ(histogram_data.count_, 0); + EXPECT_NO_THROW(aggr.Aggregate(12.0, {})); // lies in fourth bucket + EXPECT_NO_THROW(aggr.Aggregate(100.0, {})); // lies in eight bucket + histogram_data = nostd::get<HistogramPointData>(aggr.ToPoint()); + EXPECT_EQ(nostd::get<double>(histogram_data.sum_), 112); + EXPECT_EQ(histogram_data.count_, 2); + EXPECT_EQ(histogram_data.counts_[3], 1); + EXPECT_EQ(histogram_data.counts_[7], 1); + EXPECT_NO_THROW(aggr.Aggregate(13.0, {})); // lies in fourth bucket + EXPECT_NO_THROW(aggr.Aggregate(252.0, {})); // lies in ninth bucket + histogram_data = nostd::get<HistogramPointData>(aggr.ToPoint()); + EXPECT_EQ(histogram_data.count_, 4); + EXPECT_EQ(histogram_data.counts_[3], 2); + EXPECT_EQ(histogram_data.counts_[8], 1); + EXPECT_EQ(nostd::get<double>(histogram_data.sum_), 377); + + // Merge + DoubleHistogramAggregation aggr1; + aggr1.Aggregate(1.0, {}); + aggr1.Aggregate(11.0, {}); + aggr1.Aggregate(25.1, {}); + + DoubleHistogramAggregation aggr2; + aggr2.Aggregate(2.0, {}); + aggr2.Aggregate(3.0, {}); + aggr2.Aggregate(13.0, {}); + aggr2.Aggregate(28.1, {}); + aggr2.Aggregate(105.0, {}); + + auto aggr3 = aggr1.Merge(aggr2); + histogram_data = nostd::get<HistogramPointData>(aggr3->ToPoint()); + + EXPECT_EQ(histogram_data.count_, 8); // 3 each from aggr1 and aggr2 + EXPECT_EQ(histogram_data.counts_[1], 3); // 1.0, 2.0, 3.0 + EXPECT_EQ(histogram_data.counts_[3], 2); // 11.0, 13.0 + EXPECT_EQ(histogram_data.counts_[4], 2); // 25.1, 28.1 + EXPECT_EQ(histogram_data.counts_[7], 1); // 105.0 + + // Diff + auto aggr4 = aggr1.Diff(aggr2); + histogram_data = nostd::get<HistogramPointData>(aggr4->ToPoint()); + EXPECT_EQ(histogram_data.count_, 2); // aggr2:5 - aggr1:3 + EXPECT_EQ(histogram_data.counts_[1], 1); // aggr2(2.0, 3.0) - aggr1(1.0) + EXPECT_EQ(histogram_data.counts_[3], 0); // aggr2(13.0) - aggr1(11.0) + EXPECT_EQ(histogram_data.counts_[4], 0); // aggr2(28.1) - aggr1(25.1) + EXPECT_EQ(histogram_data.counts_[7], 1); // aggr2(105.0) - aggr1(0) +} +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/async_instruments_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/async_instruments_test.cc new file mode 100644 index 000000000..ff9504f78 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/async_instruments_test.cc @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/async_instruments.h" + +# include <gtest/gtest.h> + +using namespace opentelemetry; +using namespace opentelemetry::sdk::metrics; + +using M = std::map<std::string, std::string>; + +void asyc_generate_measurements_long(opentelemetry::metrics::ObserverResult<long> &observer) {} + +void asyc_generate_measurements_double(opentelemetry::metrics::ObserverResult<double> &observer) {} + +TEST(AsyncInstruments, LongObservableCounter) +{ + auto asyc_generate_meas_long = [](opentelemetry::metrics::ObserverResult<long> &observer) {}; + EXPECT_NO_THROW( + LongObservableCounter counter("long_counter", asyc_generate_meas_long, "description", "1")); +} + +TEST(AsyncInstruments, DoubleObservableCounter) +{ + auto asyc_generate_meas_double = [](opentelemetry::metrics::ObserverResult<double> &observer) {}; + EXPECT_NO_THROW(DoubleObservableCounter counter("long_counter", asyc_generate_meas_double, + "description", "1")); +} + +TEST(AsyncInstruments, LongObservableGauge) +{ + auto asyc_generate_meas_long = [](opentelemetry::metrics::ObserverResult<long> &observer) {}; + EXPECT_NO_THROW( + LongObservableGauge counter("long_counter", asyc_generate_meas_long, "description", "1")); +} + +TEST(AsyncInstruments, DoubleObservableGauge) +{ + auto asyc_generate_meas_double = [](opentelemetry::metrics::ObserverResult<double> &observer) {}; + EXPECT_NO_THROW( + DoubleObservableGauge counter("long_counter", asyc_generate_meas_double, "description", "1")); +} + +TEST(AsyncInstruments, LongObservableUpDownCounter) +{ + auto asyc_generate_meas_long = [](opentelemetry::metrics::ObserverResult<long> &observer) {}; + EXPECT_NO_THROW(LongObservableUpDownCounter counter("long_counter", asyc_generate_meas_long, + "description", "1")); +} + +TEST(AsyncInstruments, DoubleObservableUpDownCounter) +{ + auto asyc_generate_meas_double = [](opentelemetry::metrics::ObserverResult<double> &observer) {}; + EXPECT_NO_THROW(DoubleObservableUpDownCounter counter("long_counter", asyc_generate_meas_double, + "description", "1")); +} + +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/async_metric_storage_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/async_metric_storage_test.cc new file mode 100644 index 000000000..2be5332a8 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/async_metric_storage_test.cc @@ -0,0 +1,132 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/state/async_metric_storage.h" +# include "opentelemetry/common/key_value_iterable_view.h" +# include "opentelemetry/sdk/metrics/instruments.h" +# include "opentelemetry/sdk/metrics/meter_context.h" +# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/metric_reader.h" +# include "opentelemetry/sdk/metrics/observer_result.h" +# include "opentelemetry/sdk/metrics/state/metric_collector.h" + +# include <gtest/gtest.h> +# include <vector> + +using namespace opentelemetry::sdk::metrics; +using namespace opentelemetry::sdk::instrumentationlibrary; +using namespace opentelemetry::sdk::resource; + +using namespace opentelemetry::sdk::metrics; +using namespace opentelemetry::common; +using M = std::map<std::string, std::string>; + +class MockCollectorHandle : public CollectorHandle +{ +public: + MockCollectorHandle(AggregationTemporality temp) : temporality(temp) {} + + AggregationTemporality GetAggregationTemporality() noexcept override { return temporality; } + +private: + AggregationTemporality temporality; +}; + +class WritableMetricStorageTestFixture : public ::testing::TestWithParam<AggregationTemporality> +{}; + +class MeasurementFetcher +{ +public: + static void Fetcher(opentelemetry::metrics::ObserverResult<long> &observer_result, + void * /*state*/) + { + fetch_count++; + if (fetch_count == 1) + { + observer_result.Observe(20l, {{"RequestType", "GET"}}); + observer_result.Observe(10l, {{"RequestType", "PUT"}}); + number_of_get += 20l; + number_of_put += 10l; + } + else if (fetch_count == 2) + { + observer_result.Observe(40l, {{"RequestType", "GET"}}); + observer_result.Observe(20l, {{"RequestType", "PUT"}}); + number_of_get += 40l; + number_of_put += 20l; + } + } + + static void init_values() + { + fetch_count = 0; + number_of_get = 0; + number_of_put = 0; + } + + static size_t fetch_count; + static long number_of_get; + static long number_of_put; + static const size_t number_of_attributes = 2; // GET , PUT +}; + +size_t MeasurementFetcher::fetch_count; +long MeasurementFetcher::number_of_get; +long MeasurementFetcher::number_of_put; +const size_t MeasurementFetcher::number_of_attributes; + +TEST_P(WritableMetricStorageTestFixture, TestAggregation) +{ + MeasurementFetcher::init_values(); + AggregationTemporality temporality = GetParam(); + + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kObservableCounter, + InstrumentValueType::kLong}; + + auto sdk_start_ts = std::chrono::system_clock::now(); + // Some computation here + auto collection_ts = std::chrono::system_clock::now() + std::chrono::seconds(5); + + std::shared_ptr<CollectorHandle> collector(new MockCollectorHandle(temporality)); + std::vector<std::shared_ptr<CollectorHandle>> collectors; + collectors.push_back(collector); + size_t count_attributes = 0; + long value = 0; + + MeasurementFetcher measurement_fetcher; + opentelemetry::sdk::metrics::AsyncMetricStorage<long> storage(instr_desc, AggregationType::kSum, + MeasurementFetcher::Fetcher, + new DefaultAttributesProcessor()); + + storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, + [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get<SumPointData>(data_attr.point_data); + if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get<long>(data.value_), + MeasurementFetcher::number_of_get); + } + else if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get<long>(data.value_), + MeasurementFetcher::number_of_put); + } + count_attributes++; + } + return true; + }); + EXPECT_EQ(MeasurementFetcher::number_of_attributes, count_attributes); +} + +INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestLong, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); + +#endif
\ No newline at end of file diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_hashmap_benchmark.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_hashmap_benchmark.cc new file mode 100644 index 000000000..38d515a7e --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_hashmap_benchmark.cc @@ -0,0 +1,53 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include <benchmark/benchmark.h> +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/common/attributemap_hash.h" +# include "opentelemetry/sdk/metrics/aggregation/aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/drop_aggregation.h" +# include "opentelemetry/sdk/metrics/instruments.h" +# include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" + +# include <functional> +# include <vector> + +using namespace opentelemetry::sdk::metrics; +constexpr size_t MAX_THREADS = 500; +namespace +{ + +void BM_AttributseHashMap(benchmark::State &state) +{ + + AttributesHashMap hash_map; + std::vector<std::thread> workers; + std::vector<MetricAttributes> attributes = {{{"k1", "v1"}, {"k2", "v2"}}, + {{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}}}; + + std::function<std::unique_ptr<Aggregation>()> create_default_aggregation = + []() -> std::unique_ptr<Aggregation> { + return std::unique_ptr<Aggregation>(new DropAggregation); + }; + + while (state.KeepRunning()) + { + for (size_t i = 0; i < MAX_THREADS; i++) + { + workers.push_back(std::thread([&]() { + hash_map.GetOrSetDefault(attributes[i % 2], create_default_aggregation)->Aggregate(1l); + benchmark::DoNotOptimize(hash_map.Has(attributes[i % 2])); + })); + } + } + + for (auto &t : workers) + { + t.join(); + } +} + +BENCHMARK(BM_AttributseHashMap); +} // namespace +#endif +BENCHMARK_MAIN();
\ No newline at end of file diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_hashmap_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_hashmap_test.cc new file mode 100644 index 000000000..610744c8e --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_hashmap_test.cc @@ -0,0 +1,71 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" +# include <gtest/gtest.h> +# include "opentelemetry/sdk/metrics/aggregation/drop_aggregation.h" +# include "opentelemetry/sdk/metrics/instruments.h" + +# include <functional> + +using namespace opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; + +TEST(AttributesHashMap, BasicTests) +{ + + // Empty map + AttributesHashMap hash_map; + EXPECT_EQ(hash_map.Size(), 0); + MetricAttributes m1 = {{"k1", "v1"}}; + EXPECT_EQ(hash_map.Get(m1), nullptr); + EXPECT_EQ(hash_map.Has(m1), false); + + // Set + std::unique_ptr<Aggregation> aggregation1( + new DropAggregation()); // = std::unique_ptr<Aggregation>(new DropAggregation); + hash_map.Set(m1, std::move(aggregation1)); + EXPECT_NO_THROW(hash_map.Get(m1)->Aggregate(1l)); + EXPECT_EQ(hash_map.Size(), 1); + EXPECT_EQ(hash_map.Has(m1), true); + + // Set same key again + auto aggregation2 = std::unique_ptr<Aggregation>(new DropAggregation()); + hash_map.Set(m1, std::move(aggregation2)); + EXPECT_NO_THROW(hash_map.Get(m1)->Aggregate(1l)); + EXPECT_EQ(hash_map.Size(), 1); + EXPECT_EQ(hash_map.Has(m1), true); + + // Set more enteria + auto aggregation3 = std::unique_ptr<Aggregation>(new DropAggregation()); + MetricAttributes m3 = {{"k1", "v1"}, {"k2", "v2"}}; + hash_map.Set(m3, std::move(aggregation3)); + EXPECT_EQ(hash_map.Has(m1), true); + EXPECT_EQ(hash_map.Has(m3), true); + EXPECT_NO_THROW(hash_map.Get(m3)->Aggregate(1l)); + EXPECT_EQ(hash_map.Size(), 2); + + // GetOrSetDefault + std::function<std::unique_ptr<Aggregation>()> create_default_aggregation = + []() -> std::unique_ptr<Aggregation> { + return std::unique_ptr<Aggregation>(new DropAggregation); + }; + MetricAttributes m4 = {{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}}; + EXPECT_NO_THROW(hash_map.GetOrSetDefault(m4, create_default_aggregation)->Aggregate(1l)); + EXPECT_EQ(hash_map.Size(), 3); + + // Set attributes with different order - shouldn't create a new entry. + MetricAttributes m5 = {{"k2", "v2"}, {"k1", "v1"}}; + EXPECT_EQ(hash_map.Has(m5), true); + + // GetAllEnteries + size_t count = 0; + hash_map.GetAllEnteries([&count](const MetricAttributes &attributes, Aggregation &aggregation) { + count++; + return true; + }); + EXPECT_EQ(count, hash_map.Size()); +} + +#endif
\ No newline at end of file diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_processor_benchmark.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_processor_benchmark.cc new file mode 100644 index 000000000..d558a668f --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_processor_benchmark.cc @@ -0,0 +1,27 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include <benchmark/benchmark.h> +#ifndef ENABLE_METRICS_PREVIEW +# include <map> +# include "opentelemetry/sdk/metrics/view/attributes_processor.h" +using namespace opentelemetry::sdk::metrics; +namespace +{ +void BM_AttributseProcessorFilter(benchmark::State &state) +{ + std::map<std::string, int> attributes = { + {"att1", 10}, {"attr1", 20}, {"attr3", 30}, {"attr4", 40}}; + FilteringAttributesProcessor attributes_processor( + {{"attr2", true}, {"attr4", true}, {"attr6", true}}); + opentelemetry::common::KeyValueIterableView<std::map<std::string, int>> iterable(attributes); + while (state.KeepRunning()) + { + auto filtered_attributes = attributes_processor.process(iterable); + } +} + +BENCHMARK(BM_AttributseProcessorFilter); +} // namespace +#endif +BENCHMARK_MAIN(); diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_processor_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_processor_test.cc new file mode 100644 index 000000000..d496cc7b0 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_processor_test.cc @@ -0,0 +1,49 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/view/attributes_processor.h" +# include <gtest/gtest.h> + +using namespace opentelemetry::sdk::metrics; +using namespace opentelemetry::common; +using namespace opentelemetry::sdk::common; + +TEST(AttributesProcessor, FilteringAttributesProcessor) +{ + const int kNumFilterAttributes = 3; + std::unordered_map<std::string, bool> filter = { + {"attr2", true}, {"attr4", true}, {"attr6", true}}; + const int kNumAttributes = 6; + std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; + int values[kNumAttributes] = {10, 20, 30, 40, 50, 60}; + std::map<std::string, int> attributes = {{keys[0], values[0]}, {keys[1], values[1]}, + {keys[2], values[2]}, {keys[3], values[3]}, + {keys[4], values[4]}, {keys[5], values[5]}}; + FilteringAttributesProcessor attributes_processor(filter); + opentelemetry::common::KeyValueIterableView<std::map<std::string, int>> iterable(attributes); + auto filtered_attributes = attributes_processor.process(iterable); + for (auto &e : filtered_attributes) + { + EXPECT_FALSE(filter.find(e.first) == filter.end()); + } + EXPECT_EQ(filter.size(), kNumFilterAttributes); +} + +TEST(AttributesProcessor, FilteringAllAttributesProcessor) +{ + const int kNumFilterAttributes = 0; + std::unordered_map<std::string, bool> filter = {}; + const int kNumAttributes = 6; + std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; + int values[kNumAttributes] = {10, 20, 30, 40, 50, 60}; + std::map<std::string, int> attributes = {{keys[0], values[0]}, {keys[1], values[1]}, + {keys[2], values[2]}, {keys[3], values[3]}, + {keys[4], values[4]}, {keys[5], values[5]}}; + FilteringAttributesProcessor attributes_processor(filter); + opentelemetry::common::KeyValueIterableView<std::map<std::string, int>> iterable(attributes); + auto filtered_attributes = attributes_processor.process(iterable); + EXPECT_EQ(filter.size(), kNumFilterAttributes); +} + +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/BUILD b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/BUILD new file mode 100644 index 000000000..6481f679d --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/BUILD @@ -0,0 +1,47 @@ +cc_test( + name = "no_exemplar_reservoir_test", + srcs = [ + "no_exemplar_reservoir_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "never_sample_filter_test", + srcs = [ + "never_sample_filter_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "always_sample_filter_test", + srcs = [ + "always_sample_filter_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/CMakeLists.txt new file mode 100644 index 000000000..303294761 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/CMakeLists.txt @@ -0,0 +1,10 @@ +foreach(testname no_exemplar_reservoir_test never_sample_filter_test + always_sample_filter_test) + add_executable(${testname} "${testname}.cc") + target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX metrics. + TEST_LIST ${testname}) +endforeach() diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/always_sample_filter_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/always_sample_filter_test.cc new file mode 100644 index 000000000..cf4e44995 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/always_sample_filter_test.cc @@ -0,0 +1,19 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/always_sample_filter.h" +# include <gtest/gtest.h> + +using namespace opentelemetry::sdk::metrics; + +TEST(AlwaysSampleFilter, SampleMeasurement) +{ + auto filter = opentelemetry::sdk::metrics::AlwaysSampleFilter::GetAlwaysSampleFilter(); + ASSERT_TRUE( + filter->ShouldSampleMeasurement(1.0, MetricAttributes{}, opentelemetry::context::Context{})); + ASSERT_TRUE( + filter->ShouldSampleMeasurement(1l, MetricAttributes{}, opentelemetry::context::Context{})); +} + +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/never_sample_filter_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/never_sample_filter_test.cc new file mode 100644 index 000000000..930c57220 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/never_sample_filter_test.cc @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "opentelemetry/context/context.h" +#ifndef ENABLE_METRICS_PREVIEW +# include <gtest/gtest.h> +# include "opentelemetry/sdk/metrics/exemplar/never_sample_filter.h" + +using namespace opentelemetry::sdk::metrics; + +TEST(NeverSampleFilter, SampleMeasurement) +{ + auto filter = opentelemetry::sdk::metrics::NeverSampleFilter::GetNeverSampleFilter(); + ASSERT_FALSE( + filter->ShouldSampleMeasurement(1.0, MetricAttributes{}, opentelemetry::context::Context{})); + ASSERT_FALSE( + filter->ShouldSampleMeasurement(1l, MetricAttributes{}, opentelemetry::context::Context{})); +} + +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc new file mode 100644 index 000000000..3e16940ff --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc @@ -0,0 +1,22 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" +# include <gtest/gtest.h> + +using namespace opentelemetry::sdk::metrics; + +TEST(NoExemplarReservoir, OfferMeasurement) +{ + auto reservoir = opentelemetry::sdk::metrics::NoExemplarReservoir::GetNoExemplarReservoir(); + EXPECT_NO_THROW(reservoir->OfferMeasurement(1.0, MetricAttributes{}, + opentelemetry::context::Context{}, + std::chrono::system_clock::now())); + EXPECT_NO_THROW(reservoir->OfferMeasurement( + 1l, MetricAttributes{}, opentelemetry::context::Context{}, std::chrono::system_clock::now())); + auto exemplar_data = reservoir->CollectAndReset(MetricAttributes{}); + ASSERT_TRUE(exemplar_data.empty()); +} + +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/meter_provider_sdk_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/meter_provider_sdk_test.cc new file mode 100644 index 000000000..b0fabe50b --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/meter_provider_sdk_test.cc @@ -0,0 +1,91 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include <gtest/gtest.h> +# include "opentelemetry/sdk/metrics/export/metric_producer.h" +# include "opentelemetry/sdk/metrics/meter.h" +# include "opentelemetry/sdk/metrics/meter_provider.h" +# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/metric_reader.h" +# include "opentelemetry/sdk/metrics/view/instrument_selector.h" +# include "opentelemetry/sdk/metrics/view/meter_selector.h" + +using namespace opentelemetry::sdk::metrics; + +class MockMetricExporter : public MetricExporter +{ + +public: + MockMetricExporter() = default; + opentelemetry::sdk::common::ExportResult Export(const ResourceMetrics &records) noexcept override + { + return opentelemetry::sdk::common::ExportResult::kSuccess; + } + + bool ForceFlush( + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override + { + return true; + } + + bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept override + { + return true; + } +}; + +class MockMetricReader : public MetricReader +{ +public: + MockMetricReader(std::unique_ptr<MetricExporter> exporter) : exporter_(std::move(exporter)) {} + virtual bool OnForceFlush(std::chrono::microseconds timeout) noexcept override { return true; } + virtual bool OnShutDown(std::chrono::microseconds timeout) noexcept override { return true; } + virtual void OnInitialized() noexcept override {} + +private: + std::unique_ptr<MetricExporter> exporter_; +}; + +TEST(MeterProvider, GetMeter) +{ + + MeterProvider mp1; + // std::unique_ptr<View> view{std::unique_ptr<View>()}; + // MeterProvider mp1(std::move(exporters), std::move(readers), std::move(views); + auto m1 = mp1.GetMeter("test"); + auto m2 = mp1.GetMeter("test"); + auto m3 = mp1.GetMeter("different", "1.0.0"); + auto m4 = mp1.GetMeter(""); + auto m5 = mp1.GetMeter(opentelemetry::nostd::string_view{}); + auto m6 = mp1.GetMeter("different", "1.0.0", "https://opentelemetry.io/schemas/1.2.0"); + ASSERT_NE(nullptr, m1); + ASSERT_NE(nullptr, m2); + ASSERT_NE(nullptr, m3); + ASSERT_NE(nullptr, m6); + + // Should return the same instance each time. + ASSERT_EQ(m1, m2); + ASSERT_NE(m1, m3); + ASSERT_EQ(m4, m5); + ASSERT_NE(m3, m6); + + // Should be an sdk::trace::Tracer with the processor attached. +# ifdef OPENTELEMETRY_RTTI_ENABLED + auto sdkMeter1 = dynamic_cast<Meter *>(m1.get()); +# else + auto sdkMeter1 = static_cast<Meter *>(m1.get()); +# endif + ASSERT_NE(nullptr, sdkMeter1); + std::unique_ptr<MockMetricExporter> exporter(new MockMetricExporter()); + std::unique_ptr<MetricReader> reader{new MockMetricReader(std::move(exporter))}; + ASSERT_NO_THROW(mp1.AddMetricReader(std::move(reader))); + + std::unique_ptr<View> view{std::unique_ptr<View>()}; + std::unique_ptr<InstrumentSelector> instrument_selector{ + new InstrumentSelector(InstrumentType::kCounter, "instru1")}; + std::unique_ptr<MeterSelector> meter_selector{new MeterSelector("name1", "version1", "schema1")}; + ASSERT_NO_THROW( + mp1.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view))); +} +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/metric_reader_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/metric_reader_test.cc new file mode 100644 index 000000000..c9c30853d --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/metric_reader_test.cc @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/metric_reader.h" +# include <gtest/gtest.h> +# include "opentelemetry/sdk/metrics/meter_context.h" +# include "opentelemetry/sdk/metrics/metric_exporter.h" + +using namespace opentelemetry; +using namespace opentelemetry::sdk::instrumentationlibrary; +using namespace opentelemetry::sdk::metrics; + +class MockMetricReader : public MetricReader +{ +public: + MockMetricReader(AggregationTemporality aggr_temporality) : MetricReader(aggr_temporality) {} + + virtual bool OnForceFlush(std::chrono::microseconds timeout) noexcept override { return true; } + virtual bool OnShutDown(std::chrono::microseconds timeout) noexcept override { return true; } + virtual void OnInitialized() noexcept override {} +}; + +TEST(MetricReaderTest, BasicTests) +{ + AggregationTemporality aggr_temporality = AggregationTemporality::kDelta; + std::unique_ptr<MetricReader> metric_reader1(new MockMetricReader(aggr_temporality)); + EXPECT_EQ(metric_reader1->GetAggregationTemporality(), aggr_temporality); + + std::shared_ptr<MeterContext> meter_context1(new MeterContext()); + EXPECT_NO_THROW(meter_context1->AddMetricReader(std::move(metric_reader1))); + + std::unique_ptr<MetricReader> metric_reader2(new MockMetricReader(aggr_temporality)); + std::shared_ptr<MeterContext> meter_context2(new MeterContext()); + MetricProducer *metric_producer = + new MetricCollector(std::move(meter_context2), std::move(metric_reader2)); + EXPECT_NO_THROW(metric_producer->Collect([](ResourceMetrics &metric_data) { return true; })); +} +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/multi_metric_storage_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/multi_metric_storage_test.cc new file mode 100644 index 000000000..d88946485 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/multi_metric_storage_test.cc @@ -0,0 +1,62 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/state/multi_metric_storage.h" +# include "opentelemetry/common/key_value_iterable_view.h" +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/instruments.h" + +# include <gtest/gtest.h> + +using namespace opentelemetry; +using namespace opentelemetry::sdk::instrumentationlibrary; +using namespace opentelemetry::sdk::metrics; + +class TestMetricStorage : public WritableMetricStorage +{ +public: + void RecordLong(long value, const opentelemetry::context::Context &context) noexcept override + { + num_calls_long++; + } + + void RecordLong(long value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override + { + num_calls_long++; + } + + void RecordDouble(double value, const opentelemetry::context::Context &context) noexcept override + { + num_calls_double++; + } + + void RecordDouble(double value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override + { + num_calls_double++; + } + + size_t num_calls_long; + size_t num_calls_double; +}; + +TEST(MultiMetricStorageTest, BasicTests) +{ + std::shared_ptr<opentelemetry::sdk::metrics::WritableMetricStorage> storage( + new TestMetricStorage()); + MultiMetricStorage storages{}; + storages.AddStorage(storage); + EXPECT_NO_THROW(storages.RecordLong(10l, opentelemetry::context::Context{})); + EXPECT_NO_THROW(storages.RecordLong(20l, opentelemetry::context::Context{})); + + EXPECT_NO_THROW(storages.RecordDouble(10.0, opentelemetry::context::Context{})); + EXPECT_NO_THROW(storages.RecordLong(30l, opentelemetry::context::Context{})); + + EXPECT_EQ(static_cast<TestMetricStorage *>(storage.get())->num_calls_long, 3); + EXPECT_EQ(static_cast<TestMetricStorage *>(storage.get())->num_calls_double, 1); +} +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/observer_result_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/observer_result_test.cc new file mode 100644 index 000000000..a4cc28ae5 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/observer_result_test.cc @@ -0,0 +1,38 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/observer_result.h" +# include "opentelemetry/sdk/metrics/view/attributes_processor.h" + +# include <gtest/gtest.h> + +using namespace opentelemetry::sdk::metrics; +TEST(ObserverResult, BasicTests) +{ + const AttributesProcessor *attributes_processor = new DefaultAttributesProcessor(); + + ObserverResult<long> observer_result(attributes_processor); + + observer_result.Observe(10l); + observer_result.Observe(20l); + EXPECT_EQ(observer_result.GetMeasurements().size(), 1); + + std::map<std::string, int64_t> m1 = {{"k2", 12}}; + observer_result.Observe( + 30l, opentelemetry::common::KeyValueIterableView<std::map<std::string, int64_t>>(m1)); + EXPECT_EQ(observer_result.GetMeasurements().size(), 2); + + observer_result.Observe( + 40l, opentelemetry::common::KeyValueIterableView<std::map<std::string, int64_t>>(m1)); + EXPECT_EQ(observer_result.GetMeasurements().size(), 2); + + std::map<std::string, int64_t> m2 = {{"k2", 12}, {"k4", 12}}; + observer_result.Observe( + 40l, opentelemetry::common::KeyValueIterableView<std::map<std::string, int64_t>>(m2)); + EXPECT_EQ(observer_result.GetMeasurements().size(), 3); + + delete attributes_processor; +} + +#endif
\ No newline at end of file diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/periodic_exporting_metric_reader_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/periodic_exporting_metric_reader_test.cc new file mode 100644 index 000000000..5219f3110 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/periodic_exporting_metric_reader_test.cc @@ -0,0 +1,81 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW + +# include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h" +# include "opentelemetry/sdk/metrics/export/metric_producer.h" +# include "opentelemetry/sdk/metrics/metric_exporter.h" + +# include <gtest/gtest.h> + +using namespace opentelemetry; +using namespace opentelemetry::sdk::instrumentationlibrary; +using namespace opentelemetry::sdk::metrics; + +class MockPushMetricExporter : public MetricExporter +{ +public: + opentelemetry::sdk::common::ExportResult Export(const ResourceMetrics &record) noexcept override + { + records_.push_back(record); + return opentelemetry::sdk::common::ExportResult::kSuccess; + } + + bool ForceFlush( + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override + { + return false; + } + + bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept override + { + return true; + } + + size_t GetDataCount() { return records_.size(); } + +private: + std::vector<ResourceMetrics> records_; +}; + +class MockMetricProducer : public MetricProducer +{ +public: + MockMetricProducer(std::chrono::microseconds sleep_ms = std::chrono::microseconds::zero()) + : sleep_ms_{sleep_ms}, data_sent_size_(0) + {} + + bool Collect(nostd::function_ref<bool(ResourceMetrics &)> callback) noexcept override + { + std::this_thread::sleep_for(sleep_ms_); + data_sent_size_++; + ResourceMetrics data; + callback(data); + return true; + } + + size_t GetDataCount() { return data_sent_size_; } + +private: + std::chrono::microseconds sleep_ms_; + size_t data_sent_size_; +}; + +TEST(PeriodicExporingMetricReader, BasicTests) +{ + std::unique_ptr<MetricExporter> exporter(new MockPushMetricExporter()); + PeriodicExportingMetricReaderOptions options; + options.export_timeout_millis = std::chrono::milliseconds(200); + options.export_interval_millis = std::chrono::milliseconds(500); + auto exporter_ptr = exporter.get(); + PeriodicExportingMetricReader reader(std::move(exporter), options); + MockMetricProducer producer; + reader.SetMetricProducer(&producer); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + reader.Shutdown(); + EXPECT_EQ(static_cast<MockPushMetricExporter *>(exporter_ptr)->GetDataCount(), + static_cast<MockMetricProducer *>(&producer)->GetDataCount()); +} + +#endif
\ No newline at end of file diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/sync_instruments_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/sync_instruments_test.cc new file mode 100644 index 000000000..1a590d8d2 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/sync_instruments_test.cc @@ -0,0 +1,138 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/sync_instruments.h" +# include "opentelemetry/context/context.h" +# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/state/multi_metric_storage.h" + +# include <gtest/gtest.h> +# include <cmath> +# include <limits> + +using namespace opentelemetry; +using namespace opentelemetry::sdk::instrumentationlibrary; +using namespace opentelemetry::sdk::metrics; + +auto instrumentation_library = InstrumentationLibrary::Create("opentelemetry-cpp", "0.1.0"); + +using M = std::map<std::string, std::string>; + +TEST(SyncInstruments, LongCounter) +{ + InstrumentDescriptor instrument_descriptor = { + "long_counter", "description", "1", InstrumentType::kCounter, InstrumentValueType::kLong}; + std::unique_ptr<WritableMetricStorage> metric_storage(new MultiMetricStorage()); + LongCounter counter(instrument_descriptor, std::move(metric_storage)); + EXPECT_NO_THROW(counter.Add(10l)); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::context::Context{})); + + EXPECT_NO_THROW(counter.Add( + 10l, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}))); + EXPECT_NO_THROW(counter.Add( + 10l, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::common::KeyValueIterableView<M>({}))); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::common::KeyValueIterableView<M>({}), + opentelemetry::context::Context{})); +} + +TEST(SyncInstruments, DoubleCounter) +{ + InstrumentDescriptor instrument_descriptor = { + "double_counter", "description", "1", InstrumentType::kCounter, InstrumentValueType::kDouble}; + std::unique_ptr<WritableMetricStorage> metric_storage(new MultiMetricStorage()); + DoubleCounter counter(instrument_descriptor, std::move(metric_storage)); + EXPECT_NO_THROW(counter.Add(10.10)); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::context::Context{})); + + EXPECT_NO_THROW(counter.Add( + 10.10, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}))); + EXPECT_NO_THROW(counter.Add( + 10.10, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::common::KeyValueIterableView<M>({}))); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::common::KeyValueIterableView<M>({}), + opentelemetry::context::Context{})); +} + +TEST(SyncInstruments, LongUpDownCounter) +{ + InstrumentDescriptor instrument_descriptor = {"long_updowncounter", "description", "1", + InstrumentType::kUpDownCounter, + InstrumentValueType::kLong}; + std::unique_ptr<WritableMetricStorage> metric_storage(new MultiMetricStorage()); + LongUpDownCounter counter(instrument_descriptor, std::move(metric_storage)); + EXPECT_NO_THROW(counter.Add(10l)); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::context::Context{})); + + EXPECT_NO_THROW(counter.Add( + 10l, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}))); + EXPECT_NO_THROW(counter.Add( + 10l, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::common::KeyValueIterableView<M>({}))); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::common::KeyValueIterableView<M>({}), + opentelemetry::context::Context{})); +} + +TEST(SyncInstruments, DoubleUpDownCounter) +{ + InstrumentDescriptor instrument_descriptor = {"double_updowncounter", "description", "1", + InstrumentType::kUpDownCounter, + InstrumentValueType::kDouble}; + std::unique_ptr<WritableMetricStorage> metric_storage(new MultiMetricStorage()); + DoubleUpDownCounter counter(instrument_descriptor, std::move(metric_storage)); + EXPECT_NO_THROW(counter.Add(10.10)); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::context::Context{})); + + EXPECT_NO_THROW(counter.Add( + 10.10, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Add( + 10.10, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}))); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::common::KeyValueIterableView<M>({}), + opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::common::KeyValueIterableView<M>({}))); +} + +TEST(SyncInstruments, LongHistogram) +{ + InstrumentDescriptor instrument_descriptor = { + "long_histogram", "description", "1", InstrumentType::kHistogram, InstrumentValueType::kLong}; + std::unique_ptr<WritableMetricStorage> metric_storage(new MultiMetricStorage()); + LongHistogram counter(instrument_descriptor, std::move(metric_storage)); + EXPECT_NO_THROW(counter.Record(10l, opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(-10l, opentelemetry::context::Context{})); // This is ignored + + EXPECT_NO_THROW(counter.Record( + 10l, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(10l, opentelemetry::common::KeyValueIterableView<M>({}), + opentelemetry::context::Context{})); +} + +TEST(SyncInstruments, DoubleHistogram) +{ + InstrumentDescriptor instrument_descriptor = {"double_histogram", "description", "1", + InstrumentType::kHistogram, + InstrumentValueType::kDouble}; + std::unique_ptr<WritableMetricStorage> metric_storage(new MultiMetricStorage()); + DoubleHistogram counter(instrument_descriptor, std::move(metric_storage)); + EXPECT_NO_THROW(counter.Record(10.10, opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(-10.10, opentelemetry::context::Context{})); // This is ignored. + EXPECT_NO_THROW(counter.Record(std::numeric_limits<double>::quiet_NaN(), + opentelemetry::context::Context{})); // This is ignored too + EXPECT_NO_THROW(counter.Record(std::numeric_limits<double>::infinity(), + opentelemetry::context::Context{})); // This is ignored too + + EXPECT_NO_THROW(counter.Record( + 10.10, opentelemetry::common::KeyValueIterableView<M>({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(10.10, opentelemetry::common::KeyValueIterableView<M>({}), + opentelemetry::context::Context{})); +} + +#endif
\ No newline at end of file diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/sync_metric_storage_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/sync_metric_storage_test.cc new file mode 100644 index 000000000..7dfc4f947 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/sync_metric_storage_test.cc @@ -0,0 +1,246 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/state/sync_metric_storage.h" +# include "opentelemetry/common/key_value_iterable_view.h" +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/instruments.h" +# include "opentelemetry/sdk/metrics/view/attributes_processor.h" + +# include <gtest/gtest.h> +# include <map> + +using namespace opentelemetry::sdk::metrics; +using namespace opentelemetry::common; +using M = std::map<std::string, std::string>; + +class MockCollectorHandle : public CollectorHandle +{ +public: + MockCollectorHandle(AggregationTemporality temp) : temporality(temp) {} + + AggregationTemporality GetAggregationTemporality() noexcept override { return temporality; } + +private: + AggregationTemporality temporality; +}; + +class WritableMetricStorageTestFixture : public ::testing::TestWithParam<AggregationTemporality> +{}; + +TEST_P(WritableMetricStorageTestFixture, LongSumAggregation) +{ + AggregationTemporality temporality = GetParam(); + auto sdk_start_ts = std::chrono::system_clock::now(); + long expected_total_get_requests = 0; + long expected_total_put_requests = 0; + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, + InstrumentValueType::kLong}; + std::map<std::string, std::string> attributes_get = {{"RequestType", "GET"}}; + std::map<std::string, std::string> attributes_put = {{"RequestType", "PUT"}}; + + opentelemetry::sdk::metrics::SyncMetricStorage storage( + instr_desc, AggregationType::kSum, new DefaultAttributesProcessor(), + NoExemplarReservoir::GetNoExemplarReservoir()); + + storage.RecordLong(10l, KeyValueIterableView<std::map<std::string, std::string>>(attributes_get), + opentelemetry::context::Context{}); + expected_total_get_requests += 10; + + EXPECT_NO_THROW(storage.RecordLong( + 30l, KeyValueIterableView<std::map<std::string, std::string>>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 30; + + storage.RecordLong(20l, KeyValueIterableView<std::map<std::string, std::string>>(attributes_get), + opentelemetry::context::Context{}); + expected_total_get_requests += 20; + + EXPECT_NO_THROW(storage.RecordLong( + 40l, KeyValueIterableView<std::map<std::string, std::string>>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 40; + + std::shared_ptr<CollectorHandle> collector(new MockCollectorHandle(temporality)); + std::vector<std::shared_ptr<CollectorHandle>> collectors; + collectors.push_back(collector); + + // Some computation here + auto collection_ts = std::chrono::system_clock::now(); + size_t count_attributes = 0; + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get<SumPointData>(data_attr.point_data); + if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get<long>(data.value_), expected_total_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get<long>(data.value_), expected_total_put_requests); + count_attributes++; + } + } + return true; + }); + + // In case of delta temporarily, subsequent collection would contain new data points, so resetting + // the counts + if (temporality == AggregationTemporality::kDelta) + { + expected_total_get_requests = 0; + expected_total_put_requests = 0; + } + + EXPECT_NO_THROW(storage.RecordLong( + 50l, KeyValueIterableView<std::map<std::string, std::string>>(attributes_get), + opentelemetry::context::Context{})); + expected_total_get_requests += 50; + EXPECT_NO_THROW(storage.RecordLong( + 40l, KeyValueIterableView<std::map<std::string, std::string>>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 40; + + collection_ts = std::chrono::system_clock::now(); + count_attributes = 0; + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get<SumPointData>(data_attr.point_data); + if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get<long>(data.value_), expected_total_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get<long>(data.value_), expected_total_put_requests); + count_attributes++; + } + } + return true; + }); +} +INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestLong, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); + +TEST_P(WritableMetricStorageTestFixture, DoubleSumAggregation) +{ + AggregationTemporality temporality = GetParam(); + auto sdk_start_ts = std::chrono::system_clock::now(); + double expected_total_get_requests = 0; + double expected_total_put_requests = 0; + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, + InstrumentValueType::kDouble}; + std::map<std::string, std::string> attributes_get = {{"RequestType", "GET"}}; + std::map<std::string, std::string> attributes_put = {{"RequestType", "PUT"}}; + + opentelemetry::sdk::metrics::SyncMetricStorage storage( + instr_desc, AggregationType::kSum, new DefaultAttributesProcessor(), + NoExemplarReservoir::GetNoExemplarReservoir()); + + storage.RecordDouble(10.0, + KeyValueIterableView<std::map<std::string, std::string>>(attributes_get), + opentelemetry::context::Context{}); + expected_total_get_requests += 10; + + EXPECT_NO_THROW(storage.RecordDouble( + 30.0, KeyValueIterableView<std::map<std::string, std::string>>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 30; + + storage.RecordDouble(20.0, + KeyValueIterableView<std::map<std::string, std::string>>(attributes_get), + opentelemetry::context::Context{}); + expected_total_get_requests += 20; + + EXPECT_NO_THROW(storage.RecordDouble( + 40.0, KeyValueIterableView<std::map<std::string, std::string>>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 40; + + std::shared_ptr<CollectorHandle> collector(new MockCollectorHandle(temporality)); + std::vector<std::shared_ptr<CollectorHandle>> collectors; + collectors.push_back(collector); + + // Some computation here + auto collection_ts = std::chrono::system_clock::now(); + size_t count_attributes = 0; + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get<SumPointData>(data_attr.point_data); + if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get<double>(data.value_), expected_total_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get<double>(data.value_), expected_total_put_requests); + count_attributes++; + } + } + return true; + }); + + // In case of delta temporarily, subsequent collection would contain new data points, so resetting + // the counts + if (temporality == AggregationTemporality::kDelta) + { + expected_total_get_requests = 0; + expected_total_put_requests = 0; + } + + EXPECT_NO_THROW(storage.RecordDouble( + 50.0, KeyValueIterableView<std::map<std::string, std::string>>(attributes_get), + opentelemetry::context::Context{})); + expected_total_get_requests += 50; + EXPECT_NO_THROW(storage.RecordDouble( + 40.0, KeyValueIterableView<std::map<std::string, std::string>>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 40; + + collection_ts = std::chrono::system_clock::now(); + count_attributes = 0; + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get<SumPointData>(data_attr.point_data); + if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get<double>(data.value_), expected_total_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get<std::string>( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get<double>(data.value_), expected_total_put_requests); + count_attributes++; + } + } + return true; + }); +} +INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestDouble, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); + +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/view_registry_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/view_registry_test.cc new file mode 100644 index 000000000..8151d3754 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/view_registry_test.cc @@ -0,0 +1,82 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/view/view_registry.h" +# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" +# include "opentelemetry/sdk/metrics/instruments.h" +# include "opentelemetry/sdk/metrics/view/predicate.h" + +# include <gtest/gtest.h> + +using namespace opentelemetry::sdk::metrics; +using namespace opentelemetry::sdk::instrumentationlibrary; + +TEST(ViewRegistry, FindViewsEmptyRegistry) +{ + InstrumentDescriptor default_instrument_descriptor = { + "test_name", // name + "test_descr", // description + "1", // unit + InstrumentType::kCounter, // instrument type + InstrumentValueType::kLong}; + + auto default_instrumentation_lib = + InstrumentationLibrary::Create("default", "1.0.0", "https://opentelemetry.io/schemas/1.7.0"); + int count = 0; + ViewRegistry registry; + auto status = + registry.FindViews(default_instrument_descriptor, *default_instrumentation_lib.get(), + [&count](const View &view) { + count++; + EXPECT_EQ(view.GetName(), "otel-default-view"); + EXPECT_EQ(view.GetDescription(), ""); + EXPECT_EQ(view.GetAggregationType(), AggregationType::kDefault); + return true; + }); + EXPECT_EQ(count, 1); + EXPECT_EQ(status, true); +} + +TEST(ViewRegistry, FindNonExistingView) +{ + // Add view + const std::string view_name = "test_view"; + const std::string view_description = "test description"; + const std::string instrumentation_name = "name1"; + const std::string instrumentation_version = "version1"; + const std::string instrumentation_schema = "schema1"; + const std::string instrument_name = "testname"; + const InstrumentType instrument_type = InstrumentType::kCounter; + + std::unique_ptr<InstrumentSelector> instrument_selector{ + new InstrumentSelector(instrument_type, instrument_name)}; + std::unique_ptr<MeterSelector> meter_selector{ + new MeterSelector(instrumentation_name, instrumentation_version, instrumentation_schema)}; + std::unique_ptr<View> view = std::unique_ptr<View>(new View(view_name, view_description)); + + ViewRegistry registry; + registry.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view)); + InstrumentDescriptor default_instrument_descriptor = {instrument_name, // name + "test_descr", // description + "1", // unit + instrument_type, // instrument type + InstrumentValueType::kLong}; + + auto default_instrumentation_lib = InstrumentationLibrary::Create( + instrumentation_name, instrumentation_version, instrumentation_schema); + int count = 0; + auto status = + registry.FindViews(default_instrument_descriptor, *default_instrumentation_lib.get(), + [&count, &view_name, &view_description](const View &view) { + count++; +# if HAVE_WORKING_REGEX + EXPECT_EQ(view.GetName(), view_name); + EXPECT_EQ(view.GetDescription(), view_description); +# endif + return true; + }); + EXPECT_EQ(count, 1); + EXPECT_EQ(status, true); +} +#endif |