shim_mocks.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * Copyright The OpenTelemetry Authors
  3. * SPDX-License-Identifier: Apache-2.0
  4. */
  5. #pragma once
  6. #include <tuple>
  7. #include <unordered_map>
  8. #include "opentracing/propagation.h"
  9. #include "opentelemetry/baggage/baggage_context.h"
  10. #include "opentelemetry/context/propagation/text_map_propagator.h"
  11. #include "opentelemetry/trace/span.h"
  12. #include "opentelemetry/trace/span_context.h"
  13. #include "opentelemetry/trace/span_metadata.h"
  14. #include "opentelemetry/trace/tracer.h"
  15. #include "opentelemetry/trace/tracer_provider.h"
  16. namespace trace_api = opentelemetry::trace;
  17. namespace baggage = opentelemetry::baggage;
  18. namespace common = opentelemetry::common;
  19. namespace context = opentelemetry::context;
  20. namespace nostd = opentelemetry::nostd;
  21. struct MockSpan final : public trace_api::Span
  22. {
  23. void SetAttribute(nostd::string_view key, const common::AttributeValue &value) noexcept override
  24. {
  25. attribute_ = {key.data(), value};
  26. }
  27. void AddEvent(nostd::string_view name,
  28. common::SystemTimestamp timestamp,
  29. const common::KeyValueIterable &attributes) noexcept override
  30. {
  31. std::unordered_map<std::string, common::AttributeValue> attribute_map;
  32. attribute_map.reserve(attributes.size());
  33. attributes.ForEachKeyValue(
  34. [&attribute_map](nostd::string_view key, const common::AttributeValue &value) {
  35. attribute_map.emplace(key.data(), value);
  36. return true;
  37. });
  38. event_ = {name.data(), timestamp, attribute_map};
  39. }
  40. void AddEvent(nostd::string_view name,
  41. const common::KeyValueIterable &attributes) noexcept override
  42. {
  43. AddEvent(name, {}, attributes);
  44. }
  45. void AddEvent(nostd::string_view, common::SystemTimestamp) noexcept override {}
  46. void AddEvent(nostd::string_view) noexcept override {}
  47. void SetStatus(trace_api::StatusCode code, nostd::string_view description) noexcept override
  48. {
  49. status_ = {code, description.data()};
  50. }
  51. void UpdateName(nostd::string_view name) noexcept override { name_ = name.data(); }
  52. void End(const trace_api::EndSpanOptions &options) noexcept override { options_ = options; }
  53. bool IsRecording() const noexcept override { return false; }
  54. trace_api::SpanContext GetContext() const noexcept override
  55. {
  56. return trace_api::SpanContext(false, false);
  57. }
  58. std::pair<std::string, common::AttributeValue> attribute_;
  59. std::tuple<std::string,
  60. common::SystemTimestamp,
  61. std::unordered_map<std::string, common::AttributeValue>>
  62. event_;
  63. std::pair<trace_api::StatusCode, std::string> status_;
  64. std::string name_;
  65. trace_api::EndSpanOptions options_;
  66. };
  67. struct MockTracer final : public trace_api::Tracer
  68. {
  69. nostd::shared_ptr<trace_api::Span> StartSpan(
  70. nostd::string_view name,
  71. const common::KeyValueIterable &,
  72. const trace_api::SpanContextKeyValueIterable &,
  73. const trace_api::StartSpanOptions &) noexcept override
  74. {
  75. span_ = new MockSpan();
  76. span_->name_ = std::string{name};
  77. return nostd::shared_ptr<trace_api::Span>(span_);
  78. }
  79. void ForceFlushWithMicroseconds(uint64_t) noexcept override {}
  80. void CloseWithMicroseconds(uint64_t) noexcept override {}
  81. MockSpan *span_;
  82. };
  83. struct MockTracerProvider final : public trace_api::TracerProvider
  84. {
  85. nostd::shared_ptr<trace_api::Tracer> GetTracer(nostd::string_view library_name,
  86. nostd::string_view,
  87. nostd::string_view) noexcept override
  88. {
  89. library_name_ = std::string{library_name};
  90. tracer_ = new MockTracer();
  91. return nostd::shared_ptr<trace_api::Tracer>(tracer_);
  92. }
  93. std::string library_name_;
  94. MockTracer *tracer_;
  95. };
  96. struct MockPropagator : public context::propagation::TextMapPropagator
  97. {
  98. static constexpr const char *kTraceIdKey = "trace_id";
  99. static constexpr const char *kSpanIdKey = "span_id";
  100. static constexpr const char *kTraceFlagsKey = "trace_flags_id";
  101. template <class T, int N>
  102. static inline std::string ToLowerBase16(const T &id)
  103. {
  104. char buf[N] = {0};
  105. id.ToLowerBase16(buf);
  106. return std::string(buf, sizeof(buf));
  107. }
  108. // Returns the context that is stored in the carrier with the TextMapCarrier as extractor.
  109. context::Context Extract(const context::propagation::TextMapCarrier &carrier,
  110. context::Context &context) noexcept override
  111. {
  112. std::vector<std::pair<std::string, std::string>> kvs;
  113. carrier.Keys([&carrier, &kvs](nostd::string_view k) {
  114. kvs.emplace_back(k, carrier.Get(k));
  115. return true;
  116. });
  117. is_extracted = true;
  118. return baggage::SetBaggage(context,
  119. nostd::shared_ptr<baggage::Baggage>(new baggage::Baggage(kvs)));
  120. }
  121. // Sets the context for carrier with self defined rules.
  122. void Inject(context::propagation::TextMapCarrier &carrier,
  123. const context::Context &context) noexcept override
  124. {
  125. auto baggage = baggage::GetBaggage(context);
  126. baggage->GetAllEntries([&carrier](nostd::string_view k, nostd::string_view v) {
  127. carrier.Set(k, v);
  128. return true;
  129. });
  130. auto span_key_value = context.GetValue(trace_api::kSpanKey);
  131. if (nostd::holds_alternative<nostd::shared_ptr<trace_api::Span>>(span_key_value))
  132. {
  133. auto span = nostd::get<nostd::shared_ptr<trace_api::Span>>(span_key_value);
  134. if (span)
  135. {
  136. // Store span context information in TextMapCarrier to allow verifying propagation
  137. auto span_context = span->GetContext();
  138. carrier.Set(kTraceIdKey, ToLowerBase16<trace_api::TraceId, 2 * trace_api::TraceId::kSize>(
  139. span_context.trace_id()));
  140. carrier.Set(kSpanIdKey, ToLowerBase16<trace_api::SpanId, 2 * trace_api::SpanId::kSize>(
  141. span_context.span_id()));
  142. carrier.Set(kTraceFlagsKey,
  143. ToLowerBase16<trace_api::TraceFlags, 2>(span_context.trace_flags()));
  144. }
  145. }
  146. is_injected = true;
  147. }
  148. // Gets the fields set in the carrier by the `inject` method
  149. bool Fields(nostd::function_ref<bool(nostd::string_view)>) const noexcept override
  150. {
  151. return true;
  152. }
  153. bool is_extracted = false;
  154. bool is_injected = false;
  155. };
  156. struct TextMapCarrier : opentracing::TextMapReader, opentracing::TextMapWriter
  157. {
  158. TextMapCarrier(std::unordered_map<std::string, std::string> &text_map_) : text_map(text_map_) {}
  159. opentracing::expected<void> Set(opentracing::string_view key,
  160. opentracing::string_view value) const override
  161. {
  162. text_map[key] = value;
  163. return {};
  164. }
  165. opentracing::expected<opentracing::string_view> LookupKey(
  166. opentracing::string_view key) const override
  167. {
  168. if (!supports_lookup)
  169. {
  170. return opentracing::make_unexpected(opentracing::lookup_key_not_supported_error);
  171. }
  172. auto iter = text_map.find(key);
  173. if (iter != text_map.end())
  174. {
  175. return opentracing::string_view{iter->second};
  176. }
  177. else
  178. {
  179. return opentracing::make_unexpected(opentracing::key_not_found_error);
  180. }
  181. }
  182. opentracing::expected<void> ForeachKey(
  183. std::function<opentracing::expected<void>(opentracing::string_view key,
  184. opentracing::string_view value)> f) const override
  185. {
  186. ++foreach_key_call_count;
  187. for (const auto &key_value : text_map)
  188. {
  189. auto result = f(key_value.first, key_value.second);
  190. if (!result)
  191. return result;
  192. }
  193. return {};
  194. }
  195. bool supports_lookup = false;
  196. mutable int foreach_key_call_count = 0;
  197. std::unordered_map<std::string, std::string> &text_map;
  198. };
  199. struct HTTPHeadersCarrier : opentracing::HTTPHeadersReader, opentracing::HTTPHeadersWriter
  200. {
  201. HTTPHeadersCarrier(std::unordered_map<std::string, std::string> &text_map_) : text_map(text_map_)
  202. {}
  203. opentracing::expected<void> Set(opentracing::string_view key,
  204. opentracing::string_view value) const override
  205. {
  206. text_map[key] = value;
  207. return {};
  208. }
  209. opentracing::expected<void> ForeachKey(
  210. std::function<opentracing::expected<void>(opentracing::string_view key,
  211. opentracing::string_view value)> f) const override
  212. {
  213. for (const auto &key_value : text_map)
  214. {
  215. auto result = f(key_value.first, key_value.second);
  216. if (!result)
  217. return result;
  218. }
  219. return {};
  220. }
  221. std::unordered_map<std::string, std::string> &text_map;
  222. };