package config_test import ( "strings" "testing" "time" "git.wntrmute.dev/kyle/crossbar/internal/config" ) const v2Base = ` listen = "127.0.0.1:1" [hosts.a] base_url = "http://a:1" models = { "m" = { } } [hosts.b] base_url = "http://b:1" models = { "m" = { } } [hosts.b.wake] mac = "aa:bb:cc:dd:ee:ff" broadcast = "192.168.1.255:9" wait = "45s" [routes.r] hosts = ["a", "b"] peers = ["talos", "imladris"] ` func TestV2Defaults(t *testing.T) { c, err := config.Parse(strings.NewReader(v2Base)) if err != nil { t.Fatal(err) } if c.Identity != "off" { t.Errorf("identity default = %q, want off", c.Identity) } if c.Hosts["a"].Wake != nil { t.Errorf("host without [wake] must have nil Wake") } w := c.Hosts["b"].Wake if w == nil || w.MAC != "aa:bb:cc:dd:ee:ff" || w.Broadcast != "192.168.1.255:9" || w.Wait.Duration != 45*time.Second { t.Errorf("wake = %+v", w) } if p := c.Routes["r"].Peers; len(p) != 2 || p[0] != "talos" { t.Errorf("peers = %v", p) } } func TestV2Validation(t *testing.T) { good := v2Base for _, tc := range []struct{ name, text, field string }{ {"bad identity", "identity = \"maybe\"\n" + good, "identity"}, {"peers without identity", "identity = \"off\"\n" + good, "routes.r.peers"}, {"bad mac", strings.Replace(good, `mac = "aa:bb:cc:dd:ee:ff"`, `mac = "nope"`, 1), "hosts.b.wake.mac"}, {"no broadcast", strings.Replace(good, `broadcast = "192.168.1.255:9"`, `broadcast = ""`, 1), "hosts.b.wake.broadcast"}, {"wait too short", strings.Replace(good, `wait = "45s"`, `wait = "2s"`, 1), "hosts.b.wake.wait"}, {"peers on unknown route field", "identity = \"tailscale\"\n" + strings.Replace(good, `peers = ["talos", "imladris"]`, `peers = []`, 1), "routes.r.peers"}, } { _, err := config.Parse(strings.NewReader(tc.text)) e, ok := config.IsError(err) if !ok || e.Field != tc.field { t.Errorf("%s: %v, want *Error on %s", tc.name, err, tc.field) } } // identity = "header" is the test/smoke mode; "tailscale" the real one; both accept peers. for _, mode := range []string{"header", "tailscale"} { if _, err := config.Parse(strings.NewReader("identity = \"" + mode + "\"\n" + good)); err != nil { t.Errorf("identity=%s with peers: %v", mode, err) } } // wait defaults to 45s when the [wake] table omits it c, err := config.Parse(strings.NewReader("identity = \"header\"\n" + strings.Replace(good, "wait = \"45s\"\n", "", 1))) if err != nil || c.Hosts["b"].Wake == nil || c.Hosts["b"].Wake.Wait.Duration != 45*time.Second { t.Errorf("wake.wait default: %v %+v", err, c.Hosts["b"].Wake) } }