package monitor import ( "testing" ) // TestNewMonitor tests the creation of a new Monitor func TestNewMonitor(t *testing.T) { // Test that we can create a monitor without errors mon := NewMonitor([]IfaceSpec{ {Name: "test0", Label: "Test Interface A"}, {Name: "test1", Label: "Test Interface B"}, }, "/tmp/test.log") if mon == nil { t.Fatal("NewMonitor returned nil") } // Check interfaces if len(mon.interfaces) != 2 { t.Fatalf("Expected 2 interfaces, got %d", len(mon.interfaces)) } if mon.interfaces[0].Name != "test0" { t.Errorf("Expected interfaces[0].Name to be 'test0', got '%s'", mon.interfaces[0].Name) } if mon.interfaces[1].Name != "test1" { t.Errorf("Expected interfaces[1].Name to be 'test1', got '%s'", mon.interfaces[1].Name) } // Check default configuration if mon.ICMPTimeout.Milliseconds() != 500 { t.Errorf("Expected ICMPTimeout to be 500ms, got %dms", mon.ICMPTimeout.Milliseconds()) } if mon.PacketLossPings != 20 { t.Errorf("Expected PacketLossPings to be 20, got %d", mon.PacketLossPings) } // Check that host lists are initialized if mon.reachabilityHosts == nil { t.Error("reachabilityHosts is nil") } if mon.packetLossHosts == nil { t.Error("packetLossHosts is nil") } if mon.tcpHosts == nil { t.Error("tcpHosts is nil") } } // TestNewMonitorSingle verifies a monitor can be built with one interface. func TestNewMonitorSingle(t *testing.T) { mon := NewMonitor([]IfaceSpec{{Name: "eth0", Label: "default route"}}, "") if len(mon.interfaces) != 1 { t.Fatalf("Expected 1 interface, got %d", len(mon.interfaces)) } if mon.interfaces[0].Name != "eth0" { t.Errorf("Expected interfaces[0].Name to be 'eth0', got '%s'", mon.interfaces[0].Name) } } // TestAddHosts tests adding hosts to the monitor func TestAddHosts(t *testing.T) { mon := NewMonitor([]IfaceSpec{ {Name: "test0", Label: "Test A"}, {Name: "test1", Label: "Test B"}, }, "") // Test adding reachability hosts mon.AddReachabilityHost("8.8.8.8") mon.AddReachabilityHost("google.com") if len(mon.reachabilityHosts) != 2 { t.Errorf("Expected 2 reachability hosts, got %d", len(mon.reachabilityHosts)) } // Test adding packet loss hosts mon.AddPacketLossHost("github.com") if len(mon.packetLossHosts) != 1 { t.Errorf("Expected 1 packet loss host, got %d", len(mon.packetLossHosts)) } // Test adding TCP hosts mon.AddTCPHost("google.com:443") mon.AddTCPHost("github.com:443") if len(mon.tcpHosts) != 2 { t.Errorf("Expected 2 TCP hosts, got %d", len(mon.tcpHosts)) } } // TestMinMaxAvgStd tests the statistics calculation function func TestMinMaxAvgStd(t *testing.T) { tests := []struct { name string data []float64 wantMin, wantMax, wantAvg float64 }{ { name: "empty slice", data: []float64{}, wantMin: 0, wantMax: 0, wantAvg: 0, }, { name: "single value", data: []float64{5.0}, wantMin: 5.0, wantMax: 5.0, wantAvg: 5.0, }, { name: "multiple values", data: []float64{1.0, 2.0, 3.0, 4.0, 5.0}, wantMin: 1.0, wantMax: 5.0, wantAvg: 3.0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { min, max, avg, _ := MinMaxAvgStd(tt.data) if min != tt.wantMin { t.Errorf("MinMaxAvgStd() min = %v, want %v", min, tt.wantMin) } if max != tt.wantMax { t.Errorf("MinMaxAvgStd() max = %v, want %v", max, tt.wantMax) } if avg != tt.wantAvg { t.Errorf("MinMaxAvgStd() avg = %v, want %v", avg, tt.wantAvg) } }) } }