1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
4 #ifdef ENABLE_METRICS_PREVIEW
5 # include "opentelemetry/sdk/_metrics/aggregator/histogram_aggregator.h"
7 # include <gtest/gtest.h>
14 namespace metrics_api
= opentelemetry::metrics
;
16 OPENTELEMETRY_BEGIN_NAMESPACE
22 // Test updating with a uniform set of updates
23 TEST(Histogram
, Uniform
)
25 std::vector
<double> boundaries
{10, 20, 30, 40, 50};
26 HistogramAggregator
<int> alpha(metrics_api::InstrumentKind::Counter
, boundaries
);
28 EXPECT_EQ(alpha
.get_aggregator_kind(), AggregatorKind::Histogram
);
31 EXPECT_EQ(alpha
.get_checkpoint().size(), 2);
32 EXPECT_EQ(alpha
.get_counts().size(), 6);
34 for (int i
= 0; i
< 60; i
++)
41 EXPECT_EQ(alpha
.get_checkpoint()[0], 1770);
42 EXPECT_EQ(alpha
.get_checkpoint()[1], 60);
44 std::vector
<int> correct
= {10, 10, 10, 10, 10, 10};
45 EXPECT_EQ(alpha
.get_counts(), correct
);
48 // Test updating with a normal distribution
49 TEST(Histogram
, Normal
)
51 std::vector
<double> boundaries
{2, 4, 6, 8, 10, 12};
52 HistogramAggregator
<int> alpha(metrics_api::InstrumentKind::Counter
, boundaries
);
54 std::vector
<int> vals
{1, 3, 3, 5, 5, 5, 7, 7, 7, 7, 9, 9, 9, 11, 11, 13};
62 EXPECT_EQ(alpha
.get_checkpoint()[0], std::accumulate(vals
.begin(), vals
.end(), 0));
63 EXPECT_EQ(alpha
.get_checkpoint()[1], vals
.size());
65 std::vector
<int> correct
= {1, 2, 3, 4, 3, 2, 1};
66 EXPECT_EQ(alpha
.get_counts(), correct
);
69 TEST(Histogram
, Merge
)
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
);
75 std::vector
<int> vals
{1, 3, 3, 5, 5, 5, 7, 7, 7, 7, 9, 9, 9, 11, 11, 13};
81 std::vector
<int> otherVals
{1, 1, 1, 1, 11, 11, 13, 13, 13, 15};
82 for (int i
: otherVals
)
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());
94 std::vector
<int> correct
= {5, 2, 3, 4, 3, 4, 5};
95 EXPECT_EQ(alpha
.get_counts(), correct
);
98 // Update callback used to validate multi-threaded performance
99 void histogramUpdateCallback(Aggregator
<int> &agg
, std::vector
<int> vals
)
112 TEST(Histogram
, Concurrency
)
114 std::vector
<double> boundaries
{2, 4, 6, 8, 10, 12};
115 HistogramAggregator
<int> alpha(metrics_api::InstrumentKind::Counter
, boundaries
);
117 std::vector
<int> vals1(1000);
118 std::generate(vals1
.begin(), vals1
.end(), randVal
);
120 std::vector
<int> vals2(1000);
121 std::generate(vals2
.begin(), vals2
.end(), randVal
);
123 std::thread
first(histogramUpdateCallback
, std::ref(alpha
), vals1
);
124 std::thread
second(histogramUpdateCallback
, std::ref(alpha
), vals2
);
129 HistogramAggregator
<int> beta(metrics_api::InstrumentKind::Counter
, boundaries
);
131 // Timing harness to compare linear and binary insertion
132 // auto start = std::chrono::system_clock::now();
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;
148 EXPECT_EQ(alpha
.get_checkpoint(), beta
.get_checkpoint());
149 EXPECT_EQ(alpha
.get_counts(), beta
.get_counts());
154 TEST(Histogram
, Errors
)
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};
160 HistogramAggregator
<int> alpha(metrics_api::InstrumentKind::Counter
, unsortedBoundaries
));
162 HistogramAggregator
<int> beta(metrics_api::InstrumentKind::Counter
, boundaries
);
163 HistogramAggregator
<int> gamma(metrics_api::InstrumentKind::Counter
, boundaries2
);
165 EXPECT_ANY_THROW(beta
.merge(gamma
));
170 } // namespace metrics
172 OPENTELEMETRY_END_NAMESPACE