mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 11:30:15 +00:00
- Modified alerts.go for improved host alert handling - Added host_dedup_test.go for deduplication test coverage
172 lines
4.4 KiB
Go
172 lines
4.4 KiB
Go
package alerts
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/models"
|
|
)
|
|
|
|
func TestHostAgentDeduplicatesNodeAlerts(t *testing.T) {
|
|
// Test 1: Without a host agent registered, node metrics ARE checked
|
|
t.Run("node_metrics_checked_without_host_agent", func(t *testing.T) {
|
|
m := NewManager()
|
|
m.config.Enabled = true
|
|
m.config.NodeDefaults.CPU = &HysteresisThreshold{Trigger: 80, Clear: 75}
|
|
|
|
// Verify no host agent is registered
|
|
if m.hasHostAgentForNode("pi") {
|
|
t.Error("Expected no host agent for 'pi' initially")
|
|
}
|
|
|
|
node := models.Node{
|
|
ID: "node/pi",
|
|
Name: "pi",
|
|
Status: "online",
|
|
CPU: 0.95, // 95% CPU
|
|
}
|
|
|
|
// This should attempt to check metrics (even if alert doesn't fire immediately due to time thresholds)
|
|
m.CheckNode(node)
|
|
|
|
// The key test: pendingAlerts should have an entry because metrics WERE checked
|
|
m.mu.RLock()
|
|
_, hasPending := m.pendingAlerts["node/pi-cpu"]
|
|
m.mu.RUnlock()
|
|
|
|
if !hasPending {
|
|
t.Error("Expected pending alert for node CPU when no host agent registered")
|
|
}
|
|
})
|
|
|
|
// Test 2: With host agent registered, node metrics are NOT checked
|
|
t.Run("node_metrics_skipped_with_host_agent", func(t *testing.T) {
|
|
m := NewManager()
|
|
m.config.Enabled = true
|
|
m.config.NodeDefaults.CPU = &HysteresisThreshold{Trigger: 80, Clear: 75}
|
|
|
|
// Register a host agent with the same hostname BEFORE checking the node
|
|
m.RegisterHostAgentHostname("pi")
|
|
|
|
// Verify host agent IS registered
|
|
if !m.hasHostAgentForNode("pi") {
|
|
t.Error("Expected host agent for 'pi' to be registered")
|
|
}
|
|
|
|
node := models.Node{
|
|
ID: "node/pi",
|
|
Name: "pi",
|
|
Status: "online",
|
|
CPU: 0.95, // 95% CPU
|
|
}
|
|
|
|
m.CheckNode(node)
|
|
|
|
// The key test: pendingAlerts should NOT have an entry because metrics were SKIPPED
|
|
m.mu.RLock()
|
|
_, hasPending := m.pendingAlerts["node/pi-cpu"]
|
|
m.mu.RUnlock()
|
|
|
|
if hasPending {
|
|
t.Error("Expected NO pending alert for node CPU when host agent is registered")
|
|
}
|
|
})
|
|
|
|
// Test 3: After unregistering host agent, node metrics ARE checked again
|
|
t.Run("node_metrics_resume_after_host_agent_unregistered", func(t *testing.T) {
|
|
m := NewManager()
|
|
m.config.Enabled = true
|
|
m.config.NodeDefaults.CPU = &HysteresisThreshold{Trigger: 80, Clear: 75}
|
|
|
|
// Register and then unregister
|
|
m.RegisterHostAgentHostname("pi")
|
|
m.UnregisterHostAgentHostname("pi")
|
|
|
|
// Verify host agent is NOT registered
|
|
if m.hasHostAgentForNode("pi") {
|
|
t.Error("Expected host agent for 'pi' to be unregistered")
|
|
}
|
|
|
|
node := models.Node{
|
|
ID: "node/pi",
|
|
Name: "pi",
|
|
Status: "online",
|
|
CPU: 0.95, // 95% CPU
|
|
}
|
|
|
|
m.CheckNode(node)
|
|
|
|
// The key test: pendingAlerts should have an entry because metrics WERE checked
|
|
m.mu.RLock()
|
|
_, hasPending := m.pendingAlerts["node/pi-cpu"]
|
|
m.mu.RUnlock()
|
|
|
|
if !hasPending {
|
|
t.Error("Expected pending alert for node CPU after host agent unregistration")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestHostAgentDeduplicationCaseInsensitive(t *testing.T) {
|
|
m := NewManager()
|
|
|
|
// Register with lowercase
|
|
m.RegisterHostAgentHostname("myhost")
|
|
|
|
// Check should match regardless of case
|
|
if !m.hasHostAgentForNode("MYHOST") {
|
|
t.Error("Expected hasHostAgentForNode to match uppercase hostname")
|
|
}
|
|
if !m.hasHostAgentForNode("MyHost") {
|
|
t.Error("Expected hasHostAgentForNode to match mixed-case hostname")
|
|
}
|
|
if !m.hasHostAgentForNode("myhost") {
|
|
t.Error("Expected hasHostAgentForNode to match lowercase hostname")
|
|
}
|
|
}
|
|
|
|
func TestCheckHostRegistersHostname(t *testing.T) {
|
|
m := NewManager()
|
|
m.config.Enabled = true
|
|
|
|
host := models.Host{
|
|
ID: "host-test-123",
|
|
Hostname: "testhost",
|
|
CPUUsage: 50,
|
|
}
|
|
|
|
// Initially no hostname registered
|
|
if m.hasHostAgentForNode("testhost") {
|
|
t.Error("Expected no host agent registered initially")
|
|
}
|
|
|
|
// CheckHost should register the hostname
|
|
m.CheckHost(host)
|
|
|
|
if !m.hasHostAgentForNode("testhost") {
|
|
t.Error("Expected host agent hostname to be registered after CheckHost")
|
|
}
|
|
}
|
|
|
|
func TestHandleHostOfflineUnregistersHostname(t *testing.T) {
|
|
m := NewManager()
|
|
m.config.Enabled = true
|
|
|
|
host := models.Host{
|
|
ID: "host-test-456",
|
|
Hostname: "offlinehost",
|
|
}
|
|
|
|
// Register the hostname
|
|
m.RegisterHostAgentHostname(host.Hostname)
|
|
|
|
if !m.hasHostAgentForNode("offlinehost") {
|
|
t.Error("Expected host agent registered")
|
|
}
|
|
|
|
// HandleHostOffline should unregister the hostname
|
|
m.HandleHostOffline(host)
|
|
|
|
if m.hasHostAgentForNode("offlinehost") {
|
|
t.Error("Expected host agent to be unregistered after HandleHostOffline")
|
|
}
|
|
}
|