TUN-813: Clean up cloudflared dependencies

This commit is contained in:
Areg Harutyunyan
2018-07-24 18:04:33 -05:00
parent d06fc520c7
commit 0468866626
3310 changed files with 993 additions and 1223303 deletions

View File

@@ -1,148 +0,0 @@
package ext_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/mocktracer"
)
func TestPeerTags(t *testing.T) {
if ext.PeerService != "peer.service" {
t.Fatalf("Invalid PeerService %v", ext.PeerService)
}
tracer := mocktracer.New()
span := tracer.StartSpan("my-trace")
ext.PeerService.Set(span, "my-service")
ext.PeerAddress.Set(span, "my-hostname:8080")
ext.PeerHostname.Set(span, "my-hostname")
ext.PeerHostIPv4.Set(span, uint32(127<<24|1))
ext.PeerHostIPv6.Set(span, "::")
ext.PeerPort.Set(span, uint16(8080))
ext.SamplingPriority.Set(span, uint16(1))
ext.SpanKind.Set(span, ext.SpanKindRPCServerEnum)
ext.SpanKindRPCClient.Set(span)
span.Finish()
rawSpan := tracer.FinishedSpans()[0]
assert.Equal(t, map[string]interface{}{
"peer.service": "my-service",
"peer.address": "my-hostname:8080",
"peer.hostname": "my-hostname",
"peer.ipv4": uint32(127<<24 | 1),
"peer.ipv6": "::",
"peer.port": uint16(8080),
"span.kind": ext.SpanKindRPCClientEnum,
}, rawSpan.Tags())
assert.True(t, span.Context().(mocktracer.MockSpanContext).Sampled)
ext.SamplingPriority.Set(span, uint16(0))
assert.False(t, span.Context().(mocktracer.MockSpanContext).Sampled)
}
func TestHTTPTags(t *testing.T) {
tracer := mocktracer.New()
span := tracer.StartSpan("my-trace", ext.SpanKindRPCServer)
ext.HTTPUrl.Set(span, "test.biz/uri?protocol=false")
ext.HTTPMethod.Set(span, "GET")
ext.HTTPStatusCode.Set(span, 301)
span.Finish()
rawSpan := tracer.FinishedSpans()[0]
assert.Equal(t, map[string]interface{}{
"http.url": "test.biz/uri?protocol=false",
"http.method": "GET",
"http.status_code": uint16(301),
"span.kind": ext.SpanKindRPCServerEnum,
}, rawSpan.Tags())
}
func TestDBTags(t *testing.T) {
tracer := mocktracer.New()
span := tracer.StartSpan("my-trace", ext.SpanKindRPCClient)
ext.DBInstance.Set(span, "127.0.0.1:3306/customers")
ext.DBStatement.Set(span, "SELECT * FROM user_table")
ext.DBType.Set(span, "sql")
ext.DBUser.Set(span, "customer_user")
span.Finish()
rawSpan := tracer.FinishedSpans()[0]
assert.Equal(t, map[string]interface{}{
"db.instance": "127.0.0.1:3306/customers",
"db.statement": "SELECT * FROM user_table",
"db.type": "sql",
"db.user": "customer_user",
"span.kind": ext.SpanKindRPCClientEnum,
}, rawSpan.Tags())
}
func TestMiscTags(t *testing.T) {
tracer := mocktracer.New()
span := tracer.StartSpan("my-trace")
ext.Component.Set(span, "my-awesome-library")
ext.SamplingPriority.Set(span, 1)
ext.Error.Set(span, true)
span.Finish()
rawSpan := tracer.FinishedSpans()[0]
assert.Equal(t, map[string]interface{}{
"component": "my-awesome-library",
"error": true,
}, rawSpan.Tags())
}
func TestRPCServerOption(t *testing.T) {
tracer := mocktracer.New()
parent := tracer.StartSpan("my-trace")
parent.SetBaggageItem("bag", "gage")
carrier := opentracing.HTTPHeadersCarrier{}
err := tracer.Inject(parent.Context(), opentracing.HTTPHeaders, carrier)
if err != nil {
t.Fatal(err)
}
parCtx, err := tracer.Extract(opentracing.HTTPHeaders, carrier)
if err != nil {
t.Fatal(err)
}
tracer.StartSpan("my-child", ext.RPCServerOption(parCtx)).Finish()
rawSpan := tracer.FinishedSpans()[0]
assert.Equal(t, map[string]interface{}{
"span.kind": ext.SpanKindRPCServerEnum,
}, rawSpan.Tags())
assert.Equal(t, map[string]string{
"bag": "gage",
}, rawSpan.Context().(mocktracer.MockSpanContext).Baggage)
}
func TestMessageBusProducerTags(t *testing.T) {
tracer := mocktracer.New()
span := tracer.StartSpan("my-trace", ext.SpanKindProducer)
ext.MessageBusDestination.Set(span, "topic name")
span.Finish()
rawSpan := tracer.FinishedSpans()[0]
assert.Equal(t, map[string]interface{}{
"message_bus.destination": "topic name",
"span.kind": ext.SpanKindProducerEnum,
}, rawSpan.Tags())
}
func TestMessageBusConsumerTags(t *testing.T) {
tracer := mocktracer.New()
span := tracer.StartSpan("my-trace", ext.SpanKindConsumer)
ext.MessageBusDestination.Set(span, "topic name")
span.Finish()
rawSpan := tracer.FinishedSpans()[0]
assert.Equal(t, map[string]interface{}{
"message_bus.destination": "topic name",
"span.kind": ext.SpanKindConsumerEnum,
}, rawSpan.Tags())
}

View File

@@ -1,81 +0,0 @@
package opentracing
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
func TestContextWithSpan(t *testing.T) {
span := &noopSpan{}
ctx := ContextWithSpan(context.Background(), span)
span2 := SpanFromContext(ctx)
if span != span2 {
t.Errorf("Not the same span returned from context, expected=%+v, actual=%+v", span, span2)
}
ctx = context.Background()
span2 = SpanFromContext(ctx)
if span2 != nil {
t.Errorf("Expected nil span, found %+v", span2)
}
ctx = ContextWithSpan(ctx, span)
span2 = SpanFromContext(ctx)
if span != span2 {
t.Errorf("Not the same span returned from context, expected=%+v, actual=%+v", span, span2)
}
}
func TestStartSpanFromContext(t *testing.T) {
testTracer := testTracer{}
// Test the case where there *is* a Span in the Context.
{
parentSpan := &testSpan{}
parentCtx := ContextWithSpan(context.Background(), parentSpan)
childSpan, childCtx := startSpanFromContextWithTracer(parentCtx, testTracer, "child")
if !childSpan.Context().(testSpanContext).HasParent {
t.Errorf("Failed to find parent: %v", childSpan)
}
if !childSpan.(testSpan).Equal(SpanFromContext(childCtx)) {
t.Errorf("Unable to find child span in context: %v", childCtx)
}
}
// Test the case where there *is not* a Span in the Context.
{
emptyCtx := context.Background()
childSpan, childCtx := startSpanFromContextWithTracer(emptyCtx, testTracer, "child")
if childSpan.Context().(testSpanContext).HasParent {
t.Errorf("Should not have found parent: %v", childSpan)
}
if !childSpan.(testSpan).Equal(SpanFromContext(childCtx)) {
t.Errorf("Unable to find child span in context: %v", childCtx)
}
}
}
func TestStartSpanFromContextOptions(t *testing.T) {
testTracer := testTracer{}
// Test options are passed to tracer
startTime := time.Now().Add(-10 * time.Second) // ten seconds ago
span, ctx := startSpanFromContextWithTracer(
context.Background(), testTracer, "parent", StartTime(startTime), Tag{"component", "test"})
assert.Equal(t, "test", span.(testSpan).Tags["component"])
assert.Equal(t, startTime, span.(testSpan).StartTime)
// Test it also works for a child span
childStartTime := startTime.Add(3 * time.Second)
childSpan, _ := startSpanFromContextWithTracer(
ctx, testTracer, "child", StartTime(childStartTime))
assert.Equal(t, childSpan.(testSpan).Tags["component"], nil)
assert.Equal(t, childSpan.(testSpan).StartTime, childStartTime)
}

View File

@@ -1,39 +0,0 @@
package log
import (
"fmt"
"testing"
)
func TestFieldString(t *testing.T) {
testCases := []struct {
field Field
expected string
}{
{
field: String("key", "value"),
expected: "key:value",
},
{
field: Bool("key", true),
expected: "key:true",
},
{
field: Int("key", 5),
expected: "key:5",
},
{
field: Error(fmt.Errorf("err msg")),
expected: "error:err msg",
},
{
field: Error(nil),
expected: "error:<nil>",
},
}
for i, tc := range testCases {
if str := tc.field.String(); str != tc.expected {
t.Errorf("%d: expected '%s', got '%s'", i, tc.expected, str)
}
}
}

View File

@@ -1,105 +0,0 @@
package mocktracer
import (
"fmt"
"reflect"
"time"
"github.com/opentracing/opentracing-go/log"
)
// MockLogRecord represents data logged to a Span via Span.LogFields or
// Span.LogKV.
type MockLogRecord struct {
Timestamp time.Time
Fields []MockKeyValue
}
// MockKeyValue represents a single key:value pair.
type MockKeyValue struct {
Key string
// All MockLogRecord values are coerced to strings via fmt.Sprint(), though
// we retain their type separately.
ValueKind reflect.Kind
ValueString string
}
// EmitString belongs to the log.Encoder interface
func (m *MockKeyValue) EmitString(key, value string) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitBool belongs to the log.Encoder interface
func (m *MockKeyValue) EmitBool(key string, value bool) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitInt belongs to the log.Encoder interface
func (m *MockKeyValue) EmitInt(key string, value int) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitInt32 belongs to the log.Encoder interface
func (m *MockKeyValue) EmitInt32(key string, value int32) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitInt64 belongs to the log.Encoder interface
func (m *MockKeyValue) EmitInt64(key string, value int64) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitUint32 belongs to the log.Encoder interface
func (m *MockKeyValue) EmitUint32(key string, value uint32) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitUint64 belongs to the log.Encoder interface
func (m *MockKeyValue) EmitUint64(key string, value uint64) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitFloat32 belongs to the log.Encoder interface
func (m *MockKeyValue) EmitFloat32(key string, value float32) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitFloat64 belongs to the log.Encoder interface
func (m *MockKeyValue) EmitFloat64(key string, value float64) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitObject belongs to the log.Encoder interface
func (m *MockKeyValue) EmitObject(key string, value interface{}) {
m.Key = key
m.ValueKind = reflect.TypeOf(value).Kind()
m.ValueString = fmt.Sprint(value)
}
// EmitLazyLogger belongs to the log.Encoder interface
func (m *MockKeyValue) EmitLazyLogger(value log.LazyLogger) {
var meta MockKeyValue
value(&meta)
m.Key = meta.Key
m.ValueKind = meta.ValueKind
m.ValueString = meta.ValueString
}

View File

@@ -1,282 +0,0 @@
package mocktracer
import (
"fmt"
"sync"
"sync/atomic"
"time"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"
)
// MockSpanContext is an opentracing.SpanContext implementation.
//
// It is entirely unsuitable for production use, but appropriate for tests
// that want to verify tracing behavior in other frameworks/applications.
//
// By default all spans have Sampled=true flag, unless {"sampling.priority": 0}
// tag is set.
type MockSpanContext struct {
TraceID int
SpanID int
Sampled bool
Baggage map[string]string
}
var mockIDSource = uint32(42)
func nextMockID() int {
return int(atomic.AddUint32(&mockIDSource, 1))
}
// ForeachBaggageItem belongs to the SpanContext interface
func (c MockSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {
for k, v := range c.Baggage {
if !handler(k, v) {
break
}
}
}
// WithBaggageItem creates a new context with an extra baggage item.
func (c MockSpanContext) WithBaggageItem(key, value string) MockSpanContext {
var newBaggage map[string]string
if c.Baggage == nil {
newBaggage = map[string]string{key: value}
} else {
newBaggage = make(map[string]string, len(c.Baggage)+1)
for k, v := range c.Baggage {
newBaggage[k] = v
}
newBaggage[key] = value
}
// Use positional parameters so the compiler will help catch new fields.
return MockSpanContext{c.TraceID, c.SpanID, c.Sampled, newBaggage}
}
// MockSpan is an opentracing.Span implementation that exports its internal
// state for testing purposes.
type MockSpan struct {
sync.RWMutex
ParentID int
OperationName string
StartTime time.Time
FinishTime time.Time
// All of the below are protected by the embedded RWMutex.
SpanContext MockSpanContext
tags map[string]interface{}
logs []MockLogRecord
tracer *MockTracer
}
func newMockSpan(t *MockTracer, name string, opts opentracing.StartSpanOptions) *MockSpan {
tags := opts.Tags
if tags == nil {
tags = map[string]interface{}{}
}
traceID := nextMockID()
parentID := int(0)
var baggage map[string]string
sampled := true
if len(opts.References) > 0 {
traceID = opts.References[0].ReferencedContext.(MockSpanContext).TraceID
parentID = opts.References[0].ReferencedContext.(MockSpanContext).SpanID
sampled = opts.References[0].ReferencedContext.(MockSpanContext).Sampled
baggage = opts.References[0].ReferencedContext.(MockSpanContext).Baggage
}
spanContext := MockSpanContext{traceID, nextMockID(), sampled, baggage}
startTime := opts.StartTime
if startTime.IsZero() {
startTime = time.Now()
}
return &MockSpan{
ParentID: parentID,
OperationName: name,
StartTime: startTime,
tags: tags,
logs: []MockLogRecord{},
SpanContext: spanContext,
tracer: t,
}
}
// Tags returns a copy of tags accumulated by the span so far
func (s *MockSpan) Tags() map[string]interface{} {
s.RLock()
defer s.RUnlock()
tags := make(map[string]interface{})
for k, v := range s.tags {
tags[k] = v
}
return tags
}
// Tag returns a single tag
func (s *MockSpan) Tag(k string) interface{} {
s.RLock()
defer s.RUnlock()
return s.tags[k]
}
// Logs returns a copy of logs accumulated in the span so far
func (s *MockSpan) Logs() []MockLogRecord {
s.RLock()
defer s.RUnlock()
logs := make([]MockLogRecord, len(s.logs))
copy(logs, s.logs)
return logs
}
// Context belongs to the Span interface
func (s *MockSpan) Context() opentracing.SpanContext {
return s.SpanContext
}
// SetTag belongs to the Span interface
func (s *MockSpan) SetTag(key string, value interface{}) opentracing.Span {
s.Lock()
defer s.Unlock()
if key == string(ext.SamplingPriority) {
if v, ok := value.(uint16); ok {
s.SpanContext.Sampled = v > 0
return s
}
if v, ok := value.(int); ok {
s.SpanContext.Sampled = v > 0
return s
}
}
s.tags[key] = value
return s
}
// SetBaggageItem belongs to the Span interface
func (s *MockSpan) SetBaggageItem(key, val string) opentracing.Span {
s.Lock()
defer s.Unlock()
s.SpanContext = s.SpanContext.WithBaggageItem(key, val)
return s
}
// BaggageItem belongs to the Span interface
func (s *MockSpan) BaggageItem(key string) string {
s.RLock()
defer s.RUnlock()
return s.SpanContext.Baggage[key]
}
// Finish belongs to the Span interface
func (s *MockSpan) Finish() {
s.Lock()
s.FinishTime = time.Now()
s.Unlock()
s.tracer.recordSpan(s)
}
// FinishWithOptions belongs to the Span interface
func (s *MockSpan) FinishWithOptions(opts opentracing.FinishOptions) {
s.Lock()
s.FinishTime = opts.FinishTime
s.Unlock()
// Handle any late-bound LogRecords.
for _, lr := range opts.LogRecords {
s.logFieldsWithTimestamp(lr.Timestamp, lr.Fields...)
}
// Handle (deprecated) BulkLogData.
for _, ld := range opts.BulkLogData {
if ld.Payload != nil {
s.logFieldsWithTimestamp(
ld.Timestamp,
log.String("event", ld.Event),
log.Object("payload", ld.Payload))
} else {
s.logFieldsWithTimestamp(
ld.Timestamp,
log.String("event", ld.Event))
}
}
s.tracer.recordSpan(s)
}
// String allows printing span for debugging
func (s *MockSpan) String() string {
return fmt.Sprintf(
"traceId=%d, spanId=%d, parentId=%d, sampled=%t, name=%s",
s.SpanContext.TraceID, s.SpanContext.SpanID, s.ParentID,
s.SpanContext.Sampled, s.OperationName)
}
// LogFields belongs to the Span interface
func (s *MockSpan) LogFields(fields ...log.Field) {
s.logFieldsWithTimestamp(time.Now(), fields...)
}
// The caller MUST NOT hold s.Lock
func (s *MockSpan) logFieldsWithTimestamp(ts time.Time, fields ...log.Field) {
lr := MockLogRecord{
Timestamp: ts,
Fields: make([]MockKeyValue, len(fields)),
}
for i, f := range fields {
outField := &(lr.Fields[i])
f.Marshal(outField)
}
s.Lock()
defer s.Unlock()
s.logs = append(s.logs, lr)
}
// LogKV belongs to the Span interface.
//
// This implementations coerces all "values" to strings, though that is not
// something all implementations need to do. Indeed, a motivated person can and
// probably should have this do a typed switch on the values.
func (s *MockSpan) LogKV(keyValues ...interface{}) {
if len(keyValues)%2 != 0 {
s.LogFields(log.Error(fmt.Errorf("Non-even keyValues len: %v", len(keyValues))))
return
}
fields, err := log.InterleavedKVToFields(keyValues...)
if err != nil {
s.LogFields(log.Error(err), log.String("function", "LogKV"))
return
}
s.LogFields(fields...)
}
// LogEvent belongs to the Span interface
func (s *MockSpan) LogEvent(event string) {
s.LogFields(log.String("event", event))
}
// LogEventWithPayload belongs to the Span interface
func (s *MockSpan) LogEventWithPayload(event string, payload interface{}) {
s.LogFields(log.String("event", event), log.Object("payload", payload))
}
// Log belongs to the Span interface
func (s *MockSpan) Log(data opentracing.LogData) {
panic("MockSpan.Log() no longer supported")
}
// SetOperationName belongs to the Span interface
func (s *MockSpan) SetOperationName(operationName string) opentracing.Span {
s.Lock()
defer s.Unlock()
s.OperationName = operationName
return s
}
// Tracer belongs to the Span interface
func (s *MockSpan) Tracer() opentracing.Tracer {
return s.tracer
}

View File

@@ -1,105 +0,0 @@
package mocktracer
import (
"sync"
"github.com/opentracing/opentracing-go"
)
// New returns a MockTracer opentracing.Tracer implementation that's intended
// to facilitate tests of OpenTracing instrumentation.
func New() *MockTracer {
t := &MockTracer{
finishedSpans: []*MockSpan{},
injectors: make(map[interface{}]Injector),
extractors: make(map[interface{}]Extractor),
}
// register default injectors/extractors
textPropagator := new(TextMapPropagator)
t.RegisterInjector(opentracing.TextMap, textPropagator)
t.RegisterExtractor(opentracing.TextMap, textPropagator)
httpPropagator := &TextMapPropagator{HTTPHeaders: true}
t.RegisterInjector(opentracing.HTTPHeaders, httpPropagator)
t.RegisterExtractor(opentracing.HTTPHeaders, httpPropagator)
return t
}
// MockTracer is only intended for testing OpenTracing instrumentation.
//
// It is entirely unsuitable for production use, but appropriate for tests
// that want to verify tracing behavior in other frameworks/applications.
type MockTracer struct {
sync.RWMutex
finishedSpans []*MockSpan
injectors map[interface{}]Injector
extractors map[interface{}]Extractor
}
// FinishedSpans returns all spans that have been Finish()'ed since the
// MockTracer was constructed or since the last call to its Reset() method.
func (t *MockTracer) FinishedSpans() []*MockSpan {
t.RLock()
defer t.RUnlock()
spans := make([]*MockSpan, len(t.finishedSpans))
copy(spans, t.finishedSpans)
return spans
}
// Reset clears the internally accumulated finished spans. Note that any
// extant MockSpans will still append to finishedSpans when they Finish(),
// even after a call to Reset().
func (t *MockTracer) Reset() {
t.Lock()
defer t.Unlock()
t.finishedSpans = []*MockSpan{}
}
// StartSpan belongs to the Tracer interface.
func (t *MockTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span {
sso := opentracing.StartSpanOptions{}
for _, o := range opts {
o.Apply(&sso)
}
return newMockSpan(t, operationName, sso)
}
// RegisterInjector registers injector for given format
func (t *MockTracer) RegisterInjector(format interface{}, injector Injector) {
t.injectors[format] = injector
}
// RegisterExtractor registers extractor for given format
func (t *MockTracer) RegisterExtractor(format interface{}, extractor Extractor) {
t.extractors[format] = extractor
}
// Inject belongs to the Tracer interface.
func (t *MockTracer) Inject(sm opentracing.SpanContext, format interface{}, carrier interface{}) error {
spanContext, ok := sm.(MockSpanContext)
if !ok {
return opentracing.ErrInvalidCarrier
}
injector, ok := t.injectors[format]
if !ok {
return opentracing.ErrUnsupportedFormat
}
return injector.Inject(spanContext, carrier)
}
// Extract belongs to the Tracer interface.
func (t *MockTracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) {
extractor, ok := t.extractors[format]
if !ok {
return nil, opentracing.ErrUnsupportedFormat
}
return extractor.Extract(carrier)
}
func (t *MockTracer) recordSpan(span *MockSpan) {
t.Lock()
defer t.Unlock()
t.finishedSpans = append(t.finishedSpans, span)
}

View File

@@ -1,268 +0,0 @@
package mocktracer
import (
"net/http"
"reflect"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"
)
func TestMockTracer_StartSpan(t *testing.T) {
tracer := New()
span1 := tracer.StartSpan(
"a",
opentracing.Tags(map[string]interface{}{"x": "y"}))
span2 := span1.Tracer().StartSpan(
"", opentracing.ChildOf(span1.Context()))
span2.Finish()
span1.Finish()
spans := tracer.FinishedSpans()
assert.Equal(t, 2, len(spans))
parent := spans[1]
child := spans[0]
assert.Equal(t, map[string]interface{}{"x": "y"}, parent.Tags())
assert.Equal(t, child.ParentID, parent.Context().(MockSpanContext).SpanID)
}
func TestMockSpan_SetOperationName(t *testing.T) {
tracer := New()
span := tracer.StartSpan("")
span.SetOperationName("x")
assert.Equal(t, "x", span.(*MockSpan).OperationName)
}
func TestMockSpanContext_Baggage(t *testing.T) {
tracer := New()
span := tracer.StartSpan("x")
span.SetBaggageItem("x", "y")
assert.Equal(t, "y", span.BaggageItem("x"))
assert.Equal(t, map[string]string{"x": "y"}, span.Context().(MockSpanContext).Baggage)
baggage := make(map[string]string)
span.Context().ForeachBaggageItem(func(k, v string) bool {
baggage[k] = v
return true
})
assert.Equal(t, map[string]string{"x": "y"}, baggage)
span.SetBaggageItem("a", "b")
baggage = make(map[string]string)
span.Context().ForeachBaggageItem(func(k, v string) bool {
baggage[k] = v
return false // exit early
})
assert.Equal(t, 2, len(span.Context().(MockSpanContext).Baggage))
assert.Equal(t, 1, len(baggage))
}
func TestMockSpan_Tag(t *testing.T) {
tracer := New()
span := tracer.StartSpan("x")
span.SetTag("x", "y")
assert.Equal(t, "y", span.(*MockSpan).Tag("x"))
}
func TestMockSpan_Tags(t *testing.T) {
tracer := New()
span := tracer.StartSpan("x")
span.SetTag("x", "y")
assert.Equal(t, map[string]interface{}{"x": "y"}, span.(*MockSpan).Tags())
}
func TestMockTracer_FinishedSpans_and_Reset(t *testing.T) {
tracer := New()
span := tracer.StartSpan("x")
span.SetTag("x", "y")
span.Finish()
spans := tracer.FinishedSpans()
assert.Equal(t, 1, len(spans))
assert.Equal(t, map[string]interface{}{"x": "y"}, spans[0].Tags())
tracer.Reset()
spans = tracer.FinishedSpans()
assert.Equal(t, 0, len(spans))
}
func zeroOutTimestamps(recs []MockLogRecord) {
for i := range recs {
recs[i].Timestamp = time.Time{}
}
}
func TestMockSpan_LogKV(t *testing.T) {
tracer := New()
span := tracer.StartSpan("s")
span.LogKV("key0", "string0")
span.LogKV("key1", "string1", "key2", uint32(42))
span.Finish()
spans := tracer.FinishedSpans()
assert.Equal(t, 1, len(spans))
actual := spans[0].Logs()
zeroOutTimestamps(actual)
assert.Equal(t, []MockLogRecord{
MockLogRecord{
Fields: []MockKeyValue{
MockKeyValue{Key: "key0", ValueKind: reflect.String, ValueString: "string0"},
},
},
MockLogRecord{
Fields: []MockKeyValue{
MockKeyValue{Key: "key1", ValueKind: reflect.String, ValueString: "string1"},
MockKeyValue{Key: "key2", ValueKind: reflect.Uint32, ValueString: "42"},
},
},
}, actual)
}
func TestMockSpan_LogFields(t *testing.T) {
tracer := New()
span := tracer.StartSpan("s")
span.LogFields(log.String("key0", "string0"))
span.LogFields(log.String("key1", "string1"), log.Uint32("key2", uint32(42)))
span.LogFields(log.Lazy(func(fv log.Encoder) {
fv.EmitInt("key_lazy", 12)
}))
span.FinishWithOptions(opentracing.FinishOptions{
LogRecords: []opentracing.LogRecord{
{Timestamp: time.Now(), Fields: []log.Field{log.String("key9", "finish")}},
}})
spans := tracer.FinishedSpans()
assert.Equal(t, 1, len(spans))
actual := spans[0].Logs()
zeroOutTimestamps(actual)
assert.Equal(t, []MockLogRecord{
MockLogRecord{
Fields: []MockKeyValue{
MockKeyValue{Key: "key0", ValueKind: reflect.String, ValueString: "string0"},
},
},
MockLogRecord{
Fields: []MockKeyValue{
MockKeyValue{Key: "key1", ValueKind: reflect.String, ValueString: "string1"},
MockKeyValue{Key: "key2", ValueKind: reflect.Uint32, ValueString: "42"},
},
},
MockLogRecord{
Fields: []MockKeyValue{
// Note that the LazyLogger gets to control the key as well as the value.
MockKeyValue{Key: "key_lazy", ValueKind: reflect.Int, ValueString: "12"},
},
},
MockLogRecord{
Fields: []MockKeyValue{
MockKeyValue{Key: "key9", ValueKind: reflect.String, ValueString: "finish"},
},
},
}, actual)
}
func TestMockSpan_DeprecatedLogs(t *testing.T) {
tracer := New()
span := tracer.StartSpan("x")
span.LogEvent("x")
span.LogEventWithPayload("y", "z")
span.LogEvent("a")
span.FinishWithOptions(opentracing.FinishOptions{
BulkLogData: []opentracing.LogData{{Event: "f"}}})
spans := tracer.FinishedSpans()
assert.Equal(t, 1, len(spans))
actual := spans[0].Logs()
zeroOutTimestamps(actual)
assert.Equal(t, []MockLogRecord{
MockLogRecord{
Fields: []MockKeyValue{
MockKeyValue{Key: "event", ValueKind: reflect.String, ValueString: "x"},
},
},
MockLogRecord{
Fields: []MockKeyValue{
MockKeyValue{Key: "event", ValueKind: reflect.String, ValueString: "y"},
MockKeyValue{Key: "payload", ValueKind: reflect.String, ValueString: "z"},
},
},
MockLogRecord{
Fields: []MockKeyValue{
MockKeyValue{Key: "event", ValueKind: reflect.String, ValueString: "a"},
},
},
MockLogRecord{
Fields: []MockKeyValue{
MockKeyValue{Key: "event", ValueKind: reflect.String, ValueString: "f"},
},
},
}, actual)
}
func TestMockTracer_Propagation(t *testing.T) {
textCarrier := func() interface{} {
return opentracing.TextMapCarrier(make(map[string]string))
}
textLen := func(c interface{}) int {
return len(c.(opentracing.TextMapCarrier))
}
httpCarrier := func() interface{} {
httpHeaders := http.Header(make(map[string][]string))
return opentracing.HTTPHeadersCarrier(httpHeaders)
}
httpLen := func(c interface{}) int {
return len(c.(opentracing.HTTPHeadersCarrier))
}
tests := []struct {
sampled bool
format opentracing.BuiltinFormat
carrier func() interface{}
len func(interface{}) int
}{
{sampled: true, format: opentracing.TextMap, carrier: textCarrier, len: textLen},
{sampled: false, format: opentracing.TextMap, carrier: textCarrier, len: textLen},
{sampled: true, format: opentracing.HTTPHeaders, carrier: httpCarrier, len: httpLen},
{sampled: false, format: opentracing.HTTPHeaders, carrier: httpCarrier, len: httpLen},
}
for _, test := range tests {
tracer := New()
span := tracer.StartSpan("x")
span.SetBaggageItem("x", "y:z") // colon should be URL encoded as %3A
if !test.sampled {
ext.SamplingPriority.Set(span, 0)
}
mSpan := span.(*MockSpan)
assert.Equal(t, opentracing.ErrUnsupportedFormat,
tracer.Inject(span.Context(), opentracing.Binary, nil))
assert.Equal(t, opentracing.ErrInvalidCarrier,
tracer.Inject(span.Context(), opentracing.TextMap, span))
carrier := test.carrier()
err := tracer.Inject(span.Context(), test.format, carrier)
require.NoError(t, err)
assert.Equal(t, 4, test.len(carrier), "expect baggage + 2 ids + sampled")
if test.format == opentracing.HTTPHeaders {
c := carrier.(opentracing.HTTPHeadersCarrier)
assert.Equal(t, "y%3Az", c["Mockpfx-Baggage-X"][0])
}
_, err = tracer.Extract(opentracing.Binary, nil)
assert.Equal(t, opentracing.ErrUnsupportedFormat, err)
_, err = tracer.Extract(opentracing.TextMap, tracer)
assert.Equal(t, opentracing.ErrInvalidCarrier, err)
extractedContext, err := tracer.Extract(test.format, carrier)
require.NoError(t, err)
assert.Equal(t, mSpan.SpanContext.TraceID, extractedContext.(MockSpanContext).TraceID)
assert.Equal(t, mSpan.SpanContext.SpanID, extractedContext.(MockSpanContext).SpanID)
assert.Equal(t, test.sampled, extractedContext.(MockSpanContext).Sampled)
assert.Equal(t, "y:z", extractedContext.(MockSpanContext).Baggage["x"])
}
}

View File

@@ -1,120 +0,0 @@
package mocktracer
import (
"fmt"
"net/url"
"strconv"
"strings"
"github.com/opentracing/opentracing-go"
)
const mockTextMapIdsPrefix = "mockpfx-ids-"
const mockTextMapBaggagePrefix = "mockpfx-baggage-"
var emptyContext = MockSpanContext{}
// Injector is responsible for injecting SpanContext instances in a manner suitable
// for propagation via a format-specific "carrier" object. Typically the
// injection will take place across an RPC boundary, but message queues and
// other IPC mechanisms are also reasonable places to use an Injector.
type Injector interface {
// Inject takes `SpanContext` and injects it into `carrier`. The actual type
// of `carrier` depends on the `format` passed to `Tracer.Inject()`.
//
// Implementations may return opentracing.ErrInvalidCarrier or any other
// implementation-specific error if injection fails.
Inject(ctx MockSpanContext, carrier interface{}) error
}
// Extractor is responsible for extracting SpanContext instances from a
// format-specific "carrier" object. Typically the extraction will take place
// on the server side of an RPC boundary, but message queues and other IPC
// mechanisms are also reasonable places to use an Extractor.
type Extractor interface {
// Extract decodes a SpanContext instance from the given `carrier`,
// or (nil, opentracing.ErrSpanContextNotFound) if no context could
// be found in the `carrier`.
Extract(carrier interface{}) (MockSpanContext, error)
}
// TextMapPropagator implements Injector/Extractor for TextMap and HTTPHeaders formats.
type TextMapPropagator struct {
HTTPHeaders bool
}
// Inject implements the Injector interface
func (t *TextMapPropagator) Inject(spanContext MockSpanContext, carrier interface{}) error {
writer, ok := carrier.(opentracing.TextMapWriter)
if !ok {
return opentracing.ErrInvalidCarrier
}
// Ids:
writer.Set(mockTextMapIdsPrefix+"traceid", strconv.Itoa(spanContext.TraceID))
writer.Set(mockTextMapIdsPrefix+"spanid", strconv.Itoa(spanContext.SpanID))
writer.Set(mockTextMapIdsPrefix+"sampled", fmt.Sprint(spanContext.Sampled))
// Baggage:
for baggageKey, baggageVal := range spanContext.Baggage {
safeVal := baggageVal
if t.HTTPHeaders {
safeVal = url.QueryEscape(baggageVal)
}
writer.Set(mockTextMapBaggagePrefix+baggageKey, safeVal)
}
return nil
}
// Extract implements the Extractor interface
func (t *TextMapPropagator) Extract(carrier interface{}) (MockSpanContext, error) {
reader, ok := carrier.(opentracing.TextMapReader)
if !ok {
return emptyContext, opentracing.ErrInvalidCarrier
}
rval := MockSpanContext{0, 0, true, nil}
err := reader.ForeachKey(func(key, val string) error {
lowerKey := strings.ToLower(key)
switch {
case lowerKey == mockTextMapIdsPrefix+"traceid":
// Ids:
i, err := strconv.Atoi(val)
if err != nil {
return err
}
rval.TraceID = i
case lowerKey == mockTextMapIdsPrefix+"spanid":
// Ids:
i, err := strconv.Atoi(val)
if err != nil {
return err
}
rval.SpanID = i
case lowerKey == mockTextMapIdsPrefix+"sampled":
b, err := strconv.ParseBool(val)
if err != nil {
return err
}
rval.Sampled = b
case strings.HasPrefix(lowerKey, mockTextMapBaggagePrefix):
// Baggage:
if rval.Baggage == nil {
rval.Baggage = make(map[string]string)
}
safeVal := val
if t.HTTPHeaders {
// unescape errors are ignored, nothing can be done
if rawVal, err := url.QueryUnescape(val); err == nil {
safeVal = rawVal
}
}
rval.Baggage[lowerKey[len(mockTextMapBaggagePrefix):]] = safeVal
}
return nil
})
if rval.TraceID == 0 || rval.SpanID == 0 {
return emptyContext, opentracing.ErrSpanContextNotFound
}
if err != nil {
return emptyContext, err
}
return rval, nil
}

View File

@@ -1,31 +0,0 @@
package opentracing
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestChildOfAndFollowsFrom(t *testing.T) {
tests := []struct {
newOpt func(SpanContext) SpanReference
refType SpanReferenceType
name string
}{
{ChildOf, ChildOfRef, "ChildOf"},
{FollowsFrom, FollowsFromRef, "FollowsFrom"},
}
for _, test := range tests {
opts := new(StartSpanOptions)
test.newOpt(nil).Apply(opts)
require.Nil(t, opts.References, "%s(nil) must not append a reference", test.name)
ctx := new(noopSpanContext)
test.newOpt(ctx).Apply(opts)
require.Equal(t, []SpanReference{
SpanReference{ReferencedContext: ctx, Type: test.refType},
}, opts.References, "%s(ctx) must append a reference", test.name)
}
}

View File

@@ -1,93 +0,0 @@
package opentracing
import (
"net/http"
"strconv"
"testing"
)
const testHeaderPrefix = "testprefix-"
func TestTextMapCarrierInject(t *testing.T) {
m := make(map[string]string)
m["NotOT"] = "blah"
m["opname"] = "AlsoNotOT"
tracer := testTracer{}
span := tracer.StartSpan("someSpan")
fakeID := span.Context().(testSpanContext).FakeID
carrier := TextMapCarrier(m)
if err := span.Tracer().Inject(span.Context(), TextMap, carrier); err != nil {
t.Fatal(err)
}
if len(m) != 3 {
t.Errorf("Unexpected header length: %v", len(m))
}
// The prefix comes from just above; the suffix comes from
// testTracer.Inject().
if m["testprefix-fakeid"] != strconv.Itoa(fakeID) {
t.Errorf("Could not find fakeid at expected key")
}
}
func TestTextMapCarrierExtract(t *testing.T) {
m := make(map[string]string)
m["NotOT"] = "blah"
m["opname"] = "AlsoNotOT"
m["testprefix-fakeid"] = "42"
tracer := testTracer{}
carrier := TextMapCarrier(m)
extractedContext, err := tracer.Extract(TextMap, carrier)
if err != nil {
t.Fatal(err)
}
if extractedContext.(testSpanContext).FakeID != 42 {
t.Errorf("Failed to read testprefix-fakeid correctly")
}
}
func TestHTTPHeaderInject(t *testing.T) {
h := http.Header{}
h.Add("NotOT", "blah")
h.Add("opname", "AlsoNotOT")
tracer := testTracer{}
span := tracer.StartSpan("someSpan")
fakeID := span.Context().(testSpanContext).FakeID
// Use HTTPHeadersCarrier to wrap around `h`.
carrier := HTTPHeadersCarrier(h)
if err := span.Tracer().Inject(span.Context(), HTTPHeaders, carrier); err != nil {
t.Fatal(err)
}
if len(h) != 3 {
t.Errorf("Unexpected header length: %v", len(h))
}
// The prefix comes from just above; the suffix comes from
// testTracer.Inject().
if h.Get("testprefix-fakeid") != strconv.Itoa(fakeID) {
t.Errorf("Could not find fakeid at expected key")
}
}
func TestHTTPHeaderExtract(t *testing.T) {
h := http.Header{}
h.Add("NotOT", "blah")
h.Add("opname", "AlsoNotOT")
h.Add("testprefix-fakeid", "42")
tracer := testTracer{}
// Use HTTPHeadersCarrier to wrap around `h`.
carrier := HTTPHeadersCarrier(h)
spanContext, err := tracer.Extract(HTTPHeaders, carrier)
if err != nil {
t.Fatal(err)
}
if spanContext.(testSpanContext).FakeID != 42 {
t.Errorf("Failed to read testprefix-fakeid correctly")
}
}

View File

@@ -1,138 +0,0 @@
package opentracing
import (
"strconv"
"strings"
"time"
"github.com/opentracing/opentracing-go/log"
)
const testHTTPHeaderPrefix = "testprefix-"
// testTracer is a most-noop Tracer implementation that makes it possible for
// unittests to verify whether certain methods were / were not called.
type testTracer struct{}
var fakeIDSource = 1
func nextFakeID() int {
fakeIDSource++
return fakeIDSource
}
type testSpanContext struct {
HasParent bool
FakeID int
}
func (n testSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {}
type testSpan struct {
spanContext testSpanContext
OperationName string
StartTime time.Time
Tags map[string]interface{}
}
func (n testSpan) Equal(os Span) bool {
other, ok := os.(testSpan)
if !ok {
return false
}
if n.spanContext != other.spanContext {
return false
}
if n.OperationName != other.OperationName {
return false
}
if !n.StartTime.Equal(other.StartTime) {
return false
}
if len(n.Tags) != len(other.Tags) {
return false
}
for k, v := range n.Tags {
if ov, ok := other.Tags[k]; !ok || ov != v {
return false
}
}
return true
}
// testSpan:
func (n testSpan) Context() SpanContext { return n.spanContext }
func (n testSpan) SetTag(key string, value interface{}) Span { return n }
func (n testSpan) Finish() {}
func (n testSpan) FinishWithOptions(opts FinishOptions) {}
func (n testSpan) LogFields(fields ...log.Field) {}
func (n testSpan) LogKV(kvs ...interface{}) {}
func (n testSpan) SetOperationName(operationName string) Span { return n }
func (n testSpan) Tracer() Tracer { return testTracer{} }
func (n testSpan) SetBaggageItem(key, val string) Span { return n }
func (n testSpan) BaggageItem(key string) string { return "" }
func (n testSpan) LogEvent(event string) {}
func (n testSpan) LogEventWithPayload(event string, payload interface{}) {}
func (n testSpan) Log(data LogData) {}
// StartSpan belongs to the Tracer interface.
func (n testTracer) StartSpan(operationName string, opts ...StartSpanOption) Span {
sso := StartSpanOptions{}
for _, o := range opts {
o.Apply(&sso)
}
return n.startSpanWithOptions(operationName, sso)
}
func (n testTracer) startSpanWithOptions(name string, opts StartSpanOptions) Span {
fakeID := nextFakeID()
if len(opts.References) > 0 {
fakeID = opts.References[0].ReferencedContext.(testSpanContext).FakeID
}
return testSpan{
OperationName: name,
StartTime: opts.StartTime,
Tags: opts.Tags,
spanContext: testSpanContext{
HasParent: len(opts.References) > 0,
FakeID: fakeID,
},
}
}
// Inject belongs to the Tracer interface.
func (n testTracer) Inject(sp SpanContext, format interface{}, carrier interface{}) error {
spanContext := sp.(testSpanContext)
switch format {
case HTTPHeaders, TextMap:
carrier.(TextMapWriter).Set(testHTTPHeaderPrefix+"fakeid", strconv.Itoa(spanContext.FakeID))
return nil
}
return ErrUnsupportedFormat
}
// Extract belongs to the Tracer interface.
func (n testTracer) Extract(format interface{}, carrier interface{}) (SpanContext, error) {
switch format {
case HTTPHeaders, TextMap:
// Just for testing purposes... generally not a worthwhile thing to
// propagate.
sm := testSpanContext{}
err := carrier.(TextMapReader).ForeachKey(func(key, val string) error {
switch strings.ToLower(key) {
case testHTTPHeaderPrefix + "fakeid":
i, err := strconv.Atoi(val)
if err != nil {
return err
}
sm.FakeID = i
}
return nil
})
return sm, err
}
return nil, ErrSpanContextNotFound
}