span_shim_test.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  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 <functional>
  10. #include <initializer_list>
  11. #include <string>
  12. #include <thread>
  13. #include <tuple>
  14. #include <unordered_map>
  15. #include <utility>
  16. #include <vector>
  17. #include "opentracing/span.h"
  18. #include "opentracing/string_view.h"
  19. #include "opentracing/util.h"
  20. #include "opentracing/value.h"
  21. #include "opentelemetry/baggage/baggage.h"
  22. #include "opentelemetry/common/attribute_value.h"
  23. #include "opentelemetry/common/timestamp.h"
  24. #include "opentelemetry/nostd/shared_ptr.h"
  25. #include "opentelemetry/nostd/string_view.h"
  26. #include "opentelemetry/nostd/unique_ptr.h"
  27. #include "opentelemetry/nostd/variant.h"
  28. #include "opentelemetry/opentracingshim/span_shim.h"
  29. #include "opentelemetry/opentracingshim/tracer_shim.h"
  30. #include "opentelemetry/trace/span.h"
  31. #include "opentelemetry/trace/span_metadata.h"
  32. #include "shim_mocks.h"
  33. namespace trace_api = opentelemetry::trace;
  34. namespace baggage = opentelemetry::baggage;
  35. namespace nostd = opentelemetry::nostd;
  36. namespace shim = opentelemetry::opentracingshim;
  37. class SpanShimTest : public testing::Test
  38. {
  39. public:
  40. nostd::unique_ptr<shim::SpanShim> span_shim;
  41. MockSpan *mock_span;
  42. protected:
  43. virtual void SetUp() override
  44. {
  45. mock_span = new MockSpan();
  46. auto span = nostd::shared_ptr<trace_api::Span>(mock_span);
  47. auto tracer = shim::TracerShim::createTracerShim();
  48. auto tracer_shim = static_cast<shim::TracerShim *>(tracer.get());
  49. auto baggage = baggage::Baggage::GetDefault()->Set("baggage", "item");
  50. span_shim = nostd::unique_ptr<shim::SpanShim>(new shim::SpanShim(*tracer_shim, span, baggage));
  51. }
  52. virtual void TearDown() override { span_shim.reset(); }
  53. };
  54. TEST_F(SpanShimTest, HandleError)
  55. {
  56. span_shim->handleError(true);
  57. ASSERT_EQ(mock_span->status_.first, trace_api::StatusCode::kError);
  58. span_shim->handleError("true");
  59. ASSERT_EQ(mock_span->status_.first, trace_api::StatusCode::kError);
  60. span_shim->handleError(false);
  61. ASSERT_EQ(mock_span->status_.first, trace_api::StatusCode::kOk);
  62. span_shim->handleError("false");
  63. ASSERT_EQ(mock_span->status_.first, trace_api::StatusCode::kOk);
  64. span_shim->handleError(nullptr);
  65. ASSERT_EQ(mock_span->status_.first, trace_api::StatusCode::kUnset);
  66. span_shim->handleError("unknown");
  67. ASSERT_EQ(mock_span->status_.first, trace_api::StatusCode::kUnset);
  68. span_shim->handleError(42);
  69. ASSERT_EQ(mock_span->status_.first, trace_api::StatusCode::kUnset);
  70. }
  71. TEST_F(SpanShimTest, FinishWithOptions)
  72. {
  73. opentracing::FinishSpanOptions options;
  74. options.finish_steady_timestamp = opentracing::SteadyTime::clock::now();
  75. ASSERT_NE(mock_span->options_.end_steady_time, options.finish_steady_timestamp);
  76. span_shim->FinishWithOptions(options);
  77. ASSERT_EQ(mock_span->options_.end_steady_time, options.finish_steady_timestamp);
  78. }
  79. TEST_F(SpanShimTest, SetOperationName)
  80. {
  81. ASSERT_NE(mock_span->name_, "foo");
  82. span_shim->SetOperationName("foo");
  83. ASSERT_EQ(mock_span->name_, "foo");
  84. }
  85. TEST_F(SpanShimTest, SetTag_Normal)
  86. {
  87. ASSERT_NE(mock_span->attribute_.first, "foo");
  88. span_shim->SetTag("foo", "bar");
  89. ASSERT_EQ(mock_span->attribute_.first, "foo");
  90. ASSERT_STREQ(nostd::get<const char *>(mock_span->attribute_.second), "bar");
  91. }
  92. TEST_F(SpanShimTest, SetTag_Error)
  93. {
  94. ASSERT_NE(mock_span->attribute_.first, "error");
  95. span_shim->SetTag("error", true);
  96. ASSERT_NE(mock_span->attribute_.first, "error");
  97. span_shim->SetTag("error", "false");
  98. ASSERT_NE(mock_span->attribute_.first, "error");
  99. span_shim->SetTag("error", 42);
  100. ASSERT_NE(mock_span->attribute_.first, "error");
  101. span_shim->SetTag("error", nullptr);
  102. ASSERT_NE(mock_span->attribute_.first, "error");
  103. }
  104. TEST_F(SpanShimTest, BaggageItem)
  105. {
  106. ASSERT_EQ(span_shim->BaggageItem({}), "");
  107. ASSERT_EQ(span_shim->BaggageItem(""), "");
  108. ASSERT_EQ(span_shim->BaggageItem("invalid"), "");
  109. ASSERT_EQ(span_shim->BaggageItem("baggage"), "item");
  110. }
  111. TEST_F(SpanShimTest, SetBaggageItem)
  112. {
  113. span_shim->SetBaggageItem("new", "entry");
  114. ASSERT_EQ(span_shim->BaggageItem("new"), "entry");
  115. ASSERT_EQ(span_shim->BaggageItem("baggage"), "item");
  116. span_shim->SetBaggageItem("empty", "");
  117. ASSERT_EQ(span_shim->BaggageItem("empty"), "");
  118. span_shim->SetBaggageItem("no value", {});
  119. ASSERT_EQ(span_shim->BaggageItem("no value"), "");
  120. }
  121. TEST_F(SpanShimTest, SetBaggageItem_MultiThreaded)
  122. {
  123. auto span = nostd::shared_ptr<trace_api::Span>(new MockSpan());
  124. auto tracer = shim::TracerShim::createTracerShim();
  125. auto tracer_shim = static_cast<shim::TracerShim *>(tracer.get());
  126. auto baggage = baggage::Baggage::GetDefault();
  127. shim::SpanShim span_shim(*tracer_shim, span, baggage);
  128. std::vector<std::thread> threads;
  129. std::vector<std::string> keys;
  130. std::vector<std::string> values;
  131. int thread_count = 100;
  132. for (int index = 0; index < thread_count; ++index)
  133. {
  134. keys.emplace_back("key-" + std::to_string(index));
  135. values.emplace_back("value-" + std::to_string(index));
  136. threads.emplace_back(
  137. std::bind(&shim::SpanShim::SetBaggageItem, &span_shim, keys[index], values[index]));
  138. }
  139. for (auto &thread : threads)
  140. {
  141. thread.join();
  142. }
  143. for (int index = 0; index < thread_count; ++index)
  144. {
  145. ASSERT_EQ(span_shim.BaggageItem(keys[index]), values[index]);
  146. }
  147. }
  148. TEST_F(SpanShimTest, Log_NoEvent)
  149. {
  150. std::string name;
  151. common::SystemTimestamp timestamp;
  152. std::unordered_map<std::string, common::AttributeValue> attributes;
  153. span_shim->Log({{"test", 42}});
  154. std::tie(name, timestamp, attributes) = mock_span->event_;
  155. ASSERT_EQ(name, "log");
  156. ASSERT_EQ(timestamp, common::SystemTimestamp{});
  157. ASSERT_EQ(attributes.size(), 1);
  158. ASSERT_EQ(nostd::get<int64_t>(attributes["test"]), 42);
  159. }
  160. TEST_F(SpanShimTest, Log_NoEvent_Timestamp)
  161. {
  162. std::string name;
  163. common::SystemTimestamp timestamp;
  164. std::unordered_map<std::string, common::AttributeValue> attributes;
  165. auto logtime = opentracing::SystemTime::time_point::clock::now();
  166. span_shim->Log(logtime, {{"foo", "bar"}});
  167. std::tie(name, timestamp, attributes) = mock_span->event_;
  168. ASSERT_EQ(name, "log");
  169. ASSERT_EQ(timestamp, common::SystemTimestamp{logtime});
  170. ASSERT_EQ(attributes.size(), 1);
  171. ASSERT_STREQ(nostd::get<const char *>(attributes["foo"]), "bar");
  172. }
  173. TEST_F(SpanShimTest, Log_Event)
  174. {
  175. std::string name;
  176. common::SystemTimestamp timestamp;
  177. std::unordered_map<std::string, common::AttributeValue> attributes;
  178. auto logtime = opentracing::SystemTime::time_point::clock::now();
  179. std::initializer_list<std::pair<opentracing::string_view, opentracing::Value>> fields{
  180. {"event", "normal"},
  181. {"foo", opentracing::string_view{"bar"}},
  182. {"error.kind", 42},
  183. {"message", "hello"},
  184. {"stack", "overflow"}};
  185. span_shim->Log(logtime, fields);
  186. std::tie(name, timestamp, attributes) = mock_span->event_;
  187. ASSERT_EQ(name, "normal");
  188. ASSERT_EQ(timestamp, common::SystemTimestamp{logtime});
  189. ASSERT_EQ(attributes.size(), 5);
  190. ASSERT_STREQ(nostd::get<const char *>(attributes["event"]), "normal");
  191. ASSERT_EQ(nostd::get<nostd::string_view>(attributes["foo"]), nostd::string_view{"bar"});
  192. ASSERT_EQ(nostd::get<int64_t>(attributes["error.kind"]), 42);
  193. ASSERT_STREQ(nostd::get<const char *>(attributes["message"]), "hello");
  194. ASSERT_STREQ(nostd::get<const char *>(attributes["stack"]), "overflow");
  195. }
  196. TEST_F(SpanShimTest, Log_Error)
  197. {
  198. std::string name;
  199. common::SystemTimestamp timestamp;
  200. std::unordered_map<std::string, common::AttributeValue> attributes;
  201. auto logtime = opentracing::SystemTime::time_point::clock::now();
  202. std::vector<std::pair<opentracing::string_view, opentracing::Value>> fields{
  203. {"event", "error"},
  204. {"foo", opentracing::string_view{"bar"}},
  205. {"error.kind", 42},
  206. {"message", "hello"},
  207. {"stack", "overflow"}};
  208. span_shim->Log(logtime, fields);
  209. std::tie(name, timestamp, attributes) = mock_span->event_;
  210. ASSERT_EQ(name, "exception");
  211. ASSERT_EQ(timestamp, common::SystemTimestamp{logtime});
  212. ASSERT_EQ(attributes.size(), 5);
  213. ASSERT_STREQ(nostd::get<const char *>(attributes["event"]), "error");
  214. ASSERT_EQ(nostd::get<nostd::string_view>(attributes["foo"]), nostd::string_view{"bar"});
  215. ASSERT_EQ(nostd::get<int64_t>(attributes["exception.type"]), 42);
  216. ASSERT_STREQ(nostd::get<const char *>(attributes["exception.message"]), "hello");
  217. ASSERT_STREQ(nostd::get<const char *>(attributes["exception.stacktrace"]), "overflow");
  218. }