Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1243,3 +1243,47 @@ jobs:
|
python ${GITHUB_WORKSPACE}/trace-context/test/test.py http://localhost:30000/test TraceContextTest AdvancedTest
curl http://localhost:30000/stop

w3c_trace_context_compliance_v2:
name: W3C Distributed Tracing Validation V2
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0
with:
egress-policy: audit

- name: Checkout open-telemetry/opentelemetry-cpp
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: 'recursive'
- name: setup
env:
CC: /usr/bin/gcc-12
CXX: /usr/bin/g++-12
run: |
sudo -E ./ci/setup_ci_environment.sh
sudo -E apt-get install -y zlib1g-dev libcurl4-openssl-dev
- name: run w3c trace-context test server (background)
env:
CXX_STANDARD: '17'
run: |
./ci/do_ci.sh cmake.w3c.trace-context.build-server
cd $HOME/build/ext/test/w3c_tracecontext_http_test_server
./w3c_tracecontext_http_test_server &
- name: Checkout w3c/trace-context repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: w3c/trace-context
path: trace-context
- name: install dependencies
run: |
sudo apt update && sudo apt install python3-pip
sudo pip3 install aiohttp==3.11.18
- name: run w3c trace-context test suite
env:
SPEC_LEVEL: 2
run:
|
python ${GITHUB_WORKSPACE}/trace-context/test/test.py http://localhost:30000/test TraceContext2Test
curl http://localhost:30000/stop
21 changes: 21 additions & 0 deletions api/test/trace/propagation/http_text_format_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ TEST(TextMapPropagatorTest, TraceFlagsBufferGeneration)
EXPECT_EQ(MapHttpTraceContext::TraceFlagsFromHex("00"), trace::TraceFlags());
}

TEST(TextMapPropagatorTest, PropagateRandomTraceFlag)
{
TextMapCarrierTest carrier;
// Only random bit is set(02), sampled bit is not set
auto const traceparent = "00-4bf92f3577b34da6a3ce929d0e0e4736-0102030405060708-02";
// Use a remote traceparent with only the random bit set and verify the
// propagator round-trips it without forcing the sampled bit on.
carrier.headers_ = {{"traceparent", traceparent}};
auto ctx1 = context::Context{};
auto ctx2 = format.Extract(carrier, ctx1);

auto span = trace::GetSpan(ctx2);
EXPECT_TRUE(span->GetContext().IsValid());
EXPECT_FALSE(span->GetContext().IsSampled()); // Sampled bit is not set
EXPECT_TRUE(span->GetContext().trace_flags().IsRandom()); // Random bit is set

TextMapCarrierTest carrier2;
format.Inject(carrier2, ctx2);
EXPECT_EQ(carrier2.headers_["traceparent"], traceparent);
}

TEST(TextMapPropagatorTest, NoSendEmptyTraceState)
{
// If the trace state is empty, do not set the header.
Expand Down
24 changes: 24 additions & 0 deletions api/test/trace/trace_flags_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,28 @@ TEST(TraceFlagsTest, Sampled)
EXPECT_EQ(1, buf[0]);
}

TEST(TraceFlagsTest, Random)
{
TraceFlags flags{TraceFlags::kIsRandom};
EXPECT_TRUE(flags.IsRandom());
EXPECT_EQ(2, flags.flags());
EXPECT_EQ("02", Hex(flags));

uint8_t buf[1];
flags.CopyBytesTo(buf);
EXPECT_EQ(2, buf[0]);
}

TEST(TraceFlagsTest, Both)
{
TraceFlags flags{TraceFlags::kIsSampled | TraceFlags::kIsRandom};
EXPECT_TRUE(flags.IsSampled());
EXPECT_TRUE(flags.IsRandom());
EXPECT_EQ(3, flags.flags());
EXPECT_EQ("03", Hex(flags));

uint8_t buf[1];
flags.CopyBytesTo(buf);
EXPECT_EQ(3, buf[0]);
}
} // namespace
13 changes: 13 additions & 0 deletions exporters/otlp/test/otlp_recordable_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,19 @@ TEST(OtlpRecordable, SetStatus)
EXPECT_EQ(rec2.span().status().message(), "");
}

TEST(OtlpRecordable, SetTraceFlags)
{
OtlpRecordable rec;
// OTLP stores the W3C trace-flags bits on the exported span so downstream
// processors can observe the random flag.
trace_api::TraceFlags flags{
static_cast<uint8_t>(trace_api::TraceFlags::kIsSampled | trace_api::TraceFlags::kIsRandom)};

rec.SetTraceFlags(flags);

EXPECT_EQ(rec.span().flags(), static_cast<uint32_t>(flags.flags()));
}

TEST(OtlpRecordable, AddEventDefault)
{
OtlpRecordable rec;
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/trace/tracer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,13 @@ nostd::shared_ptr<opentelemetry::trace::Span> Tracer::StartSpan(
flags &= ~opentelemetry::trace::TraceFlags::kIsSampled;
}

#if 1
#if 0
Comment thread
marcalff marked this conversation as resolved.
/* https://github.com/open-telemetry/opentelemetry-specification as of v1.29.0 */
/* Support W3C Trace Context version 1. */
flags &= opentelemetry::trace::TraceFlags::kAllW3CTraceContext1Flags;
#endif

#if 0
#if 1
/* Waiting for https://github.com/open-telemetry/opentelemetry-specification/issues/3411 */
/* Support W3C Trace Context version 2. */
flags &= opentelemetry::trace::TraceFlags::kAllW3CTraceContext2Flags;
Expand Down
45 changes: 45 additions & 0 deletions sdk/test/trace/tracer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "opentelemetry/trace/span_id.h"
#include "opentelemetry/trace/span_metadata.h"
#include "opentelemetry/trace/span_startoptions.h"
#include "opentelemetry/trace/trace_flags.h"
#include "opentelemetry/trace/trace_id.h"
#include "opentelemetry/trace/trace_state.h"
#include "opentelemetry/trace/tracer.h"
Expand Down Expand Up @@ -274,6 +275,50 @@ TEST(Tracer, StartSpanSampleOff)
ASSERT_EQ(0, span_data->GetSpans().size());
}

TEST(Tracer, StartSpanSetsRandomTraceFlagForRootSpan)
{
InMemorySpanExporter *exporter = new InMemorySpanExporter();
// AlwaysOn keeps the sampled bit set while RandomIdGenerator marks the
// locally generated trace-id as random.
auto tracer = initTracer(std::unique_ptr<SpanExporter>{exporter}, new AlwaysOnSampler(),
new RandomIdGenerator());

auto span = tracer->StartSpan("span 1");
auto context = span->GetContext();

EXPECT_TRUE(context.IsValid());
EXPECT_TRUE(context.IsSampled());
EXPECT_TRUE(context.trace_flags().IsRandom());
EXPECT_EQ(context.trace_flags().flags(),
trace_api::TraceFlags::kIsSampled | trace_api::TraceFlags::kIsRandom);
}

TEST(Tracer, StartSpanPreservesRandomTraceFlagFromParent)
{
InMemorySpanExporter *exporter = new InMemorySpanExporter();
constexpr uint8_t parent_span_id_buf[] = {1, 2, 3, 4, 5, 6, 7, 8};
constexpr uint8_t parent_trace_id_buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1};
// Build a remote parent with only the random bit set so the child path can
// prove it preserves the incoming signal even when sampling is turned off.
trace_api::SpanContext parent_context{
trace_api::TraceId{parent_trace_id_buf}, trace_api::SpanId{parent_span_id_buf},
trace_api::TraceFlags{trace_api::TraceFlags::kIsRandom}, true};

auto tracer = initTracer(std::unique_ptr<SpanExporter>{exporter}, new AlwaysOffSampler());

trace_api::StartSpanOptions options;
options.parent = parent_context;

auto span = tracer->StartSpan("span 1", options);
auto context = span->GetContext();

EXPECT_TRUE(context.IsValid());
EXPECT_FALSE(context.IsSampled());
EXPECT_TRUE(context.trace_flags().IsRandom());
EXPECT_EQ(context.trace_flags().flags(), static_cast<uint8_t>(trace_api::TraceFlags::kIsRandom));
EXPECT_EQ(context.trace_id(), parent_context.trace_id());
}

TEST(Tracer, StartSpanCustomIdGenerator)
{
IdGenerator *id_generator = new MockIdGenerator();
Expand Down
Loading