package obsx import ( "context" "testing" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" semconv "go.opentelemetry.io/otel/semconv/v1.26.0" ) func setupTestTracer(t *testing.T) *tracetest.InMemoryExporter { t.Helper() exp := tracetest.NewInMemoryExporter() tp := sdktrace.NewTracerProvider(sdktrace.WithSyncer(exp)) otel.SetTracerProvider(tp) t.Cleanup(func() { _ = tp.Shutdown(context.Background()) }) return exp } func TestSetupTracer_SetsGlobalProvider(t *testing.T) { prev := otel.GetTracerProvider() t.Cleanup(func() { otel.SetTracerProvider(prev) }) cfg := TracerConfig{ ServiceName: "test-service", Endpoint: "localhost:4317", } shutdown, err := SetupTracer(context.Background(), cfg) if err != nil { t.Fatalf("SetupTracer returned error: %v", err) } t.Cleanup(func() { _ = shutdown(context.Background()) }) tp := otel.GetTracerProvider() if _, ok := tp.(*sdktrace.TracerProvider); !ok { t.Errorf("expected *sdktrace.TracerProvider, got %T", tp) } } func TestSetupTracer_DefaultSampler(t *testing.T) { cfg := TracerConfig{Sampler: 0} cfg.defaults() if cfg.Sampler != 1.0 { t.Errorf("expected default sampler=1.0, got %f", cfg.Sampler) } } func TestSetupTracer_NegativeSampler(t *testing.T) { cfg := TracerConfig{Sampler: -0.5} cfg.defaults() if cfg.Sampler != 1.0 { t.Errorf("expected default sampler=1.0 for negative value, got %f", cfg.Sampler) } } func TestSetupTracer_ServiceVersion(t *testing.T) { prev := otel.GetTracerProvider() t.Cleanup(func() { otel.SetTracerProvider(prev) }) exp := tracetest.NewInMemoryExporter() res, err := resource.New(context.Background(), resource.WithAttributes( semconv.ServiceName("version-test"), semconv.ServiceVersion("1.2.3"), ), ) if err != nil { t.Fatalf("resource.New returned error: %v", err) } tp := sdktrace.NewTracerProvider( sdktrace.WithSyncer(exp), sdktrace.WithResource(res), ) otel.SetTracerProvider(tp) t.Cleanup(func() { _ = tp.Shutdown(context.Background()) }) _, span := StartSpan(context.Background(), "test-span") span.End() spans := exp.GetSpans() if len(spans) == 0 { t.Fatal("expected at least one span") } found := false for _, attr := range spans[0].Resource.Attributes() { if string(attr.Key) == "service.version" && attr.Value.AsString() == "1.2.3" { found = true break } } if !found { t.Errorf("service.version=1.2.3 not found in resource attributes: %v", spans[0].Resource.Attributes()) } } func TestStartSpan_CreatesSpan(t *testing.T) { prev := otel.GetTracerProvider() t.Cleanup(func() { otel.SetTracerProvider(prev) }) exp := setupTestTracer(t) ctx, span := StartSpan(context.Background(), "my-operation") if ctx == nil { t.Fatal("StartSpan returned nil context") } span.End() spans := exp.GetSpans() if len(spans) == 0 { t.Fatal("expected at least one span") } if spans[0].Name != "my-operation" { t.Errorf("expected span name 'my-operation', got %q", spans[0].Name) } }