Dep helper (#2151)
* Add dep task to update go dependencies * Update go dependencies
This commit is contained in:
parent
8f8b81f56b
commit
0e8977761d
764 changed files with 172 additions and 267451 deletions
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()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue