2
0

meter_provider_sdk_test.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include <gtest/gtest.h>
  4. #include <utility>
  5. #include "common.h"
  6. #include "opentelemetry/common/macros.h"
  7. #include "opentelemetry/metrics/meter.h"
  8. #include "opentelemetry/nostd/shared_ptr.h"
  9. #include "opentelemetry/nostd/string_view.h"
  10. #include "opentelemetry/sdk/metrics/instruments.h"
  11. #include "opentelemetry/sdk/metrics/meter.h"
  12. #include "opentelemetry/sdk/metrics/meter_provider.h"
  13. #include "opentelemetry/sdk/metrics/meter_provider_factory.h"
  14. #include "opentelemetry/sdk/metrics/metric_reader.h"
  15. #include "opentelemetry/sdk/metrics/push_metric_exporter.h"
  16. #include "opentelemetry/sdk/metrics/view/instrument_selector.h"
  17. #include "opentelemetry/sdk/metrics/view/meter_selector.h"
  18. #include "opentelemetry/sdk/metrics/view/view.h"
  19. using namespace opentelemetry::sdk::metrics;
  20. TEST(MeterProvider, GetMeter)
  21. {
  22. MeterProvider mp1;
  23. // std::unique_ptr<View> view{std::unique_ptr<View>()};
  24. // MeterProvider mp1(std::move(exporters), std::move(readers), std::move(views);
  25. auto m1 = mp1.GetMeter("test");
  26. auto m2 = mp1.GetMeter("test");
  27. auto m3 = mp1.GetMeter("different", "1.0.0");
  28. auto m4 = mp1.GetMeter("");
  29. auto m5 = mp1.GetMeter(opentelemetry::nostd::string_view{});
  30. auto m6 = mp1.GetMeter("different", "1.0.0", "https://opentelemetry.io/schemas/1.2.0");
  31. ASSERT_NE(nullptr, m1);
  32. ASSERT_NE(nullptr, m2);
  33. ASSERT_NE(nullptr, m3);
  34. ASSERT_NE(nullptr, m6);
  35. // Should return the same instance each time.
  36. ASSERT_EQ(m1, m2);
  37. ASSERT_NE(m1, m3);
  38. ASSERT_EQ(m4, m5);
  39. ASSERT_NE(m3, m6);
  40. // Should be an sdk::metrics::Meter
  41. #ifdef OPENTELEMETRY_RTTI_ENABLED
  42. auto sdkMeter1 = dynamic_cast<Meter *>(m1.get());
  43. #else
  44. auto sdkMeter1 = static_cast<Meter *>(m1.get());
  45. #endif
  46. ASSERT_NE(nullptr, sdkMeter1);
  47. std::unique_ptr<MockMetricExporter> exporter(new MockMetricExporter());
  48. std::unique_ptr<MetricReader> reader{new MockMetricReader(std::move(exporter))};
  49. mp1.AddMetricReader(std::move(reader));
  50. std::unique_ptr<View> view{std::unique_ptr<View>()};
  51. std::unique_ptr<InstrumentSelector> instrument_selector{
  52. new InstrumentSelector(InstrumentType::kCounter, "instru1", "unit1")};
  53. std::unique_ptr<MeterSelector> meter_selector{new MeterSelector("name1", "version1", "schema1")};
  54. mp1.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view));
  55. // cleanup properly without crash
  56. mp1.ForceFlush();
  57. mp1.Shutdown();
  58. }
  59. #if OPENTELEMETRY_ABI_VERSION_NO >= 2
  60. TEST(MeterProvider, GetMeterAbiv2)
  61. {
  62. MeterProvider mp;
  63. auto m1 = mp.GetMeter("name1", "version1", "url1");
  64. ASSERT_NE(nullptr, m1);
  65. auto m2 = mp.GetMeter("name2", "version2", "url2", nullptr);
  66. ASSERT_NE(nullptr, m2);
  67. auto m3 = mp.GetMeter("name3", "version3", "url3", {{"accept_single_attr", true}});
  68. ASSERT_NE(nullptr, m3);
  69. {
  70. auto meter = static_cast<opentelemetry::sdk::metrics::Meter *>(m3.get());
  71. auto scope = meter->GetInstrumentationScope();
  72. auto attrs = scope->GetAttributes();
  73. ASSERT_EQ(attrs.size(), 1);
  74. auto attr = attrs.find("accept_single_attr");
  75. ASSERT_FALSE(attr == attrs.end());
  76. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<bool>(attr->second));
  77. EXPECT_EQ(opentelemetry::nostd::get<bool>(attr->second), true);
  78. }
  79. std::pair<opentelemetry::nostd::string_view, opentelemetry::common::AttributeValue> attr4 = {
  80. "accept_single_attr", true};
  81. auto m4 = mp.GetMeter("name4", "version4", "url4", {attr4});
  82. ASSERT_NE(nullptr, m4);
  83. {
  84. auto meter = static_cast<opentelemetry::sdk::metrics::Meter *>(m4.get());
  85. auto scope = meter->GetInstrumentationScope();
  86. auto attrs = scope->GetAttributes();
  87. ASSERT_EQ(attrs.size(), 1);
  88. auto attr = attrs.find("accept_single_attr");
  89. ASSERT_FALSE(attr == attrs.end());
  90. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<bool>(attr->second));
  91. EXPECT_EQ(opentelemetry::nostd::get<bool>(attr->second), true);
  92. }
  93. auto m5 = mp.GetMeter("name5", "version5", "url5", {{"foo", "1"}, {"bar", "2"}});
  94. ASSERT_NE(nullptr, m5);
  95. {
  96. auto meter = static_cast<opentelemetry::sdk::metrics::Meter *>(m5.get());
  97. auto scope = meter->GetInstrumentationScope();
  98. auto attrs = scope->GetAttributes();
  99. ASSERT_EQ(attrs.size(), 2);
  100. auto attr = attrs.find("bar");
  101. ASSERT_FALSE(attr == attrs.end());
  102. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::string>(attr->second));
  103. EXPECT_EQ(opentelemetry::nostd::get<std::string>(attr->second), "2");
  104. }
  105. std::initializer_list<
  106. std::pair<opentelemetry::nostd::string_view, opentelemetry::common::AttributeValue>>
  107. attrs6 = {{"foo", "1"}, {"bar", 42}};
  108. auto m6 = mp.GetMeter("name6", "version6", "url6", attrs6);
  109. ASSERT_NE(nullptr, m6);
  110. {
  111. auto meter = static_cast<opentelemetry::sdk::metrics::Meter *>(m6.get());
  112. auto scope = meter->GetInstrumentationScope();
  113. auto attrs = scope->GetAttributes();
  114. ASSERT_EQ(attrs.size(), 2);
  115. auto attr = attrs.find("bar");
  116. ASSERT_FALSE(attr == attrs.end());
  117. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<int>(attr->second));
  118. EXPECT_EQ(opentelemetry::nostd::get<int>(attr->second), 42);
  119. }
  120. typedef std::pair<opentelemetry::nostd::string_view, opentelemetry::common::AttributeValue> KV;
  121. std::initializer_list<KV> attrs7 = {{"foo", 3.14}, {"bar", "2"}};
  122. auto m7 = mp.GetMeter("name7", "version7", "url7", attrs7);
  123. ASSERT_NE(nullptr, m7);
  124. {
  125. auto meter = static_cast<opentelemetry::sdk::metrics::Meter *>(m7.get());
  126. auto scope = meter->GetInstrumentationScope();
  127. auto attrs = scope->GetAttributes();
  128. ASSERT_EQ(attrs.size(), 2);
  129. auto attr = attrs.find("foo");
  130. ASSERT_FALSE(attr == attrs.end());
  131. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<double>(attr->second));
  132. EXPECT_EQ(opentelemetry::nostd::get<double>(attr->second), 3.14);
  133. }
  134. auto m8 = mp.GetMeter("name8", "version8", "url8",
  135. {{"a", "string"},
  136. {"b", false},
  137. {"c", 314159},
  138. {"d", static_cast<unsigned int>(314159)},
  139. {"e", static_cast<int32_t>(-20)},
  140. {"f", static_cast<uint32_t>(20)},
  141. {"g", static_cast<int64_t>(-20)},
  142. {"h", static_cast<uint64_t>(20)},
  143. {"i", 3.1},
  144. {"j", "string"}});
  145. ASSERT_NE(nullptr, m8);
  146. {
  147. auto meter = static_cast<opentelemetry::sdk::metrics::Meter *>(m8.get());
  148. auto scope = meter->GetInstrumentationScope();
  149. auto attrs = scope->GetAttributes();
  150. ASSERT_EQ(attrs.size(), 10);
  151. auto attr = attrs.find("e");
  152. ASSERT_FALSE(attr == attrs.end());
  153. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<int32_t>(attr->second));
  154. EXPECT_EQ(opentelemetry::nostd::get<int32_t>(attr->second), -20);
  155. }
  156. std::map<std::string, opentelemetry::common::AttributeValue> attr9{
  157. {"a", "string"},
  158. {"b", false},
  159. {"c", 314159},
  160. {"d", static_cast<unsigned int>(314159)},
  161. {"e", static_cast<int32_t>(-20)},
  162. {"f", static_cast<uint32_t>(20)},
  163. {"g", static_cast<int64_t>(-20)},
  164. {"h", static_cast<uint64_t>(20)},
  165. {"i", 3.1},
  166. {"j", "string"}};
  167. auto m9 = mp.GetMeter("name9", "version9", "url9", attr9);
  168. ASSERT_NE(nullptr, m9);
  169. {
  170. auto meter = static_cast<opentelemetry::sdk::metrics::Meter *>(m9.get());
  171. auto scope = meter->GetInstrumentationScope();
  172. auto attrs = scope->GetAttributes();
  173. ASSERT_EQ(attrs.size(), 10);
  174. auto attr = attrs.find("h");
  175. ASSERT_FALSE(attr == attrs.end());
  176. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<uint64_t>(attr->second));
  177. EXPECT_EQ(opentelemetry::nostd::get<uint64_t>(attr->second), 20);
  178. }
  179. // cleanup properly without crash
  180. mp.ForceFlush();
  181. mp.Shutdown();
  182. }
  183. #endif /* OPENTELEMETRY_ABI_VERSION_NO >= 2 */
  184. #if OPENTELEMETRY_ABI_VERSION_NO >= 2
  185. TEST(MeterProvider, RemoveMeter)
  186. {
  187. MeterProvider mp;
  188. auto m1 = mp.GetMeter("test", "1", "URL");
  189. ASSERT_NE(nullptr, m1);
  190. // Will return the same meter
  191. auto m2 = mp.GetMeter("test", "1", "URL");
  192. ASSERT_NE(nullptr, m2);
  193. ASSERT_EQ(m1, m2);
  194. mp.RemoveMeter("unknown", "0", "");
  195. // Will decrease use_count() on m1 and m2
  196. mp.RemoveMeter("test", "1", "URL");
  197. // Will create a different meter
  198. auto m3 = mp.GetMeter("test", "1", "URL");
  199. ASSERT_NE(nullptr, m3);
  200. ASSERT_NE(m1, m3);
  201. ASSERT_NE(m2, m3);
  202. // Will decrease use_count() on m3
  203. mp.RemoveMeter("test", "1", "URL");
  204. // Will do nothing
  205. mp.RemoveMeter("test", "1", "URL");
  206. // cleanup properly without crash
  207. mp.ForceFlush();
  208. mp.Shutdown();
  209. }
  210. #endif /* OPENTELEMETRY_ABI_VERSION_NO >= 2 */
  211. TEST(MeterProvider, GetMeterEqualityCheck)
  212. {
  213. auto provider = MeterProviderFactory::Create();
  214. // providing the same scope names should return the same Meter
  215. auto meter_library_1a = provider->GetMeter("library_name");
  216. auto meter_library_1b = provider->GetMeter("library_name");
  217. EXPECT_EQ(meter_library_1a, meter_library_1b);
  218. // providing the same scope name and version should return the same meter
  219. auto meter_version_1a = provider->GetMeter("library_name", "v1.0");
  220. auto meter_version_1b = provider->GetMeter("library_name", "v1.0");
  221. EXPECT_EQ(meter_version_1a, meter_version_1b);
  222. // providing the same name, version, and schema urls should return the same meter
  223. auto meter_urla = provider->GetMeter("library_name", "v1.0", "url");
  224. auto meter_urlb = provider->GetMeter("library_name", "v1.0", "url");
  225. EXPECT_EQ(meter_urla, meter_urlb);
  226. }
  227. TEST(MeterProvider, GetMeterInequalityCheck)
  228. {
  229. auto provider = MeterProviderFactory::Create();
  230. auto meter_library_1 = provider->GetMeter("library_1");
  231. auto meter_library_2 = provider->GetMeter("library_2");
  232. auto meter_version_1 = provider->GetMeter("library_1", "v1.0");
  233. auto meter_version_2 = provider->GetMeter("library_1", "v2.0");
  234. auto meter_url_1 = provider->GetMeter("library_1", "v1.0", "url_1");
  235. auto meter_url_2 = provider->GetMeter("library_1", "v1.0", "url_2");
  236. // different scope names should return distinct meters
  237. EXPECT_NE(meter_library_1, meter_library_2);
  238. // different scope versions should return distinct meters
  239. EXPECT_NE(meter_version_1, meter_library_1);
  240. EXPECT_NE(meter_version_1, meter_version_2);
  241. // different scope schema urls should return distinct meters
  242. EXPECT_NE(meter_url_1, meter_library_1);
  243. EXPECT_NE(meter_url_1, meter_version_1);
  244. EXPECT_NE(meter_url_1, meter_url_2);
  245. }
  246. #if OPENTELEMETRY_ABI_VERSION_NO >= 2
  247. TEST(MeterProvider, GetMeterEqualityCheckAbiv2)
  248. {
  249. auto provider = MeterProviderFactory::Create();
  250. // providing the same name, version, schema url and attributes should return the same meter
  251. auto meter_attribute1a = provider->GetMeter("library_name", "v1.0", "url", {{"key", "one"}});
  252. auto meter_attribute1b = provider->GetMeter("library_name", "v1.0", "url", {{"key", "one"}});
  253. EXPECT_EQ(meter_attribute1a, meter_attribute1b);
  254. }
  255. TEST(MeterProvider, GetMeterInequalityCheckAbiv2)
  256. {
  257. auto provider = MeterProviderFactory::Create();
  258. auto meter_1 = provider->GetMeter("library_name", "v1.0", "url");
  259. auto meter_attribute_1 = provider->GetMeter("library_name", "v1.0", "url", {{"key", "one"}});
  260. auto meter_attribute_2 = provider->GetMeter("library_name", "v1.0", "url", {{"key", "two"}});
  261. // different scope attributes should return distinct meters
  262. EXPECT_NE(meter_attribute_1, meter_1);
  263. EXPECT_NE(meter_attribute_1, meter_attribute_2);
  264. }
  265. #endif /* OPENTELEMETRY_ABI_VERSION_NO >= 2 */