// Copyright 2025, IPng Networks GmbH, Pim van Pelt package vpp import ( "go.fd.io/govpp/binapi/interface_types" "testing" ) func TestNewInterfaceManager(t *testing.T) { client := NewVPPClient() manager := NewInterfaceManager(client) if manager == nil { t.Fatal("NewInterfaceManager() returned nil") } if manager.client != client { t.Error("InterfaceManager should store the provided client") } if manager.eventCallback != nil { t.Error("InterfaceManager should have nil callback initially") } } func TestInterfaceManagerSetEventCallback(t *testing.T) { client := NewVPPClient() manager := NewInterfaceManager(client) var callbackCalled bool var receivedDetails []InterfaceDetails callback := func(details []InterfaceDetails) { callbackCalled = true receivedDetails = details } manager.SetEventCallback(callback) if manager.eventCallback == nil { t.Error("SetEventCallback() should store the callback") } // Test callback execution testDetails := []InterfaceDetails{ { SwIfIndex: 1, InterfaceName: "test-interface", MacAddress: []byte{0xde, 0xad, 0xbe, 0xef, 0x00, 0x01}, Speed: 1000000000, AdminStatus: true, OperStatus: true, MTU: 1500, }, } manager.eventCallback(testDetails) if !callbackCalled { t.Error("Callback should have been called") } if len(receivedDetails) != 1 { t.Errorf("Expected 1 interface detail, got %d", len(receivedDetails)) } if receivedDetails[0].InterfaceName != "test-interface" { t.Errorf("Expected interface name 'test-interface', got %q", receivedDetails[0].InterfaceName) } } func TestInterfaceManagerGetAllInterfaceDetailsWithoutConnection(t *testing.T) { client := NewVPPClient() manager := NewInterfaceManager(client) _, err := manager.GetAllInterfaceDetails() if err == nil { t.Error("GetAllInterfaceDetails() should return error when not connected") } vppErr, ok := err.(*VPPError) if !ok { t.Errorf("Expected VPPError, got %T", err) } if vppErr.Message != "VPP client not connected" { t.Errorf("Expected specific error message, got: %s", vppErr.Message) } } func TestInterfaceManagerStartEventWatcherWithoutConnection(t *testing.T) { client := NewVPPClient() manager := NewInterfaceManager(client) err := manager.StartEventWatcher() if err == nil { t.Error("StartEventWatcher() should return error when not connected") } vppErr, ok := err.(*VPPError) if !ok { t.Errorf("Expected VPPError, got %T", err) } if vppErr.Message != "VPP client not connected" { t.Errorf("Expected specific error message, got: %s", vppErr.Message) } } func TestInterfaceManagerHandleInterfaceEventWithoutCallback(t *testing.T) { client := NewVPPClient() manager := NewInterfaceManager(client) // Should not panic when callback is nil manager.handleInterfaceEvent() } func TestInterfaceDetails(t *testing.T) { details := InterfaceDetails{ SwIfIndex: interface_types.InterfaceIndex(42), InterfaceName: "GigabitEthernet0/8/0", MacAddress: []byte{0x02, 0xfe, 0x3c, 0x4d, 0x5e, 0x6f}, Speed: 10000000000, // 10 Gbps AdminStatus: true, OperStatus: false, MTU: 9000, } if details.SwIfIndex != 42 { t.Errorf("Expected SwIfIndex 42, got %d", details.SwIfIndex) } if details.InterfaceName != "GigabitEthernet0/8/0" { t.Errorf("Expected interface name 'GigabitEthernet0/8/0', got %q", details.InterfaceName) } if len(details.MacAddress) != 6 { t.Errorf("Expected MAC address length 6, got %d", len(details.MacAddress)) } if details.Speed != 10000000000 { t.Errorf("Expected speed 10000000000, got %d", details.Speed) } if !details.AdminStatus { t.Error("Expected AdminStatus true") } if details.OperStatus { t.Error("Expected OperStatus false") } if details.MTU != 9000 { t.Errorf("Expected MTU 9000, got %d", details.MTU) } } func TestInterfaceEventCallback(t *testing.T) { var callbackInvoked bool var callbackDetails []InterfaceDetails callback := InterfaceEventCallback(func(details []InterfaceDetails) { callbackInvoked = true callbackDetails = details }) testDetails := []InterfaceDetails{ {SwIfIndex: 1, InterfaceName: "test1"}, {SwIfIndex: 2, InterfaceName: "test2"}, } callback(testDetails) if !callbackInvoked { t.Error("Callback should have been invoked") } if len(callbackDetails) != 2 { t.Errorf("Expected 2 interface details, got %d", len(callbackDetails)) } if callbackDetails[0].InterfaceName != "test1" { t.Errorf("Expected first interface 'test1', got %q", callbackDetails[0].InterfaceName) } if callbackDetails[1].InterfaceName != "test2" { t.Errorf("Expected second interface 'test2', got %q", callbackDetails[1].InterfaceName) } }