package zipkin_test import ( "context" "testing" zipkin "github.com/openzipkin/zipkin-go" "github.com/openzipkin/zipkin-go/propagation/b3" "github.com/openzipkin/zipkin-go/reporter/recorder" "google.golang.org/grpc" "google.golang.org/grpc/metadata" "github.com/go-kit/kit/endpoint" kitzipkin "github.com/go-kit/kit/tracing/zipkin" grpctransport "github.com/go-kit/kit/transport/grpc" ) type dummy struct{} func unaryInterceptor( ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption, ) error { return nil } func TestGRPCClientTrace(t *testing.T) { rec := recorder.NewReporter() defer rec.Close() tr, _ := zipkin.NewTracer(rec) clientTracer := kitzipkin.GRPCClientTrace(tr) cc, err := grpc.Dial( "", grpc.WithUnaryInterceptor(unaryInterceptor), grpc.WithInsecure(), ) if err != nil { t.Fatalf("unable to create gRPC dialer: %s", err.Error()) } ep := grpctransport.NewClient( cc, "dummyService", "dummyMethod", func(context.Context, interface{}) (interface{}, error) { return nil, nil }, func(context.Context, interface{}) (interface{}, error) { return nil, nil }, dummy{}, clientTracer, ).Endpoint() parentSpan := tr.StartSpan("test") ctx := zipkin.NewContext(context.Background(), parentSpan) if _, err = ep(ctx, nil); err != nil { t.Errorf("unexpected error: %s", err.Error()) } spans := rec.Flush() if want, have := 1, len(spans); want != have { t.Fatalf("incorrect number of spans, want %d, have %d", want, have) } if spans[0].SpanContext.ParentID == nil { t.Fatalf("incorrect parent ID, want %s have nil", parentSpan.Context().ID) } if want, have := parentSpan.Context().ID, *spans[0].SpanContext.ParentID; want != have { t.Fatalf("incorrect parent ID, want %s, have %s", want, have) } } func TestGRPCServerTrace(t *testing.T) { rec := recorder.NewReporter() defer rec.Close() tr, _ := zipkin.NewTracer(rec) serverTracer := kitzipkin.GRPCServerTrace(tr) server := grpctransport.NewServer( endpoint.Nop, func(context.Context, interface{}) (interface{}, error) { return nil, nil }, func(context.Context, interface{}) (interface{}, error) { return nil, nil }, serverTracer, ) md := metadata.MD{} parentSpan := tr.StartSpan("test") b3.InjectGRPC(&md)(parentSpan.Context()) ctx := metadata.NewIncomingContext(context.Background(), md) server.ServeGRPC(ctx, nil) spans := rec.Flush() if want, have := 1, len(spans); want != have { t.Fatalf("incorrect number of spans, want %d, have %d", want, have) } if want, have := parentSpan.Context().TraceID, spans[0].SpanContext.TraceID; want != have { t.Errorf("incorrect TraceID, want %+v, have %+v", want, have) } if want, have := parentSpan.Context().ID, spans[0].SpanContext.ID; want != have { t.Errorf("incorrect span ID, want %d, have %d", want, have) } }