Skip to content
This repository has been archived by the owner on Jan 24, 2023. It is now read-only.

Commit

Permalink
B3 single header implementation (#80)
Browse files Browse the repository at this point in the history
* work on #66 - B3 single header implementation

* first pass at B3 single header encoding

* added first specs

* finished all specs for verifying encoding

* added first cut at B3 parsing engine

* added parsing test cases

* passed all parsing specs

* fixed special case bugs with B3 Single Header parser

* added specs to cover changes to B3Propagator

* close #66 - finished implementing single header format
  • Loading branch information
Aaronontheweb committed Jan 2, 2019
1 parent f1f1fb4 commit 812ba83
Show file tree
Hide file tree
Showing 6 changed files with 551 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,67 @@ public void B3HeaderExtractionShouldTolerateTrueForSampled()

extracted2.Sampled.Should().BeFalse();
}

/// <summary>
/// https://github.com/petabridge/Petabridge.Tracing.Zipkin/issues/66
/// </summary>
[Fact(DisplayName = "B3Propagator should be able to parse single header format")]
public void B3HeaderExtractionShouldHandleSingleHeaderFormat()
{
var traceId = Tracer.IdProvider.NextTraceId();

var context = new SpanContext(traceId, Tracer.IdProvider.NextSpanId(), Tracer.IdProvider.NextSpanId(), false, true);
var carrier = new Dictionary<string, string>();

var b3SingleHeader = new B3SingleHeaderPropagator();
b3SingleHeader.Inject(context, new TextMapInjectAdapter(carrier));

var extracted =
(SpanContext)Tracer.Extract(BuiltinFormats.HttpHeaders, new TextMapExtractAdapter(carrier));

extracted.Should().Be(context);
}

/// <summary>
/// https://github.com/petabridge/Petabridge.Tracing.Zipkin/issues/66
/// </summary>
[Fact(DisplayName = "B3Propagator should be able to inject single header format")]
public void B3HeaderInjectionShouldHandleSingleHeaderFormat()
{
var traceId = Tracer.IdProvider.NextTraceId();

var context = new SpanContext(traceId, Tracer.IdProvider.NextSpanId(), Tracer.IdProvider.NextSpanId(), false, true);
var carrier = new Dictionary<string, string>();

// tracer2 will inject with single headers
var tracer2 = new MockZipkinTracer(propagtor:new B3Propagator(true));
tracer2.Inject(context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(carrier));

// single header only
carrier.Count.Should().Be(1);

// tracer1 will still be able to read and extract single headers
var extracted = Tracer.Extract(BuiltinFormats.HttpHeaders, new TextMapExtractAdapter(carrier));
extracted.Should().Be(context);
}

[Fact(DisplayName = "Should be able to override IPropagator implementation via ZipkinTracerOptions")]
public void ShouldOverridePropagatorViaZipkinTracerOptions()
{
var tracerOptions = new ZipkinTracerOptions(Endpoint.Testing, new NoOpReporter())
{
Propagator = new B3SingleHeaderPropagator()
};

var tracer = new ZipkinTracer(tracerOptions);

var traceId = Tracer.IdProvider.NextTraceId();

var context = new SpanContext(traceId, Tracer.IdProvider.NextSpanId(), Tracer.IdProvider.NextSpanId(), false, true);
var carrier = new Dictionary<string, string>();

tracer.Inject(context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(carrier));
carrier.Count.Should().Be(1);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
using System;
using System.Collections.Generic;
using System.Text;
using FluentAssertions;
using Petabridge.Tracing.Zipkin.Propagation;
using Petabridge.Tracing.Zipkin.Tracers;
using Xunit;
using static Petabridge.Tracing.Zipkin.Propagation.B3SingleHeaderFormatter;

namespace Petabridge.Tracing.Zipkin.Tests.Propagation
{
public class B3SingleHeaderFormatterSpecs
{
public B3SingleHeaderFormatterSpecs()
{
Tracer = new MockZipkinTracer(propagtor: new B3Propagator());
}

public readonly MockZipkinTracer Tracer;

[Fact(DisplayName = "Should write 64bit B3 single format header without sampling")]
public void ShouldWriteB3SingleHeaderWithoutSampling()
{
var context = new SpanContext(new TraceId(1), 3);

var b3Header = WriteB3SingleFormat(context);
b3Header.Should().Be(context.TraceId + "-" + context.SpanId);
b3Header.Should().Be(Encoding.UTF8.GetString(WriteB3SingleFormatAsBytes(context)));
}

[Fact(DisplayName = "Should write 64bit B3 single format header with sampling")]
public void ShouldWriteB3SingleHeaderWithSampling()
{
var context = new SpanContext(new TraceId(1), 3, sampled:true);

var b3Header = WriteB3SingleFormat(context);
b3Header.Should().Be(context.TraceId + "-" + context.SpanId + "-1");
b3Header.Should().Be(Encoding.UTF8.GetString(WriteB3SingleFormatAsBytes(context)));
}

[Fact(DisplayName = "Should write 64bit B3 single format header with debug")]
public void ShouldWriteB3SingleHeaderWithDebug()
{
var context = new SpanContext(new TraceId(1), 3, debug: true);

var b3Header = WriteB3SingleFormat(context);
b3Header.Should().Be(context.TraceId + "-" + context.SpanId + "-d");
b3Header.Should().Be(Encoding.UTF8.GetString(WriteB3SingleFormatAsBytes(context)));
}

[Fact(DisplayName = "Should write 64bit B3 single format header with a parent id and sampling")]
public void ShouldWriteB3SingleHeaderWithParentAndSampling()
{
var context = new SpanContext(new TraceId(1), 3, parentId:Tracer.IdProvider.NextSpanId(), sampled: true);

var b3Header = WriteB3SingleFormat(context);
b3Header.Should().Be(context.TraceId + "-" + context.SpanId + "-1-" + context.ParentId);
b3Header.Should().Be(Encoding.UTF8.GetString(WriteB3SingleFormatAsBytes(context)));
}

[Fact(DisplayName = "Should write 64bit B3 single format header with a parent id only")]
public void ShouldWriteB3SingleHeaderWithParentIdOnly()
{
var context = new SpanContext(new TraceId(1), 3, parentId: "18974c44954cf23f");

var b3Header = WriteB3SingleFormat(context);
b3Header.Should().Be(context.TraceId + "-" + context.SpanId + "-" + context.ParentId);
b3Header.Should().Be(Encoding.UTF8.GetString(WriteB3SingleFormatAsBytes(context)));
}

[Fact(DisplayName = "Should write 128bit B3 single format header without sampling")]
public void ShouldWriteB3SingleHeaderWithoutSampling128Bit()
{
var context = new SpanContext(new TraceId(1,1), 3);

var b3Header = WriteB3SingleFormat(context);
b3Header.Should().Be(context.TraceId + "-" + context.SpanId);
b3Header.Should().Be(Encoding.UTF8.GetString(WriteB3SingleFormatAsBytes(context)));
}

[Fact(DisplayName = "Should write 128bit B3 single format header with sampling")]
public void ShouldWriteB3SingleHeaderWithSampling128Bit()
{
var context = new SpanContext(new TraceId(1, 1), 3, sampled:true);

var b3Header = WriteB3SingleFormat(context);
b3Header.Should().Be(context.TraceId + "-" + context.SpanId + "-1");
b3Header.Should().Be(Encoding.UTF8.GetString(WriteB3SingleFormatAsBytes(context)));
}

[Fact(DisplayName = "Should write 128bit B3 single format header with sampling and parent id (max length)")]
public void ShouldWriteB3SingleHeaderWithSamplingAndParentId128Bit()
{
var context = new SpanContext(new TraceId(1, 1), 3, parentId: Tracer.IdProvider.NextSpanId(), sampled: true);

var b3Header = WriteB3SingleFormat(context);
b3Header.Should().Be(context.TraceId + "-" + context.SpanId + "-1-" + context.ParentId);
b3Header.Should().Be(Encoding.UTF8.GetString(WriteB3SingleFormatAsBytes(context)));
}

[Fact(DisplayName = "Should write 128bit B3 single format header with parent id only")]
public void ShouldWriteB3SingleHeaderWithParentIdOnly128Bit()
{
var context = new SpanContext(new TraceId(1, 1), 3, parentId: Tracer.IdProvider.NextSpanId());

var b3Header = WriteB3SingleFormat(context);
b3Header.Should().Be(context.TraceId + "-" + context.SpanId + "-" + context.ParentId);
b3Header.Should().Be(Encoding.UTF8.GetString(WriteB3SingleFormatAsBytes(context)));
}


[Fact(DisplayName = "Should parse 128bit B3 single format header with sampling and parent id (max length)")]
public void ShouldParseB3SingleHeaderWithSamplingAndParentId128Bit()
{
var context = new SpanContext(new TraceId(1, 1), 3, parentId: Tracer.IdProvider.NextSpanId(), sampled: true);

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}

[Fact(DisplayName = "Should parse 128bit B3 single format header with sampling")]
public void ShouldParseB3SingleHeaderWithSampling128Bit()
{
var context = new SpanContext(new TraceId(1, 1), 3, sampled: true);

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}

[Fact(DisplayName = "Should parse 128bit B3 single format header with debug")]
public void ShouldParseB3SingleHeaderWithDebug128Bit()
{
var context = new SpanContext(new TraceId(1, 1), 3, debug: true);

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}

[Fact(DisplayName = "Should parse 128bit B3 single format header")]
public void ShouldParseB3SingleHeader128Bit()
{
var context = new SpanContext(new TraceId(1, 1), 3);

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}

[Fact(DisplayName = "Should parse 128bit B3 single format header with parentId only")]
public void ShouldParseB3SingleHeaderParentIdOnly128Bit()
{
var context = new SpanContext(new TraceId(1, 1), 3, parentId: "1aae83b1d7e325ce");

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}

[Fact(DisplayName = "Should parse 64bit B3 single format header with sampling and parent id")]
public void ShouldParseB3SingleHeaderWithSamplingAndParentId()
{
var context = new SpanContext(new TraceId(1), 3, parentId: Tracer.IdProvider.NextSpanId(), sampled: true);

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}

[Fact(DisplayName = "Should parse 64bit B3 single format header with sampling")]
public void ShouldParseB3SingleHeaderWithSampling()
{
var context = new SpanContext(new TraceId(1), 3, sampled: true);

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}

[Fact(DisplayName = "Should parse 64bit B3 single format header with debug")]
public void ShouldParseB3SingleHeaderWithDebug()
{
var context = new SpanContext(new TraceId(1), 3, debug: true);

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}

[Fact(DisplayName = "Should parse 64bit B3 single format header")]
public void ShouldParseB3SingleHeader()
{
var context = new SpanContext(new TraceId(1), 3);

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}

[Fact(DisplayName = "Should parse 64bit B3 single format header with parent id")]
public void ShouldParseB3SingleHeaderWithParentId()
{
var context = new SpanContext(new TraceId(1), 3, parentId: Tracer.IdProvider.NextSpanId());

var b3Header = WriteB3SingleFormat(context);
var b3HeaderParsed = ParseB3SingleFormat(b3Header);

b3HeaderParsed.Should().Be(context);
b3HeaderParsed.Sampled.Should().Be(context.Sampled);
b3HeaderParsed.Debug.Should().Be(context.Debug);
}
}
}
Loading

0 comments on commit 812ba83

Please sign in to comment.