test: Add comprehensive tests for HandleHostOffline function
Tests all branches: - Empty host ID returns early - Alerts disabled returns early - DisableAllHostsOffline clears alert and confirmation tracking - Override DisableConnectivity clears alert and returns - Override Disabled clears alert and returns - Existing alert updates LastSeen only - Insufficient confirmations waits for more - Sufficient confirmations (3) creates alert with metadata Coverage improvement: - HandleHostOffline: 64.0% → 100% - alerts package: 53.5% → 54.0%
This commit is contained in:
parent
1647b232db
commit
46eccd561a
1 changed files with 177 additions and 0 deletions
|
|
@ -4596,3 +4596,180 @@ func TestApplyGlobalOfflineSettingsLocked(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandleHostOffline(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
t.Run("empty host ID returns early", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
m := NewManager()
|
||||||
|
m.config.Enabled = true
|
||||||
|
|
||||||
|
host := models.Host{ID: "", Hostname: "test-host"}
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
|
||||||
|
// No alert should be created
|
||||||
|
if len(m.activeAlerts) != 0 {
|
||||||
|
t.Errorf("expected 0 alerts, got %d", len(m.activeAlerts))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("alerts disabled returns early", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
m := NewManager()
|
||||||
|
m.config.Enabled = false
|
||||||
|
|
||||||
|
host := models.Host{ID: "host1", Hostname: "test-host"}
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
|
||||||
|
// No alert should be created
|
||||||
|
if len(m.activeAlerts) != 0 {
|
||||||
|
t.Errorf("expected 0 alerts, got %d", len(m.activeAlerts))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("DisableAllHostsOffline clears alert and returns", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
m := NewManager()
|
||||||
|
m.config.Enabled = true
|
||||||
|
m.config.DisableAllHostsOffline = true
|
||||||
|
|
||||||
|
// Pre-create an alert and confirmation
|
||||||
|
alertID := "host-offline-host1"
|
||||||
|
m.activeAlerts[alertID] = &Alert{ID: alertID, Type: "host-offline"}
|
||||||
|
m.offlineConfirmations["host:host1"] = 5
|
||||||
|
|
||||||
|
host := models.Host{ID: "host1", Hostname: "test-host"}
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
|
||||||
|
// Alert should be cleared and confirmations removed
|
||||||
|
if _, exists := m.activeAlerts[alertID]; exists {
|
||||||
|
t.Error("expected alert to be cleared")
|
||||||
|
}
|
||||||
|
if _, exists := m.offlineConfirmations["host:host1"]; exists {
|
||||||
|
t.Error("expected offlineConfirmations to be cleared")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("override DisableConnectivity clears alert and returns", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
m := NewManager()
|
||||||
|
m.config.Enabled = true
|
||||||
|
m.config.Overrides = map[string]ThresholdConfig{
|
||||||
|
"host1": {DisableConnectivity: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-create an alert and confirmation
|
||||||
|
alertID := "host-offline-host1"
|
||||||
|
m.activeAlerts[alertID] = &Alert{ID: alertID, Type: "host-offline"}
|
||||||
|
m.offlineConfirmations["host:host1"] = 5
|
||||||
|
|
||||||
|
host := models.Host{ID: "host1", Hostname: "test-host"}
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
|
||||||
|
// Alert should be cleared and confirmations removed
|
||||||
|
if _, exists := m.activeAlerts[alertID]; exists {
|
||||||
|
t.Error("expected alert to be cleared")
|
||||||
|
}
|
||||||
|
if _, exists := m.offlineConfirmations["host:host1"]; exists {
|
||||||
|
t.Error("expected offlineConfirmations to be cleared")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("override Disabled clears alert and returns", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
m := NewManager()
|
||||||
|
m.config.Enabled = true
|
||||||
|
m.config.Overrides = map[string]ThresholdConfig{
|
||||||
|
"host1": {Disabled: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
host := models.Host{ID: "host1", Hostname: "test-host"}
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
|
||||||
|
// No alert should be created
|
||||||
|
if len(m.activeAlerts) != 0 {
|
||||||
|
t.Errorf("expected 0 alerts, got %d", len(m.activeAlerts))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("existing alert updates LastSeen", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
m := NewManager()
|
||||||
|
m.config.Enabled = true
|
||||||
|
|
||||||
|
alertID := "host-offline-host1"
|
||||||
|
oldTime := time.Now().Add(-1 * time.Hour)
|
||||||
|
m.activeAlerts[alertID] = &Alert{ID: alertID, Type: "host-offline", LastSeen: oldTime}
|
||||||
|
|
||||||
|
host := models.Host{ID: "host1", Hostname: "test-host"}
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
|
||||||
|
// LastSeen should be updated
|
||||||
|
alert := m.activeAlerts[alertID]
|
||||||
|
if alert.LastSeen.Before(time.Now().Add(-1 * time.Minute)) {
|
||||||
|
t.Errorf("expected LastSeen to be updated to recent time, got %v", alert.LastSeen)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("insufficient confirmations waits", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
m := NewManager()
|
||||||
|
m.config.Enabled = true
|
||||||
|
|
||||||
|
host := models.Host{ID: "host1", Hostname: "test-host"}
|
||||||
|
|
||||||
|
// First two calls should not create alert
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
if len(m.activeAlerts) != 0 {
|
||||||
|
t.Errorf("expected 0 alerts after 1st call, got %d", len(m.activeAlerts))
|
||||||
|
}
|
||||||
|
if m.offlineConfirmations["host:host1"] != 1 {
|
||||||
|
t.Errorf("expected 1 confirmation, got %d", m.offlineConfirmations["host:host1"])
|
||||||
|
}
|
||||||
|
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
if len(m.activeAlerts) != 0 {
|
||||||
|
t.Errorf("expected 0 alerts after 2nd call, got %d", len(m.activeAlerts))
|
||||||
|
}
|
||||||
|
if m.offlineConfirmations["host:host1"] != 2 {
|
||||||
|
t.Errorf("expected 2 confirmations, got %d", m.offlineConfirmations["host:host1"])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("sufficient confirmations creates alert", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
m := NewManager()
|
||||||
|
m.config.Enabled = true
|
||||||
|
|
||||||
|
host := models.Host{
|
||||||
|
ID: "host1",
|
||||||
|
Hostname: "test-host",
|
||||||
|
DisplayName: "Test Host",
|
||||||
|
Platform: "linux",
|
||||||
|
OSName: "Ubuntu",
|
||||||
|
OSVersion: "22.04",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make 3 calls to reach required confirmations
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
m.HandleHostOffline(host)
|
||||||
|
|
||||||
|
// Alert should now be created
|
||||||
|
alertID := "host-offline-host1"
|
||||||
|
alert, exists := m.activeAlerts[alertID]
|
||||||
|
if !exists {
|
||||||
|
t.Fatal("expected alert to be created after 3 confirmations")
|
||||||
|
}
|
||||||
|
if alert.Type != "host-offline" {
|
||||||
|
t.Errorf("expected type 'host-offline', got '%s'", alert.Type)
|
||||||
|
}
|
||||||
|
if alert.Level != AlertLevelCritical {
|
||||||
|
t.Errorf("expected level Critical, got '%s'", alert.Level)
|
||||||
|
}
|
||||||
|
if alert.ResourceName == "" {
|
||||||
|
t.Error("expected ResourceName to be set")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue