package inventory import ( "testing" "github.com/novox/mesh-controller/internal/catalogue" ) // The seat set is data the control plane owns (novox/hq ADR 0122): seeded from the binary's // defaults, read back as the working set, and thereafter an operator's to change without a rebuild. func TestSeatsAreSeededFromTheDefaultsAndReadBack(t *testing.T) { inv := ForTest(t) defaults := catalogue.DefaultSeats() added, err := inv.SeedSeats(t.Context(), defaults) if err != nil { t.Fatal(err) } if added != len(defaults) { t.Fatalf("seeded %d of %d seats", added, len(defaults)) } got, err := inv.Seats(t.Context()) if err != nil { t.Fatal(err) } if len(got) != len(defaults) { t.Fatalf("read back %d seats, seeded %d", len(got), len(defaults)) } // The set round-trips: name, scope and what it delivers survive the store. by := map[string]catalogue.Seat{} for _, s := range got { by[s.Name] = s } for _, d := range defaults { if by[d.Name].Scope != d.Scope || by[d.Name].Delivers != d.Delivers { t.Errorf("%s came back as %+v, seeded %+v", d.Name, by[d.Name], d) } } } // Re-seeding an already-seeded set adds nothing and changes nothing — every deploy runs SeedSeats, // and a mesh already holding the set must be left exactly as it is (an operator's edit to a row // included). A row's fields are not overwritten: on conflict the insert does nothing. // // (Phase 1 keys the table by name, so a seat *renamed* in the table would have its old name // re-seeded — the move to a stable id a rename does not touch is the next step, ADR 0122. This test // asserts only the property that holds now: an unchanged set re-seeds to a no-op.) func TestReSeedingAnUnchangedSetIsANoOp(t *testing.T) { inv := ForTest(t) defaults := catalogue.DefaultSeats() if _, err := inv.SeedSeats(t.Context(), defaults); err != nil { t.Fatal(err) } // An operator changes a row's scope in the table — the point of it being data. if _, err := inv.store.Pool().Exec(t.Context(), `update seat set scope = 'mesh' where name = 'node-uplink'`); err != nil { t.Fatal(err) } added, err := inv.SeedSeats(t.Context(), defaults) if err != nil { t.Fatal(err) } if added != 0 { t.Fatalf("re-seeding an already-present set added %d rows", added) } got, err := inv.Seats(t.Context()) if err != nil { t.Fatal(err) } for _, s := range got { if s.Name == "node-uplink" && s.Scope != "mesh" { t.Fatalf("re-seeding overwrote the operator's change: node-uplink scope is %q", s.Scope) } } }