summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/opentelemetry-cpp/sdk/test/_metrics/meter_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/sdk/test/_metrics/meter_test.cc')
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/test/_metrics/meter_test.cc297
1 files changed, 297 insertions, 0 deletions
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/_metrics/meter_test.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/_metrics/meter_test.cc
new file mode 100644
index 000000000..73ff1f9bd
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/_metrics/meter_test.cc
@@ -0,0 +1,297 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#ifdef ENABLE_METRICS_PREVIEW
+# include <gtest/gtest.h>
+# include <future>
+
+# include "opentelemetry/sdk/_metrics/meter.h"
+
+using namespace opentelemetry::sdk::metrics;
+namespace metrics_api = opentelemetry::metrics;
+namespace common = opentelemetry::common;
+namespace nostd = opentelemetry::nostd;
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+
+TEST(Meter, CreateSyncInstruments)
+{
+ // Test that there are no errors creating synchronous instruments.
+ Meter m("Test");
+
+ m.NewShortCounter("Test-short-counter", "For testing", "Unitless", true);
+ m.NewIntCounter("Test-int-counter", "For testing", "Unitless", true);
+ m.NewFloatCounter("Test-float-counter", "For testing", "Unitless", true);
+ m.NewDoubleCounter("Test-double-counter", "For testing", "Unitless", true);
+
+ m.NewShortUpDownCounter("Test-short-ud-counter", "For testing", "Unitless", true);
+ m.NewIntUpDownCounter("Test-int-ud-counter", "For testing", "Unitless", true);
+ m.NewFloatUpDownCounter("Test-float-ud-counter", "For testing", "Unitless", true);
+ m.NewDoubleUpDownCounter("Test-double-ud-counter", "For testing", "Unitless", true);
+
+ m.NewShortValueRecorder("Test-short-recorder", "For testing", "Unitless", true);
+ m.NewIntValueRecorder("Test-int-recorder", "For testing", "Unitless", true);
+ m.NewFloatValueRecorder("Test-float-recorder", "For testing", "Unitless", true);
+ m.NewDoubleValueRecorder("Test-double-recorder", "For testing", "Unitless", true);
+}
+
+// Dummy functions for asynchronous instrument constructors
+void ShortCallback(metrics_api::ObserverResult<short>) {}
+void IntCallback(metrics_api::ObserverResult<int>) {}
+void FloatCallback(metrics_api::ObserverResult<float>) {}
+void DoubleCallback(metrics_api::ObserverResult<double>) {}
+
+TEST(Meter, CreateAsyncInstruments)
+{
+ // Test that there are no errors when creating asynchronous instruments.
+ Meter m("Test");
+
+ m.NewShortSumObserver("Test-short-sum-obs", "For testing", "Unitless", true, &ShortCallback);
+ m.NewIntSumObserver("Test-int-sum-obs", "For testing", "Unitless", true, &IntCallback);
+ m.NewFloatSumObserver("Test-float-sum-obs", "For testing", "Unitless", true, &FloatCallback);
+ m.NewDoubleSumObserver("Test-double-sum-obs", "For testing", "Unitless", true, &DoubleCallback);
+
+ m.NewShortUpDownSumObserver("Test-short-ud-sum-obs", "For testing", "Unitless", true,
+ &ShortCallback);
+ m.NewIntUpDownSumObserver("Test-int-ud-sum-obs", "For testing", "Unitless", true, &IntCallback);
+ m.NewFloatUpDownSumObserver("Test-float-ud-sum-obs", "For testing", "Unitless", true,
+ &FloatCallback);
+ m.NewDoubleUpDownSumObserver("Test-double-ud-sum-obs", "For testing", "Unitless", true,
+ &DoubleCallback);
+
+ m.NewShortValueObserver("Test-short-val-obs", "For testing", "Unitless", true, &ShortCallback);
+ m.NewIntValueObserver("Test-int-val-obs", "For testing", "Unitless", true, &IntCallback);
+ m.NewFloatValueObserver("Test-float-val-obs", "For testing", "Unitless", true, &FloatCallback);
+ m.NewDoubleValueObserver("Test-double-val-obs", "For testing", "Unitless", true, &DoubleCallback);
+}
+
+TEST(Meter, CollectSyncInstruments)
+{
+ // Verify that the records returned on a call to Collect() are correct for synchronous
+ // instruments.
+ Meter m("Test");
+
+ ASSERT_EQ(m.Collect().size(), 0);
+
+ auto counter = m.NewShortCounter("Test-counter", "For testing", "Unitless", true);
+
+ std::map<std::string, std::string> labels = {{"Key", "Value"}};
+ auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+
+ counter->add(1, labelkv);
+
+ std::vector<Record> res = m.Collect();
+ auto agg_var = res[0].GetAggregator();
+ auto agg = nostd::get<0>(agg_var);
+
+ ASSERT_EQ(agg->get_checkpoint()[0], 1);
+
+ // Now call add() and Collect() again to ensure that the value in the underlying
+ // aggregator was reset to the default.
+
+ counter->add(10, labelkv);
+
+ res = m.Collect();
+ agg_var = res[0].GetAggregator();
+ agg = nostd::get<0>(agg_var);
+
+ ASSERT_EQ(agg->get_checkpoint()[0], 10);
+}
+
+TEST(Meter, CollectDeletedSync)
+{
+ // Verify that calling Collect() after creating a synchronous instrument and destroying
+ // the return pointer does not result in a segfault.
+
+ Meter m("Test");
+
+ ASSERT_EQ(m.Collect().size(), 0);
+
+ std::map<std::string, std::string> labels = {{"Key", "Value"}};
+ auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+ {
+ auto counter = m.NewShortCounter("Test-counter", "For testing", "Unitless", true);
+ counter->add(1, labelkv);
+ } // counter shared_ptr deleted here
+
+ std::vector<Record> res = m.Collect();
+ auto agg_var = res[0].GetAggregator();
+ auto agg = nostd::get<0>(agg_var);
+
+ ASSERT_EQ(agg->get_checkpoint()[0], 1);
+}
+
+// Dummy function for asynchronous instrument constructors.
+void Callback(metrics_api::ObserverResult<short> result)
+{
+ std::map<std::string, std::string> labels = {{"key", "value"}};
+ auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+ result.observe(1, labelkv);
+}
+
+TEST(Meter, CollectAsyncInstruments)
+{
+ // Verify that the records returned on a call to Collect() are correct for asynchronous
+ // instruments.
+ Meter m("Test");
+
+ ASSERT_EQ(m.Collect().size(), 0);
+
+ auto sumobs =
+ m.NewShortSumObserver("Test-counter", "For testing", "Unitless", true, &ShortCallback);
+
+ std::map<std::string, std::string> labels = {{"Key", "Value"}};
+ auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+
+ sumobs->observe(1, labelkv);
+
+ std::vector<Record> res = m.Collect();
+ auto agg_var = res[0].GetAggregator();
+ auto agg = nostd::get<0>(agg_var);
+
+ ASSERT_EQ(agg->get_checkpoint()[0], 1);
+
+ // Now call observe() and Collect() again to ensure that the value in the underlying
+ // aggregator was reset to the default.
+
+ sumobs->observe(10, labelkv);
+
+ res = m.Collect();
+ agg_var = res[0].GetAggregator();
+ agg = nostd::get<0>(agg_var);
+
+ ASSERT_EQ(agg->get_checkpoint()[0], 10);
+}
+
+TEST(Meter, CollectDeletedAsync)
+{
+ // Verify that calling Collect() after creating an asynchronous instrument and destroying
+ // the return pointer does not result in a segfault.
+
+ Meter m("Test");
+
+ ASSERT_EQ(m.Collect().size(), 0);
+
+ std::map<std::string, std::string> labels = {{"Key", "Value"}};
+ auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+ {
+ auto sumobs = m.NewShortSumObserver("Test-counter", "For testing", "Unitless", true, &Callback);
+ sumobs->observe(1, labelkv);
+ } // sumobs shared_ptr deleted here
+
+ std::vector<Record> res = m.Collect();
+ auto agg_var = res[0].GetAggregator();
+ auto agg = nostd::get<0>(agg_var);
+
+ ASSERT_EQ(agg->get_checkpoint()[0], 1);
+}
+
+TEST(Meter, RecordBatch)
+{
+ // This tests that RecordBatch appropriately updates the aggregators of the instruments
+ // passed to the function. Short, int, float, and double data types are tested.
+ Meter m("Test");
+
+ auto scounter = m.NewShortCounter("Test-scounter", "For testing", "Unitless", true);
+ auto icounter = m.NewIntCounter("Test-icounter", "For testing", "Unitless", true);
+ auto fcounter = m.NewFloatCounter("Test-fcounter", "For testing", "Unitless", true);
+ auto dcounter = m.NewDoubleCounter("Test-dcounter", "For testing", "Unitless", true);
+
+ std::map<std::string, std::string> labels = {{"Key", "Value"}};
+ auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+
+ metrics_api::SynchronousInstrument<short> *sinstr_arr[] = {scounter.get()};
+ short svalues_arr[] = {1};
+
+ nostd::span<metrics_api::SynchronousInstrument<short> *> sinstrs{sinstr_arr};
+ nostd::span<const short, 1> svalues{svalues_arr};
+
+ m.RecordShortBatch(labelkv, sinstrs, svalues);
+ std::vector<Record> res = m.Collect();
+ auto short_agg_var = res[0].GetAggregator();
+ auto short_agg = nostd::get<0>(short_agg_var);
+ ASSERT_EQ(short_agg->get_checkpoint()[0], 1);
+
+ metrics_api::SynchronousInstrument<int> *iinstr_arr[] = {icounter.get()};
+ int ivalues_arr[] = {1};
+
+ nostd::span<metrics_api::SynchronousInstrument<int> *> iinstrs{iinstr_arr};
+ nostd::span<const int, 1> ivalues{ivalues_arr};
+
+ m.RecordIntBatch(labelkv, iinstrs, ivalues);
+ res = m.Collect();
+ auto int_agg_var = res[0].GetAggregator();
+ auto int_agg = nostd::get<1>(int_agg_var);
+ ASSERT_EQ(int_agg->get_checkpoint()[0], 1);
+
+ metrics_api::SynchronousInstrument<float> *finstr_arr[] = {fcounter.get()};
+ float fvalues_arr[] = {1.0};
+
+ nostd::span<metrics_api::SynchronousInstrument<float> *> finstrs{finstr_arr};
+ nostd::span<const float, 1> fvalues{fvalues_arr};
+
+ m.RecordFloatBatch(labelkv, finstrs, fvalues);
+ res = m.Collect();
+ auto float_agg_var = res[0].GetAggregator();
+ auto float_agg = nostd::get<2>(float_agg_var);
+ ASSERT_EQ(float_agg->get_checkpoint()[0], 1.0);
+
+ metrics_api::SynchronousInstrument<double> *dinstr_arr[] = {dcounter.get()};
+ double dvalues_arr[] = {1.0};
+
+ nostd::span<metrics_api::SynchronousInstrument<double> *> dinstrs{dinstr_arr};
+ nostd::span<const double, 1> dvalues{dvalues_arr};
+
+ m.RecordDoubleBatch(labelkv, dinstrs, dvalues);
+ res = m.Collect();
+ auto double_agg_var = res[0].GetAggregator();
+ auto double_agg = nostd::get<3>(double_agg_var);
+ ASSERT_EQ(double_agg->get_checkpoint()[0], 1.0);
+}
+
+TEST(Meter, DisableCollectSync)
+{
+ Meter m("Test");
+ std::map<std::string, std::string> labels = {{"Key", "Value"}};
+ auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+ auto c = m.NewShortCounter("c", "", "", false);
+ c->add(1, labelkv);
+ ASSERT_EQ(m.Collect().size(), 0);
+}
+
+TEST(Meter, DisableCollectAsync)
+{
+ Meter m("Test");
+ std::map<std::string, std::string> labels = {{"Key", "Value"}};
+ auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+ auto c = m.NewShortValueObserver("c", "", "", false, &ShortCallback);
+ c->observe(1, labelkv);
+ ASSERT_EQ(m.Collect().size(), 0);
+}
+
+TEST(MeterStringUtil, IsValid)
+{
+# if __EXCEPTIONS
+ Meter m("Test");
+ ASSERT_ANY_THROW(m.NewShortCounter("", "Empty name is invalid", " ", true));
+ ASSERT_ANY_THROW(m.NewShortCounter("1a", "Can't begin with a number", " ", true));
+ ASSERT_ANY_THROW(m.NewShortCounter(".a", "Can't begin with punctuation", " ", true));
+ ASSERT_ANY_THROW(m.NewShortCounter(" a", "Can't begin with space", " ", true));
+ ASSERT_ANY_THROW(m.NewShortCounter(
+ "te^ s=%t", "Only alphanumeric ., -, and _ characters are allowed", " ", true));
+# endif
+}
+
+TEST(MeterStringUtil, AlreadyExists)
+{
+# if __EXCEPTIONS
+ Meter m("Test");
+
+ m.NewShortCounter("a", "First instance of instrument named 'a'", "", true);
+ ASSERT_ANY_THROW(m.NewShortCounter("a", "Second (illegal) instrument named 'a'", "", true));
+ ASSERT_ANY_THROW(m.NewShortSumObserver("a", "Still illegal even though it is not a short counter",
+ "", true, &ShortCallback));
+# endif
+}
+OPENTELEMETRY_END_NAMESPACE
+#endif