package tracing // Tests for tracing initialization, config parsing, and helper wrappers. import ( "context" "errors" "testing" "github.com/stretchr/testify/require" ) // TestNewTracer_Disabled verifies disabled mode initializes and safely starts spans. func TestNewTracer_Disabled(t *testing.T) { cfg := DefaultConfig() cfg.Enabled = false tracer, err := NewTracer(cfg) require.NoError(t, err) require.NotNil(t, tracer) ctx, span := tracer.StartSpan(context.Background(), "test") require.NotNil(t, ctx) require.NotNil(t, span) require.NotPanics(t, func() { span.SetAttribute("k", "v") span.RecordError(errors.New("boom")) span.End() }) } // TestNewTracer_Enabled verifies enabled mode initializes tracer components. func TestNewTracer_Enabled(t *testing.T) { cfg := DefaultConfig() cfg.Enabled = true tracer, err := NewTracer(cfg) require.NoError(t, err) require.NotNil(t, tracer) require.NoError(t, tracer.Shutdown(context.Background())) } // TestShutdown_Disabled verifies shutdown is a no-op when tracing is disabled. func TestShutdown_Disabled(t *testing.T) { tracer, err := NewTracer(DefaultConfig()) require.NoError(t, err) err = tracer.Shutdown(context.Background()) require.NoError(t, err) } // TestTraceServiceOperation verifies tracing wraps a service operation and returns errors. func TestTraceServiceOperation(t *testing.T) { tracer, err := NewTracer(DefaultConfig()) require.NoError(t, err) expected := errors.New("boom") err = TraceServiceOperation(context.Background(), tracer, "svc", "op", func(ctx context.Context) error { return expected }) require.Equal(t, expected, err) } // TestTraceDatabaseOperation verifies tracing wraps a database operation and calls the function. func TestTraceDatabaseOperation(t *testing.T) { tracer, err := NewTracer(DefaultConfig()) require.NoError(t, err) called := false err = TraceDatabaseOperation(context.Background(), tracer, "select", "users", func(ctx context.Context) error { called = true return nil }) require.NoError(t, err) require.True(t, called) } // TestConfigFromEnvDefaults verifies defaults are used when env vars are absent or empty. func TestConfigFromEnvDefaults(t *testing.T) { t.Setenv("TRACING_ENABLED", "") t.Setenv("TRACING_SERVICE_NAME", "") t.Setenv("TRACING_SERVICE_VERSION", "") t.Setenv("TRACING_ENVIRONMENT", "") t.Setenv("TRACING_OTLP_ENDPOINT", "") t.Setenv("TRACING_JAEGER_ENDPOINT", "") t.Setenv("TRACING_SAMPLE_RATE", "") cfg := ConfigFromEnv() def := DefaultConfig() require.Equal(t, def, cfg) } // TestConfigFromEnvOverrides verifies valid env vars override defaults. func TestConfigFromEnvOverrides(t *testing.T) { t.Setenv("TRACING_ENABLED", "true") t.Setenv("TRACING_SERVICE_NAME", "gateway") t.Setenv("TRACING_SERVICE_VERSION", "1.2.3") t.Setenv("TRACING_ENVIRONMENT", "production") t.Setenv("TRACING_OTLP_ENDPOINT", "https://otel-collector:4318/v1/traces") t.Setenv("TRACING_JAEGER_ENDPOINT", "http://jaeger:14268/api/traces") t.Setenv("TRACING_SAMPLE_RATE", "0.25") cfg := ConfigFromEnv() require.True(t, cfg.Enabled) require.Equal(t, "gateway", cfg.ServiceName) require.Equal(t, "1.2.3", cfg.ServiceVersion) require.Equal(t, "production", cfg.Environment) require.Equal(t, "https://otel-collector:4318/v1/traces", cfg.OTLPEndpoint) require.Equal(t, "http://jaeger:14268/api/traces", cfg.JaegerEndpoint) require.Equal(t, 0.25, cfg.SampleRate) } // TestConfigFromEnvInvalidSampleRate verifies invalid sample rate falls back to default. func TestConfigFromEnvInvalidSampleRate(t *testing.T) { t.Setenv("TRACING_SAMPLE_RATE", "not-a-float") cfg := ConfigFromEnv() require.Equal(t, DefaultConfig().SampleRate, cfg.SampleRate) } // TestConfigFromEnvLegacyEndpointFallback verifies legacy env var is used when OTLP endpoint is unset. func TestConfigFromEnvLegacyEndpointFallback(t *testing.T) { t.Setenv("TRACING_OTLP_ENDPOINT", "") t.Setenv("TRACING_JAEGER_ENDPOINT", "http://legacy:14268/api/traces") cfg := ConfigFromEnv() require.Equal(t, "http://legacy:14268/api/traces", cfg.OTLPEndpoint) require.Equal(t, "http://legacy:14268/api/traces", cfg.JaegerEndpoint) } // TestConfigFromEnvEndpointPrecedence verifies OTLP endpoint has precedence over legacy Jaeger endpoint. func TestConfigFromEnvEndpointPrecedence(t *testing.T) { t.Setenv("TRACING_OTLP_ENDPOINT", "https://collector:4318/v1/traces") t.Setenv("TRACING_JAEGER_ENDPOINT", "http://legacy:14268/api/traces") cfg := ConfigFromEnv() require.Equal(t, "https://collector:4318/v1/traces", cfg.OTLPEndpoint) require.Equal(t, "http://legacy:14268/api/traces", cfg.JaegerEndpoint) }