diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/gintrace_test.go b/instrumentation/github.com/gin-gonic/gin/otelgin/gintrace_test.go deleted file mode 100644 index ecef39e3aeb..00000000000 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/gintrace_test.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -// Based on https://github.com/DataDog/dd-trace-go/blob/8fb554ff7cf694267f9077ae35e27ce4689ed8b6/contrib/gin-gonic/gin/gintrace_test.go - -package otelgin - -import ( - "context" - "net/http" - "net/http/httptest" - "testing" - - "github.com/gin-gonic/gin" - "github.com/stretchr/testify/assert" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/trace" - "go.opentelemetry.io/otel/trace/noop" - - b3prop "go.opentelemetry.io/contrib/propagators/b3" -) - -func init() { - gin.SetMode(gin.ReleaseMode) // silence annoying log msgs -} - -func TestGetSpanNotInstrumented(t *testing.T) { - router := gin.New() - router.GET("/ping", func(c *gin.Context) { - // Assert we don't have a span on the context. - span := trace.SpanFromContext(c.Request.Context()) - ok := !span.SpanContext().IsValid() - assert.True(t, ok) - _, _ = c.Writer.Write([]byte("ok")) - }) - r := httptest.NewRequest("GET", "/ping", nil) - w := httptest.NewRecorder() - router.ServeHTTP(w, r) - response := w.Result() //nolint:bodyclose // False positive for httptest.ResponseRecorder: https://github.com/timakin/bodyclose/issues/59. - assert.Equal(t, http.StatusOK, response.StatusCode) -} - -func TestPropagationWithGlobalPropagators(t *testing.T) { - provider := noop.NewTracerProvider() - otel.SetTextMapPropagator(b3prop.New()) - - r := httptest.NewRequest("GET", "/user/123", nil) - w := httptest.NewRecorder() - - ctx := context.Background() - sc := trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: trace.TraceID{0x01}, - SpanID: trace.SpanID{0x01}, - }) - ctx = trace.ContextWithRemoteSpanContext(ctx, sc) - ctx, _ = provider.Tracer(ScopeName).Start(ctx, "test") - otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(r.Header)) - - router := gin.New() - router.Use(Middleware("foobar", WithTracerProvider(provider))) - router.GET("/user/:id", func(c *gin.Context) { - span := trace.SpanFromContext(c.Request.Context()) - assert.Equal(t, sc.TraceID(), span.SpanContext().TraceID()) - assert.Equal(t, sc.SpanID(), span.SpanContext().SpanID()) - }) - - router.ServeHTTP(w, r) -} - -func TestPropagationWithCustomPropagators(t *testing.T) { - provider := noop.NewTracerProvider() - b3 := b3prop.New() - - r := httptest.NewRequest("GET", "/user/123", nil) - w := httptest.NewRecorder() - - ctx := context.Background() - sc := trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: trace.TraceID{0x01}, - SpanID: trace.SpanID{0x01}, - }) - ctx = trace.ContextWithRemoteSpanContext(ctx, sc) - ctx, _ = provider.Tracer(ScopeName).Start(ctx, "test") - b3.Inject(ctx, propagation.HeaderCarrier(r.Header)) - - router := gin.New() - router.Use(Middleware("foobar", WithTracerProvider(provider), WithPropagators(b3))) - router.GET("/user/:id", func(c *gin.Context) { - span := trace.SpanFromContext(c.Request.Context()) - assert.Equal(t, sc.TraceID(), span.SpanContext().TraceID()) - assert.Equal(t, sc.SpanID(), span.SpanContext().SpanID()) - }) - - router.ServeHTTP(w, r) -} diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/go.mod b/instrumentation/github.com/gin-gonic/gin/otelgin/go.mod index 06efaeee2ac..f7de5b3d3e5 100644 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/go.mod +++ b/instrumentation/github.com/gin-gonic/gin/otelgin/go.mod @@ -2,12 +2,9 @@ module go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otel go 1.22 -replace go.opentelemetry.io/contrib/propagators/b3 => ../../../../../propagators/b3 - require ( github.com/gin-gonic/gin v1.10.0 github.com/stretchr/testify v1.10.0 - go.opentelemetry.io/contrib/propagators/b3 v1.32.0 go.opentelemetry.io/otel v1.32.0 go.opentelemetry.io/otel/trace v1.32.0 ) diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/test/gintrace_test.go b/instrumentation/github.com/gin-gonic/gin/otelgin/test/gintrace_test.go index fb8698422dc..e648640ab58 100644 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/test/gintrace_test.go +++ b/instrumentation/github.com/gin-gonic/gin/otelgin/test/gintrace_test.go @@ -16,21 +16,94 @@ import ( "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/net/context" "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" + b3prop "go.opentelemetry.io/contrib/propagators/b3" "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" - - "go.opentelemetry.io/otel/attribute" - oteltrace "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/noop" ) func init() { gin.SetMode(gin.ReleaseMode) // silence annoying log msgs } +func TestGetSpanNotInstrumented(t *testing.T) { + router := gin.New() + router.GET("/ping", func(c *gin.Context) { + // Assert we don't have a span on the context. + span := trace.SpanFromContext(c.Request.Context()) + ok := !span.SpanContext().IsValid() + assert.True(t, ok) + _, _ = c.Writer.Write([]byte("ok")) + }) + r := httptest.NewRequest("GET", "/ping", nil) + w := httptest.NewRecorder() + router.ServeHTTP(w, r) + response := w.Result() //nolint:bodyclose // False positive for httptest.ResponseRecorder: https://github.com/timakin/bodyclose/issues/59. + assert.Equal(t, http.StatusOK, response.StatusCode) +} + +func TestPropagationWithGlobalPropagators(t *testing.T) { + provider := noop.NewTracerProvider() + otel.SetTextMapPropagator(b3prop.New()) + + r := httptest.NewRequest("GET", "/user/123", nil) + w := httptest.NewRecorder() + + ctx := context.Background() + sc := trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: trace.TraceID{0x01}, + SpanID: trace.SpanID{0x01}, + }) + ctx = trace.ContextWithRemoteSpanContext(ctx, sc) + ctx, _ = provider.Tracer(otelgin.ScopeName).Start(ctx, "test") + otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(r.Header)) + + router := gin.New() + router.Use(otelgin.Middleware("foobar", otelgin.WithTracerProvider(provider))) + router.GET("/user/:id", func(c *gin.Context) { + span := trace.SpanFromContext(c.Request.Context()) + assert.Equal(t, sc.TraceID(), span.SpanContext().TraceID()) + assert.Equal(t, sc.SpanID(), span.SpanContext().SpanID()) + }) + + router.ServeHTTP(w, r) +} + +func TestPropagationWithCustomPropagators(t *testing.T) { + provider := noop.NewTracerProvider() + b3 := b3prop.New() + + r := httptest.NewRequest("GET", "/user/123", nil) + w := httptest.NewRecorder() + + ctx := context.Background() + sc := trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: trace.TraceID{0x01}, + SpanID: trace.SpanID{0x01}, + }) + ctx = trace.ContextWithRemoteSpanContext(ctx, sc) + ctx, _ = provider.Tracer(otelgin.ScopeName).Start(ctx, "test") + b3.Inject(ctx, propagation.HeaderCarrier(r.Header)) + + router := gin.New() + router.Use(otelgin.Middleware("foobar", otelgin.WithTracerProvider(provider), otelgin.WithPropagators(b3))) + router.GET("/user/:id", func(c *gin.Context) { + span := trace.SpanFromContext(c.Request.Context()) + assert.Equal(t, sc.TraceID(), span.SpanContext().TraceID()) + assert.Equal(t, sc.SpanID(), span.SpanContext().SpanID()) + }) + + router.ServeHTTP(w, r) +} + func TestChildSpanFromGlobalTracer(t *testing.T) { sr := tracetest.NewSpanRecorder() otel.SetTracerProvider(sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr))) @@ -85,7 +158,7 @@ func TestTrace200(t *testing.T) { require.Len(t, spans, 1) span := spans[0] assert.Equal(t, "/user/:id", span.Name()) - assert.Equal(t, oteltrace.SpanKindServer, span.SpanKind()) + assert.Equal(t, trace.SpanKindServer, span.SpanKind()) attr := span.Attributes() assert.Contains(t, attr, attribute.String("net.host.name", "foobar")) assert.Contains(t, attr, attribute.Int("http.status_code", http.StatusOK)) @@ -209,7 +282,7 @@ func TestHTTPRouteWithSpanNameFormatter(t *testing.T) { require.Len(t, spans, 1) span := spans[0] assert.Equal(t, "/user/123", span.Name()) - assert.Equal(t, oteltrace.SpanKindServer, span.SpanKind()) + assert.Equal(t, trace.SpanKindServer, span.SpanKind()) attr := span.Attributes() assert.Contains(t, attr, attribute.String("http.method", "GET")) assert.Contains(t, attr, attribute.String("http.route", "/user/:id")) diff --git a/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.mod b/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.mod index 28e56a0d15b..6361ab97166 100644 --- a/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.mod +++ b/instrumentation/github.com/gin-gonic/gin/otelgin/test/go.mod @@ -6,9 +6,11 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/stretchr/testify v1.10.0 go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.57.0 + go.opentelemetry.io/contrib/propagators/b3 v1.32.0 go.opentelemetry.io/otel v1.32.0 go.opentelemetry.io/otel/sdk v1.32.0 go.opentelemetry.io/otel/trace v1.32.0 + golang.org/x/net v0.31.0 ) require ( @@ -39,13 +41,13 @@ require ( go.opentelemetry.io/otel/metric v1.32.0 // indirect golang.org/x/arch v0.12.0 // indirect golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect golang.org/x/sys v0.27.0 // indirect golang.org/x/text v0.20.0 // indirect google.golang.org/protobuf v1.35.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) -replace go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin => ../ - -replace go.opentelemetry.io/contrib/propagators/b3 => ../../../../../../propagators/b3 +replace ( + go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin => ../ + go.opentelemetry.io/contrib/propagators/b3 => ../../../../../../propagators/b3 +)