add opentelemetry test (#1002)
parent
10805577f5
commit
dec6309c55
@ -0,0 +1,347 @@
|
|||||||
|
package opentelemetry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.opentelemetry.io/otel"
|
||||||
|
"go.opentelemetry.io/otel/propagation"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
traceIDStr = "4bf92f3577b34da6a3ce929d0e0e4736"
|
||||||
|
spanIDStr = "00f067aa0ba902b7"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
traceID = mustTraceIDFromHex(traceIDStr)
|
||||||
|
spanID = mustSpanIDFromHex(spanIDStr)
|
||||||
|
)
|
||||||
|
|
||||||
|
func mustTraceIDFromHex(s string) (t trace.TraceID) {
|
||||||
|
var err error
|
||||||
|
t, err = trace.TraceIDFromHex(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustSpanIDFromHex(s string) (t trace.SpanID) {
|
||||||
|
var err error
|
||||||
|
t, err = trace.SpanIDFromHex(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExtractValidTraceContext(t *testing.T) {
|
||||||
|
stateStr := "key1=value1,key2=value2"
|
||||||
|
state, err := trace.ParseTraceState(stateStr)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
traceparent string
|
||||||
|
tracestate string
|
||||||
|
sc trace.SpanContext
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "not sampled",
|
||||||
|
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "sampled",
|
||||||
|
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
TraceFlags: trace.FlagsSampled,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid tracestate",
|
||||||
|
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
|
||||||
|
tracestate: stateStr,
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
TraceState: state,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid tracestate perserves traceparent",
|
||||||
|
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
|
||||||
|
tracestate: "invalid$@#=invalid",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "future version not sampled",
|
||||||
|
traceparent: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "future version sampled",
|
||||||
|
traceparent: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
TraceFlags: trace.FlagsSampled,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "future version sample bit set",
|
||||||
|
traceparent: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
TraceFlags: trace.FlagsSampled,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "future version sample bit not set",
|
||||||
|
traceparent: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-08",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "future version additional data",
|
||||||
|
traceparent: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00-XYZxsf09",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "B3 format ending in dash",
|
||||||
|
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00-",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "future version B3 format ending in dash",
|
||||||
|
traceparent: "03-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00-",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
|
||||||
|
propagator := otel.GetTextMapPropagator()
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
md := metadata.MD{}
|
||||||
|
md.Set("traceparent", tt.traceparent)
|
||||||
|
md.Set("tracestate", tt.tracestate)
|
||||||
|
_, spanCtx := Extract(ctx, propagator, &md)
|
||||||
|
assert.Equal(t, tt.sc, spanCtx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExtractInvalidTraceContext(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
header string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "wrong version length",
|
||||||
|
header: "0000-00000000000000000000000000000000-0000000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "wrong trace ID length",
|
||||||
|
header: "00-ab00000000000000000000000000000000-cd00000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "wrong span ID length",
|
||||||
|
header: "00-ab000000000000000000000000000000-cd0000000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "wrong trace flag length",
|
||||||
|
header: "00-ab000000000000000000000000000000-cd00000000000000-0100",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bogus version",
|
||||||
|
header: "qw-00000000000000000000000000000000-0000000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bogus trace ID",
|
||||||
|
header: "00-qw000000000000000000000000000000-cd00000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bogus span ID",
|
||||||
|
header: "00-ab000000000000000000000000000000-qw00000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bogus trace flag",
|
||||||
|
header: "00-ab000000000000000000000000000000-cd00000000000000-qw",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "upper case version",
|
||||||
|
header: "A0-00000000000000000000000000000000-0000000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "upper case trace ID",
|
||||||
|
header: "00-AB000000000000000000000000000000-cd00000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "upper case span ID",
|
||||||
|
header: "00-ab000000000000000000000000000000-CD00000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "upper case trace flag",
|
||||||
|
header: "00-ab000000000000000000000000000000-cd00000000000000-A1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "zero trace ID and span ID",
|
||||||
|
header: "00-00000000000000000000000000000000-0000000000000000-01",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "trace-flag unused bits set",
|
||||||
|
header: "00-ab000000000000000000000000000000-cd00000000000000-09",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "missing options",
|
||||||
|
header: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty options",
|
||||||
|
header: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
|
||||||
|
propagator := otel.GetTextMapPropagator()
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
md := metadata.MD{}
|
||||||
|
md.Set("traceparent", tt.header)
|
||||||
|
_, spanCtx := Extract(ctx, propagator, &md)
|
||||||
|
assert.Equal(t, trace.SpanContext{}, spanCtx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInjectValidTraceContext(t *testing.T) {
|
||||||
|
stateStr := "key1=value1,key2=value2"
|
||||||
|
state, err := trace.ParseTraceState(stateStr)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
traceparent string
|
||||||
|
tracestate string
|
||||||
|
sc trace.SpanContext
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "not sampled",
|
||||||
|
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "sampled",
|
||||||
|
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
TraceFlags: trace.FlagsSampled,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unsupported trace flag bits dropped",
|
||||||
|
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
TraceFlags: 0xff,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with tracestate",
|
||||||
|
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
|
||||||
|
tracestate: stateStr,
|
||||||
|
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||||
|
TraceID: traceID,
|
||||||
|
SpanID: spanID,
|
||||||
|
TraceState: state,
|
||||||
|
Remote: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
|
||||||
|
propagator := otel.GetTextMapPropagator()
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx = trace.ContextWithRemoteSpanContext(ctx, tt.sc)
|
||||||
|
|
||||||
|
want := metadata.MD{}
|
||||||
|
want.Set("traceparent", tt.traceparent)
|
||||||
|
if len(tt.tracestate) > 0 {
|
||||||
|
want.Set("tracestate", tt.tracestate)
|
||||||
|
}
|
||||||
|
|
||||||
|
md := metadata.MD{}
|
||||||
|
Inject(ctx, propagator, &md)
|
||||||
|
assert.Equal(t, want, md)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInvalidSpanContextDropped(t *testing.T) {
|
||||||
|
invalidSC := trace.SpanContext{}
|
||||||
|
require.False(t, invalidSC.IsValid())
|
||||||
|
ctx := trace.ContextWithRemoteSpanContext(context.Background(), invalidSC)
|
||||||
|
|
||||||
|
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
|
||||||
|
propagator := otel.GetTextMapPropagator()
|
||||||
|
|
||||||
|
md := metadata.MD{}
|
||||||
|
Inject(ctx, propagator, &md)
|
||||||
|
mm := &metadataSupplier{
|
||||||
|
metadata: &md,
|
||||||
|
}
|
||||||
|
assert.Equal(t, "", mm.Get("traceparent"), "injected invalid SpanContext")
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package opentelemetry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseFullMethod(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
fullMethod string
|
||||||
|
name string
|
||||||
|
attr []attribute.KeyValue
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
fullMethod: "/grpc.test.EchoService/Echo",
|
||||||
|
name: "grpc.test.EchoService/Echo",
|
||||||
|
attr: []attribute.KeyValue{
|
||||||
|
semconv.RPCServiceKey.String("grpc.test.EchoService"),
|
||||||
|
semconv.RPCMethodKey.String("Echo"),
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
fullMethod: "/com.example.ExampleRmiService/exampleMethod",
|
||||||
|
name: "com.example.ExampleRmiService/exampleMethod",
|
||||||
|
attr: []attribute.KeyValue{
|
||||||
|
semconv.RPCServiceKey.String("com.example.ExampleRmiService"),
|
||||||
|
semconv.RPCMethodKey.String("exampleMethod"),
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
fullMethod: "/MyCalcService.Calculator/Add",
|
||||||
|
name: "MyCalcService.Calculator/Add",
|
||||||
|
attr: []attribute.KeyValue{
|
||||||
|
semconv.RPCServiceKey.String("MyCalcService.Calculator"),
|
||||||
|
semconv.RPCMethodKey.String("Add"),
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
fullMethod: "/MyServiceReference.ICalculator/Add",
|
||||||
|
name: "MyServiceReference.ICalculator/Add",
|
||||||
|
attr: []attribute.KeyValue{
|
||||||
|
semconv.RPCServiceKey.String("MyServiceReference.ICalculator"),
|
||||||
|
semconv.RPCMethodKey.String("Add"),
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
fullMethod: "/MyServiceWithNoPackage/theMethod",
|
||||||
|
name: "MyServiceWithNoPackage/theMethod",
|
||||||
|
attr: []attribute.KeyValue{
|
||||||
|
semconv.RPCServiceKey.String("MyServiceWithNoPackage"),
|
||||||
|
semconv.RPCMethodKey.String("theMethod"),
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
fullMethod: "/pkg.srv",
|
||||||
|
name: "pkg.srv",
|
||||||
|
attr: []attribute.KeyValue(nil),
|
||||||
|
}, {
|
||||||
|
fullMethod: "/pkg.srv/",
|
||||||
|
name: "pkg.srv/",
|
||||||
|
attr: []attribute.KeyValue{
|
||||||
|
semconv.RPCServiceKey.String("pkg.srv"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
n, a := ParseFullMethod(test.fullMethod)
|
||||||
|
assert.Equal(t, test.name, n)
|
||||||
|
assert.Equal(t, test.attr, a)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue