package dynamicrouting import ( "encoding/json" "os" "path/filepath" "strings" "testing" ) func TestBFDSaveFailureRestoresMemory(t *testing.T) { root := t.TempDir() bad := filepath.Join(root, "directory") if err := os.Mkdir(bad, 0700); err != nil { t.Fatal(err) } old := BFDNeighbor{ID: "peer", Address: "192.0.2.1", Disabled: true} m := &Manager{configPath: bad, config: DynamicConfig{BFDNeighbors: []BFDNeighbor{old}}} _, err := m.SaveBFDNeighbor(BFDNeighbor{ID: "peer", Address: old.Address, Disabled: false}) if err == nil { t.Fatal("expected failure") } if got := m.ListBFDNeighbors(); len(got) != 1 || !got[0].Disabled { t.Fatalf("configuration changed: %+v", got) } } func TestBFDApplyFailureRestoresConfig(t *testing.T) { root := t.TempDir() birdDir := filepath.Join(root, "bird.conf.new") if err := os.Mkdir(birdDir, 0700); err != nil { t.Fatal(err) } old := BFDNeighbor{ID: "peer", Address: "192.0.2.1", Disabled: true} path := filepath.Join(root, "dynamic.json") m := &Manager{configPath: path, birdConfigPath: filepath.Join(root, "bird.conf"), config: DynamicConfig{BFDNeighbors: []BFDNeighbor{old}}} if err := m.save(); err != nil { t.Fatal(err) } _, err := m.SaveBFDNeighbor(BFDNeighbor{ID: "peer", Address: old.Address, Disabled: false}) if err == nil || !strings.Contains(err.Error(), "apply BFD") { t.Fatalf("unexpected: %v", err) } var saved DynamicConfig data, err := os.ReadFile(path) if err != nil { t.Fatal(err) } if err = json.Unmarshal(data, &saved); err != nil { t.Fatal(err) } if len(saved.BFDNeighbors) != 1 || !saved.BFDNeighbors[0].Disabled || !m.ListBFDNeighbors()[0].Disabled { t.Fatalf("configuration not restored: %+v", saved.BFDNeighbors) } } func TestActiveEIGRPRequiresVtysh(t *testing.T) { t.Setenv("PATH", t.TempDir()) m := &Manager{config: DynamicConfig{EIGRPInstances: []EIGRPInstance{{Name: "test", Disabled: false}}}} if err := m.applyFRREigrpConfig(); err == nil || !strings.Contains(err.Error(), "vtysh") { t.Fatalf("expected vtysh error, got %v", err) } m.config.EIGRPInstances[0].Disabled = true if err := m.applyFRREigrpConfig(); err != nil { t.Fatalf("inactive EIGRP: %v", err) } }