veza/veza-backend-api/internal/services/monitoring_alerting_service_test.go

250 lines
6.3 KiB
Go

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
// }