mirror of
https://github.com/go-kratos/kratos.git
synced 2025-02-13 13:48:51 +02:00
test(middleware/tracing): tracing unit test enhancement (#1484)
* use t.Setenv * add tracing test * lint fix * update go test env to go@1.17 * remove grep * rename Transport
This commit is contained in:
parent
db2122860d
commit
04bc0e63ba
2
.github/workflows/go.yml
vendored
2
.github/workflows/go.yml
vendored
@ -32,7 +32,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
go-version: 1.17
|
||||
|
||||
- name: Build
|
||||
run: go build ./...
|
||||
|
8
config/env/env_test.go
vendored
8
config/env/env_test.go
vendored
@ -55,9 +55,7 @@ func TestEnvWithPrefix(t *testing.T) {
|
||||
}
|
||||
|
||||
for k, v := range envs {
|
||||
if err := os.Setenv(k, v); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Setenv(k, v)
|
||||
}
|
||||
|
||||
c := config.New(config.WithSource(
|
||||
@ -163,9 +161,7 @@ func TestEnvWithoutPrefix(t *testing.T) {
|
||||
}
|
||||
|
||||
for k, v := range envs {
|
||||
if err := os.Setenv(k, v); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Setenv(k, v)
|
||||
}
|
||||
|
||||
c := config.New(config.WithSource(
|
||||
|
158
middleware/tracing/span_test.go
Normal file
158
middleware/tracing/span_test.go
Normal file
@ -0,0 +1,158 @@
|
||||
package tracing
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
||||
)
|
||||
|
||||
func Test_parseFullMethod(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fullMethod string
|
||||
want string
|
||||
wantAttr []attribute.KeyValue
|
||||
}{
|
||||
{
|
||||
name: "/foo.bar/hello",
|
||||
fullMethod: "/foo.bar/hello",
|
||||
want: "foo.bar/hello",
|
||||
wantAttr: []attribute.KeyValue{
|
||||
semconv.RPCServiceKey.String("foo.bar"),
|
||||
semconv.RPCMethodKey.String("hello"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "/foo.bar/hello/world",
|
||||
fullMethod: "/foo.bar/hello/world",
|
||||
want: "foo.bar/hello/world",
|
||||
wantAttr: []attribute.KeyValue{
|
||||
semconv.RPCServiceKey.String("foo.bar"),
|
||||
semconv.RPCMethodKey.String("hello/world"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "/hello",
|
||||
fullMethod: "/hello",
|
||||
want: "hello",
|
||||
wantAttr: []attribute.KeyValue{attribute.Key("rpc.operation").String("/hello")},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, got1 := parseFullMethod(tt.fullMethod)
|
||||
if got != tt.want {
|
||||
t.Errorf("parseFullMethod() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
if !reflect.DeepEqual(got1, tt.wantAttr) {
|
||||
t.Errorf("parseFullMethod() got1 = %v, want %v", got1, tt.wantAttr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_peerAttr(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
addr string
|
||||
want []attribute.KeyValue
|
||||
}{
|
||||
{
|
||||
name: "nil addr",
|
||||
addr: ":8080",
|
||||
want: []attribute.KeyValue{
|
||||
semconv.NetPeerIPKey.String("127.0.0.1"),
|
||||
semconv.NetPeerPortKey.String("8080"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "normal addr without port",
|
||||
addr: "192.168.0.1",
|
||||
want: []attribute.KeyValue(nil),
|
||||
},
|
||||
{
|
||||
name: "normal addr with port",
|
||||
addr: "192.168.0.1:8080",
|
||||
want: []attribute.KeyValue{
|
||||
semconv.NetPeerIPKey.String("192.168.0.1"),
|
||||
semconv.NetPeerPortKey.String("8080"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dns addr",
|
||||
addr: "foo:8080",
|
||||
want: []attribute.KeyValue{
|
||||
semconv.NetPeerIPKey.String("foo"),
|
||||
semconv.NetPeerPortKey.String("8080"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := peerAttr(tt.addr); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("peerAttr() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_parseTarget(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
endpoint string
|
||||
wantAddress string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "http",
|
||||
endpoint: "http://foo.bar:8080",
|
||||
wantAddress: "http://foo.bar:8080",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "http",
|
||||
endpoint: "http://127.0.0.1:8080",
|
||||
wantAddress: "http://127.0.0.1:8080",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "without protocol",
|
||||
endpoint: "foo.bar:8080",
|
||||
wantAddress: "foo.bar:8080",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "grpc",
|
||||
endpoint: "grpc://foo.bar",
|
||||
wantAddress: "grpc://foo.bar",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "with path",
|
||||
endpoint: "/foo",
|
||||
wantAddress: "foo",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "with path",
|
||||
endpoint: "http://127.0.0.1/hello",
|
||||
wantAddress: "hello",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotAddress, err := parseTarget(tt.endpoint)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("parseTarget() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if gotAddress != tt.wantAddress {
|
||||
t.Errorf("parseTarget() = %v, want %v", gotAddress, tt.wantAddress)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -3,15 +3,18 @@ package tracing
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
"github.com/go-kratos/kratos/v2/transport"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
tracesdk "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
var _ transport.Transporter = &Transport{}
|
||||
var _ transport.Transporter = &mockTransport{}
|
||||
|
||||
type headerCarrier http.Header
|
||||
|
||||
@ -34,25 +37,25 @@ func (hc headerCarrier) Keys() []string {
|
||||
return keys
|
||||
}
|
||||
|
||||
type Transport struct {
|
||||
type mockTransport struct {
|
||||
kind transport.Kind
|
||||
endpoint string
|
||||
operation string
|
||||
header headerCarrier
|
||||
}
|
||||
|
||||
func (tr *Transport) Kind() transport.Kind { return tr.kind }
|
||||
func (tr *Transport) Endpoint() string { return tr.endpoint }
|
||||
func (tr *Transport) Operation() string { return tr.operation }
|
||||
func (tr *Transport) RequestHeader() transport.Header { return tr.header }
|
||||
func (tr *Transport) ReplyHeader() transport.Header { return tr.header }
|
||||
func (tr *mockTransport) Kind() transport.Kind { return tr.kind }
|
||||
func (tr *mockTransport) Endpoint() string { return tr.endpoint }
|
||||
func (tr *mockTransport) Operation() string { return tr.operation }
|
||||
func (tr *mockTransport) RequestHeader() transport.Header { return tr.header }
|
||||
func (tr *mockTransport) ReplyHeader() transport.Header { return tr.header }
|
||||
|
||||
func TestTracing(t *testing.T) {
|
||||
func TestTracer(t *testing.T) {
|
||||
carrier := headerCarrier{}
|
||||
tp := tracesdk.NewTracerProvider(tracesdk.WithSampler(tracesdk.TraceIDRatioBased(0)))
|
||||
|
||||
// caller use Inject
|
||||
tracer := NewTracer(
|
||||
cliTracer := NewTracer(
|
||||
trace.SpanKindClient,
|
||||
WithTracerProvider(tp),
|
||||
WithPropagator(
|
||||
@ -60,17 +63,17 @@ func TestTracing(t *testing.T) {
|
||||
),
|
||||
)
|
||||
|
||||
ts := &Transport{kind: transport.KindHTTP, header: carrier}
|
||||
ts := &mockTransport{kind: transport.KindHTTP, header: carrier}
|
||||
|
||||
ctx, aboveSpan := tracer.Start(transport.NewClientContext(context.Background(), ts), ts.Operation(), ts.RequestHeader())
|
||||
defer tracer.End(ctx, aboveSpan, nil, nil)
|
||||
ctx, aboveSpan := cliTracer.Start(transport.NewClientContext(context.Background(), ts), ts.Operation(), ts.RequestHeader())
|
||||
defer cliTracer.End(ctx, aboveSpan, nil, nil)
|
||||
|
||||
// server use Extract fetch traceInfo from carrier
|
||||
tracer = NewTracer(trace.SpanKindServer, WithPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})))
|
||||
ts = &Transport{kind: transport.KindHTTP, header: carrier}
|
||||
svrTracer := NewTracer(trace.SpanKindServer, WithPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})))
|
||||
ts = &mockTransport{kind: transport.KindHTTP, header: carrier}
|
||||
|
||||
ctx, span := tracer.Start(transport.NewServerContext(ctx, ts), ts.Operation(), ts.RequestHeader())
|
||||
defer tracer.End(ctx, span, nil, nil)
|
||||
ctx, span := svrTracer.Start(transport.NewServerContext(ctx, ts), ts.Operation(), ts.RequestHeader())
|
||||
defer svrTracer.End(ctx, span, nil, nil)
|
||||
|
||||
if aboveSpan.SpanContext().TraceID() != span.SpanContext().TraceID() {
|
||||
t.Fatalf("TraceID failed to deliver")
|
||||
@ -80,3 +83,110 @@ func TestTracing(t *testing.T) {
|
||||
t.Fatalf("traceHeader failed to deliver")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
tr := &mockTransport{
|
||||
kind: transport.KindHTTP,
|
||||
endpoint: "server:2233",
|
||||
operation: "/test.server/hello",
|
||||
header: headerCarrier{},
|
||||
}
|
||||
|
||||
tracer := NewTracer(
|
||||
trace.SpanKindClient,
|
||||
WithTracerProvider(tracesdk.NewTracerProvider()),
|
||||
)
|
||||
|
||||
logger := log.NewStdLogger(os.Stdout)
|
||||
logger = log.With(logger, "span_id", SpanID())
|
||||
logger = log.With(logger, "trace_id", TraceID())
|
||||
|
||||
var (
|
||||
childSpanID string
|
||||
childTraceID string
|
||||
)
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
_ = log.WithContext(ctx, logger).Log(log.LevelInfo,
|
||||
"kind", "server",
|
||||
)
|
||||
childSpanID = SpanID()(ctx).(string)
|
||||
childTraceID = TraceID()(ctx).(string)
|
||||
return req.(string) + "https://go-kratos.dev", nil
|
||||
}
|
||||
|
||||
var ctx context.Context
|
||||
ctx, span := tracer.Start(
|
||||
transport.NewServerContext(context.Background(), tr),
|
||||
tr.Operation(),
|
||||
tr.RequestHeader(),
|
||||
)
|
||||
|
||||
_, err := Server(
|
||||
WithTracerProvider(tracesdk.NewTracerProvider()),
|
||||
WithPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})),
|
||||
)(next)(ctx, "test server: ")
|
||||
|
||||
span.End()
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, childSpanID)
|
||||
assert.NotEqual(t, span.SpanContext().SpanID().String(), childSpanID)
|
||||
assert.Equal(t, span.SpanContext().TraceID().String(), childTraceID)
|
||||
|
||||
_, err = Server(
|
||||
WithTracerProvider(tracesdk.NewTracerProvider()),
|
||||
WithPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})),
|
||||
)(next)(context.Background(), "test server: ")
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, childSpanID)
|
||||
assert.Empty(t, childTraceID)
|
||||
}
|
||||
|
||||
func TestClient(t *testing.T) {
|
||||
tr := &mockTransport{
|
||||
kind: transport.KindHTTP,
|
||||
endpoint: "server:2233",
|
||||
operation: "/test.server/hello",
|
||||
header: headerCarrier{},
|
||||
}
|
||||
|
||||
tracer := NewTracer(
|
||||
trace.SpanKindClient,
|
||||
WithTracerProvider(tracesdk.NewTracerProvider()),
|
||||
)
|
||||
|
||||
logger := log.NewStdLogger(os.Stdout)
|
||||
logger = log.With(logger, "span_id", SpanID())
|
||||
logger = log.With(logger, "trace_id", TraceID())
|
||||
|
||||
var (
|
||||
childSpanID string
|
||||
childTraceID string
|
||||
)
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
_ = log.WithContext(ctx, logger).Log(log.LevelInfo,
|
||||
"kind", "client",
|
||||
)
|
||||
childSpanID = SpanID()(ctx).(string)
|
||||
childTraceID = TraceID()(ctx).(string)
|
||||
return req.(string) + "https://go-kratos.dev", nil
|
||||
}
|
||||
|
||||
var ctx context.Context
|
||||
ctx, span := tracer.Start(
|
||||
transport.NewClientContext(context.Background(), tr),
|
||||
tr.Operation(),
|
||||
tr.RequestHeader(),
|
||||
)
|
||||
|
||||
_, err := Client(
|
||||
WithTracerProvider(tracesdk.NewTracerProvider()),
|
||||
WithPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})),
|
||||
)(next)(ctx, "test client: ")
|
||||
|
||||
span.End()
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, childSpanID)
|
||||
assert.NotEqual(t, span.SpanContext().SpanID().String(), childSpanID)
|
||||
assert.Equal(t, span.SpanContext().TraceID().String(), childTraceID)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user