bgp_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package dynamicrouting
  2. import (
  3. "strings"
  4. "testing"
  5. "time"
  6. )
  7. func TestBGPConfigGeneration(t *testing.T) {
  8. m := &Manager{}
  9. m.config.BGPInstance = BGPInstance{
  10. Enabled: true,
  11. AS: 65001,
  12. RouterID: "192.168.131.56",
  13. RedistributeStatic: true,
  14. }
  15. m.config.BGPNetworks = []BGPNetwork{
  16. {
  17. ID: "net-1",
  18. Network: "192.168.100.0/24",
  19. Disabled: false,
  20. },
  21. }
  22. m.config.BGPPeers = []BGPPeer{
  23. {
  24. ID: "peer-1",
  25. Name: "TestPeer",
  26. RemoteAddress: "192.168.129.225",
  27. RemoteAS: 65555,
  28. Passive: true,
  29. NexthopSelf: true,
  30. RedistStatic: true,
  31. OutputNetworks: []string{"192.168.200.0/24"},
  32. },
  33. }
  34. // Mock bird and birdc
  35. dir := t.TempDir()
  36. t.Setenv("PATH", dir+":"+dir)
  37. // Test configuration generation
  38. sb := &strings.Builder{}
  39. // Test the export filter logic directly
  40. exportSources := []string{`source = RTS_BGP`}
  41. if m.config.BGPPeers[0].RedistStatic || m.config.BGPInstance.RedistributeStatic {
  42. exportSources = append(exportSources, `source ~ [ RTS_STATIC, RTS_INHERIT ]`)
  43. }
  44. exportRule := strings.Join(exportSources, ") || (")
  45. if !strings.Contains(exportRule, "RTS_INHERIT") {
  46. t.Fatalf("Expected exportRule to contain RTS_INHERIT for kernel static routes, got %s", exportRule)
  47. }
  48. _ = sb
  49. }
  50. func TestParseBirdSinceToUptime(t *testing.T) {
  51. refTime := time.Date(2026, 11, 2, 12, 0, 0, 0, time.Local)
  52. tests := []struct {
  53. name string
  54. input string
  55. expected string
  56. }{
  57. {
  58. name: "ISO long same day",
  59. input: "2026-11-02 10:06:15",
  60. expected: "01h 53m 45s",
  61. },
  62. {
  63. name: "ISO long with milliseconds",
  64. input: "2026-11-02 10:06:15.123",
  65. expected: "01h 53m 44s",
  66. },
  67. {
  68. name: "ISO long previous day",
  69. input: "2026-10-31 13:15:43",
  70. expected: "1d 22h 44m 17s",
  71. },
  72. {
  73. name: "Date only",
  74. input: "2026-10-31",
  75. expected: "2d 12h 00m 00s",
  76. },
  77. {
  78. name: "Time only with ms",
  79. input: "10:06:15.631",
  80. expected: "01h 53m 45s",
  81. },
  82. {
  83. name: "Empty",
  84. input: "",
  85. expected: "",
  86. },
  87. {
  88. name: "Invalid",
  89. input: "not-a-date",
  90. expected: "",
  91. },
  92. }
  93. for _, tc := range tests {
  94. t.Run(tc.name, func(t *testing.T) {
  95. got := parseBirdSinceToUptime(tc.input, refTime)
  96. if got != tc.expected {
  97. t.Errorf("%s: got %q, want %q", tc.name, got, tc.expected)
  98. }
  99. })
  100. }
  101. }
  102. func TestTranslateRos7RuleToBird(t *testing.T) {
  103. tests := []struct {
  104. name string
  105. rule RoutingFilterRule
  106. contains []string
  107. omits []string
  108. }{
  109. {
  110. name: "Equals conversion in script",
  111. rule: RoutingFilterRule{
  112. Rule: "if (dst in 10.0.0.0/8 && dst-len == 24) { accept; }",
  113. },
  114. contains: []string{"net ~ [ 10.0.0.0/8+ ]", "net.len = 24", ") then {"},
  115. omits: []string{"==", "dst-len"},
  116. },
  117. {
  118. name: "Inequality preserved",
  119. rule: RoutingFilterRule{
  120. Rule: "if (dst != 192.168.1.0/24) { accept; }",
  121. },
  122. contains: []string{"net != 192.168.1.0/24"},
  123. omits: []string{"dst !="},
  124. },
  125. {
  126. name: "Passthrough action in structured form",
  127. rule: RoutingFilterRule{
  128. Prefix: "10.0.0.0/8",
  129. Action: "passthrough",
  130. SetLocalPref: 150,
  131. },
  132. contains: []string{"bgp_local_pref = 150;"},
  133. omits: []string{"accept;", "reject;"},
  134. },
  135. }
  136. for _, tc := range tests {
  137. t.Run(tc.name, func(t *testing.T) {
  138. got := translateRos7RuleToBird(&tc.rule)
  139. for _, exp := range tc.contains {
  140. if !strings.Contains(got, exp) {
  141. t.Errorf("%s: expected to contain %q, got: %s", tc.name, exp, got)
  142. }
  143. }
  144. for _, om := range tc.omits {
  145. if strings.Contains(got, om) {
  146. t.Errorf("%s: expected to NOT contain %q, got: %s", tc.name, om, got)
  147. }
  148. }
  149. })
  150. }
  151. }