package services import ( "testing" "time" "go.uber.org/zap" ) func TestNewMonitoringAlertingService(t *testing.T) { config := MonitoringConfig{ PrometheusURL: "", Logger: zap.NewNop(), } service, err := NewMonitoringAlertingService(config) if err != nil { t.Fatalf("NewMonitoringAlertingService() error = %v", err) } if service == nil { t.Error("NewMonitoringAlertingService() returned nil") } if service.logger == nil { t.Error("NewMonitoringAlertingService() returned service with nil logger") } if service.rules == nil { t.Error("NewMonitoringAlertingService() returned service with nil rules") } if service.activeAlerts == nil { t.Error("NewMonitoringAlertingService() returned service with nil activeAlerts") } } func TestMonitoringAlertingService_AddAlertRule(t *testing.T) { config := MonitoringConfig{ Logger: zap.NewNop(), } service, err := NewMonitoringAlertingService(config) if err != nil { t.Fatalf("NewMonitoringAlertingService() error = %v", err) } rule := AlertRule{ Name: "test_rule", Query: "up", Threshold: 1.0, Severity: SeverityWarning, Duration: 5 * time.Minute, Description: "Test rule", Enabled: true, } service.AddAlertRule(rule) rules := service.GetAlertRules() if len(rules) != 1 { t.Errorf("AddAlertRule() rules count = %d, want 1", len(rules)) } if rules[0].Name != "test_rule" { t.Errorf("AddAlertRule() rule name = %s, want test_rule", rules[0].Name) } } func TestMonitoringAlertingService_GetAlertRules(t *testing.T) { config := MonitoringConfig{ Logger: zap.NewNop(), } service, err := NewMonitoringAlertingService(config) if err != nil { t.Fatalf("NewMonitoringAlertingService() error = %v", err) } // Add multiple rules service.AddAlertRule(AlertRule{Name: "rule1", Enabled: true}) service.AddAlertRule(AlertRule{Name: "rule2", Enabled: true}) rules := service.GetAlertRules() if len(rules) != 2 { t.Errorf("GetAlertRules() returned %d rules, want 2", len(rules)) } } func TestMonitoringAlertingService_GetActiveAlerts(t *testing.T) { config := MonitoringConfig{ Logger: zap.NewNop(), } service, err := NewMonitoringAlertingService(config) if err != nil { t.Fatalf("NewMonitoringAlertingService() error = %v", err) } alerts := service.GetActiveAlerts() if len(alerts) != 0 { t.Errorf("GetActiveAlerts() returned %d alerts, want 0", len(alerts)) } } func TestMonitoringAlertingService_ResolveAlert(t *testing.T) { config := MonitoringConfig{ Logger: zap.NewNop(), } service, err := NewMonitoringAlertingService(config) if err != nil { t.Fatalf("NewMonitoringAlertingService() error = %v", err) } // Try to resolve non-existent alert err = service.ResolveAlert("nonexistent") if err == nil { t.Error("ResolveAlert() should return error for non-existent alert") } } func TestMonitoringAlertingService_GetAlertByRuleName(t *testing.T) { config := MonitoringConfig{ Logger: zap.NewNop(), } service, err := NewMonitoringAlertingService(config) if err != nil { t.Fatalf("NewMonitoringAlertingService() error = %v", err) } // Get non-existent alert alert, exists := service.GetAlertByRuleName("nonexistent") if exists { t.Error("GetAlertByRuleName() should return false for non-existent alert") } if alert != nil { t.Error("GetAlertByRuleName() should return nil for non-existent alert") } } func TestMonitoringAlertingService_SetNotificationFunc(t *testing.T) { config := MonitoringConfig{ Logger: zap.NewNop(), } service, err := NewMonitoringAlertingService(config) if err != nil { t.Fatalf("NewMonitoringAlertingService() error = %v", err) } notificationCalled := false service.SetNotificationFunc(func(*MonitoringAlertNotification) error { notificationCalled = true return nil }) // Verify function is set (can't test directly, but we can check it doesn't panic) if service == nil { t.Error("SetNotificationFunc() failed") } _ = notificationCalled } func TestGetDefaultAlertRules(t *testing.T) { rules := GetDefaultAlertRules() if len(rules) == 0 { t.Error("GetDefaultAlertRules() returned empty rules") } // Check that default rules have required fields for _, rule := range rules { if rule.Name == "" { t.Error("GetDefaultAlertRules() rule missing name") } if rule.Query == "" { t.Error("GetDefaultAlertRules() rule missing query") } if rule.Severity == "" { t.Error("GetDefaultAlertRules() rule missing severity") } } } func TestAlertSeverity_Constants(t *testing.T) { if SeverityCritical == "" { t.Error("SeverityCritical constant is empty") } if SeverityWarning == "" { t.Error("SeverityWarning constant is empty") } if SeverityInfo == "" { t.Error("SeverityInfo constant is empty") } } func TestAlertStatus_Constants(t *testing.T) { if AlertStatusFiring == "" { t.Error("AlertStatusFiring constant is empty") } if AlertStatusResolved == "" { t.Error("AlertStatusResolved constant is empty") } if AlertStatusPending == "" { t.Error("AlertStatusPending constant is empty") } } // Note: Full integration tests would require: // 1. A running Prometheus instance // 2. Actual metrics being exported // 3. Verification of alert firing and resolution // 4. Testing of notification functions // // Example integration test structure: // func TestMonitoringAlertingService_CheckAlerts_Integration(t *testing.T) { // // Skip if Prometheus not available // prometheusURL := os.Getenv("PROMETHEUS_URL") // if prometheusURL == "" { // t.Skip("Prometheus not configured") // } // // config := MonitoringConfig{ // PrometheusURL: prometheusURL, // Logger: zap.NewNop(), // } // // service, err := NewMonitoringAlertingService(config) // if err != nil { // t.Fatalf("NewMonitoringAlertingService() error = %v", err) // } // // // Add a test rule // rule := AlertRule{ // Name: "test_rule", // Query: "up", // Threshold: 1.0, // Severity: SeverityWarning, // Enabled: true, // } // service.AddAlertRule(rule) // // ctx := context.Background() // err = service.CheckAlerts(ctx) // if err != nil { // t.Fatalf("CheckAlerts() error = %v", err) // } // // // Verify alerts were checked // alerts := service.GetActiveAlerts() // // Assert based on actual Prometheus metrics // }