Files
mesh-catalog/modules/postgres/cmd/postgres-provider/retire_pg_test.go
T
jschoubben 35ff67bda0
mesh/delivery-group group feat/774-l3-reland rejected: composed together: the checker's verdict at the members' heads (b48c90fea31f): integration: mesh-self-ch…
mesh/delivery closed: a newer head of the same pull request
mesh/check failed: integration: mesh-self-check/cmd/mesh-self-check.TestTheSelfCheckWholeRunsOnTheBus: the run answered {Run:doctor-1793351737-1 At:20…
Design 47's last milestones: the keeper, self-check, healers, hand-acts, provisioner, vault, artifact sweep, disk readings, credential forms (issues 774, 1952, 1953, 1954, 1955)
One commit with exactly the tree of the reviewed head 35b4509c0a, on main 12c2574c9d, so two compiled programs added and removed on the branch leave no trace in history (issue 1577).
2026-10-30 02:21:51 +01:00

168 lines
7.4 KiB
Go

package main
// What retired means in postgres, held against the statements sent (retire_pg.go); the server's side
// of it — the login refused, the data kept, a deletion dropping only its own — is live_test.go's.
import (
"git.novox.be/novox/mesh-sdk/go/provider/harness"
"strings"
"testing"
"time"
)
// ADR 0570 clause 5, on the operator's yes: the login's database and objects go to its keeper, marked; its sessions
// end; the login is dropped; the database is not.
func TestRetiringHandsTheDatabaseToAKeeperAndRemovesTheLogin(t *testing.T) {
f, c := newFake(admin)
f.answer(`shobj_description\(oid`, []string{"c"}, []string{`{"mesh":"consumer","node":"ace"}`})
f.answer(`pg_roles WHERE rolname = 'mesh_ace_letta'$`, []string{"?column?"}, []string{"1"})
f.answer(`pg_database WHERE datname = 'mesh_ace_letta'$`, []string{"?column?"}, []string{"1"})
at := time.Date(2026, 10, 6, 12, 0, 0, 0, time.UTC)
if err := c.RetireRole(ctx, "mesh_ace_letta", "the operator approved its retirement", at); err != nil {
t.Fatal(err)
}
var order []string
for _, call := range f.calls {
switch {
case strings.HasPrefix(call.SQL, "SELECT"):
case strings.HasPrefix(call.SQL, "REASSIGN"), strings.HasPrefix(call.SQL, "DROP OWNED"):
order = append(order, call.Database+": "+call.SQL)
default:
order = append(order, call.SQL)
}
}
if !has(f.statements(), `pg_terminate_backend.*usename = 'mesh_ace_letta'`) {
t.Fatal(strings.Join(f.statements(), "\n"))
}
want := []string{
`CREATE ROLE "mesh_ace_letta~retired" NOLOGIN`,
`COMMENT ON ROLE "mesh_ace_letta~retired" IS '{"mesh":"consumer","node":"ace","retired":"2026-10-06T12:00:00Z","why":"the operator approved its retirement","login":"mesh_ace_letta"}'`,
`ALTER ROLE "mesh_ace_letta" NOLOGIN`,
`mesh_ace_letta: REASSIGN OWNED BY "mesh_ace_letta" TO "mesh_ace_letta~retired"`,
`mesh_ace_letta: DROP OWNED BY "mesh_ace_letta"`,
`DROP ROLE "mesh_ace_letta"`,
}
if strings.Join(order, "\n") != strings.Join(want, "\n") {
t.Fatalf("sent:\n%s\nwant:\n%s", strings.Join(order, "\n"), strings.Join(want, "\n"))
}
if has(f.statements(), `DROP DATABASE|REVOKE|ALLOW_CONNECTIONS|RENAME`) {
t.Fatal("retiring touched the database:", strings.Join(f.statements(), "\n"))
}
// No such role: nothing to retire, nothing done.
f, c = newFake(admin)
if err := c.RetireRole(ctx, "gone", "x", at); err != nil || has(f.statements(), `ALTER|COMMENT|CREATE|DROP`) {
t.Fatal(f.statements(), err)
}
}
// A login made again takes back what its keeper kept, and the keeper goes; with no keeper, nothing is sent.
func TestALoginMadeAgainReclaimsWhatItsKeeperKept(t *testing.T) {
f, c := newFake(admin)
if err := c.Reclaim(ctx, "mesh_ace_letta", "mesh_ace_letta"); err != nil || has(f.statements(), `REASSIGN|DROP`) {
t.Fatal(f.statements(), err)
}
f, c = newFake(admin)
f.answer(`pg_roles WHERE rolname = 'mesh_ace_letta~retired'$`, []string{"?column?"}, []string{"1"})
if err := c.Reclaim(ctx, "mesh_ace_letta", "mesh_ace_letta"); err != nil {
t.Fatal(err)
}
var got []string
for _, call := range f.calls[1:] {
got = append(got, call.Database+": "+call.SQL)
}
want := `mesh_ace_letta: REASSIGN OWNED BY "mesh_ace_letta~retired" TO "mesh_ace_letta"` + "\n" +
`mesh_ace_letta: DROP OWNED BY "mesh_ace_letta~retired"` + "\n" + `postgres: DROP ROLE "mesh_ace_letta~retired"`
if strings.Join(got, "\n") != want {
t.Fatal(strings.Join(got, "\n"))
}
}
func TestTheInventoryIsWhatTheMeshMadeByMarkOrShape(t *testing.T) {
f, c := newFake(admin)
f.answer(`FROM pg_roles r`, []string{"rolname", "rolcanlogin", "mark", "mesh_shaped", "size"},
[]string{"active_marked", "t", `{"mesh":"consumer","node":"ace"}`, "f", "100"},
[]string{"active_shaped", "t", "", "t", "200"},
[]string{"retired_marked", "f", `{"mesh":"consumer","node":"ace","retired":"2026-10-06T12:00:00Z","why":"gone"}`, "t", "300"},
[]string{"locked_before", "f", "", "t", "400"},
[]string{"hal_registry", "t", "", "f", "500"},
[]string{"jochens", "t", "", "t", ""},
[]string{"mesh_ace_umami~retired", "f", `{"mesh":"consumer","node":"ace","retired":"2026-10-29T12:00:00Z","why":"approved","login":"mesh_ace_umami"}`, "f", "600"},
)
f.answer(`_deleted_`, []string{"datname", "size"}, []string{"mesh_novox_gitea_deleted_20261005", "7771827"})
inv, err := c.Inventory(ctx)
if err != nil {
t.Fatal(err)
}
if strings.Join(inv.Active, ",") != "active_marked,active_shaped" {
t.Fatalf("active: %v", inv.Active)
}
if len(inv.Retired) != 4 {
t.Fatalf("%+v", inv.Retired)
}
r := inv.Retired[0]
if r.Consumer != "retired_marked" || r.Node != "ace" || r.Why != "gone" || r.SizeBytes != 300 ||
r.RetiredAt.Format(time.RFC3339) != "2026-10-06T12:00:00Z" {
t.Fatalf("%+v", r)
}
if r := inv.Retired[1]; r.Consumer != "locked_before" || !r.RetiredAt.IsZero() || r.Kind != harness.KindConsumer {
t.Fatalf("found locked without a mark: %+v", r)
}
if r := inv.Retired[2]; r.Consumer != "mesh_ace_umami" || r.SizeBytes != 600 || r.Why != "approved" {
t.Fatalf("a keeper is listed under the login it keeps for: %+v", r)
}
if r := inv.Retired[3]; r.Kind != KindSetAside || r.RetiredAt.Format("20060102") != "20261005" || r.SizeBytes != 7771827 {
t.Fatalf("set aside: %+v", r)
}
}
func TestDeletingRefusesALoginThatCanConnect(t *testing.T) {
f, c := newFake(admin)
f.answer(`SELECT rolcanlogin`, []string{"rolcanlogin"}, []string{"t"})
if _, err := c.DeleteRetired(ctx, harness.Retired{Consumer: "mesh_ace_baserow", Kind: harness.KindConsumer}); err == nil {
t.Fatal("deleted an active consumer")
}
noDrop(t, f.statements())
f, c = newFake(admin)
if _, err := c.DeleteRetired(ctx, harness.Retired{Consumer: "mesh_ace_baserow", Kind: KindSetAside}); err == nil {
t.Fatal("dropped a database not set aside")
}
noDrop(t, f.statements())
}
func TestDeletingDropsTheDatabaseThenTheRole(t *testing.T) {
f, c := newFake(admin)
f.answer(`SELECT rolcanlogin`, []string{"rolcanlogin"}, []string{"f"})
f.answer(`SELECT pg_database_size`, []string{"size"}, []string{"9000"})
freed, err := c.DeleteRetired(ctx, harness.Retired{Consumer: "mesh_ace_letta", Kind: harness.KindConsumer})
if err != nil || freed != 9000 {
t.Fatal(freed, err)
}
sql := strings.Join(f.statements(), "\n")
db, role := strings.Index(sql, `DROP DATABASE "mesh_ace_letta"`), strings.Index(sql, `DROP ROLE "mesh_ace_letta"`)
if db < 0 || role < db {
t.Fatal(sql)
}
// A login removed on retiring: the database, then its keeper.
f, c = newFake(admin)
f.answer(`SELECT pg_database_size`, []string{"size"}, []string{"9000"})
f.answer(`pg_roles WHERE rolname = 'mesh_ace_umami~retired'$`, []string{"?column?"}, []string{"1"})
if _, err := c.DeleteRetired(ctx, harness.Retired{Consumer: "mesh_ace_umami", Kind: harness.KindConsumer}); err != nil {
t.Fatal(err)
}
sql = strings.Join(f.statements(), "\n")
db, keeper := strings.Index(sql, `DROP DATABASE "mesh_ace_umami"`), strings.Index(sql, `DROP ROLE "mesh_ace_umami~retired"`)
if db < 0 || keeper < db {
t.Fatal(sql)
}
// A role still owning a set-aside database is kept, and said.
f, c = newFake(admin)
f.answer(`SELECT rolcanlogin`, []string{"rolcanlogin"}, []string{"f"})
f.answer(`SELECT datname FROM pg_database WHERE datdba`, []string{"datname"}, []string{"mesh_ace_letta_deleted_20261005"})
if _, err := c.DeleteRetired(ctx, harness.Retired{Consumer: "mesh_ace_letta", Kind: harness.KindConsumer}); err == nil ||
!strings.Contains(err.Error(), "still owns") || has(f.statements(), `DROP ROLE`) {
t.Fatal(err, f.statements())
}
}