package admin_test import ( "encoding/json" "path/filepath" "strings" "testing" "time" "git.wntrmute.dev/kyle/crossbar/internal/admin" "git.wntrmute.dev/kyle/crossbar/internal/config" "git.wntrmute.dev/kyle/crossbar/internal/health" "git.wntrmute.dev/kyle/crossbar/internal/lease" "git.wntrmute.dev/kyle/crossbar/internal/limiter" "git.wntrmute.dev/kyle/crossbar/internal/store" ) // The routes view lists a template once, under its own name, with the leases of every concrete // route it matched. A concrete route can be pinned; the template itself cannot. func TestRoutesViewAndPinWithTemplates(t *testing.T) { cfg, err := config.Parse(strings.NewReader(` listen = "127.0.0.1:1" [hosts.alpha] base_url = "http://alpha:1" models = { "m" = { parallel = 2 } } [routes."opencode-*"] hosts = ["alpha"] default_model = "m" `)) if err != nil { t.Fatal(err) } st, err := store.Open(filepath.Join(t.TempDir(), "x.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = st.Close() }) hosts := &fakeHosts{ st: map[string]health.Status{"alpha": {Healthy: true, Loaded: []string{"m"}}}, draining: map[string]bool{}, } lt, err := lease.New(st, hosts, hosts, 30*time.Minute) if err != nil { t.Fatal(err) } if _, _, err := lt.Acquire(lease.Key{Route: "opencode-projecta-4242", FP: "fp1", Model: "m"}, []string{"alpha"}, time.Now()); err != nil { t.Fatal(err) } if _, _, err := lt.Acquire(lease.Key{Route: "opencode-projectb-7", FP: "fp2", Model: "m"}, []string{"alpha"}, time.Now()); err != nil { t.Fatal(err) } lim := limiter.New() lim.Configure("alpha", "m", 2, 8) r := &rig{h: admin.Handler(cfg, hosts, lt, lim, st, hosts), store: st, leases: lt, hosts: hosts} rec := r.do(t, "GET", "/_crossbar/routes", "") if rec.Code != 200 { t.Fatalf("%d %s", rec.Code, rec.Body.String()) } var out map[string]admin.RouteView if err := json.Unmarshal(rec.Body.Bytes(), &out); err != nil { t.Fatal(err) } v, ok := out["opencode-*"] if !ok || len(out) != 1 { t.Fatalf("routes view keys = %v, want exactly the template", keysOf(out)) } if len(v.Hosts) != 1 || v.Hosts[0] != "alpha" || v.DefaultModel != "m" || len(v.Leases) != 2 { t.Errorf("template view = %+v, want hosts [alpha], model m and the two concrete routes' leases", v) } rec = r.do(t, "POST", "/_crossbar/routes/opencode-projecta-4242", `{"host":"alpha","pin":true}`) if rec.Code != 200 { t.Errorf("pin of a concrete templated route: %d %s, want 200", rec.Code, rec.Body.String()) } rec = r.do(t, "POST", "/_crossbar/routes/opencode-*", `{"host":"alpha","pin":true}`) if rec.Code != 404 { t.Errorf("pin of the template itself: %d, want 404 unknown route", rec.Code) } rec = r.do(t, "POST", "/_crossbar/routes/opencode-nothing-yet", `{"host":"alpha","pin":true}`) if rec.Code != 200 { t.Errorf("pin of a not-yet-seen concrete route under a template: %d %s, want 200 (it is a valid route)", rec.Code, rec.Body.String()) } } func keysOf(m map[string]admin.RouteView) []string { out := make([]string, 0, len(m)) for k := range m { out = append(out, k) } return out }