]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/sdk/test/_metrics/histogram_aggregator_test.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / sdk / test / _metrics / histogram_aggregator_test.cc
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3
4 #ifdef ENABLE_METRICS_PREVIEW
5 # include "opentelemetry/sdk/_metrics/aggregator/histogram_aggregator.h"
6
7 # include <gtest/gtest.h>
8 # include <iostream>
9 # include <numeric>
10 # include <thread>
11
12 // #include <chrono>
13
14 namespace metrics_api = opentelemetry::metrics;
15
16 OPENTELEMETRY_BEGIN_NAMESPACE
17 namespace sdk
18 {
19 namespace metrics
20 {
21
22 // Test updating with a uniform set of updates
23 TEST(Histogram, Uniform)
24 {
25 std::vector<double> boundaries{10, 20, 30, 40, 50};
26 HistogramAggregator<int> alpha(metrics_api::InstrumentKind::Counter, boundaries);
27
28 EXPECT_EQ(alpha.get_aggregator_kind(), AggregatorKind::Histogram);
29
30 alpha.checkpoint();
31 EXPECT_EQ(alpha.get_checkpoint().size(), 2);
32 EXPECT_EQ(alpha.get_counts().size(), 6);
33
34 for (int i = 0; i < 60; i++)
35 {
36 alpha.update(i);
37 }
38
39 alpha.checkpoint();
40
41 EXPECT_EQ(alpha.get_checkpoint()[0], 1770);
42 EXPECT_EQ(alpha.get_checkpoint()[1], 60);
43
44 std::vector<int> correct = {10, 10, 10, 10, 10, 10};
45 EXPECT_EQ(alpha.get_counts(), correct);
46 }
47
48 // Test updating with a normal distribution
49 TEST(Histogram, Normal)
50 {
51 std::vector<double> boundaries{2, 4, 6, 8, 10, 12};
52 HistogramAggregator<int> alpha(metrics_api::InstrumentKind::Counter, boundaries);
53
54 std::vector<int> vals{1, 3, 3, 5, 5, 5, 7, 7, 7, 7, 9, 9, 9, 11, 11, 13};
55 for (int i : vals)
56 {
57 alpha.update(i);
58 }
59
60 alpha.checkpoint();
61
62 EXPECT_EQ(alpha.get_checkpoint()[0], std::accumulate(vals.begin(), vals.end(), 0));
63 EXPECT_EQ(alpha.get_checkpoint()[1], vals.size());
64
65 std::vector<int> correct = {1, 2, 3, 4, 3, 2, 1};
66 EXPECT_EQ(alpha.get_counts(), correct);
67 }
68
69 TEST(Histogram, Merge)
70 {
71 std::vector<double> boundaries{2, 4, 6, 8, 10, 12};
72 HistogramAggregator<int> alpha(metrics_api::InstrumentKind::Counter, boundaries);
73 HistogramAggregator<int> beta(metrics_api::InstrumentKind::Counter, boundaries);
74
75 std::vector<int> vals{1, 3, 3, 5, 5, 5, 7, 7, 7, 7, 9, 9, 9, 11, 11, 13};
76 for (int i : vals)
77 {
78 alpha.update(i);
79 }
80
81 std::vector<int> otherVals{1, 1, 1, 1, 11, 11, 13, 13, 13, 15};
82 for (int i : otherVals)
83 {
84 beta.update(i);
85 }
86
87 alpha.merge(beta);
88 alpha.checkpoint();
89
90 EXPECT_EQ(alpha.get_checkpoint()[0], std::accumulate(vals.begin(), vals.end(), 0) +
91 std::accumulate(otherVals.begin(), otherVals.end(), 0));
92 EXPECT_EQ(alpha.get_checkpoint()[1], vals.size() + otherVals.size());
93
94 std::vector<int> correct = {5, 2, 3, 4, 3, 4, 5};
95 EXPECT_EQ(alpha.get_counts(), correct);
96 }
97
98 // Update callback used to validate multi-threaded performance
99 void histogramUpdateCallback(Aggregator<int> &agg, std::vector<int> vals)
100 {
101 for (int i : vals)
102 {
103 agg.update(i);
104 }
105 }
106
107 int randVal()
108 {
109 return rand() % 15;
110 }
111
112 TEST(Histogram, Concurrency)
113 {
114 std::vector<double> boundaries{2, 4, 6, 8, 10, 12};
115 HistogramAggregator<int> alpha(metrics_api::InstrumentKind::Counter, boundaries);
116
117 std::vector<int> vals1(1000);
118 std::generate(vals1.begin(), vals1.end(), randVal);
119
120 std::vector<int> vals2(1000);
121 std::generate(vals2.begin(), vals2.end(), randVal);
122
123 std::thread first(histogramUpdateCallback, std::ref(alpha), vals1);
124 std::thread second(histogramUpdateCallback, std::ref(alpha), vals2);
125
126 first.join();
127 second.join();
128
129 HistogramAggregator<int> beta(metrics_api::InstrumentKind::Counter, boundaries);
130
131 // Timing harness to compare linear and binary insertion
132 // auto start = std::chrono::system_clock::now();
133 for (int i : vals1)
134 {
135 beta.update(i);
136 }
137 for (int i : vals2)
138 {
139 beta.update(i);
140 }
141 // auto end = std::chrono::system_clock::now();
142 // auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
143 // std::cout <<"Update time: " <<elapsed.count() <<std::endl;
144
145 alpha.checkpoint();
146 beta.checkpoint();
147
148 EXPECT_EQ(alpha.get_checkpoint(), beta.get_checkpoint());
149 EXPECT_EQ(alpha.get_counts(), beta.get_counts());
150 }
151
152 # if __EXCEPTIONS
153
154 TEST(Histogram, Errors)
155 {
156 std::vector<double> boundaries{2, 4, 6, 8, 10, 12};
157 std::vector<double> boundaries2{1, 4, 6, 8, 10, 12};
158 std::vector<double> unsortedBoundaries{10, 12, 4, 6, 8};
159 EXPECT_ANY_THROW(
160 HistogramAggregator<int> alpha(metrics_api::InstrumentKind::Counter, unsortedBoundaries));
161
162 HistogramAggregator<int> beta(metrics_api::InstrumentKind::Counter, boundaries);
163 HistogramAggregator<int> gamma(metrics_api::InstrumentKind::Counter, boundaries2);
164
165 EXPECT_ANY_THROW(beta.merge(gamma));
166 }
167
168 # endif
169
170 } // namespace metrics
171 } // namespace sdk
172 OPENTELEMETRY_END_NAMESPACE
173 #endif