Skip to content

Commit

Permalink
Unit tests for shim utils
Browse files Browse the repository at this point in the history
  • Loading branch information
chusitoo committed Jan 4, 2023
1 parent 81b8557 commit 1fc7f33
Show file tree
Hide file tree
Showing 9 changed files with 403 additions and 202 deletions.
65 changes: 37 additions & 28 deletions opentracing-shim/include/shim_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,21 @@

#pragma once

#include <opentelemetry/baggage/baggage.h>
#include <opentelemetry/common/attribute_value.h>
#include <opentelemetry/context/propagation/text_map_propagator.h>
#include <opentelemetry/nostd/type_traits.h>
#include <opentracing/propagation.h>
#include <opentracing/value.h>

OPENTELEMETRY_BEGIN_NAMESPACE
namespace opentracingshim::shimutils
namespace opentracingshim::utils
{

using opentelemetry::common::AttributeValue;

static inline AttributeValue attributeFromValue(const opentracing::Value& value)
static inline opentelemetry::common::AttributeValue attributeFromValue(const opentracing::Value& value)
{
using opentelemetry::common::AttributeValue;

static struct
{
AttributeValue operator()(bool v) { return v; }
Expand All @@ -21,12 +28,12 @@ static inline AttributeValue attributeFromValue(const opentracing::Value& value)
AttributeValue operator()(uint64_t v) { return v; }
AttributeValue operator()(std::string v) { return v.c_str(); }
AttributeValue operator()(opentracing::string_view v) { return nostd::string_view{v.data()}; }
AttributeValue operator()(std::nullptr_t) { return std::string{}; }
AttributeValue operator()(std::nullptr_t) { return nostd::string_view{}; }
AttributeValue operator()(const char* v) { return v; }
AttributeValue operator()(opentracing::util::recursive_wrapper<opentracing::Values>) { return std::string{}; }
AttributeValue operator()(opentracing::util::recursive_wrapper<opentracing::Dictionary>) { return std::string{}; }
AttributeValue operator()(opentracing::util::recursive_wrapper<opentracing::Values>) { return nostd::string_view{}; }
AttributeValue operator()(opentracing::util::recursive_wrapper<opentracing::Dictionary>) { return nostd::string_view{}; }
} AttributeMapper;

return opentracing::Value::visit(value, AttributeMapper);
}

Expand Down Expand Up @@ -54,7 +61,7 @@ class CarrierWriterShim : public opentelemetry::context::propagation::TextMapCar
{
public:
CarrierWriterShim(const T& writer) : writer_(writer) {}

// returns the value associated with the passed key.
virtual nostd::string_view Get(nostd::string_view key) const noexcept override
{
Expand All @@ -76,30 +83,32 @@ class CarrierReaderShim : public opentelemetry::context::propagation::TextMapCar
{
public:
CarrierReaderShim(const T& reader) : reader_(reader) {}

// returns the value associated with the passed key.
virtual nostd::string_view Get(nostd::string_view key) const noexcept override
{
// First try carrier.LookupKey since that can potentially be the fastest approach.
auto result = reader_.LookupKey(key.data());
nostd::string_view value;

if (!result.has_value() ||
opentracing::are_errors_equal(result.error(), opentracing::lookup_key_not_supported_error))
// First try carrier.LookupKey since that can potentially be the fastest approach.
if (auto result = reader_.LookupKey(key.data()))
{
value = result.value().data();
}
else // Fall back to iterating through all of the keys.
{
// Fall back to iterating through all of the keys.
reader_.ForeachKey([key, &result]
reader_.ForeachKey([key, &value]
(opentracing::string_view k, opentracing::string_view v) -> opentracing::expected<void> {
if (key == k)
if (k == key.data())
{
result = opentracing::make_expected(v);
value = v.data();
// Found key, so bail out of the loop with a success error code.
return opentracing::make_unexpected(std::error_code{});
}
return opentracing::make_expected();
});
}

return nostd::string_view{ result.has_value() ? result.value().data() : "" };
return value;
}

// stores the key-value pair.
Expand All @@ -111,29 +120,29 @@ class CarrierReaderShim : public opentelemetry::context::propagation::TextMapCar
// list of all the keys in the carrier.
virtual bool Keys(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override
{
reader_.ForeachKey([&callback]
(opentracing::string_view k, opentracing::string_view v) -> opentracing::expected<void> {
callback(k.data());
return opentracing::make_expected();
});
return true;
return reader_.ForeachKey([&callback]
(opentracing::string_view key, opentracing::string_view) -> opentracing::expected<void> {
return callback(key.data())
? opentracing::make_expected()
: opentracing::make_unexpected(std::error_code{});
}).has_value();
}

private:
const T& reader_;
};

static inline bool isBaggageEmpty(const BaggagePtr& baggage)
static inline bool isBaggageEmpty(const nostd::shared_ptr<opentelemetry::baggage::Baggage>& baggage)
{
if (baggage)
{
return baggage->GetAllEntries([](nostd::string_view, nostd::string_view){
return false;
});
});
}

return true;
}

} // namespace opentracingshim::shimutils
} // namespace opentracingshim::utils
OPENTELEMETRY_END_NAMESPACE
4 changes: 2 additions & 2 deletions opentracing-shim/include/span_context_shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "opentracing/span.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace opentracingshim
namespace opentracingshim
{

using BaggagePtr = nostd::shared_ptr<opentelemetry::baggage::Baggage>;
Expand All @@ -35,4 +35,4 @@ class SpanContextShim final : public opentracing::SpanContext
};

} // namespace opentracingshim
OPENTELEMETRY_END_NAMESPACE
OPENTELEMETRY_END_NAMESPACE
4 changes: 2 additions & 2 deletions opentracing-shim/include/span_shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "opentracing/span.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace opentracingshim
namespace opentracingshim
{

using SpanPtr = nostd::shared_ptr<opentelemetry::trace::Span>;
Expand Down Expand Up @@ -49,4 +49,4 @@ class SpanShim : public opentracing::Span
};

} // namespace opentracingshim
OPENTELEMETRY_END_NAMESPACE
OPENTELEMETRY_END_NAMESPACE
65 changes: 20 additions & 45 deletions opentracing-shim/include/tracer_shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,62 +11,37 @@
#include "opentracing/tracer.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace opentracingshim
namespace opentracingshim
{

using TracerPtr = nostd::shared_ptr<opentelemetry::trace::Tracer>;
using TracerProviderPtr = nostd::shared_ptr<opentelemetry::trace::TracerProvider>;
using PropagatorPtr = nostd::shared_ptr<opentelemetry::context::propagation::TextMapPropagator>;

struct OpenTracingPropagators {
PropagatorPtr text_map;
PropagatorPtr http_headers;
PropagatorPtr text_map;
PropagatorPtr http_headers;
};

class TracerShim : public opentracing::Tracer
{
public:
/**
* Creates a {@code opentracing::Tracer} shim out of
* {@code Provider::GetTracerProvider()} and
* {@code GlobalTextMapPropagator::GetGlobalPropagator()}.
*
* @returns a {@code opentracing::Tracer}.
*/
static inline std::shared_ptr<opentracing::Tracer> createTracerShim() noexcept
// This operation MUST accept the following parameters:
// - An OpenTelemetry TracerProvider. This operation MUST use this TracerProvider to obtain a
// Tracer with the name opentracing-shim along with the current shim library version.
// - OpenTelemetry Propagators to be used to perform injection and extraction for the the
// OpenTracing TextMap and HTTPHeaders formats. If not specified, no Propagator values will
// be stored in the Shim, and the global OpenTelemetry TextMap propagator will be used for
// both OpenTracing TextMap and HTTPHeaders formats.
static inline std::shared_ptr<opentracing::Tracer> createTracerShim(
const TracerProviderPtr& provider = opentelemetry::trace::Provider::GetTracerProvider(),
const OpenTracingPropagators& propagators = {}) noexcept
{
return createTracerShim(opentelemetry::trace::Provider::GetTracerProvider());
}

/**
* Creates a {@code opentracing::Tracer} shim using the provided
* {@code TracerProvider} and
* {@code TextMapPropagator} instance.
*
* @param provider the {@code TracerProvider} instance used to create this shim.
* @param propagators the {@code OpenTracingPropagators} instance used to create this shim.
* @returns a {@code opentracing::Tracer}.
*/
static inline std::shared_ptr<opentracing::Tracer> createTracerShim(const TracerProviderPtr& provider,
const OpenTracingPropagators& propagators = {}) noexcept
{
return createTracerShim(provider->GetTracer("opentracing-shim"), propagators);
}

/**
* Creates a {@code opentracing::Tracer} shim using provided
* {@code Tracer} instance and
* {@code GlobalTextMapPropagator::GetGlobalPropagator()}.
*
* @returns a {@code opentracing::Tracer}.
*/
static inline std::shared_ptr<opentracing::Tracer> createTracerShim(const TracerPtr& tracer,
const OpenTracingPropagators& propagators = {}) noexcept
{
return std::shared_ptr<opentracing::Tracer>(new (std::nothrow) TracerShim(tracer, propagators));
return std::shared_ptr<opentracing::Tracer>(
new (std::nothrow) TracerShim(provider->GetTracer("opentracing-shim"), propagators));
}
// Overrides
std::unique_ptr<opentracing::Span> StartSpanWithOptions(opentracing::string_view operation_name,
std::unique_ptr<opentracing::Span> StartSpanWithOptions(opentracing::string_view operation_name,
const opentracing::StartSpanOptions& options) const noexcept override;
opentracing::expected<void> Inject(const opentracing::SpanContext& sc,
std::ostream& writer) const override;
Expand All @@ -83,11 +58,11 @@ class TracerShim : public opentracing::Tracer
explicit TracerShim(const TracerPtr& tracer, const OpenTracingPropagators& propagators)
: tracer_(tracer), propagators_(propagators) {}
template <typename T>
opentracing::expected<void> injectImpl(const opentracing::SpanContext& sc,
const T& writer,
opentracing::expected<void> injectImpl(const opentracing::SpanContext& sc,
const T& writer,
const PropagatorPtr& propagator) const;
template <typename T>
opentracing::expected<std::unique_ptr<opentracing::SpanContext>> extractImpl(const T& reader,
opentracing::expected<std::unique_ptr<opentracing::SpanContext>> extractImpl(const T& reader,
const PropagatorPtr& propagator) const;

TracerPtr tracer_;
Expand All @@ -96,4 +71,4 @@ class TracerShim : public opentracing::Tracer
};

} // namespace opentracingshim
OPENTELEMETRY_END_NAMESPACE
OPENTELEMETRY_END_NAMESPACE
8 changes: 4 additions & 4 deletions opentracing-shim/src/span_shim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void SpanShim::handleError(const opentracing::Value& value) noexcept
// - false maps to Ok
// - no value being set maps to Unset.
auto code = StatusCode::kUnset;
const auto& str_value = shimutils::stringFromValue(value);
const auto& str_value = utils::stringFromValue(value);

if (str_value == "true")
{
Expand Down Expand Up @@ -59,7 +59,7 @@ void SpanShim::SetTag(opentracing::string_view key, const opentracing::Value& va
}
else
{
span_->SetAttribute(key.data(), shimutils::attributeFromValue(value));
span_->SetAttribute(key.data(), utils::attributeFromValue(value));
}
}

Expand Down Expand Up @@ -106,7 +106,7 @@ void SpanShim::logImpl(opentracing::SystemTime timestamp, nostd::span<const Even
// The Add Event’s name parameter MUST be the value with the event key
// in the pair set, or else fallback to use the log literal string.
const auto event = std::find_if(fields.begin(), fields.end(), [](EventEntry item){ return item.first == "event"; });
auto name = (event != fields.end()) ? shimutils::stringFromValue(event->second) : std::string{"log"};
auto name = (event != fields.end()) ? utils::stringFromValue(event->second) : std::string{"log"};
// If pair set contains an event=error entry, the values MUST be mapped to an Event
// with the conventions outlined in the Exception semantic conventions document:
bool is_error = (name == opentracing::ext::error);
Expand All @@ -119,7 +119,7 @@ void SpanShim::logImpl(opentracing::SystemTime timestamp, nostd::span<const Even
for (const auto& entry : fields)
{
auto key = entry.first;
const auto& value = shimutils::attributeFromValue(entry.second);
const auto& value = utils::attributeFromValue(entry.second);
// ... including mapping of the following key/value pairs:
// - error.kind maps to exception.type.
// - message maps to exception.message.
Expand Down
12 changes: 4 additions & 8 deletions opentracing-shim/src/tracer_shim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ static LinksList makeReferenceLinks(const opentracing::StartSpanOptions& options

LinksList links;
links.reserve(options.references.size());

// All values in the list MUST be added as Links with the reference type value
// as a Link attribute, i.e. opentracing.ref_type set to follows_from or child_of
for (const auto& entry : options.references)
Expand Down Expand Up @@ -94,7 +93,6 @@ static BaggagePtr makeBaggage(const opentracing::StartSpanOptions& options) noex
using namespace opentelemetry::baggage;

std::unordered_map<std::string, std::string> baggage_items;

// If a list of Span references is specified...
for (const auto& entry : options.references)
{
Expand All @@ -111,7 +109,6 @@ static BaggagePtr makeBaggage(const opentracing::StartSpanOptions& options) noex
});
}
}

// If no such lisf of references is specified, the current Baggage
// MUST be used as the initial value of the newly created Span.
return baggage_items.empty()
Expand All @@ -128,7 +125,7 @@ static std::vector<std::pair<std::string, common::AttributeValue>> makeTags(cons
// be set at the creation time of the OpenTelemetry Span.
for (const auto& entry : options.tags)
{
tags.emplace_back(entry.first, shimutils::attributeFromValue(entry.second));
tags.emplace_back(entry.first, utils::attributeFromValue(entry.second));
}

return tags;
Expand All @@ -145,7 +142,6 @@ std::unique_ptr<opentracing::Span> TracerShim::StartSpanWithOptions(opentracing:
const auto& links = detail::makeReferenceLinks(options);
const auto& baggage = detail::makeBaggage(options);
const auto& attributes = detail::makeTags(options);

auto span = tracer_->StartSpan(operation_name.data(), attributes, links, opts);
auto span_shim = new SpanShim(*this, span, baggage);

Expand Down Expand Up @@ -237,7 +233,7 @@ opentracing::expected<void> TracerShim::injectImpl(const opentracing::SpanContex
// It MUST inject any non-empty Baggage even amidst no valid SpanContext.
const auto& context = opentelemetry::baggage::SetBaggage(current_context, context_shim->baggage());

shimutils::CarrierWriterShim<T> carrier{writer};
utils::CarrierWriterShim<T> carrier{writer};
propagator->Inject(carrier, context);
}

Expand All @@ -250,7 +246,7 @@ opentracing::expected<std::unique_ptr<opentracing::SpanContext>> TracerShim::ext
{
// Extract the underlying OpenTelemetry Span and Baggage using either the explicitly registered
// or the global OpenTelemetry Propagators, as configured at construction time.
shimutils::CarrierReaderShim<T> carrier{reader};
utils::CarrierReaderShim<T> carrier{reader};
auto current_context = opentelemetry::context::RuntimeContext::GetCurrent();
auto context = propagator->Extract(carrier, current_context);
auto span_context = opentelemetry::trace::GetSpan(context)->GetContext();
Expand All @@ -259,7 +255,7 @@ opentracing::expected<std::unique_ptr<opentracing::SpanContext>> TracerShim::ext
// If the extracted SpanContext is invalid AND the extracted Baggage is empty,
// this operation MUST return a null value, and otherwise it MUST return a
// SpanContext Shim instance with the extracted values.
SpanContextShim* context_shim = (!span_context.IsValid() && shimutils::isBaggageEmpty(baggage))
SpanContextShim* context_shim = (!span_context.IsValid() && utils::isBaggageEmpty(baggage))
? nullptr
: new SpanContextShim(span_context, baggage);

Expand Down
Loading

0 comments on commit 1fc7f33

Please sign in to comment.