shim_utils_test.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * Copyright The OpenTelemetry Authors
  3. * SPDX-License-Identifier: Apache-2.0
  4. */
  5. #include <gtest/gtest.h>
  6. #include <stdint.h>
  7. #include <algorithm>
  8. #include <chrono>
  9. #include <map>
  10. #include <string>
  11. #include <tuple>
  12. #include <utility>
  13. #include <vector>
  14. #include "opentracing/propagation.h"
  15. #include "opentracing/span.h"
  16. #include "opentracing/string_view.h"
  17. #include "opentracing/tracer.h"
  18. #include "opentracing/util.h"
  19. #include "opentracing/value.h"
  20. #include "opentracing/variant/recursive_wrapper.hpp"
  21. #include "opentelemetry/baggage/baggage.h"
  22. #include "opentelemetry/baggage/baggage_context.h"
  23. #include "opentelemetry/common/attribute_value.h"
  24. #include "opentelemetry/common/key_value_iterable.h"
  25. #include "opentelemetry/common/timestamp.h"
  26. #include "opentelemetry/context/runtime_context.h"
  27. #include "opentelemetry/nostd/function_ref.h"
  28. #include "opentelemetry/nostd/shared_ptr.h"
  29. #include "opentelemetry/nostd/string_view.h"
  30. #include "opentelemetry/nostd/variant.h"
  31. #include "opentelemetry/opentracingshim/shim_utils.h"
  32. #include "opentelemetry/opentracingshim/span_context_shim.h"
  33. #include "opentelemetry/trace/span_context.h"
  34. #include "opentelemetry/trace/span_startoptions.h"
  35. #include "shim_mocks.h"
  36. namespace trace_api = opentelemetry::trace;
  37. namespace baggage = opentelemetry::baggage;
  38. namespace common = opentelemetry::common;
  39. namespace nostd = opentelemetry::nostd;
  40. namespace shim = opentelemetry::opentracingshim;
  41. TEST(ShimUtilsTest, IsBaggageEmpty)
  42. {
  43. auto none = nostd::shared_ptr<baggage::Baggage>(nullptr);
  44. ASSERT_TRUE(shim::utils::isBaggageEmpty(none));
  45. auto empty = nostd::shared_ptr<baggage::Baggage>(new baggage::Baggage({}));
  46. ASSERT_TRUE(shim::utils::isBaggageEmpty(empty));
  47. std::map<std::string, std::string> list{{"foo", "bar"}};
  48. auto non_empty = nostd::shared_ptr<baggage::Baggage>(new baggage::Baggage(list));
  49. ASSERT_FALSE(shim::utils::isBaggageEmpty(non_empty));
  50. }
  51. TEST(ShimUtilsTest, StringFromValue)
  52. {
  53. ASSERT_EQ(shim::utils::stringFromValue(true), "true");
  54. ASSERT_EQ(shim::utils::stringFromValue(false), "false");
  55. ASSERT_EQ(shim::utils::stringFromValue(1234.567890), "1234.567890");
  56. ASSERT_EQ(shim::utils::stringFromValue(42l), "42");
  57. ASSERT_EQ(shim::utils::stringFromValue(55ul), "55");
  58. ASSERT_EQ(shim::utils::stringFromValue(std::string{"a string"}), "a string");
  59. ASSERT_EQ(shim::utils::stringFromValue(opentracing::string_view{"a string view"}),
  60. "a string view");
  61. ASSERT_EQ(shim::utils::stringFromValue(nullptr), "");
  62. ASSERT_EQ(shim::utils::stringFromValue("a char ptr"), "a char ptr");
  63. opentracing::util::recursive_wrapper<opentracing::Values> values{};
  64. ASSERT_EQ(shim::utils::stringFromValue(values.get()), "");
  65. opentracing::util::recursive_wrapper<opentracing::Dictionary> dict{};
  66. ASSERT_EQ(shim::utils::stringFromValue(dict.get()), "");
  67. }
  68. TEST(ShimUtilsTest, AttributeFromValue)
  69. {
  70. auto value = shim::utils::attributeFromValue(true);
  71. ASSERT_EQ(value.index(), common::AttributeType::kTypeBool);
  72. ASSERT_TRUE(nostd::get<bool>(value));
  73. value = shim::utils::attributeFromValue(false);
  74. ASSERT_EQ(value.index(), common::AttributeType::kTypeBool);
  75. ASSERT_FALSE(nostd::get<bool>(value));
  76. value = shim::utils::attributeFromValue(1234.567890);
  77. ASSERT_EQ(value.index(), common::AttributeType::kTypeDouble);
  78. ASSERT_EQ(nostd::get<double>(value), 1234.567890);
  79. value = shim::utils::attributeFromValue(42l);
  80. ASSERT_EQ(value.index(), common::AttributeType::kTypeInt64);
  81. ASSERT_EQ(nostd::get<int64_t>(value), 42l);
  82. value = shim::utils::attributeFromValue(55ul);
  83. ASSERT_EQ(value.index(), common::AttributeType::kTypeUInt64);
  84. ASSERT_EQ(nostd::get<uint64_t>(value), 55ul);
  85. opentracing::Value str{std::string{"a string"}};
  86. value = shim::utils::attributeFromValue(str);
  87. ASSERT_EQ(value.index(), common::AttributeType::kTypeString);
  88. ASSERT_EQ(nostd::get<nostd::string_view>(value), nostd::string_view{"a string"});
  89. value = shim::utils::attributeFromValue(opentracing::string_view{"a string view"});
  90. ASSERT_EQ(value.index(), common::AttributeType::kTypeString);
  91. ASSERT_EQ(nostd::get<nostd::string_view>(value), nostd::string_view{"a string view"});
  92. value = shim::utils::attributeFromValue(nullptr);
  93. ASSERT_EQ(value.index(), common::AttributeType::kTypeString);
  94. ASSERT_EQ(nostd::get<nostd::string_view>(value), nostd::string_view{});
  95. value = shim::utils::attributeFromValue("a char ptr");
  96. ASSERT_EQ(value.index(), common::AttributeType::kTypeCString);
  97. ASSERT_EQ(nostd::get<const char *>(value), "a char ptr");
  98. opentracing::util::recursive_wrapper<opentracing::Values> values{};
  99. value = shim::utils::attributeFromValue(values.get());
  100. ASSERT_EQ(value.index(), common::AttributeType::kTypeString);
  101. ASSERT_EQ(nostd::get<nostd::string_view>(value), nostd::string_view{});
  102. opentracing::util::recursive_wrapper<opentracing::Dictionary> dict{};
  103. value = shim::utils::attributeFromValue(dict.get());
  104. ASSERT_EQ(value.index(), common::AttributeType::kTypeString);
  105. ASSERT_EQ(nostd::get<nostd::string_view>(value), nostd::string_view{});
  106. }
  107. TEST(ShimUtilsTest, MakeOptionsShim_EmptyRefs)
  108. {
  109. opentracing::StartSpanOptions options;
  110. options.start_system_timestamp = opentracing::SystemTime::time_point::clock::now();
  111. options.start_steady_timestamp = opentracing::SteadyTime::time_point::clock::now();
  112. auto options_shim = shim::utils::makeOptionsShim(options);
  113. ASSERT_EQ(options_shim.start_system_time,
  114. common::SystemTimestamp{options.start_system_timestamp});
  115. ASSERT_EQ(options_shim.start_steady_time,
  116. common::SteadyTimestamp{options.start_steady_timestamp});
  117. ASSERT_EQ(nostd::get<trace_api::SpanContext>(options_shim.parent),
  118. trace_api::SpanContext::GetInvalid());
  119. }
  120. TEST(ShimUtilsTest, MakeOptionsShim_InvalidSpanContext)
  121. {
  122. opentracing::StartSpanOptions options;
  123. options.start_system_timestamp = opentracing::SystemTime::time_point::clock::now();
  124. options.start_steady_timestamp = opentracing::SteadyTime::time_point::clock::now();
  125. options.references = {{opentracing::SpanReferenceType::FollowsFromRef, nullptr}};
  126. auto options_shim = shim::utils::makeOptionsShim(options);
  127. ASSERT_EQ(options_shim.start_system_time,
  128. common::SystemTimestamp{options.start_system_timestamp});
  129. ASSERT_EQ(options_shim.start_steady_time,
  130. common::SteadyTimestamp{options.start_steady_timestamp});
  131. ASSERT_EQ(nostd::get<trace_api::SpanContext>(options_shim.parent),
  132. trace_api::SpanContext::GetInvalid());
  133. }
  134. TEST(ShimUtilsTest, MakeOptionsShim_FirstChildOf)
  135. {
  136. auto span_context_shim = nostd::shared_ptr<shim::SpanContextShim>(new shim::SpanContextShim(
  137. trace_api::SpanContext::GetInvalid(), baggage::Baggage::GetDefault()));
  138. auto span_context = static_cast<opentracing::SpanContext *>(span_context_shim.get());
  139. opentracing::StartSpanOptions options;
  140. options.start_system_timestamp = opentracing::SystemTime::time_point::clock::now();
  141. options.start_steady_timestamp = opentracing::SteadyTime::time_point::clock::now();
  142. options.references = {{opentracing::SpanReferenceType::FollowsFromRef, nullptr},
  143. {opentracing::SpanReferenceType::ChildOfRef, span_context},
  144. {opentracing::SpanReferenceType::ChildOfRef, nullptr}};
  145. auto options_shim = shim::utils::makeOptionsShim(options);
  146. ASSERT_EQ(options_shim.start_system_time,
  147. common::SystemTimestamp{options.start_system_timestamp});
  148. ASSERT_EQ(options_shim.start_steady_time,
  149. common::SteadyTimestamp{options.start_steady_timestamp});
  150. ASSERT_EQ(nostd::get<trace_api::SpanContext>(options_shim.parent), span_context_shim->context());
  151. }
  152. TEST(ShimUtilsTest, MakeOptionsShim_FirstInList)
  153. {
  154. auto span_context_shim = nostd::shared_ptr<shim::SpanContextShim>(new shim::SpanContextShim(
  155. trace_api::SpanContext::GetInvalid(), baggage::Baggage::GetDefault()));
  156. auto span_context = static_cast<opentracing::SpanContext *>(span_context_shim.get());
  157. opentracing::StartSpanOptions options;
  158. options.start_system_timestamp = opentracing::SystemTime::time_point::clock::now();
  159. options.start_steady_timestamp = opentracing::SteadyTime::time_point::clock::now();
  160. options.references = {{opentracing::SpanReferenceType::FollowsFromRef, span_context},
  161. {opentracing::SpanReferenceType::FollowsFromRef, nullptr}};
  162. auto options_shim = shim::utils::makeOptionsShim(options);
  163. ASSERT_EQ(options_shim.start_system_time,
  164. common::SystemTimestamp{options.start_system_timestamp});
  165. ASSERT_EQ(options_shim.start_steady_time,
  166. common::SteadyTimestamp{options.start_steady_timestamp});
  167. ASSERT_EQ(nostd::get<trace_api::SpanContext>(options_shim.parent), span_context_shim->context());
  168. }
  169. TEST(ShimUtilsTest, MakeIterableLinks)
  170. {
  171. auto span_context_shim1 = nostd::shared_ptr<shim::SpanContextShim>(new shim::SpanContextShim(
  172. trace_api::SpanContext::GetInvalid(), baggage::Baggage::GetDefault()));
  173. auto span_context1 = static_cast<opentracing::SpanContext *>(span_context_shim1.get());
  174. auto span_context_shim2 = nostd::shared_ptr<shim::SpanContextShim>(new shim::SpanContextShim(
  175. trace_api::SpanContext::GetInvalid(), baggage::Baggage::GetDefault()));
  176. auto span_context2 = static_cast<opentracing::SpanContext *>(span_context_shim2.get());
  177. opentracing::StartSpanOptions options;
  178. auto empty = shim::utils::makeIterableLinks(options);
  179. ASSERT_EQ(empty.size(), 0);
  180. options.references = {{opentracing::SpanReferenceType::FollowsFromRef, nullptr},
  181. {opentracing::SpanReferenceType::FollowsFromRef, span_context1},
  182. {opentracing::SpanReferenceType::ChildOfRef, span_context2}};
  183. auto full = shim::utils::makeIterableLinks(options);
  184. ASSERT_EQ(full.size(), 3);
  185. std::vector<std::tuple<trace_api::SpanContext, nostd::string_view, common::AttributeValue>> links;
  186. full.ForEachKeyValue([&links](trace_api::SpanContext ctx, const common::KeyValueIterable &it) {
  187. it.ForEachKeyValue([&links, &ctx](nostd::string_view key, common::AttributeValue value) {
  188. links.emplace_back(ctx, key, value);
  189. return false;
  190. });
  191. return true;
  192. });
  193. ASSERT_EQ(links.size(), 2);
  194. trace_api::SpanContext ctx = trace_api::SpanContext::GetInvalid();
  195. nostd::string_view key;
  196. common::AttributeValue value;
  197. std::tie(ctx, key, value) = links[0];
  198. ASSERT_EQ(ctx, span_context_shim1->context());
  199. ASSERT_EQ(key, "opentracing.ref_type");
  200. ASSERT_EQ(nostd::get<nostd::string_view>(value), "follows_from");
  201. std::tie(ctx, key, value) = links[1];
  202. ASSERT_EQ(ctx, span_context_shim2->context());
  203. ASSERT_EQ(key, "opentracing.ref_type");
  204. ASSERT_EQ(nostd::get<nostd::string_view>(value), "child_of");
  205. }
  206. TEST(ShimUtilsTest, MakeBaggage_EmptyRefs)
  207. {
  208. auto baggage = baggage::Baggage::GetDefault()->Set("foo", "bar");
  209. std::string value;
  210. ASSERT_TRUE(baggage->GetValue("foo", value));
  211. ASSERT_EQ(value, "bar");
  212. auto context = context::RuntimeContext::GetCurrent();
  213. auto new_context = baggage::SetBaggage(context, baggage);
  214. auto token = context::RuntimeContext::Attach(new_context);
  215. ASSERT_EQ(context::RuntimeContext::GetCurrent(), new_context);
  216. opentracing::StartSpanOptions options;
  217. auto new_baggage = shim::utils::makeBaggage(options);
  218. ASSERT_TRUE(new_baggage->GetValue("foo", value));
  219. ASSERT_EQ(value, "bar");
  220. }
  221. TEST(ShimUtilsTest, MakeBaggage_NonEmptyRefs)
  222. {
  223. auto span_context_shim1 = nostd::shared_ptr<shim::SpanContextShim>(new shim::SpanContextShim(
  224. trace_api::SpanContext::GetInvalid(),
  225. baggage::Baggage::GetDefault()->Set("test", "foo")->Set("test1", "hello")));
  226. auto span_context1 = static_cast<opentracing::SpanContext *>(span_context_shim1.get());
  227. auto span_context_shim2 = nostd::shared_ptr<shim::SpanContextShim>(new shim::SpanContextShim(
  228. trace_api::SpanContext::GetInvalid(),
  229. baggage::Baggage::GetDefault()->Set("test", "bar")->Set("test2", "world")));
  230. auto span_context2 = static_cast<opentracing::SpanContext *>(span_context_shim2.get());
  231. opentracing::StartSpanOptions options;
  232. options.references = {{opentracing::SpanReferenceType::FollowsFromRef, span_context1},
  233. {opentracing::SpanReferenceType::ChildOfRef, span_context2}};
  234. auto baggage = shim::utils::makeBaggage(options);
  235. std::string value;
  236. ASSERT_TRUE(baggage->GetValue("test", value));
  237. ASSERT_EQ(value, "foo");
  238. ASSERT_TRUE(baggage->GetValue("test1", value));
  239. ASSERT_EQ(value, "hello");
  240. ASSERT_TRUE(baggage->GetValue("test2", value));
  241. ASSERT_EQ(value, "world");
  242. }
  243. TEST(ShimUtilsTest, MakeIterableTags)
  244. {
  245. opentracing::StartSpanOptions options;
  246. auto empty = shim::utils::makeIterableTags(options);
  247. ASSERT_EQ(empty.size(), 0);
  248. options.tags = {{"foo", 42.0}, {"bar", true}, {"baz", "test"}};
  249. auto full = shim::utils::makeIterableTags(options);
  250. ASSERT_EQ(full.size(), 3);
  251. std::vector<std::pair<nostd::string_view, common::AttributeValue>> attributes;
  252. full.ForEachKeyValue([&attributes](nostd::string_view key, common::AttributeValue value) {
  253. attributes.push_back({key, value});
  254. return true;
  255. });
  256. ASSERT_EQ(attributes[0].first, "foo");
  257. ASSERT_EQ(nostd::get<double>(attributes[0].second), 42.0);
  258. ASSERT_EQ(attributes[1].first, "bar");
  259. ASSERT_TRUE(nostd::get<bool>(attributes[1].second));
  260. ASSERT_EQ(attributes[2].first, "baz");
  261. ASSERT_STREQ(nostd::get<const char *>(attributes[2].second), "test");
  262. }