417 lines
12 KiB
Go
417 lines
12 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseBirdOutput(t *testing.T) {
|
|
file, err := os.Open("testdata/sample_output.txt")
|
|
if err != nil {
|
|
t.Fatalf("Failed to open test file: %v", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
protocols, err := parseBirdOutput(file)
|
|
if err != nil {
|
|
t.Fatalf("parseBirdOutput() failed: %v", err)
|
|
}
|
|
|
|
// Check we got the expected number of protocols
|
|
expectedProtocols := 8 // device1, direct1, kernel4, static4, ospf4, fogixp_47498_ipv4_3, fogixp_47498_ipv6_1, fogixp_47498_ipv6_2
|
|
if len(protocols) != expectedProtocols {
|
|
t.Errorf("Expected %d protocols, got %d", expectedProtocols, len(protocols))
|
|
}
|
|
|
|
// Test Device protocol
|
|
device := findProtocol(protocols, "device1")
|
|
if device == nil {
|
|
t.Fatal("device1 protocol not found")
|
|
}
|
|
if device.Proto != "Device" {
|
|
t.Errorf("Expected proto 'Device', got '%s'", device.Proto)
|
|
}
|
|
if device.State != "up" {
|
|
t.Errorf("Expected state 'up', got '%s'", device.State)
|
|
}
|
|
if device.Table != "---" {
|
|
t.Errorf("Expected table '---', got '%s'", device.Table)
|
|
}
|
|
|
|
// Test Direct protocol with channels
|
|
direct := findProtocol(protocols, "direct1")
|
|
if direct == nil {
|
|
t.Fatal("direct1 protocol not found")
|
|
}
|
|
if direct.Proto != "Direct" {
|
|
t.Errorf("Expected proto 'Direct', got '%s'", direct.Proto)
|
|
}
|
|
if len(direct.Channels) != 2 {
|
|
t.Errorf("Expected 2 channels, got %d", len(direct.Channels))
|
|
}
|
|
|
|
// Test direct1 ipv4 channel
|
|
ipv4Chan := findChannel(direct.Channels, "ipv4")
|
|
if ipv4Chan == nil {
|
|
t.Fatal("ipv4 channel not found in direct1")
|
|
}
|
|
if ipv4Chan.State != "UP" {
|
|
t.Errorf("Expected channel state 'UP', got '%s'", ipv4Chan.State)
|
|
}
|
|
if ipv4Chan.Table != "master4" {
|
|
t.Errorf("Expected table 'master4', got '%s'", ipv4Chan.Table)
|
|
}
|
|
if ipv4Chan.Preference != 240 {
|
|
t.Errorf("Expected preference 240, got %d", ipv4Chan.Preference)
|
|
}
|
|
if ipv4Chan.InputFilter != "ACCEPT" {
|
|
t.Errorf("Expected input filter 'ACCEPT', got '%s'", ipv4Chan.InputFilter)
|
|
}
|
|
if ipv4Chan.OutputFilter != "REJECT" {
|
|
t.Errorf("Expected output filter 'REJECT', got '%s'", ipv4Chan.OutputFilter)
|
|
}
|
|
|
|
// Test route stats
|
|
if ipv4Chan.Routes.Imported != 10 {
|
|
t.Errorf("Expected 10 imported routes, got %d", ipv4Chan.Routes.Imported)
|
|
}
|
|
if ipv4Chan.Routes.Exported != 0 {
|
|
t.Errorf("Expected 0 exported routes, got %d", ipv4Chan.Routes.Exported)
|
|
}
|
|
if ipv4Chan.Routes.Preferred != 10 {
|
|
t.Errorf("Expected 10 preferred routes, got %d", ipv4Chan.Routes.Preferred)
|
|
}
|
|
|
|
// Test import stats
|
|
if ipv4Chan.ImportStats.Updates != 155 {
|
|
t.Errorf("Expected 155 import updates, got %d", ipv4Chan.ImportStats.Updates)
|
|
}
|
|
if ipv4Chan.ImportStats.Rejected != 0 {
|
|
t.Errorf("Expected 0 import rejected, got %d", ipv4Chan.ImportStats.Rejected)
|
|
}
|
|
if ipv4Chan.ImportStats.Filtered != 0 {
|
|
t.Errorf("Expected 0 import filtered, got %d", ipv4Chan.ImportStats.Filtered)
|
|
}
|
|
if ipv4Chan.ImportStats.Ignored != 0 {
|
|
t.Errorf("Expected 0 import ignored, got %d", ipv4Chan.ImportStats.Ignored)
|
|
}
|
|
if ipv4Chan.ImportStats.Accepted != 155 {
|
|
t.Errorf("Expected 155 import accepted, got %d", ipv4Chan.ImportStats.Accepted)
|
|
}
|
|
if ipv4Chan.ImportStats.Withdraws != 153 {
|
|
t.Errorf("Expected 153 import withdraws, got %d", ipv4Chan.ImportStats.Withdraws)
|
|
}
|
|
|
|
// Test export stats
|
|
if ipv4Chan.ExportStats.Updates != 0 {
|
|
t.Errorf("Expected 0 export updates, got %d", ipv4Chan.ExportStats.Updates)
|
|
}
|
|
if ipv4Chan.ExportStats.Withdraws != 0 {
|
|
t.Errorf("Expected 0 export withdraws, got %d", ipv4Chan.ExportStats.Withdraws)
|
|
}
|
|
|
|
// Test direct1 ipv6 channel
|
|
ipv6Chan := findChannel(direct.Channels, "ipv6")
|
|
if ipv6Chan == nil {
|
|
t.Fatal("ipv6 channel not found in direct1")
|
|
}
|
|
if ipv6Chan.Routes.Imported != 5 {
|
|
t.Errorf("Expected 5 imported routes, got %d", ipv6Chan.Routes.Imported)
|
|
}
|
|
}
|
|
|
|
func TestParseBGPProtocol(t *testing.T) {
|
|
file, err := os.Open("testdata/sample_output.txt")
|
|
if err != nil {
|
|
t.Fatalf("Failed to open test file: %v", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
protocols, err := parseBirdOutput(file)
|
|
if err != nil {
|
|
t.Fatalf("parseBirdOutput() failed: %v", err)
|
|
}
|
|
|
|
// Test BGP protocol (established)
|
|
bgp := findProtocol(protocols, "fogixp_47498_ipv4_3")
|
|
if bgp == nil {
|
|
t.Fatal("fogixp_47498_ipv4_3 protocol not found")
|
|
}
|
|
if bgp.Proto != "BGP" {
|
|
t.Errorf("Expected proto 'BGP', got '%s'", bgp.Proto)
|
|
}
|
|
if bgp.State != "up" {
|
|
t.Errorf("Expected state 'up', got '%s'", bgp.State)
|
|
}
|
|
if bgp.Info != "Established" {
|
|
t.Errorf("Expected info 'Established', got '%s'", bgp.Info)
|
|
}
|
|
|
|
// Test BGP info
|
|
if bgp.BGPInfo == nil {
|
|
t.Fatal("BGP info is nil")
|
|
}
|
|
if bgp.BGPInfo.BGPState != "Established" {
|
|
t.Errorf("Expected BGP state 'Established', got '%s'", bgp.BGPInfo.BGPState)
|
|
}
|
|
if bgp.BGPInfo.NeighborAddr != "185.1.147.3" {
|
|
t.Errorf("Expected neighbor address '185.1.147.3', got '%s'", bgp.BGPInfo.NeighborAddr)
|
|
}
|
|
if bgp.BGPInfo.NeighborAS != "47498" {
|
|
t.Errorf("Expected neighbor AS '47498', got '%s'", bgp.BGPInfo.NeighborAS)
|
|
}
|
|
if bgp.BGPInfo.LocalAS != "8298" {
|
|
t.Errorf("Expected local AS '8298', got '%s'", bgp.BGPInfo.LocalAS)
|
|
}
|
|
if bgp.BGPInfo.NeighborID != "185.1.147.3" {
|
|
t.Errorf("Expected neighbor ID '185.1.147.3', got '%s'", bgp.BGPInfo.NeighborID)
|
|
}
|
|
|
|
// Test BGP timers
|
|
if bgp.BGPInfo.HoldTimer != 174.765 {
|
|
t.Errorf("Expected hold timer 174.765, got %f", bgp.BGPInfo.HoldTimer)
|
|
}
|
|
if bgp.BGPInfo.KeepaliveTimer != 30.587 {
|
|
t.Errorf("Expected keepalive timer 30.587, got %f", bgp.BGPInfo.KeepaliveTimer)
|
|
}
|
|
if bgp.BGPInfo.SendHoldTimer != 425.866 {
|
|
t.Errorf("Expected send hold timer 425.866, got %f", bgp.BGPInfo.SendHoldTimer)
|
|
}
|
|
|
|
// Test BGP channel
|
|
if len(bgp.Channels) != 1 {
|
|
t.Errorf("Expected 1 channel, got %d", len(bgp.Channels))
|
|
}
|
|
bgpChan := findChannel(bgp.Channels, "ipv4")
|
|
if bgpChan == nil {
|
|
t.Fatal("ipv4 channel not found in fogixp_47498_ipv4_3")
|
|
}
|
|
if bgpChan.Routes.Imported != 44589 {
|
|
t.Errorf("Expected 44589 imported routes, got %d", bgpChan.Routes.Imported)
|
|
}
|
|
if bgpChan.Routes.Filtered != 6 {
|
|
t.Errorf("Expected 6 filtered routes, got %d", bgpChan.Routes.Filtered)
|
|
}
|
|
if bgpChan.Routes.Exported != 27 {
|
|
t.Errorf("Expected 27 exported routes, got %d", bgpChan.Routes.Exported)
|
|
}
|
|
if bgpChan.Routes.Preferred != 4173 {
|
|
t.Errorf("Expected 4173 preferred routes, got %d", bgpChan.Routes.Preferred)
|
|
}
|
|
}
|
|
|
|
func TestParseKernelProtocol(t *testing.T) {
|
|
file, err := os.Open("testdata/sample_output.txt")
|
|
if err != nil {
|
|
t.Fatalf("Failed to open test file: %v", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
protocols, err := parseBirdOutput(file)
|
|
if err != nil {
|
|
t.Fatalf("parseBirdOutput() failed: %v", err)
|
|
}
|
|
|
|
kernel := findProtocol(protocols, "kernel4")
|
|
if kernel == nil {
|
|
t.Fatal("kernel4 protocol not found")
|
|
}
|
|
|
|
if len(kernel.Channels) != 1 {
|
|
t.Fatalf("Expected 1 channel, got %d", len(kernel.Channels))
|
|
}
|
|
|
|
ipv4Chan := kernel.Channels[0]
|
|
if ipv4Chan.Routes.Exported != 1044496 {
|
|
t.Errorf("Expected 1044496 exported routes, got %d", ipv4Chan.Routes.Exported)
|
|
}
|
|
if ipv4Chan.ExportStats.Updates != 1684718679 {
|
|
t.Errorf("Expected 1684718679 export updates, got %d", ipv4Chan.ExportStats.Updates)
|
|
}
|
|
if ipv4Chan.ExportStats.Filtered != 143 {
|
|
t.Errorf("Expected 143 export filtered, got %d", ipv4Chan.ExportStats.Filtered)
|
|
}
|
|
if ipv4Chan.ExportStats.Accepted != 1684718536 {
|
|
t.Errorf("Expected 1684718536 export accepted, got %d", ipv4Chan.ExportStats.Accepted)
|
|
}
|
|
if ipv4Chan.ExportStats.Withdraws != 37968736 {
|
|
t.Errorf("Expected 37968736 export withdraws, got %d", ipv4Chan.ExportStats.Withdraws)
|
|
}
|
|
}
|
|
|
|
func TestParseOSPFProtocol(t *testing.T) {
|
|
file, err := os.Open("testdata/sample_output.txt")
|
|
if err != nil {
|
|
t.Fatalf("Failed to open test file: %v", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
protocols, err := parseBirdOutput(file)
|
|
if err != nil {
|
|
t.Fatalf("parseBirdOutput() failed: %v", err)
|
|
}
|
|
|
|
ospf := findProtocol(protocols, "ospf4")
|
|
if ospf == nil {
|
|
t.Fatal("ospf4 protocol not found")
|
|
}
|
|
|
|
if ospf.Proto != "OSPF" {
|
|
t.Errorf("Expected proto 'OSPF', got '%s'", ospf.Proto)
|
|
}
|
|
if ospf.Info != "Running" {
|
|
t.Errorf("Expected info 'Running', got '%s'", ospf.Info)
|
|
}
|
|
|
|
if len(ospf.Channels) != 1 {
|
|
t.Fatalf("Expected 1 channel, got %d", len(ospf.Channels))
|
|
}
|
|
|
|
ipv4Chan := ospf.Channels[0]
|
|
if ipv4Chan.InputFilter != "f_ospf" {
|
|
t.Errorf("Expected input filter 'f_ospf', got '%s'", ipv4Chan.InputFilter)
|
|
}
|
|
if ipv4Chan.Routes.Imported != 26 {
|
|
t.Errorf("Expected 26 imported routes, got %d", ipv4Chan.Routes.Imported)
|
|
}
|
|
if ipv4Chan.Routes.Exported != 4 {
|
|
t.Errorf("Expected 4 exported routes, got %d", ipv4Chan.Routes.Exported)
|
|
}
|
|
if ipv4Chan.Routes.Preferred != 25 {
|
|
t.Errorf("Expected 25 preferred routes, got %d", ipv4Chan.Routes.Preferred)
|
|
}
|
|
}
|
|
|
|
func TestParseStaticProtocol(t *testing.T) {
|
|
file, err := os.Open("testdata/sample_output.txt")
|
|
if err != nil {
|
|
t.Fatalf("Failed to open test file: %v", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
protocols, err := parseBirdOutput(file)
|
|
if err != nil {
|
|
t.Fatalf("parseBirdOutput() failed: %v", err)
|
|
}
|
|
|
|
static := findProtocol(protocols, "static4")
|
|
if static == nil {
|
|
t.Fatal("static4 protocol not found")
|
|
}
|
|
|
|
if static.Proto != "Static" {
|
|
t.Errorf("Expected proto 'Static', got '%s'", static.Proto)
|
|
}
|
|
|
|
if len(static.Channels) != 1 {
|
|
t.Fatalf("Expected 1 channel, got %d", len(static.Channels))
|
|
}
|
|
|
|
ipv4Chan := static.Channels[0]
|
|
if ipv4Chan.Preference != 200 {
|
|
t.Errorf("Expected preference 200, got %d", ipv4Chan.Preference)
|
|
}
|
|
if ipv4Chan.Routes.Imported != 3 {
|
|
t.Errorf("Expected 3 imported routes, got %d", ipv4Chan.Routes.Imported)
|
|
}
|
|
}
|
|
|
|
func TestParseBirdOutputWithRealFile(t *testing.T) {
|
|
// Test with the actual birdc.show.proto.all file if it exists
|
|
if _, err := os.Stat("../../birdc.show.proto.all"); os.IsNotExist(err) {
|
|
t.Skip("Real birdc.show.proto.all file not found, skipping")
|
|
}
|
|
|
|
file, err := os.Open("../../birdc.show.proto.all")
|
|
if err != nil {
|
|
t.Fatalf("Failed to open real file: %v", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
protocols, err := parseBirdOutput(file)
|
|
if err != nil {
|
|
t.Fatalf("parseBirdOutput() failed on real file: %v", err)
|
|
}
|
|
|
|
if len(protocols) == 0 {
|
|
t.Error("Expected at least one protocol from real file")
|
|
}
|
|
|
|
// Check that we have various protocol types
|
|
hasDevice := false
|
|
hasBGP := false
|
|
for _, p := range protocols {
|
|
if p.Proto == "Device" {
|
|
hasDevice = true
|
|
}
|
|
if p.Proto == "BGP" {
|
|
hasBGP = true
|
|
}
|
|
}
|
|
|
|
if !hasDevice {
|
|
t.Error("Expected to find at least one Device protocol")
|
|
}
|
|
if !hasBGP {
|
|
t.Error("Expected to find at least one BGP protocol")
|
|
}
|
|
}
|
|
|
|
func TestParseEmptyFile(t *testing.T) {
|
|
// Create a temporary empty file
|
|
tmpFile, err := os.CreateTemp("", "empty-*.txt")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp file: %v", err)
|
|
}
|
|
defer os.Remove(tmpFile.Name())
|
|
tmpFile.Close()
|
|
|
|
file, err := os.Open(tmpFile.Name())
|
|
if err != nil {
|
|
t.Fatalf("Failed to open temp file: %v", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
protocols, err := parseBirdOutput(file)
|
|
if err != nil {
|
|
t.Fatalf("parseBirdOutput() failed: %v", err)
|
|
}
|
|
|
|
if len(protocols) != 0 {
|
|
t.Errorf("Expected 0 protocols from empty file, got %d", len(protocols))
|
|
}
|
|
}
|
|
|
|
func TestParseFileNotFound(t *testing.T) {
|
|
_, err := os.Open("/tmp/does-not-exist-bird-test-12345.txt")
|
|
if err == nil {
|
|
t.Error("Expected error when opening non-existent file")
|
|
}
|
|
}
|
|
|
|
// Helper functions
|
|
func findProtocol(protocols []Protocol, name string) *Protocol {
|
|
for i := range protocols {
|
|
if protocols[i].Name == name {
|
|
return &protocols[i]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func findChannel(channels []Channel, name string) *Channel {
|
|
for i := range channels {
|
|
if channels[i].Name == name {
|
|
return &channels[i]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// TestMain to handle flag parsing for tests
|
|
func TestMain(m *testing.M) {
|
|
flag.Parse()
|
|
os.Exit(m.Run())
|
|
}
|