github.com/rudderlabs/rudder-go-kit@v0.30.0/stats/internal/otel/traces_test.go (about) 1 package otel 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "net/http" 8 "testing" 9 "time" 10 11 "github.com/ory/dockertest/v3" 12 "github.com/stretchr/testify/require" 13 "go.opentelemetry.io/otel/attribute" 14 "go.opentelemetry.io/otel/codes" 15 "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" 16 "go.opentelemetry.io/otel/propagation" 17 "go.opentelemetry.io/otel/trace" 18 19 "github.com/rudderlabs/rudder-go-kit/stats/testhelper/tracemodel" 20 "github.com/rudderlabs/rudder-go-kit/testhelper/assert" 21 "github.com/rudderlabs/rudder-go-kit/testhelper/docker/resource/zipkin" 22 ) 23 24 func TestTraces(t *testing.T) { 25 buf := &bytes.Buffer{} 26 ctx := context.Background() 27 exp, err := stdouttrace.New( 28 stdouttrace.WithPrettyPrint(), 29 stdouttrace.WithWriter(buf), 30 ) 31 require.NoError(t, err) 32 33 t.Cleanup(func() { 34 require.NoError(t, exp.Shutdown(ctx)) 35 }) 36 37 res, err := NewResource(t.Name(), "v1.2.3", 38 attribute.String("instanceName", "my-instance-id"), 39 ) 40 require.NoError(t, err) 41 42 var om Manager 43 tp, _, err := om.Setup(ctx, res, 44 WithCustomTracerProvider(exp, WithTracingSamplingRate(1.0), WithTracingSyncer()), 45 WithTextMapPropagator(propagation.NewCompositeTextMapPropagator( 46 propagation.TraceContext{}, propagation.Baggage{}, 47 )), 48 ) 49 require.NoError(t, err) 50 t.Cleanup(func() { require.NoError(t, om.Shutdown(context.Background())) }) 51 52 fooTracer := tp.Tracer("my-tracer") 53 ctx, span := fooTracer.Start(ctx, "my-span", trace.WithAttributes(attribute.String("foo", "bar"))) 54 55 span.SetStatus(codes.Ok, "okey-dokey") 56 time.Sleep(123 * time.Millisecond) 57 span.End() 58 59 var data tracemodel.Span 60 require.NoError(t, json.Unmarshal(buf.Bytes(), &data)) 61 require.Equal(t, "my-span", data.Name) 62 require.Equal(t, "my-tracer", data.InstrumentationLibrary.Name) 63 require.Equal(t, []tracemodel.Attributes{ 64 { 65 Key: "foo", 66 Value: tracemodel.Value{Type: "STRING", Value: "bar"}, 67 }, 68 }, data.Attributes) 69 require.Equal(t, "Ok", data.Status.Code) 70 require.InDelta(t, 123, data.EndTime.Sub(data.StartTime).Milliseconds(), 50) 71 } 72 73 func TestZipkinIntegration(t *testing.T) { 74 pool, err := dockertest.NewPool("") 75 require.NoError(t, err) 76 77 zipkinContainer, err := zipkin.Setup(pool, t) 78 require.NoError(t, err) 79 80 res, err := NewResource(t.Name(), "v1.2.3", 81 attribute.String("instanceName", "my-instance-id"), 82 ) 83 require.NoError(t, err) 84 85 var ( 86 om Manager 87 ctx = context.Background() 88 zipkinURL = "http://localhost:" + zipkinContainer.Port + "/api/v2/spans" 89 ) 90 tp, _, err := om.Setup(ctx, res, 91 WithTracerProvider(zipkinURL, 92 WithTracingSamplingRate(1.0), 93 WithTracingSyncer(), 94 WithZipkin(), 95 ), 96 WithTextMapPropagator(propagation.NewCompositeTextMapPropagator( 97 propagation.TraceContext{}, propagation.Baggage{}, 98 )), 99 ) 100 require.NoError(t, err) 101 t.Cleanup(func() { require.NoError(t, om.Shutdown(context.Background())) }) 102 103 _, span := tp.Tracer("my-tracer").Start(ctx, "my-span") 104 time.Sleep(123 * time.Millisecond) 105 span.End() 106 107 zipkinSpansURL := zipkinURL + "?serviceName=" + t.Name() 108 getSpansReq, err := http.NewRequest(http.MethodGet, zipkinSpansURL, nil) 109 require.NoError(t, err) 110 111 spansBody := assert.RequireEventuallyStatusCode(t, http.StatusOK, getSpansReq) 112 require.Equal(t, `["my-span"]`, spansBody) 113 }