summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/opentelemetry-cpp/sdk/test/metrics
diff options
context:
space:
mode:
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/sdk/test/metrics')
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/BUILD203
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/CMakeLists.txt34
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/aggregation_test.cc182
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/async_instruments_test.cc60
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/async_metric_storage_test.cc132
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_hashmap_benchmark.cc53
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_hashmap_test.cc71
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_processor_benchmark.cc27
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/attributes_processor_test.cc49
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/BUILD47
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/CMakeLists.txt10
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/always_sample_filter_test.cc19
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/never_sample_filter_test.cc20
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc22
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/meter_provider_sdk_test.cc91
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/metric_reader_test.cc39
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/multi_metric_storage_test.cc62
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/observer_result_test.cc38
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/periodic_exporting_metric_reader_test.cc81
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/sync_instruments_test.cc138
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/sync_metric_storage_test.cc246
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/metrics/view_registry_test.cc82
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