]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/sdk/test/_metrics/meter_test.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / sdk / test / _metrics / meter_test.cc
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3
4 #ifdef ENABLE_METRICS_PREVIEW
5 # include <gtest/gtest.h>
6 # include <future>
7
8 # include "opentelemetry/sdk/_metrics/meter.h"
9
10 using namespace opentelemetry::sdk::metrics;
11 namespace metrics_api = opentelemetry::metrics;
12 namespace common = opentelemetry::common;
13 namespace nostd = opentelemetry::nostd;
14
15 OPENTELEMETRY_BEGIN_NAMESPACE
16
17 TEST(Meter, CreateSyncInstruments)
18 {
19 // Test that there are no errors creating synchronous instruments.
20 Meter m("Test");
21
22 m.NewShortCounter("Test-short-counter", "For testing", "Unitless", true);
23 m.NewIntCounter("Test-int-counter", "For testing", "Unitless", true);
24 m.NewFloatCounter("Test-float-counter", "For testing", "Unitless", true);
25 m.NewDoubleCounter("Test-double-counter", "For testing", "Unitless", true);
26
27 m.NewShortUpDownCounter("Test-short-ud-counter", "For testing", "Unitless", true);
28 m.NewIntUpDownCounter("Test-int-ud-counter", "For testing", "Unitless", true);
29 m.NewFloatUpDownCounter("Test-float-ud-counter", "For testing", "Unitless", true);
30 m.NewDoubleUpDownCounter("Test-double-ud-counter", "For testing", "Unitless", true);
31
32 m.NewShortValueRecorder("Test-short-recorder", "For testing", "Unitless", true);
33 m.NewIntValueRecorder("Test-int-recorder", "For testing", "Unitless", true);
34 m.NewFloatValueRecorder("Test-float-recorder", "For testing", "Unitless", true);
35 m.NewDoubleValueRecorder("Test-double-recorder", "For testing", "Unitless", true);
36 }
37
38 // Dummy functions for asynchronous instrument constructors
39 void ShortCallback(metrics_api::ObserverResult<short>) {}
40 void IntCallback(metrics_api::ObserverResult<int>) {}
41 void FloatCallback(metrics_api::ObserverResult<float>) {}
42 void DoubleCallback(metrics_api::ObserverResult<double>) {}
43
44 TEST(Meter, CreateAsyncInstruments)
45 {
46 // Test that there are no errors when creating asynchronous instruments.
47 Meter m("Test");
48
49 m.NewShortSumObserver("Test-short-sum-obs", "For testing", "Unitless", true, &ShortCallback);
50 m.NewIntSumObserver("Test-int-sum-obs", "For testing", "Unitless", true, &IntCallback);
51 m.NewFloatSumObserver("Test-float-sum-obs", "For testing", "Unitless", true, &FloatCallback);
52 m.NewDoubleSumObserver("Test-double-sum-obs", "For testing", "Unitless", true, &DoubleCallback);
53
54 m.NewShortUpDownSumObserver("Test-short-ud-sum-obs", "For testing", "Unitless", true,
55 &ShortCallback);
56 m.NewIntUpDownSumObserver("Test-int-ud-sum-obs", "For testing", "Unitless", true, &IntCallback);
57 m.NewFloatUpDownSumObserver("Test-float-ud-sum-obs", "For testing", "Unitless", true,
58 &FloatCallback);
59 m.NewDoubleUpDownSumObserver("Test-double-ud-sum-obs", "For testing", "Unitless", true,
60 &DoubleCallback);
61
62 m.NewShortValueObserver("Test-short-val-obs", "For testing", "Unitless", true, &ShortCallback);
63 m.NewIntValueObserver("Test-int-val-obs", "For testing", "Unitless", true, &IntCallback);
64 m.NewFloatValueObserver("Test-float-val-obs", "For testing", "Unitless", true, &FloatCallback);
65 m.NewDoubleValueObserver("Test-double-val-obs", "For testing", "Unitless", true, &DoubleCallback);
66 }
67
68 TEST(Meter, CollectSyncInstruments)
69 {
70 // Verify that the records returned on a call to Collect() are correct for synchronous
71 // instruments.
72 Meter m("Test");
73
74 ASSERT_EQ(m.Collect().size(), 0);
75
76 auto counter = m.NewShortCounter("Test-counter", "For testing", "Unitless", true);
77
78 std::map<std::string, std::string> labels = {{"Key", "Value"}};
79 auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
80
81 counter->add(1, labelkv);
82
83 std::vector<Record> res = m.Collect();
84 auto agg_var = res[0].GetAggregator();
85 auto agg = nostd::get<0>(agg_var);
86
87 ASSERT_EQ(agg->get_checkpoint()[0], 1);
88
89 // Now call add() and Collect() again to ensure that the value in the underlying
90 // aggregator was reset to the default.
91
92 counter->add(10, labelkv);
93
94 res = m.Collect();
95 agg_var = res[0].GetAggregator();
96 agg = nostd::get<0>(agg_var);
97
98 ASSERT_EQ(agg->get_checkpoint()[0], 10);
99 }
100
101 TEST(Meter, CollectDeletedSync)
102 {
103 // Verify that calling Collect() after creating a synchronous instrument and destroying
104 // the return pointer does not result in a segfault.
105
106 Meter m("Test");
107
108 ASSERT_EQ(m.Collect().size(), 0);
109
110 std::map<std::string, std::string> labels = {{"Key", "Value"}};
111 auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
112 {
113 auto counter = m.NewShortCounter("Test-counter", "For testing", "Unitless", true);
114 counter->add(1, labelkv);
115 } // counter shared_ptr deleted here
116
117 std::vector<Record> res = m.Collect();
118 auto agg_var = res[0].GetAggregator();
119 auto agg = nostd::get<0>(agg_var);
120
121 ASSERT_EQ(agg->get_checkpoint()[0], 1);
122 }
123
124 // Dummy function for asynchronous instrument constructors.
125 void Callback(metrics_api::ObserverResult<short> result)
126 {
127 std::map<std::string, std::string> labels = {{"key", "value"}};
128 auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
129 result.observe(1, labelkv);
130 }
131
132 TEST(Meter, CollectAsyncInstruments)
133 {
134 // Verify that the records returned on a call to Collect() are correct for asynchronous
135 // instruments.
136 Meter m("Test");
137
138 ASSERT_EQ(m.Collect().size(), 0);
139
140 auto sumobs =
141 m.NewShortSumObserver("Test-counter", "For testing", "Unitless", true, &ShortCallback);
142
143 std::map<std::string, std::string> labels = {{"Key", "Value"}};
144 auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
145
146 sumobs->observe(1, labelkv);
147
148 std::vector<Record> res = m.Collect();
149 auto agg_var = res[0].GetAggregator();
150 auto agg = nostd::get<0>(agg_var);
151
152 ASSERT_EQ(agg->get_checkpoint()[0], 1);
153
154 // Now call observe() and Collect() again to ensure that the value in the underlying
155 // aggregator was reset to the default.
156
157 sumobs->observe(10, labelkv);
158
159 res = m.Collect();
160 agg_var = res[0].GetAggregator();
161 agg = nostd::get<0>(agg_var);
162
163 ASSERT_EQ(agg->get_checkpoint()[0], 10);
164 }
165
166 TEST(Meter, CollectDeletedAsync)
167 {
168 // Verify that calling Collect() after creating an asynchronous instrument and destroying
169 // the return pointer does not result in a segfault.
170
171 Meter m("Test");
172
173 ASSERT_EQ(m.Collect().size(), 0);
174
175 std::map<std::string, std::string> labels = {{"Key", "Value"}};
176 auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
177 {
178 auto sumobs = m.NewShortSumObserver("Test-counter", "For testing", "Unitless", true, &Callback);
179 sumobs->observe(1, labelkv);
180 } // sumobs shared_ptr deleted here
181
182 std::vector<Record> res = m.Collect();
183 auto agg_var = res[0].GetAggregator();
184 auto agg = nostd::get<0>(agg_var);
185
186 ASSERT_EQ(agg->get_checkpoint()[0], 1);
187 }
188
189 TEST(Meter, RecordBatch)
190 {
191 // This tests that RecordBatch appropriately updates the aggregators of the instruments
192 // passed to the function. Short, int, float, and double data types are tested.
193 Meter m("Test");
194
195 auto scounter = m.NewShortCounter("Test-scounter", "For testing", "Unitless", true);
196 auto icounter = m.NewIntCounter("Test-icounter", "For testing", "Unitless", true);
197 auto fcounter = m.NewFloatCounter("Test-fcounter", "For testing", "Unitless", true);
198 auto dcounter = m.NewDoubleCounter("Test-dcounter", "For testing", "Unitless", true);
199
200 std::map<std::string, std::string> labels = {{"Key", "Value"}};
201 auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
202
203 metrics_api::SynchronousInstrument<short> *sinstr_arr[] = {scounter.get()};
204 short svalues_arr[] = {1};
205
206 nostd::span<metrics_api::SynchronousInstrument<short> *> sinstrs{sinstr_arr};
207 nostd::span<const short, 1> svalues{svalues_arr};
208
209 m.RecordShortBatch(labelkv, sinstrs, svalues);
210 std::vector<Record> res = m.Collect();
211 auto short_agg_var = res[0].GetAggregator();
212 auto short_agg = nostd::get<0>(short_agg_var);
213 ASSERT_EQ(short_agg->get_checkpoint()[0], 1);
214
215 metrics_api::SynchronousInstrument<int> *iinstr_arr[] = {icounter.get()};
216 int ivalues_arr[] = {1};
217
218 nostd::span<metrics_api::SynchronousInstrument<int> *> iinstrs{iinstr_arr};
219 nostd::span<const int, 1> ivalues{ivalues_arr};
220
221 m.RecordIntBatch(labelkv, iinstrs, ivalues);
222 res = m.Collect();
223 auto int_agg_var = res[0].GetAggregator();
224 auto int_agg = nostd::get<1>(int_agg_var);
225 ASSERT_EQ(int_agg->get_checkpoint()[0], 1);
226
227 metrics_api::SynchronousInstrument<float> *finstr_arr[] = {fcounter.get()};
228 float fvalues_arr[] = {1.0};
229
230 nostd::span<metrics_api::SynchronousInstrument<float> *> finstrs{finstr_arr};
231 nostd::span<const float, 1> fvalues{fvalues_arr};
232
233 m.RecordFloatBatch(labelkv, finstrs, fvalues);
234 res = m.Collect();
235 auto float_agg_var = res[0].GetAggregator();
236 auto float_agg = nostd::get<2>(float_agg_var);
237 ASSERT_EQ(float_agg->get_checkpoint()[0], 1.0);
238
239 metrics_api::SynchronousInstrument<double> *dinstr_arr[] = {dcounter.get()};
240 double dvalues_arr[] = {1.0};
241
242 nostd::span<metrics_api::SynchronousInstrument<double> *> dinstrs{dinstr_arr};
243 nostd::span<const double, 1> dvalues{dvalues_arr};
244
245 m.RecordDoubleBatch(labelkv, dinstrs, dvalues);
246 res = m.Collect();
247 auto double_agg_var = res[0].GetAggregator();
248 auto double_agg = nostd::get<3>(double_agg_var);
249 ASSERT_EQ(double_agg->get_checkpoint()[0], 1.0);
250 }
251
252 TEST(Meter, DisableCollectSync)
253 {
254 Meter m("Test");
255 std::map<std::string, std::string> labels = {{"Key", "Value"}};
256 auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
257 auto c = m.NewShortCounter("c", "", "", false);
258 c->add(1, labelkv);
259 ASSERT_EQ(m.Collect().size(), 0);
260 }
261
262 TEST(Meter, DisableCollectAsync)
263 {
264 Meter m("Test");
265 std::map<std::string, std::string> labels = {{"Key", "Value"}};
266 auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
267 auto c = m.NewShortValueObserver("c", "", "", false, &ShortCallback);
268 c->observe(1, labelkv);
269 ASSERT_EQ(m.Collect().size(), 0);
270 }
271
272 TEST(MeterStringUtil, IsValid)
273 {
274 # if __EXCEPTIONS
275 Meter m("Test");
276 ASSERT_ANY_THROW(m.NewShortCounter("", "Empty name is invalid", " ", true));
277 ASSERT_ANY_THROW(m.NewShortCounter("1a", "Can't begin with a number", " ", true));
278 ASSERT_ANY_THROW(m.NewShortCounter(".a", "Can't begin with punctuation", " ", true));
279 ASSERT_ANY_THROW(m.NewShortCounter(" a", "Can't begin with space", " ", true));
280 ASSERT_ANY_THROW(m.NewShortCounter(
281 "te^ s=%t", "Only alphanumeric ., -, and _ characters are allowed", " ", true));
282 # endif
283 }
284
285 TEST(MeterStringUtil, AlreadyExists)
286 {
287 # if __EXCEPTIONS
288 Meter m("Test");
289
290 m.NewShortCounter("a", "First instance of instrument named 'a'", "", true);
291 ASSERT_ANY_THROW(m.NewShortCounter("a", "Second (illegal) instrument named 'a'", "", true));
292 ASSERT_ANY_THROW(m.NewShortSumObserver("a", "Still illegal even though it is not a short counter",
293 "", true, &ShortCallback));
294 # endif
295 }
296 OPENTELEMETRY_END_NAMESPACE
297 #endif