mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 17:53:21 -04:00 
			
		
		
		
	Dep helper (#2151)
* Add dep task to update go dependencies * Update go dependencies
This commit is contained in:
		
				
					committed by
					
						 Miek Gieben
						Miek Gieben
					
				
			
			
				
	
			
			
			
						parent
						
							8f8b81f56b
						
					
				
				
					commit
					0e8977761d
				
			
							
								
								
									
										58
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/config_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/config_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,58 +0,0 @@ | ||||
| package opentracing | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	ot "github.com/opentracing/opentracing-go" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestConfigurationDefaults(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	assert.Equal(true, config.Enabled) | ||||
| 	assert.Equal(false, config.Debug) | ||||
| 	assert.Equal(float64(1), config.SampleRate) | ||||
| 	assert.Equal("opentracing.test", config.ServiceName) | ||||
| 	assert.Equal("localhost", config.AgentHostname) | ||||
| 	assert.Equal("8126", config.AgentPort) | ||||
| } | ||||
|  | ||||
| func TestConfiguration(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	config.SampleRate = 0 | ||||
| 	config.ServiceName = "api-intake" | ||||
| 	config.AgentHostname = "ddagent.consul.local" | ||||
| 	config.AgentPort = "58126" | ||||
| 	tracer, closer, err := NewTracer(config) | ||||
| 	assert.NotNil(tracer) | ||||
| 	assert.NotNil(closer) | ||||
| 	assert.Nil(err) | ||||
| 	assert.Equal("api-intake", tracer.(*Tracer).config.ServiceName) | ||||
| } | ||||
|  | ||||
| func TestTracerServiceName(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	config.ServiceName = "" | ||||
| 	tracer, closer, err := NewTracer(config) | ||||
| 	assert.Nil(tracer) | ||||
| 	assert.Nil(closer) | ||||
| 	assert.NotNil(err) | ||||
| 	assert.Equal("A Datadog Tracer requires a valid `ServiceName` set", err.Error()) | ||||
| } | ||||
|  | ||||
| func TestDisabledTracer(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	config.Enabled = false | ||||
| 	tracer, closer, err := NewTracer(config) | ||||
| 	assert.IsType(&ot.NoopTracer{}, tracer) | ||||
| 	assert.IsType(&noopCloser{}, closer) | ||||
| 	assert.Nil(err) | ||||
| } | ||||
							
								
								
									
										29
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/context_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/context_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,29 +0,0 @@ | ||||
| package opentracing | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestSpanContextBaggage(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	ctx := SpanContext{} | ||||
| 	ctx = ctx.WithBaggageItem("key", "value") | ||||
| 	assert.Equal("value", ctx.baggage["key"]) | ||||
| } | ||||
|  | ||||
| func TestSpanContextIterator(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	baggageIterator := make(map[string]string) | ||||
| 	ctx := SpanContext{baggage: map[string]string{"key": "value"}} | ||||
| 	ctx.ForeachBaggageItem(func(k, v string) bool { | ||||
| 		baggageIterator[k] = v | ||||
| 		return true | ||||
| 	}) | ||||
|  | ||||
| 	assert.Len(baggageIterator, 1) | ||||
| 	assert.Equal("value", baggageIterator["key"]) | ||||
| } | ||||
							
								
								
									
										30
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/example_context_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/example_context_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,30 +0,0 @@ | ||||
| package opentracing_test | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	opentracing "github.com/opentracing/opentracing-go" | ||||
| ) | ||||
|  | ||||
| // You can leverage the Golang `Context` for intra-process propagation of | ||||
| // Spans. In this example we create a root Span, so that it can be reused | ||||
| // in a nested function to create a child Span. | ||||
| func Example_startContext() { | ||||
| 	// create a new root Span and return a new Context that includes | ||||
| 	// the Span itself | ||||
| 	ctx := context.Background() | ||||
| 	rootSpan, ctx := opentracing.StartSpanFromContext(ctx, "web.request") | ||||
| 	defer rootSpan.Finish() | ||||
|  | ||||
| 	requestHandler(ctx) | ||||
| } | ||||
|  | ||||
| func requestHandler(ctx context.Context) { | ||||
| 	// retrieve the previously set root Span | ||||
| 	span := opentracing.SpanFromContext(ctx) | ||||
| 	span.SetTag("resource.name", "/") | ||||
|  | ||||
| 	// or simply create a new child Span from the previous Context | ||||
| 	childSpan, _ := opentracing.StartSpanFromContext(ctx, "sql.query") | ||||
| 	defer childSpan.Finish() | ||||
| } | ||||
							
								
								
									
										30
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/example_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/example_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,30 +0,0 @@ | ||||
| package opentracing_test | ||||
|  | ||||
| import ( | ||||
| 	// ddtrace namespace is suggested | ||||
| 	ddtrace "github.com/DataDog/dd-trace-go/opentracing" | ||||
| 	opentracing "github.com/opentracing/opentracing-go" | ||||
| ) | ||||
|  | ||||
| func Example_initialization() { | ||||
| 	// create a Tracer configuration | ||||
| 	config := ddtrace.NewConfiguration() | ||||
| 	config.ServiceName = "api-intake" | ||||
| 	config.AgentHostname = "ddagent.consul.local" | ||||
|  | ||||
| 	// initialize a Tracer and ensure a graceful shutdown | ||||
| 	// using the `closer.Close()` | ||||
| 	tracer, closer, err := ddtrace.NewTracer(config) | ||||
| 	if err != nil { | ||||
| 		// handle the configuration error | ||||
| 	} | ||||
| 	defer closer.Close() | ||||
|  | ||||
| 	// set the Datadog tracer as a GlobalTracer | ||||
| 	opentracing.SetGlobalTracer(tracer) | ||||
| 	startWebServer() | ||||
| } | ||||
|  | ||||
| func startWebServer() { | ||||
| 	// start a web server | ||||
| } | ||||
							
								
								
									
										24
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/example_tracing_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/example_tracing_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,24 +0,0 @@ | ||||
| package opentracing_test | ||||
|  | ||||
| import ( | ||||
| 	opentracing "github.com/opentracing/opentracing-go" | ||||
| ) | ||||
|  | ||||
| // You can use the GlobalTracer to create a root Span. If you need to create a hierarchy, | ||||
| // simply use the `ChildOf` reference | ||||
| func Example_startSpan() { | ||||
| 	// use the GlobalTracer previously set | ||||
| 	rootSpan := opentracing.StartSpan("web.request") | ||||
| 	defer rootSpan.Finish() | ||||
|  | ||||
| 	// set the reference to create a hierarchy of spans | ||||
| 	reference := opentracing.ChildOf(rootSpan.Context()) | ||||
| 	childSpan := opentracing.StartSpan("sql.query", reference) | ||||
| 	defer childSpan.Finish() | ||||
|  | ||||
| 	dbQuery() | ||||
| } | ||||
|  | ||||
| func dbQuery() { | ||||
| 	// start a database query | ||||
| } | ||||
							
								
								
									
										81
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/propagators_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/propagators_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,81 +0,0 @@ | ||||
| package opentracing | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
| 	"testing" | ||||
|  | ||||
| 	opentracing "github.com/opentracing/opentracing-go" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestTracerPropagationDefaults(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
|  | ||||
| 	root := tracer.StartSpan("web.request") | ||||
| 	ctx := root.Context() | ||||
| 	headers := http.Header{} | ||||
|  | ||||
| 	// inject the SpanContext | ||||
| 	carrier := opentracing.HTTPHeadersCarrier(headers) | ||||
| 	err := tracer.Inject(ctx, opentracing.HTTPHeaders, carrier) | ||||
| 	assert.Nil(err) | ||||
|  | ||||
| 	// retrieve the SpanContext | ||||
| 	propagated, err := tracer.Extract(opentracing.HTTPHeaders, carrier) | ||||
| 	assert.Nil(err) | ||||
|  | ||||
| 	tCtx, ok := ctx.(SpanContext) | ||||
| 	assert.True(ok) | ||||
| 	tPropagated, ok := propagated.(SpanContext) | ||||
| 	assert.True(ok) | ||||
|  | ||||
| 	// compare if there is a Context match | ||||
| 	assert.Equal(tCtx.traceID, tPropagated.traceID) | ||||
| 	assert.Equal(tCtx.spanID, tPropagated.spanID) | ||||
|  | ||||
| 	// ensure a child can be created | ||||
| 	child := tracer.StartSpan("db.query", opentracing.ChildOf(propagated)) | ||||
| 	tRoot, ok := root.(*Span) | ||||
| 	assert.True(ok) | ||||
| 	tChild, ok := child.(*Span) | ||||
| 	assert.True(ok) | ||||
|  | ||||
| 	assert.NotEqual(uint64(0), tChild.Span.TraceID) | ||||
| 	assert.NotEqual(uint64(0), tChild.Span.SpanID) | ||||
| 	assert.Equal(tRoot.Span.SpanID, tChild.Span.ParentID) | ||||
| 	assert.Equal(tRoot.Span.TraceID, tChild.Span.ParentID) | ||||
|  | ||||
| 	tid := strconv.FormatUint(tRoot.Span.TraceID, 10) | ||||
| 	pid := strconv.FormatUint(tRoot.Span.SpanID, 10) | ||||
|  | ||||
| 	// hardcode header names to fail test if defaults are changed | ||||
| 	assert.Equal(headers.Get("x-datadog-trace-id"), tid) | ||||
| 	assert.Equal(headers.Get("x-datadog-parent-id"), pid) | ||||
| } | ||||
|  | ||||
| func TestTracerTextMapPropagationHeader(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	config.TextMapPropagator = NewTextMapPropagator("bg-", "tid", "pid") | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
|  | ||||
| 	root := tracer.StartSpan("web.request").SetBaggageItem("item", "x").(*Span) | ||||
| 	ctx := root.Context() | ||||
| 	headers := http.Header{} | ||||
|  | ||||
| 	carrier := opentracing.HTTPHeadersCarrier(headers) | ||||
| 	err := tracer.Inject(ctx, opentracing.HTTPHeaders, carrier) | ||||
| 	assert.Nil(err) | ||||
|  | ||||
| 	tid := strconv.FormatUint(root.Span.TraceID, 10) | ||||
| 	pid := strconv.FormatUint(root.Span.SpanID, 10) | ||||
|  | ||||
| 	assert.Equal(headers.Get("tid"), tid) | ||||
| 	assert.Equal(headers.Get("pid"), pid) | ||||
| 	assert.Equal(headers.Get("bg-item"), "x") | ||||
| } | ||||
							
								
								
									
										129
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/span_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										129
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/span_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,129 +0,0 @@ | ||||
| package opentracing | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	opentracing "github.com/opentracing/opentracing-go" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestSpanBaggage(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	span := NewSpan("web.request") | ||||
| 	span.SetBaggageItem("key", "value") | ||||
| 	assert.Equal("value", span.BaggageItem("key")) | ||||
| } | ||||
|  | ||||
| func TestSpanContext(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	span := NewSpan("web.request") | ||||
| 	assert.NotNil(span.Context()) | ||||
| } | ||||
|  | ||||
| func TestSpanOperationName(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	span := NewSpan("web.request") | ||||
| 	span.SetOperationName("http.request") | ||||
| 	assert.Equal("http.request", span.Span.Name) | ||||
| } | ||||
|  | ||||
| func TestSpanFinish(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	span := NewSpan("web.request") | ||||
| 	span.Finish() | ||||
|  | ||||
| 	assert.True(span.Span.Duration > 0) | ||||
| } | ||||
|  | ||||
| func TestSpanFinishWithTime(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	finishTime := time.Now().Add(10 * time.Second) | ||||
| 	span := NewSpan("web.request") | ||||
| 	span.FinishWithOptions(opentracing.FinishOptions{FinishTime: finishTime}) | ||||
|  | ||||
| 	duration := finishTime.UnixNano() - span.Span.Start | ||||
| 	assert.Equal(duration, span.Span.Duration) | ||||
| } | ||||
|  | ||||
| func TestSpanSetTag(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	span := NewSpan("web.request") | ||||
| 	span.SetTag("component", "tracer") | ||||
| 	assert.Equal("tracer", span.Meta["component"]) | ||||
|  | ||||
| 	span.SetTag("tagInt", 1234) | ||||
| 	assert.Equal("1234", span.Meta["tagInt"]) | ||||
| } | ||||
|  | ||||
| func TestSpanSetDatadogTags(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	span := NewSpan("web.request") | ||||
| 	span.SetTag("span.type", "http") | ||||
| 	span.SetTag("service.name", "db-cluster") | ||||
| 	span.SetTag("resource.name", "SELECT * FROM users;") | ||||
|  | ||||
| 	assert.Equal("http", span.Span.Type) | ||||
| 	assert.Equal("db-cluster", span.Span.Service) | ||||
| 	assert.Equal("SELECT * FROM users;", span.Span.Resource) | ||||
| } | ||||
|  | ||||
| func TestSpanSetErrorTag(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	for _, tt := range []struct { | ||||
| 		name string      // span name | ||||
| 		val  interface{} // tag value | ||||
| 		msg  string      // error message | ||||
| 		typ  string      // error type | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "error.error", | ||||
| 			val:  errors.New("some error"), | ||||
| 			msg:  "some error", | ||||
| 			typ:  "*errors.errorString", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "error.string", | ||||
| 			val:  "some string error", | ||||
| 			msg:  "some string error", | ||||
| 			typ:  "*errors.errorString", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "error.struct", | ||||
| 			val:  struct{ N int }{5}, | ||||
| 			msg:  "{5}", | ||||
| 			typ:  "*errors.errorString", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "error.other", | ||||
| 			val:  1, | ||||
| 			msg:  "1", | ||||
| 			typ:  "*errors.errorString", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "error.nil", | ||||
| 			val:  nil, | ||||
| 			msg:  "", | ||||
| 			typ:  "", | ||||
| 		}, | ||||
| 	} { | ||||
| 		span := NewSpan(tt.name) | ||||
| 		span.SetTag(Error, tt.val) | ||||
|  | ||||
| 		assert.Equal(span.Meta["error.msg"], tt.msg) | ||||
| 		assert.Equal(span.Meta["error.type"], tt.typ) | ||||
|  | ||||
| 		if tt.val != nil { | ||||
| 			assert.NotEqual(span.Meta["error.stack"], "") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										131
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/tracer_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										131
									
								
								vendor/github.com/DataDog/dd-trace-go/opentracing/tracer_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,131 +0,0 @@ | ||||
| package opentracing | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	ddtrace "github.com/DataDog/dd-trace-go/tracer" | ||||
| 	opentracing "github.com/opentracing/opentracing-go" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestDefaultTracer(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
| 	tTracer, ok := tracer.(*Tracer) | ||||
| 	assert.True(ok) | ||||
|  | ||||
| 	assert.Equal(tTracer.impl, ddtrace.DefaultTracer) | ||||
| } | ||||
|  | ||||
| func TestTracerStartSpan(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
|  | ||||
| 	span, ok := tracer.StartSpan("web.request").(*Span) | ||||
| 	assert.True(ok) | ||||
|  | ||||
| 	assert.NotEqual(uint64(0), span.Span.TraceID) | ||||
| 	assert.NotEqual(uint64(0), span.Span.SpanID) | ||||
| 	assert.Equal(uint64(0), span.Span.ParentID) | ||||
| 	assert.Equal("web.request", span.Span.Name) | ||||
| 	assert.Equal("opentracing.test", span.Span.Service) | ||||
| 	assert.NotNil(span.Span.Tracer()) | ||||
| } | ||||
|  | ||||
| func TestTracerStartChildSpan(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
|  | ||||
| 	root := tracer.StartSpan("web.request") | ||||
| 	child := tracer.StartSpan("db.query", opentracing.ChildOf(root.Context())) | ||||
| 	tRoot, ok := root.(*Span) | ||||
| 	assert.True(ok) | ||||
| 	tChild, ok := child.(*Span) | ||||
| 	assert.True(ok) | ||||
|  | ||||
| 	assert.NotEqual(uint64(0), tChild.Span.TraceID) | ||||
| 	assert.NotEqual(uint64(0), tChild.Span.SpanID) | ||||
| 	assert.Equal(tRoot.Span.SpanID, tChild.Span.ParentID) | ||||
| 	assert.Equal(tRoot.Span.TraceID, tChild.Span.ParentID) | ||||
| } | ||||
|  | ||||
| func TestTracerBaggagePropagation(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
|  | ||||
| 	root := tracer.StartSpan("web.request") | ||||
| 	root.SetBaggageItem("key", "value") | ||||
| 	child := tracer.StartSpan("db.query", opentracing.ChildOf(root.Context())) | ||||
| 	context, ok := child.Context().(SpanContext) | ||||
| 	assert.True(ok) | ||||
|  | ||||
| 	assert.Equal("value", context.baggage["key"]) | ||||
| } | ||||
|  | ||||
| func TestTracerBaggageImmutability(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
|  | ||||
| 	root := tracer.StartSpan("web.request") | ||||
| 	root.SetBaggageItem("key", "value") | ||||
| 	child := tracer.StartSpan("db.query", opentracing.ChildOf(root.Context())) | ||||
| 	child.SetBaggageItem("key", "changed!") | ||||
| 	parentContext, ok := root.Context().(SpanContext) | ||||
| 	assert.True(ok) | ||||
| 	childContext, ok := child.Context().(SpanContext) | ||||
| 	assert.True(ok) | ||||
|  | ||||
| 	assert.Equal("value", parentContext.baggage["key"]) | ||||
| 	assert.Equal("changed!", childContext.baggage["key"]) | ||||
| } | ||||
|  | ||||
| func TestTracerSpanTags(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
|  | ||||
| 	tag := opentracing.Tag{Key: "key", Value: "value"} | ||||
| 	span, ok := tracer.StartSpan("web.request", tag).(*Span) | ||||
| 	assert.True(ok) | ||||
|  | ||||
| 	assert.Equal("value", span.Span.Meta["key"]) | ||||
| } | ||||
|  | ||||
| func TestTracerSpanGlobalTags(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	config.GlobalTags["key"] = "value" | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
|  | ||||
| 	span := tracer.StartSpan("web.request").(*Span) | ||||
| 	assert.Equal("value", span.Span.Meta["key"]) | ||||
|  | ||||
| 	child := tracer.StartSpan("db.query", opentracing.ChildOf(span.Context())).(*Span) | ||||
| 	assert.Equal("value", child.Span.Meta["key"]) | ||||
| } | ||||
|  | ||||
| func TestTracerSpanStartTime(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := NewConfiguration() | ||||
| 	tracer, _, _ := NewTracer(config) | ||||
|  | ||||
| 	startTime := time.Now().Add(-10 * time.Second) | ||||
| 	span, ok := tracer.StartSpan("web.request", opentracing.StartTime(startTime)).(*Span) | ||||
| 	assert.True(ok) | ||||
|  | ||||
| 	assert.Equal(startTime.UnixNano(), span.Span.Start) | ||||
| } | ||||
							
								
								
									
										105
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/buffer_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/buffer_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,105 +0,0 @@ | ||||
| package tracer | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	testInitSize = 2 | ||||
| 	testMaxSize  = 5 | ||||
| ) | ||||
|  | ||||
| func TestSpanBufferPushOne(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	buffer := newSpanBuffer(newTracerChans(), testInitSize, testMaxSize) | ||||
| 	assert.NotNil(buffer) | ||||
| 	assert.Len(buffer.spans, 0) | ||||
|  | ||||
| 	traceID := NextSpanID() | ||||
| 	root := NewSpan("name1", "a-service", "a-resource", traceID, traceID, 0, nil) | ||||
| 	root.buffer = buffer | ||||
|  | ||||
| 	buffer.Push(root) | ||||
| 	assert.Len(buffer.spans, 1, "there is one span in the buffer") | ||||
| 	assert.Equal(root, buffer.spans[0], "the span is the one pushed before") | ||||
|  | ||||
| 	root.Finish() | ||||
|  | ||||
| 	select { | ||||
| 	case trace := <-buffer.channels.trace: | ||||
| 		assert.Len(trace, 1, "there was a trace in the channel") | ||||
| 		assert.Equal(root, trace[0], "the trace in the channel is the one pushed before") | ||||
| 		assert.Equal(0, buffer.Len(), "no more spans in the buffer") | ||||
| 	case err := <-buffer.channels.err: | ||||
| 		assert.Fail("unexpected error:", err.Error()) | ||||
| 		t.Logf("buffer: %v", buffer) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestSpanBufferPushNoFinish(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	buffer := newSpanBuffer(newTracerChans(), testInitSize, testMaxSize) | ||||
| 	assert.NotNil(buffer) | ||||
| 	assert.Len(buffer.spans, 0) | ||||
|  | ||||
| 	traceID := NextSpanID() | ||||
| 	root := NewSpan("name1", "a-service", "a-resource", traceID, traceID, 0, nil) | ||||
| 	root.buffer = buffer | ||||
|  | ||||
| 	buffer.Push(root) | ||||
| 	assert.Len(buffer.spans, 1, "there is one span in the buffer") | ||||
| 	assert.Equal(root, buffer.spans[0], "the span is the one pushed before") | ||||
|  | ||||
| 	select { | ||||
| 	case <-buffer.channels.trace: | ||||
| 		assert.Fail("span was not finished, should not be flushed") | ||||
| 		t.Logf("buffer: %v", buffer) | ||||
| 	case err := <-buffer.channels.err: | ||||
| 		assert.Fail("unexpected error:", err.Error()) | ||||
| 		t.Logf("buffer: %v", buffer) | ||||
| 	case <-time.After(time.Second / 10): | ||||
| 		t.Logf("expected timeout, nothing should show up in buffer as the trace is not finished") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestSpanBufferPushSeveral(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	buffer := newSpanBuffer(newTracerChans(), testInitSize, testMaxSize) | ||||
| 	assert.NotNil(buffer) | ||||
| 	assert.Len(buffer.spans, 0) | ||||
|  | ||||
| 	traceID := NextSpanID() | ||||
| 	root := NewSpan("name1", "a-service", "a-resource", traceID, traceID, 0, nil) | ||||
| 	span2 := NewSpan("name2", "a-service", "a-resource", NextSpanID(), traceID, root.SpanID, nil) | ||||
| 	span3 := NewSpan("name3", "a-service", "a-resource", NextSpanID(), traceID, root.SpanID, nil) | ||||
| 	span3a := NewSpan("name3", "a-service", "a-resource", NextSpanID(), traceID, span3.SpanID, nil) | ||||
|  | ||||
| 	spans := []*Span{root, span2, span3, span3a} | ||||
|  | ||||
| 	for i, span := range spans { | ||||
| 		span.buffer = buffer | ||||
| 		buffer.Push(span) | ||||
| 		assert.Len(buffer.spans, i+1, "there is one more span in the buffer") | ||||
| 		assert.Equal(span, buffer.spans[i], "the span is the one pushed before") | ||||
| 	} | ||||
|  | ||||
| 	for _, span := range spans { | ||||
| 		span.Finish() | ||||
| 	} | ||||
|  | ||||
| 	select { | ||||
| 	case trace := <-buffer.channels.trace: | ||||
| 		assert.Len(trace, 4, "there was one trace with the right number of spans in the channel") | ||||
| 		for _, span := range spans { | ||||
| 			assert.Contains(trace, span, "the trace contains the spans") | ||||
| 		} | ||||
| 	case err := <-buffer.channels.err: | ||||
| 		assert.Fail("unexpected error:", err.Error()) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										117
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/channels_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										117
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/channels_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,117 +0,0 @@ | ||||
| package tracer | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestPushTrace(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	channels := newTracerChans() | ||||
|  | ||||
| 	trace := []*Span{ | ||||
| 		&Span{ | ||||
| 			Name:     "pylons.request", | ||||
| 			Service:  "pylons", | ||||
| 			Resource: "/", | ||||
| 		}, | ||||
| 		&Span{ | ||||
| 			Name:     "pylons.request", | ||||
| 			Service:  "pylons", | ||||
| 			Resource: "/foo", | ||||
| 		}, | ||||
| 	} | ||||
| 	channels.pushTrace(trace) | ||||
|  | ||||
| 	assert.Len(channels.trace, 1, "there should be data in channel") | ||||
| 	assert.Len(channels.traceFlush, 0, "no flush requested yet") | ||||
|  | ||||
| 	pushed := <-channels.trace | ||||
| 	assert.Equal(trace, pushed) | ||||
|  | ||||
| 	many := traceChanLen/2 + 1 | ||||
| 	for i := 0; i < many; i++ { | ||||
| 		channels.pushTrace(make([]*Span, i)) | ||||
| 	} | ||||
| 	assert.Len(channels.trace, many, "all traces should be in the channel, not yet blocking") | ||||
| 	assert.Len(channels.traceFlush, 1, "a trace flush should have been requested") | ||||
|  | ||||
| 	for i := 0; i < cap(channels.trace); i++ { | ||||
| 		channels.pushTrace(make([]*Span, i)) | ||||
| 	} | ||||
| 	assert.Len(channels.trace, traceChanLen, "buffer should be full") | ||||
| 	assert.NotEqual(0, len(channels.err), "there should be an error logged") | ||||
| 	err := <-channels.err | ||||
| 	assert.Equal(&errorTraceChanFull{Len: traceChanLen}, err) | ||||
| } | ||||
|  | ||||
| func TestPushService(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	channels := newTracerChans() | ||||
|  | ||||
| 	service := Service{ | ||||
| 		Name:    "redis-master", | ||||
| 		App:     "redis", | ||||
| 		AppType: "db", | ||||
| 	} | ||||
| 	channels.pushService(service) | ||||
|  | ||||
| 	assert.Len(channels.service, 1, "there should be data in channel") | ||||
| 	assert.Len(channels.serviceFlush, 0, "no flush requested yet") | ||||
|  | ||||
| 	pushed := <-channels.service | ||||
| 	assert.Equal(service, pushed) | ||||
|  | ||||
| 	many := serviceChanLen/2 + 1 | ||||
| 	for i := 0; i < many; i++ { | ||||
| 		channels.pushService(Service{ | ||||
| 			Name:    fmt.Sprintf("service%d", i), | ||||
| 			App:     "custom", | ||||
| 			AppType: "web", | ||||
| 		}) | ||||
| 	} | ||||
| 	assert.Len(channels.service, many, "all services should be in the channel, not yet blocking") | ||||
| 	assert.Len(channels.serviceFlush, 1, "a service flush should have been requested") | ||||
|  | ||||
| 	for i := 0; i < cap(channels.service); i++ { | ||||
| 		channels.pushService(Service{ | ||||
| 			Name:    fmt.Sprintf("service%d", i), | ||||
| 			App:     "custom", | ||||
| 			AppType: "web", | ||||
| 		}) | ||||
| 	} | ||||
| 	assert.Len(channels.service, serviceChanLen, "buffer should be full") | ||||
| 	assert.NotEqual(0, len(channels.err), "there should be an error logged") | ||||
| 	err := <-channels.err | ||||
| 	assert.Equal(&errorServiceChanFull{Len: serviceChanLen}, err) | ||||
| } | ||||
|  | ||||
| func TestPushErr(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	channels := newTracerChans() | ||||
|  | ||||
| 	err := fmt.Errorf("ooops") | ||||
| 	channels.pushErr(err) | ||||
|  | ||||
| 	assert.Len(channels.err, 1, "there should be data in channel") | ||||
| 	assert.Len(channels.errFlush, 0, "no flush requested yet") | ||||
|  | ||||
| 	pushed := <-channels.err | ||||
| 	assert.Equal(err, pushed) | ||||
|  | ||||
| 	many := errChanLen/2 + 1 | ||||
| 	for i := 0; i < many; i++ { | ||||
| 		channels.pushErr(fmt.Errorf("err %d", i)) | ||||
| 	} | ||||
| 	assert.Len(channels.err, many, "all errs should be in the channel, not yet blocking") | ||||
| 	assert.Len(channels.errFlush, 1, "a err flush should have been requested") | ||||
| 	for i := 0; i < cap(channels.err); i++ { | ||||
| 		channels.pushErr(fmt.Errorf("err %d", i)) | ||||
| 	} | ||||
| 	// if we reach this, means pushErr is not blocking, which is what we want to double-check | ||||
| } | ||||
							
								
								
									
										69
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/context_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										69
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/context_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,69 +0,0 @@ | ||||
| package tracer | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"context" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestContextWithSpanDefault(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	// create a new context with a span | ||||
| 	span := SpanFromContextDefault(nil) | ||||
| 	assert.NotNil(span) | ||||
|  | ||||
| 	ctx := context.Background() | ||||
| 	assert.NotNil(SpanFromContextDefault(ctx)) | ||||
| } | ||||
|  | ||||
| func TestSpanFromContext(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	// create a new context with a span | ||||
| 	ctx := context.Background() | ||||
| 	tracer := NewTracer() | ||||
| 	expectedSpan := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	ctx = ContextWithSpan(ctx, expectedSpan) | ||||
|  | ||||
| 	span, ok := SpanFromContext(ctx) | ||||
| 	assert.True(ok) | ||||
| 	assert.Equal(expectedSpan, span) | ||||
| } | ||||
|  | ||||
| func TestSpanFromContextNil(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	// create a context without a span | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	span, ok := SpanFromContext(ctx) | ||||
| 	assert.False(ok) | ||||
| 	assert.Nil(span) | ||||
|  | ||||
| 	span, ok = SpanFromContext(nil) | ||||
| 	assert.False(ok) | ||||
| 	assert.Nil(span) | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestSpanMissingParent(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
|  | ||||
| 	// assuming we're in an inner function and we | ||||
| 	// forget the nil or ok checks | ||||
| 	ctx := context.Background() | ||||
| 	span, _ := SpanFromContext(ctx) | ||||
|  | ||||
| 	// span is nil according to the API | ||||
| 	child := tracer.NewChildSpan("redis.command", span) | ||||
| 	child.Finish() | ||||
|  | ||||
| 	// the child is finished but it's not recorded in | ||||
| 	// the tracer buffer because the service is missing | ||||
| 	assert.True(child.Duration > 0) | ||||
| 	assert.Equal(1, len(tracer.channels.trace)) | ||||
| } | ||||
							
								
								
									
										114
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/encoder_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										114
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/encoder_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,114 +0,0 @@ | ||||
| package tracer | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/ugorji/go/codec" | ||||
| ) | ||||
|  | ||||
| func TestEncoderContentType(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	testCases := []struct { | ||||
| 		encoder     Encoder | ||||
| 		contentType string | ||||
| 	}{ | ||||
| 		{newJSONEncoder(), "application/json"}, | ||||
| 		{newMsgpackEncoder(), "application/msgpack"}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tc := range testCases { | ||||
| 		assert.Equal(tc.contentType, tc.encoder.ContentType()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestJSONEncoding(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	testCases := []struct { | ||||
| 		traces int | ||||
| 		size   int | ||||
| 	}{ | ||||
| 		{1, 1}, | ||||
| 		{3, 1}, | ||||
| 		{1, 3}, | ||||
| 		{3, 3}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tc := range testCases { | ||||
| 		payload := getTestTrace(tc.traces, tc.size) | ||||
| 		encoder := newJSONEncoder() | ||||
| 		err := encoder.EncodeTraces(payload) | ||||
| 		assert.Nil(err) | ||||
|  | ||||
| 		// decode to check the right encoding | ||||
| 		var traces [][]*Span | ||||
| 		dec := json.NewDecoder(encoder.buffer) | ||||
| 		err = dec.Decode(&traces) | ||||
| 		assert.Nil(err) | ||||
| 		assert.Len(traces, tc.traces) | ||||
|  | ||||
| 		for _, trace := range traces { | ||||
| 			assert.Len(trace, tc.size) | ||||
| 			span := trace[0] | ||||
| 			assert.Equal(uint64(42), span.TraceID) | ||||
| 			assert.Equal(uint64(52), span.SpanID) | ||||
| 			assert.Equal(uint64(42), span.ParentID) | ||||
| 			assert.Equal("web", span.Type) | ||||
| 			assert.Equal("high.throughput", span.Service) | ||||
| 			assert.Equal("sending.events", span.Name) | ||||
| 			assert.Equal("SEND /data", span.Resource) | ||||
| 			assert.Equal(int64(1481215590883401105), span.Start) | ||||
| 			assert.Equal(int64(1000000000), span.Duration) | ||||
| 			assert.Equal("192.168.0.1", span.Meta["http.host"]) | ||||
| 			assert.Equal(float64(41.99), span.Metrics["http.monitor"]) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestMsgpackEncoding(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	testCases := []struct { | ||||
| 		traces int | ||||
| 		size   int | ||||
| 	}{ | ||||
| 		{1, 1}, | ||||
| 		{3, 1}, | ||||
| 		{1, 3}, | ||||
| 		{3, 3}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tc := range testCases { | ||||
| 		payload := getTestTrace(tc.traces, tc.size) | ||||
| 		encoder := newMsgpackEncoder() | ||||
| 		err := encoder.EncodeTraces(payload) | ||||
| 		assert.Nil(err) | ||||
|  | ||||
| 		// decode to check the right encoding | ||||
| 		var traces [][]*Span | ||||
| 		var mh codec.MsgpackHandle | ||||
| 		dec := codec.NewDecoder(encoder.buffer, &mh) | ||||
| 		err = dec.Decode(&traces) | ||||
| 		assert.Nil(err) | ||||
| 		assert.Len(traces, tc.traces) | ||||
|  | ||||
| 		for _, trace := range traces { | ||||
| 			assert.Len(trace, tc.size) | ||||
| 			span := trace[0] | ||||
| 			assert.Equal(uint64(42), span.TraceID) | ||||
| 			assert.Equal(uint64(52), span.SpanID) | ||||
| 			assert.Equal(uint64(42), span.ParentID) | ||||
| 			assert.Equal("web", span.Type) | ||||
| 			assert.Equal("high.throughput", span.Service) | ||||
| 			assert.Equal("sending.events", span.Name) | ||||
| 			assert.Equal("SEND /data", span.Resource) | ||||
| 			assert.Equal(int64(1481215590883401105), span.Start) | ||||
| 			assert.Equal(int64(1000000000), span.Duration) | ||||
| 			assert.Equal("192.168.0.1", span.Meta["http.host"]) | ||||
| 			assert.Equal(float64(41.99), span.Metrics["http.monitor"]) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										98
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/errors_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										98
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/errors_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,98 +0,0 @@ | ||||
| package tracer | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestErrorSpanBufFull(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	err := &errorSpanBufFull{Len: 42} | ||||
| 	assert.Equal("span buffer is full (length: 42)", err.Error()) | ||||
| 	assert.Equal("ErrorSpanBufFull", errorKey(err)) | ||||
| } | ||||
|  | ||||
| func TestErrorTraceChanFull(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	err := &errorTraceChanFull{Len: 42} | ||||
| 	assert.Equal("trace channel is full (length: 42)", err.Error()) | ||||
| 	assert.Equal("ErrorTraceChanFull", errorKey(err)) | ||||
| } | ||||
|  | ||||
| func TestErrorServiceChanFull(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	err := &errorServiceChanFull{Len: 42} | ||||
| 	assert.Equal("service channel is full (length: 42)", err.Error()) | ||||
| 	assert.Equal("ErrorServiceChanFull", errorKey(err)) | ||||
| } | ||||
|  | ||||
| func TestErrorTraceIDMismatch(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	err := &errorTraceIDMismatch{Expected: 42, Actual: 65535} | ||||
| 	assert.Equal("trace ID mismatch (expected: 2a actual: ffff)", err.Error()) | ||||
| 	assert.Equal("ErrorTraceIDMismatch", errorKey(err)) | ||||
| } | ||||
|  | ||||
| func TestErrorNoSpanBuf(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	err := &errorNoSpanBuf{SpanName: "do"} | ||||
| 	assert.Equal("no span buffer (span name: 'do')", err.Error()) | ||||
| } | ||||
|  | ||||
| func TestErrorFlushLostTraces(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	err := &errorFlushLostTraces{Nb: 100} | ||||
| 	assert.Equal("unable to flush traces, lost 100 traces", err.Error()) | ||||
| } | ||||
|  | ||||
| func TestErrorFlushLostServices(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	err := &errorFlushLostServices{Nb: 100} | ||||
| 	assert.Equal("unable to flush services, lost 100 services", err.Error()) | ||||
| } | ||||
|  | ||||
| func TestErrorKey(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	assert.Equal("this is something unexpected", errorKey(fmt.Errorf("this is something unexpected"))) | ||||
| 	assert.Equal("", errorKey(nil)) | ||||
| } | ||||
|  | ||||
| func TestAggregateErrors(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	errChan := make(chan error, 100) | ||||
| 	errChan <- &errorSpanBufFull{Len: 1000} | ||||
| 	errChan <- &errorSpanBufFull{Len: 1000} | ||||
| 	errChan <- &errorSpanBufFull{Len: 1000} | ||||
| 	errChan <- &errorSpanBufFull{Len: 1000} | ||||
| 	errChan <- &errorFlushLostTraces{Nb: 42} | ||||
| 	errChan <- &errorTraceIDMismatch{Expected: 42, Actual: 1} | ||||
| 	errChan <- &errorTraceIDMismatch{Expected: 42, Actual: 4095} | ||||
|  | ||||
| 	errs := aggregateErrors(errChan) | ||||
|  | ||||
| 	assert.Equal(map[string]errorSummary{ | ||||
| 		"ErrorSpanBufFull": errorSummary{ | ||||
| 			Count:   4, | ||||
| 			Example: "span buffer is full (length: 1000)", | ||||
| 		}, | ||||
| 		"ErrorTraceIDMismatch": errorSummary{ | ||||
| 			Count:   2, | ||||
| 			Example: "trace ID mismatch (expected: 2a actual: fff)", | ||||
| 		}, | ||||
| 		"ErrorFlushLostTraces": errorSummary{ | ||||
| 			Count:   1, | ||||
| 			Example: "unable to flush traces, lost 42 traces", | ||||
| 		}, | ||||
| 	}, errs) | ||||
| } | ||||
							
								
								
									
										73
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/example_context_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										73
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/example_context_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,73 +0,0 @@ | ||||
| package tracer_test | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/DataDog/dd-trace-go/tracer" | ||||
| ) | ||||
|  | ||||
| func saveFile(ctx context.Context, path string, r io.Reader) error { | ||||
| 	// Start a new span that is the child of the span stored in the context, and | ||||
| 	// attach it to the current context. If the context has no span, it will | ||||
| 	// return an empty root span. | ||||
| 	span, ctx := tracer.NewChildSpanWithContext("filestore.saveFile", ctx) | ||||
| 	defer span.Finish() | ||||
|  | ||||
| 	// save the file contents. | ||||
| 	file, err := os.Create(path) | ||||
| 	if err != nil { | ||||
| 		span.SetError(err) | ||||
| 		return err | ||||
| 	} | ||||
| 	defer file.Close() | ||||
|  | ||||
| 	_, err = io.Copy(file, r) | ||||
| 	span.SetError(err) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func saveFileHandler(w http.ResponseWriter, r *http.Request) { | ||||
| 	// the name of the operation we're measuring | ||||
| 	name := "http.request" | ||||
| 	service := "example-filestore" | ||||
| 	resource := "/saveFile" | ||||
|  | ||||
| 	// This is the main entry point of our application, so we create a root span | ||||
| 	// that includes the service and resource name. | ||||
| 	span := tracer.NewRootSpan(name, service, resource) | ||||
| 	defer span.Finish() | ||||
|  | ||||
| 	// Add the span to the request's context so we can pass the tracing information | ||||
| 	// down the stack. | ||||
| 	ctx := span.Context(r.Context()) | ||||
|  | ||||
| 	// Do the work. | ||||
| 	err := saveFile(ctx, "/tmp/example", r.Body) | ||||
| 	span.SetError(err) // no-op if err == nil | ||||
|  | ||||
| 	if err != nil { | ||||
| 		http.Error(w, fmt.Sprintf("error saving file! %s", err), 500) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	w.Write([]byte("saved file!")) | ||||
| } | ||||
|  | ||||
| // Tracing the hierarchy of spans in a request is a key part of tracing. This, for example, | ||||
| // let's a developer associate all of the database calls in a web request. As of Go 1.7, | ||||
| // the standard way of doing this is with the context package. Along with supporting | ||||
| // deadlines, cancellation signals and more, Contexts are perfect for passing (optional) | ||||
| // telemetry data through your stack. | ||||
| // | ||||
| // Read more about contexts here: https://golang.org/pkg/context/ | ||||
| // | ||||
| // Here is an example illustrating how to pass tracing data with contexts. | ||||
| func Example_context() { | ||||
| 	http.HandleFunc("/saveFile", saveFileHandler) | ||||
| 	log.Fatal(http.ListenAndServe(":8080", nil)) | ||||
| } | ||||
							
								
								
									
										23
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/example_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/example_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,23 +0,0 @@ | ||||
| package tracer_test | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/DataDog/dd-trace-go/tracer" | ||||
| ) | ||||
|  | ||||
| func Example() { | ||||
| 	span := tracer.NewRootSpan("http.client.request", "example.com", "/user/{id}") | ||||
| 	defer span.Finish() | ||||
|  | ||||
| 	url := "http://example.com/user/123" | ||||
|  | ||||
| 	resp, err := http.Get(url) | ||||
| 	if err != nil { | ||||
| 		span.SetError(err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	span.SetMeta("http.status", resp.Status) | ||||
| 	span.SetMeta("http.url", url) | ||||
| } | ||||
							
								
								
									
										289
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/span_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										289
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/span_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,289 +0,0 @@ | ||||
| package tracer | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
|  | ||||
| 	"github.com/DataDog/dd-trace-go/tracer/ext" | ||||
| ) | ||||
|  | ||||
| func TestSpanStart(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	// a new span sets the Start after the initialization | ||||
| 	assert.NotEqual(int64(0), span.Start) | ||||
| } | ||||
|  | ||||
| func TestSpanString(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	// don't bother checking the contents, just make sure it works. | ||||
| 	assert.NotEqual("", span.String()) | ||||
| 	span.Finish() | ||||
| 	assert.NotEqual("", span.String()) | ||||
| } | ||||
|  | ||||
| func TestSpanSetMeta(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	// check the map is properly initialized | ||||
| 	span.SetMeta("status.code", "200") | ||||
| 	assert.Equal("200", span.Meta["status.code"]) | ||||
|  | ||||
| 	// operating on a finished span is a no-op | ||||
| 	nMeta := len(span.Meta) | ||||
| 	span.Finish() | ||||
| 	span.SetMeta("finished.test", "true") | ||||
| 	assert.Equal(len(span.Meta), nMeta) | ||||
| 	assert.Equal(span.Meta["finished.test"], "") | ||||
| } | ||||
|  | ||||
| func TestSpanSetMetas(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	span.SetSamplingPriority(0) // avoid interferences with "_sampling_priority_v1" meta | ||||
| 	metas := map[string]string{ | ||||
| 		"error.msg":   "Something wrong", | ||||
| 		"error.type":  "*errors.errorString", | ||||
| 		"status.code": "200", | ||||
| 		"system.pid":  "29176", | ||||
| 	} | ||||
| 	extraMetas := map[string]string{ | ||||
| 		"custom.1": "something custom", | ||||
| 		"custom.2": "something even more special", | ||||
| 	} | ||||
| 	nopMetas := map[string]string{ | ||||
| 		"nopKey1": "nopValue1", | ||||
| 		"nopKey2": "nopValue2", | ||||
| 	} | ||||
|  | ||||
| 	// check the map is properly initialized | ||||
| 	span.SetMetas(metas) | ||||
| 	assert.Equal(len(metas), len(span.Meta)) | ||||
| 	for k := range metas { | ||||
| 		assert.Equal(metas[k], span.Meta[k]) | ||||
| 	} | ||||
|  | ||||
| 	// check a second call adds the new metas, but does not remove old ones | ||||
| 	span.SetMetas(extraMetas) | ||||
| 	assert.Equal(len(metas)+len(extraMetas), len(span.Meta)) | ||||
| 	for k := range extraMetas { | ||||
| 		assert.Equal(extraMetas[k], span.Meta[k]) | ||||
| 	} | ||||
|  | ||||
| 	assert.Equal(span.Meta["status.code"], "200") | ||||
|  | ||||
| 	// operating on a finished span is a no-op | ||||
| 	span.Finish() | ||||
| 	span.SetMetas(nopMetas) | ||||
| 	assert.Equal(len(metas)+len(extraMetas), len(span.Meta)) | ||||
| 	for k := range nopMetas { | ||||
| 		assert.Equal("", span.Meta[k]) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestSpanSetMetric(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	// check the map is properly initialized | ||||
| 	span.SetMetric("bytes", 1024.42) | ||||
| 	assert.Equal(1, len(span.Metrics)) | ||||
| 	assert.Equal(1024.42, span.Metrics["bytes"]) | ||||
|  | ||||
| 	// operating on a finished span is a no-op | ||||
| 	span.Finish() | ||||
| 	span.SetMetric("finished.test", 1337) | ||||
| 	assert.Equal(1, len(span.Metrics)) | ||||
| 	assert.Equal(0.0, span.Metrics["finished.test"]) | ||||
| } | ||||
|  | ||||
| func TestSpanError(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	// check the error is set in the default meta | ||||
| 	err := errors.New("Something wrong") | ||||
| 	span.SetError(err) | ||||
| 	assert.Equal(int32(1), span.Error) | ||||
| 	assert.Equal("Something wrong", span.Meta["error.msg"]) | ||||
| 	assert.Equal("*errors.errorString", span.Meta["error.type"]) | ||||
| 	assert.NotEqual("", span.Meta["error.stack"]) | ||||
|  | ||||
| 	// operating on a finished span is a no-op | ||||
| 	span = tracer.NewRootSpan("flask.request", "flask", "/") | ||||
| 	nMeta := len(span.Meta) | ||||
| 	span.Finish() | ||||
| 	span.SetError(err) | ||||
| 	assert.Equal(int32(0), span.Error) | ||||
| 	assert.Equal(nMeta, len(span.Meta)) | ||||
| 	assert.Equal("", span.Meta["error.msg"]) | ||||
| 	assert.Equal("", span.Meta["error.type"]) | ||||
| 	assert.Equal("", span.Meta["error.stack"]) | ||||
| } | ||||
|  | ||||
| func TestSpanError_Typed(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	// check the error is set in the default meta | ||||
| 	err := &boomError{} | ||||
| 	span.SetError(err) | ||||
| 	assert.Equal(int32(1), span.Error) | ||||
| 	assert.Equal("boom", span.Meta["error.msg"]) | ||||
| 	assert.Equal("*tracer.boomError", span.Meta["error.type"]) | ||||
| 	assert.NotEqual("", span.Meta["error.stack"]) | ||||
| } | ||||
|  | ||||
| func TestEmptySpan(t *testing.T) { | ||||
| 	// ensure the empty span won't crash the app | ||||
| 	var span Span | ||||
| 	span.SetMeta("a", "b") | ||||
| 	span.SetError(nil) | ||||
| 	span.Finish() | ||||
|  | ||||
| 	var s *Span | ||||
| 	s.SetMeta("a", "b") | ||||
| 	s.SetError(nil) | ||||
| 	s.Finish() | ||||
| } | ||||
|  | ||||
| func TestSpanErrorNil(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	// don't set the error if it's nil | ||||
| 	nMeta := len(span.Meta) | ||||
| 	span.SetError(nil) | ||||
| 	assert.Equal(int32(0), span.Error) | ||||
| 	assert.Equal(nMeta, len(span.Meta)) | ||||
| } | ||||
|  | ||||
| func TestSpanFinish(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	wait := time.Millisecond * 2 | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	// the finish should set finished and the duration | ||||
| 	time.Sleep(wait) | ||||
| 	span.Finish() | ||||
| 	assert.True(span.Duration > int64(wait)) | ||||
| 	assert.True(span.finished) | ||||
| } | ||||
|  | ||||
| func TestSpanFinishTwice(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	wait := time.Millisecond * 2 | ||||
|  | ||||
| 	tracer, _ := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	assert.Len(tracer.channels.trace, 0) | ||||
|  | ||||
| 	// the finish must be idempotent | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	time.Sleep(wait) | ||||
| 	span.Finish() | ||||
| 	assert.Len(tracer.channels.trace, 1) | ||||
|  | ||||
| 	previousDuration := span.Duration | ||||
| 	time.Sleep(wait) | ||||
| 	span.Finish() | ||||
| 	assert.Equal(previousDuration, span.Duration) | ||||
| 	assert.Len(tracer.channels.trace, 1) | ||||
| } | ||||
|  | ||||
| func TestSpanContext(t *testing.T) { | ||||
| 	ctx := context.Background() | ||||
| 	_, ok := SpanFromContext(ctx) | ||||
| 	assert.False(t, ok) | ||||
|  | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	ctx = span.Context(ctx) | ||||
| 	s2, ok := SpanFromContext(ctx) | ||||
| 	assert.True(t, ok) | ||||
| 	assert.Equal(t, span.SpanID, s2.SpanID) | ||||
|  | ||||
| } | ||||
|  | ||||
| // Prior to a bug fix, this failed when running `go test -race` | ||||
| func TestSpanModifyWhileFlushing(t *testing.T) { | ||||
| 	tracer, _ := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	done := make(chan struct{}) | ||||
| 	go func() { | ||||
| 		span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 		span.Finish() | ||||
| 		// It doesn't make much sense to update the span after it's been finished, | ||||
| 		// but an error in a user's code could lead to this. | ||||
| 		span.SetMeta("race_test", "true") | ||||
| 		span.SetMetric("race_test2", 133.7) | ||||
| 		span.SetMetrics("race_test3", 133.7) | ||||
| 		span.SetError(errors.New("t")) | ||||
| 		done <- struct{}{} | ||||
| 	}() | ||||
|  | ||||
| 	run := true | ||||
| 	for run { | ||||
| 		select { | ||||
| 		case <-done: | ||||
| 			run = false | ||||
| 		default: | ||||
| 			tracer.flushTraces() | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestSpanSamplingPriority(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
|  | ||||
| 	span := tracer.NewRootSpan("my.name", "my.service", "my.resource") | ||||
| 	assert.Equal(0.0, span.Metrics["_sampling_priority_v1"], "default sampling priority if undefined is 0") | ||||
| 	assert.False(span.HasSamplingPriority(), "by default, sampling priority is undefined") | ||||
| 	assert.Equal(0, span.GetSamplingPriority(), "default sampling priority for root spans is 0") | ||||
|  | ||||
| 	childSpan := tracer.NewChildSpan("my.child", span) | ||||
| 	assert.Equal(span.Metrics["_sampling_priority_v1"], childSpan.Metrics["_sampling_priority_v1"]) | ||||
| 	assert.Equal(span.HasSamplingPriority(), childSpan.HasSamplingPriority()) | ||||
| 	assert.Equal(span.GetSamplingPriority(), childSpan.GetSamplingPriority()) | ||||
|  | ||||
| 	for _, priority := range []int{ | ||||
| 		ext.PriorityUserReject, | ||||
| 		ext.PriorityAutoReject, | ||||
| 		ext.PriorityAutoKeep, | ||||
| 		ext.PriorityUserKeep, | ||||
| 		999, // not used yet, but we should allow it | ||||
| 	} { | ||||
| 		span.SetSamplingPriority(priority) | ||||
| 		assert.True(span.HasSamplingPriority()) | ||||
| 		assert.Equal(priority, span.GetSamplingPriority()) | ||||
| 		childSpan = tracer.NewChildSpan("my.child", span) | ||||
| 		assert.Equal(span.Metrics["_sampling_priority_v1"], childSpan.Metrics["_sampling_priority_v1"]) | ||||
| 		assert.Equal(span.HasSamplingPriority(), childSpan.HasSamplingPriority()) | ||||
| 		assert.Equal(span.GetSamplingPriority(), childSpan.GetSamplingPriority()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type boomError struct{} | ||||
|  | ||||
| func (e *boomError) Error() string { return "boom" } | ||||
							
								
								
									
										30
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/time_windows_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/time_windows_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,30 +0,0 @@ | ||||
| package tracer | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func BenchmarkNormalTimeNow(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		lowPrecisionNow() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func BenchmarkHighPrecisionTime(b *testing.B) { | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		highPrecisionNow() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestHighPrecisionTimerIsMoreAccurate(t *testing.T) { | ||||
| 	startLow := lowPrecisionNow() | ||||
| 	startHigh := highPrecisionNow() | ||||
| 	stopHigh := highPrecisionNow() | ||||
| 	for stopHigh == startHigh { | ||||
| 		stopHigh = highPrecisionNow() | ||||
| 	} | ||||
| 	stopLow := lowPrecisionNow() | ||||
| 	assert.Equal(t, int64(0), stopLow-startLow) | ||||
| } | ||||
							
								
								
									
										648
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/tracer_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										648
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/tracer_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,648 +0,0 @@ | ||||
| package tracer | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"github.com/DataDog/dd-trace-go/tracer/ext" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"sync" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestDefaultTracer(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	var wg sync.WaitGroup | ||||
|  | ||||
| 	// the default client must be available | ||||
| 	assert.NotNil(DefaultTracer) | ||||
|  | ||||
| 	// package free functions must proxy the calls to the | ||||
| 	// default client | ||||
| 	root := NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	NewChildSpan("pylons.request", root) | ||||
|  | ||||
| 	wg.Add(2) | ||||
|  | ||||
| 	go func() { | ||||
| 		for i := 0; i < 1000; i++ { | ||||
| 			Disable() | ||||
| 			Enable() | ||||
| 		} | ||||
| 		wg.Done() | ||||
| 	}() | ||||
|  | ||||
| 	go func() { | ||||
| 		for i := 0; i < 1000; i++ { | ||||
| 			_ = DefaultTracer.Enabled() | ||||
| 		} | ||||
| 		wg.Done() | ||||
| 	}() | ||||
|  | ||||
| 	wg.Wait() | ||||
| } | ||||
|  | ||||
| func TestNewSpan(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	// the tracer must create root spans | ||||
| 	tracer := NewTracer() | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	assert.Equal(uint64(0), span.ParentID) | ||||
| 	assert.Equal("pylons", span.Service) | ||||
| 	assert.Equal("pylons.request", span.Name) | ||||
| 	assert.Equal("/", span.Resource) | ||||
| } | ||||
|  | ||||
| func TestNewSpanFromContextNil(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
|  | ||||
| 	child := tracer.NewChildSpanFromContext("abc", nil) | ||||
| 	assert.Equal("abc", child.Name) | ||||
| 	assert.Equal("", child.Service) | ||||
|  | ||||
| 	child = tracer.NewChildSpanFromContext("def", context.Background()) | ||||
| 	assert.Equal("def", child.Name) | ||||
| 	assert.Equal("", child.Service) | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestNewChildSpanWithContext(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer := NewTracer() | ||||
|  | ||||
| 	// nil context | ||||
| 	span, ctx := tracer.NewChildSpanWithContext("abc", nil) | ||||
| 	assert.Equal("abc", span.Name) | ||||
| 	assert.Equal("", span.Service) | ||||
| 	assert.Equal(span.ParentID, span.SpanID) // it should be a root span | ||||
| 	assert.Equal(span.Tracer(), tracer) | ||||
| 	// the returned ctx should contain the created span | ||||
| 	assert.NotNil(ctx) | ||||
| 	ctxSpan, ok := SpanFromContext(ctx) | ||||
| 	assert.True(ok) | ||||
| 	assert.Equal(span, ctxSpan) | ||||
|  | ||||
| 	// context without span | ||||
| 	span, ctx = tracer.NewChildSpanWithContext("abc", context.Background()) | ||||
| 	assert.Equal("abc", span.Name) | ||||
| 	assert.Equal("", span.Service) | ||||
| 	assert.Equal(span.ParentID, span.SpanID) // it should be a root span | ||||
| 	// the returned ctx should contain the created span | ||||
| 	assert.NotNil(ctx) | ||||
| 	ctxSpan, ok = SpanFromContext(ctx) | ||||
| 	assert.True(ok) | ||||
| 	assert.Equal(span, ctxSpan) | ||||
|  | ||||
| 	// context with span | ||||
| 	parent := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	parentCTX := ContextWithSpan(context.Background(), parent) | ||||
| 	span, ctx = tracer.NewChildSpanWithContext("def", parentCTX) | ||||
| 	assert.Equal("def", span.Name) | ||||
| 	assert.Equal("pylons", span.Service) | ||||
| 	assert.Equal(parent.Service, span.Service) | ||||
| 	// the created span should be a child of the parent span | ||||
| 	assert.Equal(span.ParentID, parent.SpanID) | ||||
| 	// the returned ctx should contain the created span | ||||
| 	assert.NotNil(ctx) | ||||
| 	ctxSpan, ok = SpanFromContext(ctx) | ||||
| 	assert.True(ok) | ||||
| 	assert.Equal(ctxSpan, span) | ||||
| } | ||||
|  | ||||
| func TestNewSpanFromContext(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	// the tracer must create child spans | ||||
| 	tracer := NewTracer() | ||||
| 	parent := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	ctx := ContextWithSpan(context.Background(), parent) | ||||
|  | ||||
| 	child := tracer.NewChildSpanFromContext("redis.command", ctx) | ||||
| 	// ids and services are inherited | ||||
| 	assert.Equal(parent.SpanID, child.ParentID) | ||||
| 	assert.Equal(parent.TraceID, child.TraceID) | ||||
| 	assert.Equal(parent.Service, child.Service) | ||||
| 	// the resource is not inherited and defaults to the name | ||||
| 	assert.Equal("redis.command", child.Resource) | ||||
| 	// the tracer instance is the same | ||||
| 	assert.Equal(tracer, parent.tracer) | ||||
| 	assert.Equal(tracer, child.tracer) | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestNewSpanChild(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	// the tracer must create child spans | ||||
| 	tracer := NewTracer() | ||||
| 	parent := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	child := tracer.NewChildSpan("redis.command", parent) | ||||
| 	// ids and services are inherited | ||||
| 	assert.Equal(parent.SpanID, child.ParentID) | ||||
| 	assert.Equal(parent.TraceID, child.TraceID) | ||||
| 	assert.Equal(parent.Service, child.Service) | ||||
| 	// the resource is not inherited and defaults to the name | ||||
| 	assert.Equal("redis.command", child.Resource) | ||||
| 	// the tracer instance is the same | ||||
| 	assert.Equal(tracer, parent.tracer) | ||||
| 	assert.Equal(tracer, child.tracer) | ||||
| } | ||||
|  | ||||
| func TestNewRootSpanHasPid(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	tracer := NewTracer() | ||||
| 	root := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	assert.Equal(strconv.Itoa(os.Getpid()), root.GetMeta(ext.Pid)) | ||||
| } | ||||
|  | ||||
| func TestNewChildHasNoPid(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	tracer := NewTracer() | ||||
| 	root := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	child := tracer.NewChildSpan("redis.command", root) | ||||
|  | ||||
| 	assert.Equal("", child.GetMeta(ext.Pid)) | ||||
| } | ||||
|  | ||||
| func TestTracerDisabled(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	// disable the tracer and be sure that the span is not added | ||||
| 	tracer := NewTracer() | ||||
| 	tracer.SetEnabled(false) | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	span.Finish() | ||||
| 	assert.Len(tracer.channels.trace, 0) | ||||
| } | ||||
|  | ||||
| func TestTracerEnabledAgain(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	// disable the tracer and enable it again | ||||
| 	tracer := NewTracer() | ||||
| 	tracer.SetEnabled(false) | ||||
| 	preSpan := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	preSpan.Finish() | ||||
| 	assert.Len(tracer.channels.trace, 0) | ||||
| 	tracer.SetEnabled(true) | ||||
| 	postSpan := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	postSpan.Finish() | ||||
| 	assert.Len(tracer.channels.trace, 1) | ||||
| } | ||||
|  | ||||
| func TestTracerSampler(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	sampleRate := 0.5 | ||||
| 	tracer := NewTracer() | ||||
| 	tracer.SetSampleRate(sampleRate) | ||||
|  | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 	// The span might be sampled or not, we don't know, but at least it should have the sample rate metric | ||||
| 	assert.Equal(sampleRate, span.Metrics[sampleRateMetricKey]) | ||||
| } | ||||
|  | ||||
| func TestTracerEdgeSampler(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	// a sample rate of 0 should sample nothing | ||||
| 	tracer0 := NewTracer() | ||||
| 	tracer0.SetSampleRate(0) | ||||
| 	// a sample rate of 1 should sample everything | ||||
| 	tracer1 := NewTracer() | ||||
| 	tracer1.SetSampleRate(1) | ||||
|  | ||||
| 	count := traceChanLen / 3 | ||||
|  | ||||
| 	for i := 0; i < count; i++ { | ||||
| 		span0 := tracer0.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 		span0.Finish() | ||||
| 		span1 := tracer1.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 		span1.Finish() | ||||
| 	} | ||||
|  | ||||
| 	assert.Len(tracer0.channels.trace, 0) | ||||
| 	assert.Len(tracer1.channels.trace, count) | ||||
|  | ||||
| 	tracer0.Stop() | ||||
| 	tracer1.Stop() | ||||
| } | ||||
|  | ||||
| func TestTracerConcurrent(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer, transport := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	// Wait for three different goroutines that should create | ||||
| 	// three different traces with one child each | ||||
| 	var wg sync.WaitGroup | ||||
| 	wg.Add(3) | ||||
| 	go func() { | ||||
| 		defer wg.Done() | ||||
| 		tracer.NewRootSpan("pylons.request", "pylons", "/").Finish() | ||||
| 	}() | ||||
| 	go func() { | ||||
| 		defer wg.Done() | ||||
| 		tracer.NewRootSpan("pylons.request", "pylons", "/home").Finish() | ||||
| 	}() | ||||
| 	go func() { | ||||
| 		defer wg.Done() | ||||
| 		tracer.NewRootSpan("pylons.request", "pylons", "/trace").Finish() | ||||
| 	}() | ||||
|  | ||||
| 	wg.Wait() | ||||
| 	tracer.ForceFlush() | ||||
| 	traces := transport.Traces() | ||||
| 	assert.Len(traces, 3) | ||||
| 	assert.Len(traces[0], 1) | ||||
| 	assert.Len(traces[1], 1) | ||||
| 	assert.Len(traces[2], 1) | ||||
| } | ||||
|  | ||||
| func TestTracerParentFinishBeforeChild(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer, transport := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	// Testing an edge case: a child refers to a parent that is already closed. | ||||
|  | ||||
| 	parent := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	parent.Finish() | ||||
|  | ||||
| 	tracer.ForceFlush() | ||||
| 	traces := transport.Traces() | ||||
| 	assert.Len(traces, 1) | ||||
| 	assert.Len(traces[0], 1) | ||||
| 	assert.Equal(parent, traces[0][0]) | ||||
|  | ||||
| 	child := tracer.NewChildSpan("redis.command", parent) | ||||
| 	child.Finish() | ||||
|  | ||||
| 	tracer.ForceFlush() | ||||
|  | ||||
| 	traces = transport.Traces() | ||||
| 	assert.Len(traces, 1) | ||||
| 	assert.Len(traces[0], 1) | ||||
| 	assert.Equal(child, traces[0][0]) | ||||
| 	assert.Equal(parent.SpanID, traces[0][0].ParentID, "child should refer to parent, even if they have been flushed separately") | ||||
| } | ||||
|  | ||||
| func TestTracerConcurrentMultipleSpans(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer, transport := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	// Wait for two different goroutines that should create | ||||
| 	// two traces with two children each | ||||
| 	var wg sync.WaitGroup | ||||
| 	wg.Add(2) | ||||
| 	go func() { | ||||
| 		defer wg.Done() | ||||
| 		parent := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 		child := tracer.NewChildSpan("redis.command", parent) | ||||
| 		child.Finish() | ||||
| 		parent.Finish() | ||||
| 	}() | ||||
| 	go func() { | ||||
| 		defer wg.Done() | ||||
| 		parent := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 		child := tracer.NewChildSpan("redis.command", parent) | ||||
| 		child.Finish() | ||||
| 		parent.Finish() | ||||
| 	}() | ||||
|  | ||||
| 	wg.Wait() | ||||
| 	tracer.ForceFlush() | ||||
| 	traces := transport.Traces() | ||||
| 	assert.Len(traces, 2) | ||||
| 	assert.Len(traces[0], 2) | ||||
| 	assert.Len(traces[1], 2) | ||||
| } | ||||
|  | ||||
| func TestTracerAtomicFlush(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer, transport := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	// Make sure we don't flush partial bits of traces | ||||
| 	root := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	span := tracer.NewChildSpan("redis.command", root) | ||||
| 	span1 := tracer.NewChildSpan("redis.command.1", span) | ||||
| 	span2 := tracer.NewChildSpan("redis.command.2", span) | ||||
| 	span.Finish() | ||||
| 	span1.Finish() | ||||
| 	span2.Finish() | ||||
|  | ||||
| 	tracer.ForceFlush() | ||||
| 	traces := transport.Traces() | ||||
| 	assert.Len(traces, 0, "nothing should be flushed now as span2 is not finished yet") | ||||
|  | ||||
| 	root.Finish() | ||||
|  | ||||
| 	tracer.ForceFlush() | ||||
| 	traces = transport.Traces() | ||||
| 	assert.Len(traces, 1) | ||||
| 	assert.Len(traces[0], 4, "all spans should show up at once") | ||||
| } | ||||
|  | ||||
| func TestTracerServices(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer, transport := getTestTracer() | ||||
|  | ||||
| 	tracer.SetServiceInfo("svc1", "a", "b") | ||||
| 	tracer.SetServiceInfo("svc2", "c", "d") | ||||
| 	tracer.SetServiceInfo("svc1", "e", "f") | ||||
|  | ||||
| 	tracer.Stop() | ||||
|  | ||||
| 	assert.Len(transport.services, 2) | ||||
|  | ||||
| 	svc1 := transport.services["svc1"] | ||||
| 	assert.NotNil(svc1) | ||||
| 	assert.Equal("svc1", svc1.Name) | ||||
| 	assert.Equal("e", svc1.App) | ||||
| 	assert.Equal("f", svc1.AppType) | ||||
|  | ||||
| 	svc2 := transport.services["svc2"] | ||||
| 	assert.NotNil(svc2) | ||||
| 	assert.Equal("svc2", svc2.Name) | ||||
| 	assert.Equal("c", svc2.App) | ||||
| 	assert.Equal("d", svc2.AppType) | ||||
| } | ||||
|  | ||||
| func TestTracerServicesDisabled(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tracer, transport := getTestTracer() | ||||
|  | ||||
| 	tracer.SetEnabled(false) | ||||
| 	tracer.SetServiceInfo("svc1", "a", "b") | ||||
| 	tracer.Stop() | ||||
|  | ||||
| 	assert.Len(transport.services, 0) | ||||
| } | ||||
|  | ||||
| func TestTracerMeta(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	var nilTracer *Tracer | ||||
| 	nilTracer.SetMeta("key", "value") | ||||
| 	assert.Nil(nilTracer.getAllMeta(), "nil tracer should return nil meta") | ||||
|  | ||||
| 	tracer, _ := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	assert.Nil(tracer.getAllMeta(), "by default, no meta") | ||||
| 	tracer.SetMeta("env", "staging") | ||||
|  | ||||
| 	span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	assert.Equal("staging", span.GetMeta("env")) | ||||
| 	assert.Equal("", span.GetMeta("component")) | ||||
| 	span.Finish() | ||||
| 	assert.Equal(map[string]string{"env": "staging"}, tracer.getAllMeta(), "there should be one meta") | ||||
|  | ||||
| 	tracer.SetMeta("component", "core") | ||||
| 	span = tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	assert.Equal("staging", span.GetMeta("env")) | ||||
| 	assert.Equal("core", span.GetMeta("component")) | ||||
| 	span.Finish() | ||||
| 	assert.Equal(map[string]string{"env": "staging", "component": "core"}, tracer.getAllMeta(), "there should be two entries") | ||||
|  | ||||
| 	tracer.SetMeta("env", "prod") | ||||
| 	span = tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 	assert.Equal("prod", span.GetMeta("env")) | ||||
| 	assert.Equal("core", span.GetMeta("component")) | ||||
| 	span.SetMeta("env", "sandbox") | ||||
| 	assert.Equal("sandbox", span.GetMeta("env")) | ||||
| 	assert.Equal("core", span.GetMeta("component")) | ||||
| 	span.Finish() | ||||
|  | ||||
| 	assert.Equal(map[string]string{"env": "prod", "component": "core"}, tracer.getAllMeta(), "key1 should have been updated") | ||||
| } | ||||
|  | ||||
| func TestTracerRace(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	tracer, transport := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	total := (traceChanLen / 3) / 10 | ||||
| 	var wg sync.WaitGroup | ||||
| 	wg.Add(total) | ||||
|  | ||||
| 	// Trying to be quite brutal here, firing lots of concurrent things, finishing in | ||||
| 	// different orders, and modifying spans after creation. | ||||
| 	for n := 0; n < total; n++ { | ||||
| 		i := n // keep local copy | ||||
| 		odd := ((i % 2) != 0) | ||||
| 		go func() { | ||||
| 			if i%11 == 0 { | ||||
| 				time.Sleep(time.Microsecond) | ||||
| 			} | ||||
|  | ||||
| 			tracer.SetMeta("foo", "bar") | ||||
|  | ||||
| 			parent := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
|  | ||||
| 			NewChildSpan("redis.command", parent).Finish() | ||||
| 			child := NewChildSpan("async.service", parent) | ||||
|  | ||||
| 			if i%13 == 0 { | ||||
| 				time.Sleep(time.Microsecond) | ||||
| 			} | ||||
|  | ||||
| 			if odd { | ||||
| 				parent.SetMeta("odd", "true") | ||||
| 				parent.SetMetric("oddity", 1) | ||||
| 				parent.Finish() | ||||
| 			} else { | ||||
| 				child.SetMeta("odd", "false") | ||||
| 				child.SetMetric("oddity", 0) | ||||
| 				child.Finish() | ||||
| 			} | ||||
|  | ||||
| 			if i%17 == 0 { | ||||
| 				time.Sleep(time.Microsecond) | ||||
| 			} | ||||
|  | ||||
| 			if odd { | ||||
| 				child.Resource = "HGETALL" | ||||
| 				child.SetMeta("odd", "false") | ||||
| 				child.SetMetric("oddity", 0) | ||||
| 			} else { | ||||
| 				parent.Resource = "/" + strconv.Itoa(i) + ".html" | ||||
| 				parent.SetMeta("odd", "true") | ||||
| 				parent.SetMetric("oddity", 1) | ||||
| 			} | ||||
|  | ||||
| 			if i%19 == 0 { | ||||
| 				time.Sleep(time.Microsecond) | ||||
| 			} | ||||
|  | ||||
| 			if odd { | ||||
| 				child.Finish() | ||||
| 			} else { | ||||
| 				parent.Finish() | ||||
| 			} | ||||
|  | ||||
| 			wg.Done() | ||||
| 		}() | ||||
| 	} | ||||
|  | ||||
| 	wg.Wait() | ||||
|  | ||||
| 	tracer.ForceFlush() | ||||
| 	traces := transport.Traces() | ||||
| 	assert.Len(traces, total, "we should have exactly as many traces as expected") | ||||
| 	for _, trace := range traces { | ||||
| 		assert.Len(trace, 3, "each trace should have exactly 3 spans") | ||||
| 		var parent, child, redis *Span | ||||
| 		for _, span := range trace { | ||||
| 			assert.Equal("bar", span.GetMeta("foo"), "tracer meta should have been applied to all spans") | ||||
| 			switch span.Name { | ||||
| 			case "pylons.request": | ||||
| 				parent = span | ||||
| 			case "async.service": | ||||
| 				child = span | ||||
| 			case "redis.command": | ||||
| 				redis = span | ||||
| 			default: | ||||
| 				assert.Fail("unexpected span", span) | ||||
| 			} | ||||
| 		} | ||||
| 		assert.NotNil(parent) | ||||
| 		assert.NotNil(child) | ||||
| 		assert.NotNil(redis) | ||||
|  | ||||
| 		assert.Equal(uint64(0), parent.ParentID) | ||||
| 		assert.Equal(parent.TraceID, parent.SpanID) | ||||
|  | ||||
| 		assert.Equal(parent.TraceID, redis.TraceID) | ||||
| 		assert.Equal(parent.TraceID, child.TraceID) | ||||
|  | ||||
| 		assert.Equal(parent.TraceID, redis.ParentID) | ||||
| 		assert.Equal(parent.TraceID, child.ParentID) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestWorker is definitely a flaky test, as here we test that the worker | ||||
| // background task actually does flush things. Most other tests are and should | ||||
| // be using ForceFlush() to make sure things are really sent to transport. | ||||
| // Here, we just wait until things show up, as we would do with a real program. | ||||
| func TestWorker(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	tracer, transport := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	n := traceChanLen * 10 // put more traces than the chan size, on purpose | ||||
| 	for i := 0; i < n; i++ { | ||||
| 		root := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 		child := tracer.NewChildSpan("redis.command", root) | ||||
| 		child.Finish() | ||||
| 		root.Finish() | ||||
| 	} | ||||
|  | ||||
| 	now := time.Now() | ||||
| 	count := 0 | ||||
| 	for time.Now().Before(now.Add(time.Minute)) && count < traceChanLen { | ||||
| 		nbTraces := len(transport.Traces()) | ||||
| 		if nbTraces > 0 { | ||||
| 			t.Logf("popped %d traces", nbTraces) | ||||
| 		} | ||||
| 		count += nbTraces | ||||
| 		time.Sleep(time.Millisecond) | ||||
| 	} | ||||
| 	// here we just check that we have "enough traces". In practice, lots of them | ||||
| 	// are dropped, it's another interesting side-effect of this test: it does | ||||
| 	// trigger error messages (which are repeated, so it aggregates them etc.) | ||||
| 	if count < traceChanLen { | ||||
| 		assert.Fail(fmt.Sprintf("timeout, not enough traces in buffer (%d/%d)", count, n)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // BenchmarkConcurrentTracing tests the performance of spawning a lot of | ||||
| // goroutines where each one creates a trace with a parent and a child. | ||||
| func BenchmarkConcurrentTracing(b *testing.B) { | ||||
| 	tracer, _ := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	b.ResetTimer() | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		go func() { | ||||
| 			parent := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 			defer parent.Finish() | ||||
|  | ||||
| 			for i := 0; i < 10; i++ { | ||||
| 				tracer.NewChildSpan("redis.command", parent).Finish() | ||||
| 			} | ||||
| 		}() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // BenchmarkTracerAddSpans tests the performance of creating and finishing a root | ||||
| // span. It should include the encoding overhead. | ||||
| func BenchmarkTracerAddSpans(b *testing.B) { | ||||
| 	tracer, _ := getTestTracer() | ||||
| 	defer tracer.Stop() | ||||
|  | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		span := tracer.NewRootSpan("pylons.request", "pylons", "/") | ||||
| 		span.Finish() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // getTestTracer returns a Tracer with a DummyTransport | ||||
| func getTestTracer() (*Tracer, *dummyTransport) { | ||||
| 	transport := &dummyTransport{getEncoder: msgpackEncoderFactory} | ||||
| 	tracer := NewTracerTransport(transport) | ||||
| 	return tracer, transport | ||||
| } | ||||
|  | ||||
| // Mock Transport with a real Encoder | ||||
| type dummyTransport struct { | ||||
| 	getEncoder encoderFactory | ||||
| 	traces     [][]*Span | ||||
| 	services   map[string]Service | ||||
|  | ||||
| 	sync.RWMutex // required because of some poll-testing (eg: worker) | ||||
| } | ||||
|  | ||||
| func (t *dummyTransport) SendTraces(traces [][]*Span) (*http.Response, error) { | ||||
| 	t.Lock() | ||||
| 	t.traces = append(t.traces, traces...) | ||||
| 	t.Unlock() | ||||
|  | ||||
| 	encoder := t.getEncoder() | ||||
| 	return nil, encoder.EncodeTraces(traces) | ||||
| } | ||||
|  | ||||
| func (t *dummyTransport) SendServices(services map[string]Service) (*http.Response, error) { | ||||
| 	t.Lock() | ||||
| 	t.services = services | ||||
| 	t.Unlock() | ||||
|  | ||||
| 	encoder := t.getEncoder() | ||||
| 	return nil, encoder.EncodeServices(services) | ||||
| } | ||||
|  | ||||
| func (t *dummyTransport) Traces() [][]*Span { | ||||
| 	t.Lock() | ||||
| 	defer t.Unlock() | ||||
|  | ||||
| 	traces := t.traces | ||||
| 	t.traces = nil | ||||
| 	return traces | ||||
| } | ||||
|  | ||||
| func (t *dummyTransport) SetHeader(key, value string) {} | ||||
							
								
								
									
										202
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/transport_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/DataDog/dd-trace-go/tracer/transport_test.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,202 +0,0 @@ | ||||
| package tracer | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"net/url" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| // getTestSpan returns a Span with different fields set | ||||
| func getTestSpan() *Span { | ||||
| 	return &Span{ | ||||
| 		TraceID:  42, | ||||
| 		SpanID:   52, | ||||
| 		ParentID: 42, | ||||
| 		Type:     "web", | ||||
| 		Service:  "high.throughput", | ||||
| 		Name:     "sending.events", | ||||
| 		Resource: "SEND /data", | ||||
| 		Start:    1481215590883401105, | ||||
| 		Duration: 1000000000, | ||||
| 		Meta:     map[string]string{"http.host": "192.168.0.1"}, | ||||
| 		Metrics:  map[string]float64{"http.monitor": 41.99}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // getTestTrace returns a list of traces that is composed by ``traceN`` number | ||||
| // of traces, each one composed by ``size`` number of spans. | ||||
| func getTestTrace(traceN, size int) [][]*Span { | ||||
| 	var traces [][]*Span | ||||
|  | ||||
| 	for i := 0; i < traceN; i++ { | ||||
| 		trace := []*Span{} | ||||
| 		for j := 0; j < size; j++ { | ||||
| 			trace = append(trace, getTestSpan()) | ||||
| 		} | ||||
| 		traces = append(traces, trace) | ||||
| 	} | ||||
| 	return traces | ||||
| } | ||||
|  | ||||
| func getTestServices() map[string]Service { | ||||
| 	return map[string]Service{ | ||||
| 		"svc1": Service{Name: "scv1", App: "a", AppType: "b"}, | ||||
| 		"svc2": Service{Name: "scv2", App: "c", AppType: "d"}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type mockDatadogAPIHandler struct { | ||||
| 	t *testing.T | ||||
| } | ||||
|  | ||||
| func (m mockDatadogAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 	assert := assert.New(m.t) | ||||
|  | ||||
| 	header := r.Header.Get("X-Datadog-Trace-Count") | ||||
| 	assert.NotEqual("", header, "X-Datadog-Trace-Count header should be here") | ||||
| 	count, err := strconv.Atoi(header) | ||||
| 	assert.Nil(err, "header should be an int") | ||||
| 	assert.NotEqual(0, count, "there should be a non-zero amount of traces") | ||||
| } | ||||
|  | ||||
| func mockDatadogAPINewServer(t *testing.T) *httptest.Server { | ||||
| 	handler := mockDatadogAPIHandler{t: t} | ||||
| 	server := httptest.NewServer(handler) | ||||
| 	return server | ||||
| } | ||||
|  | ||||
| func TestTracesAgentIntegration(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	testCases := []struct { | ||||
| 		payload [][]*Span | ||||
| 	}{ | ||||
| 		{getTestTrace(1, 1)}, | ||||
| 		{getTestTrace(10, 1)}, | ||||
| 		{getTestTrace(1, 10)}, | ||||
| 		{getTestTrace(10, 10)}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tc := range testCases { | ||||
| 		transport := newHTTPTransport(defaultHostname, defaultPort) | ||||
| 		response, err := transport.SendTraces(tc.payload) | ||||
| 		assert.NoError(err) | ||||
| 		assert.NotNil(response) | ||||
| 		assert.Equal(200, response.StatusCode) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestAPIDowngrade(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	transport := newHTTPTransport(defaultHostname, defaultPort) | ||||
| 	transport.traceURL = "http://localhost:8126/v0.0/traces" | ||||
|  | ||||
| 	// if we get a 404 we should downgrade the API | ||||
| 	traces := getTestTrace(2, 2) | ||||
| 	response, err := transport.SendTraces(traces) | ||||
| 	assert.NoError(err) | ||||
| 	assert.NotNil(response) | ||||
| 	assert.Equal(200, response.StatusCode) | ||||
| } | ||||
|  | ||||
| func TestEncoderDowngrade(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	transport := newHTTPTransport(defaultHostname, defaultPort) | ||||
| 	transport.traceURL = "http://localhost:8126/v0.2/traces" | ||||
|  | ||||
| 	// if we get a 415 because of a wrong encoder, we should downgrade the encoder | ||||
| 	traces := getTestTrace(2, 2) | ||||
| 	response, err := transport.SendTraces(traces) | ||||
| 	assert.NoError(err) | ||||
| 	assert.NotNil(response) | ||||
| 	assert.Equal(200, response.StatusCode) | ||||
| } | ||||
|  | ||||
| func TestTransportServices(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	transport := newHTTPTransport(defaultHostname, defaultPort) | ||||
|  | ||||
| 	response, err := transport.SendServices(getTestServices()) | ||||
| 	assert.NoError(err) | ||||
| 	assert.NotNil(response) | ||||
| 	assert.Equal(200, response.StatusCode) | ||||
| } | ||||
|  | ||||
| func TestTransportServicesDowngrade_0_0(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	transport := newHTTPTransport(defaultHostname, defaultPort) | ||||
| 	transport.serviceURL = "http://localhost:8126/v0.0/services" | ||||
|  | ||||
| 	response, err := transport.SendServices(getTestServices()) | ||||
| 	assert.NoError(err) | ||||
| 	assert.NotNil(response) | ||||
| 	assert.Equal(200, response.StatusCode) | ||||
| } | ||||
|  | ||||
| func TestTransportServicesDowngrade_0_2(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	transport := newHTTPTransport(defaultHostname, defaultPort) | ||||
| 	transport.serviceURL = "http://localhost:8126/v0.2/services" | ||||
|  | ||||
| 	response, err := transport.SendServices(getTestServices()) | ||||
| 	assert.NoError(err) | ||||
| 	assert.NotNil(response) | ||||
| 	assert.Equal(200, response.StatusCode) | ||||
| } | ||||
|  | ||||
| func TestTransportEncoderPool(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	transport := newHTTPTransport(defaultHostname, defaultPort) | ||||
|  | ||||
| 	// MsgpackEncoder is the default encoder of the pool | ||||
| 	encoder := transport.getEncoder() | ||||
| 	assert.Equal("application/msgpack", encoder.ContentType()) | ||||
| } | ||||
|  | ||||
| func TestTransportSwitchEncoder(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	transport := newHTTPTransport(defaultHostname, defaultPort) | ||||
| 	transport.changeEncoder(jsonEncoderFactory) | ||||
|  | ||||
| 	// MsgpackEncoder is the default encoder of the pool | ||||
| 	encoder := transport.getEncoder() | ||||
| 	assert.Equal("application/json", encoder.ContentType()) | ||||
| } | ||||
|  | ||||
| func TestTraceCountHeader(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	testCases := []struct { | ||||
| 		payload [][]*Span | ||||
| 	}{ | ||||
| 		{getTestTrace(1, 1)}, | ||||
| 		{getTestTrace(10, 1)}, | ||||
| 		{getTestTrace(100, 10)}, | ||||
| 	} | ||||
|  | ||||
| 	receiver := mockDatadogAPINewServer(t) | ||||
| 	parsedURL, err := url.Parse(receiver.URL) | ||||
| 	assert.NoError(err) | ||||
| 	host := parsedURL.Host | ||||
| 	hostItems := strings.Split(host, ":") | ||||
| 	assert.Equal(2, len(hostItems), "port should be given, as it's chosen randomly") | ||||
| 	hostname := hostItems[0] | ||||
| 	port := hostItems[1] | ||||
| 	for _, tc := range testCases { | ||||
| 		transport := newHTTPTransport(hostname, port) | ||||
| 		response, err := transport.SendTraces(tc.payload) | ||||
| 		assert.NoError(err) | ||||
| 		assert.NotNil(response) | ||||
| 		assert.Equal(200, response.StatusCode) | ||||
| 	} | ||||
|  | ||||
| 	receiver.Close() | ||||
| } | ||||
		Reference in New Issue
	
	Block a user