package observability_test import ( "context" "testing" "time" "github.com/AmaniQuery/amaniquery/pkg/observability" ) // TestNewLogger tests logger creation func TestNewLogger_Info(t *testing.T) { logger, err := observability.NewLogger("info", "json") if err != nil { t.Fatalf("NewLogger failed: %v", err) } if logger == nil { t.Fatal("Expected non-nil logger") } logger.Sync() } // TestNewLogger_Debug tests debug level logger func TestNewLogger_Debug(t *testing.T) { logger, err := observability.NewLogger("debug", "console") if err != nil { t.Fatalf("NewLogger failed: %v", err) } if logger == nil { t.Fatal("Expected non-nil logger") } logger.Sync() } // TestNewLogger_Error tests error level logger func TestNewLogger_Error(t *testing.T) { logger, err := observability.NewLogger("error", "json") if err != nil { t.Fatalf("NewLogger failed: %v", err) } if logger == nil { t.Fatal("Expected non-nil logger") } logger.Sync() } // TestNewLogger_InvalidLevel tests invalid log level fallback func TestNewLogger_InvalidLevel(t *testing.T) { // Should default to info level on invalid input logger, err := observability.NewLogger("invalid", "json") if err != nil { t.Fatalf("NewLogger failed: %v", err) } if logger == nil { t.Fatal("Expected non-nil logger") } logger.Sync() } // TestInitProvider tests tracing provider initialization func TestInitProvider_Disabled(t *testing.T) { cfg := observability.Config{ ServiceName: "test-service", ServiceVersion: "1.0.0", TracingEnabled: false, // Disabled MetricsEnabled: false, } shutdown, err := observability.InitProvider(cfg) if err != nil { t.Fatalf("InitProvider failed: %v", err) } if shutdown != nil { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := shutdown(ctx); err != nil { t.Errorf("Shutdown failed: %v", err) } } } // TestStartMetricsServer tests metrics server startup func TestStartMetricsServer(t *testing.T) { // Use a random high port to avoid conflicts server := observability.StartMetricsServer(0) // Port 0 for auto-assign if server == nil { t.Fatal("Expected non-nil server") } // Give it a moment to start time.Sleep(100 * time.Millisecond) // Shutdown ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := server.Shutdown(ctx); err != nil { t.Errorf("Shutdown failed: %v", err) } } // TestUnaryServerInterceptor tests gRPC unary interceptor func TestUnaryServerInterceptor(t *testing.T) { interceptor := observability.UnaryServerInterceptor() if interceptor == nil { t.Fatal("Expected non-nil interceptor") } } // TestStreamServerInterceptor tests gRPC stream interceptor func TestStreamServerInterceptor(t *testing.T) { interceptor := observability.StreamServerInterceptor() if interceptor == nil { t.Fatal("Expected non-nil interceptor") } } // TestRecordQuery tests query metric recording func TestRecordQuery(t *testing.T) { // Just verify it doesn't panic observability.RecordQuery("success", true, "vector", 100*time.Millisecond) observability.RecordQuery("error", false, "hybrid", 50*time.Millisecond) } // TestRecordRetrieval tests retrieval metric recording func TestRecordRetrieval(t *testing.T) { // Just verify it doesn't panic observability.RecordRetrieval("vector", 50*time.Millisecond) observability.RecordRetrieval("keyword", 30*time.Millisecond) observability.RecordRetrieval("hybrid", 80*time.Millisecond) } // TestRecordGeneration tests generation metric recording func TestRecordGeneration(t *testing.T) { // Just verify it doesn't panic observability.RecordGeneration(200 * time.Millisecond) observability.RecordGeneration(100 * time.Millisecond) } // TestRecordTokens tests token usage metric recording func TestRecordTokens(t *testing.T) { // Just verify it doesn't panic observability.RecordTokens("input", 100) observability.RecordTokens("output", 50) } // TestRecordCacheHit tests cache hit metric recording func TestRecordCacheHit(t *testing.T) { // Just verify it doesn't panic observability.RecordCacheHit("local") observability.RecordCacheHit("redis") } // TestRecordCacheMiss tests cache miss metric recording func TestRecordCacheMiss(t *testing.T) { // Just verify it doesn't panic observability.RecordCacheMiss("local") observability.RecordCacheMiss("redis") } // TestRecordDocumentIndexed tests document indexed metric recording func TestRecordDocumentIndexed(t *testing.T) { // Just verify it doesn't panic observability.RecordDocumentIndexed() } // TestRecordError tests error metric recording func TestRecordError(t *testing.T) { // Just verify it doesn't panic observability.RecordError("api_error", "gateway") observability.RecordError("timeout", "retriever") } // TestIncrementDecrementConnections tests connection tracking func TestIncrementDecrementConnections(t *testing.T) { // Just verify it doesn't panic observability.IncrementConnections() observability.IncrementConnections() observability.DecrementConnections() } // BenchmarkRecordQuery benchmarks query recording func BenchmarkRecordQuery(b *testing.B) { for i := 0; i < b.N; i++ { observability.RecordQuery("success", true, "vector", time.Millisecond) } } // BenchmarkRecordRetrieval benchmarks retrieval recording func BenchmarkRecordRetrieval(b *testing.B) { for i := 0; i < b.N; i++ { observability.RecordRetrieval("vector", time.Millisecond) } } // BenchmarkRecordCacheHit benchmarks cache hit recording func BenchmarkRecordCacheHit(b *testing.B) { for i := 0; i < b.N; i++ { observability.RecordCacheHit("local") } }