protocols_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package dynamicrouting
  2. import (
  3. "os"
  4. "os/exec"
  5. "strings"
  6. "testing"
  7. )
  8. func TestAllProtocolsBirdConfigGeneration(t *testing.T) {
  9. mgr := &Manager{
  10. config: DynamicConfig{
  11. BGPInstance: BGPInstance{
  12. Enabled: true,
  13. AS: 65001,
  14. RouterID: "10.42.62.254",
  15. },
  16. BGPPeers: []BGPPeer{
  17. {
  18. ID: "peer-1",
  19. Name: "Uplink",
  20. RemoteAddress: "10.42.36.253",
  21. RemoteAS: 65002,
  22. UseBFD: true,
  23. },
  24. },
  25. OSPFInstances: []OSPFInstance{
  26. {
  27. ID: "ospf-1",
  28. Name: "Default",
  29. Version: 2,
  30. RouterID: "10.42.62.254",
  31. Enabled: true,
  32. },
  33. },
  34. OSPFAreas: []OSPFArea{
  35. {
  36. ID: "area-0",
  37. Name: "Default",
  38. AreaID: "0.0.0.0",
  39. AreaType: "default",
  40. },
  41. },
  42. OSPFInterfaces: []OSPFInterface{
  43. {
  44. ID: "ospf-if-1",
  45. Interfaces: "eth0",
  46. Area: "Default",
  47. Cost: 10,
  48. UseBFD: true,
  49. },
  50. },
  51. BFDInstance: BFDInstance{
  52. Enabled: true,
  53. },
  54. BFDInterfaces: []BFDInterface{
  55. {
  56. ID: "bfd-if-1",
  57. Interface: "eth0",
  58. MinRxInterval: 100,
  59. MinTxInterval: 100,
  60. Multiplier: 3,
  61. },
  62. },
  63. BFDNeighbors: []BFDNeighbor{
  64. {
  65. ID: "bfd-nbr-1",
  66. Address: "10.42.36.253",
  67. Interface: "eth0",
  68. },
  69. },
  70. RIPInstances: []RIPInstance{
  71. {
  72. ID: "rip-1",
  73. Name: "default",
  74. Version: 2,
  75. Enabled: true,
  76. RedistributeConnected: true,
  77. RedistributeStatic: true,
  78. },
  79. },
  80. RIPInterfaces: []RIPInterface{
  81. {
  82. ID: "rip-if-1",
  83. Instance: "default",
  84. Interface: "eth0",
  85. Metric: 1,
  86. Mode: "multicast",
  87. UseBFD: true,
  88. },
  89. },
  90. BabelInstances: []BabelInstance{
  91. {
  92. ID: "babel-1",
  93. Name: "default",
  94. RouterID: "10.42.62.254",
  95. Enabled: true,
  96. RedistributeConnected: true,
  97. },
  98. },
  99. BabelInterfaces: []BabelInterface{
  100. {
  101. ID: "babel-if-1",
  102. Instance: "default",
  103. Interface: "eth0",
  104. Type: "wired",
  105. RxCost: 10,
  106. HelloInterval: 4,
  107. UpdateInterval: 16,
  108. },
  109. },
  110. RAdvInstances: []RAdvInstance{
  111. {
  112. ID: "radv-1",
  113. Name: "default",
  114. Enabled: true,
  115. },
  116. },
  117. RAdvInterfaces: []RAdvInterface{
  118. {
  119. ID: "radv-if-1",
  120. Instance: "default",
  121. Interface: "eth0",
  122. MinRAInterval: 200,
  123. MaxRAInterval: 600,
  124. DefaultLifetime: 1800,
  125. Prefixes: []string{"2001:db8:1::/64"},
  126. RDNSS: []string{"2001:4860:4860::8888"},
  127. },
  128. },
  129. },
  130. }
  131. cfg := mgr.generateBirdConfig()
  132. // Verify all protocol blocks are generated
  133. if !strings.Contains(cfg, "protocol bfd bfd_main") {
  134. t.Errorf("Expected protocol bfd bfd_main in config, got:\n%s", cfg)
  135. }
  136. if !strings.Contains(cfg, "protocol rip rip_default") {
  137. t.Errorf("Expected protocol rip in config, got:\n%s", cfg)
  138. }
  139. if !strings.Contains(cfg, "protocol babel babel_default") {
  140. t.Errorf("Expected protocol babel in config, got:\n%s", cfg)
  141. }
  142. if !strings.Contains(cfg, "protocol radv radv_default") {
  143. t.Errorf("Expected protocol radv in config, got:\n%s", cfg)
  144. }
  145. if !strings.Contains(cfg, "bfd yes;") {
  146. t.Errorf("Expected bfd yes; in peer and interface, got:\n%s", cfg)
  147. }
  148. // Validate generated config directly with BIRD 2 compiler if bird binary is available
  149. if _, err := exec.LookPath("bird"); err == nil {
  150. tmpFile, err := os.CreateTemp("", "bird_val_*.conf")
  151. if err != nil {
  152. t.Fatalf("Failed to create temp file: %v", err)
  153. }
  154. defer os.Remove(tmpFile.Name())
  155. if _, err := tmpFile.WriteString(cfg); err != nil {
  156. t.Fatalf("Failed to write temp file: %v", err)
  157. }
  158. tmpFile.Close()
  159. cmd := exec.Command("bird", "-p", "-c", tmpFile.Name())
  160. out, err := cmd.CombinedOutput()
  161. if err != nil {
  162. t.Fatalf("bird -p validation failed: %s\nConfig:\n%s", string(out), cfg)
  163. }
  164. }
  165. }