Files
mesh-catalog/modules/postgres/cmd/postgres-provider/harness_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

137 lines
4.5 KiB
Go

package main
import (
"context"
"encoding/json"
"git.novox.be/novox/mesh-sdk/go/provider/harness"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
type world struct {
t *testing.T
dir string
receives string
now time.Time
h *harness.Harness
a *recorder
said []string
}
func newWorld(t *testing.T) *world {
w := &world{t: t, dir: t.TempDir(), now: time.Date(2026, 10, 5, 12, 0, 0, 0, time.UTC), a: &recorder{}}
w.receives = filepath.Join(w.dir, "mesh.json")
w.h = &harness.Harness{Resource: "postgres-database", Receives: w.receives, Adapter: w.a,
Now: func() time.Time { return w.now },
Log: func(f string, a ...any) { w.said = append(w.said, f) }}
return w
}
// recorder is an adapter that remembers what it was asked to create; the loop's own behaviour is proven in the SDK's
// harness package, and this module's tests hold only what the module adds (issue 849).
type recorder struct{ created []harness.Provision }
func (r *recorder) Create(_ context.Context, p harness.Provision) error {
r.created = append(r.created, p)
return nil
}
func (r *recorder) Retire(context.Context, string, map[string]any, string, time.Time) error {
return nil
}
func (r *recorder) Holds(context.Context, harness.Provision) (bool, error) { return true, nil }
func (r *recorder) Inventory(context.Context) (harness.Inventory, error) {
return harness.Inventory{}, nil
}
func (r *recorder) Delete(context.Context, harness.Retired) (int64, error) { return 0, nil }
func (w *world) give(given ...map[string]any) {
for _, g := range given {
secret := filepath.Join(w.dir, g["as"].(string)+".secret")
if err := os.WriteFile(secret, []byte("pw-"+g["as"].(string)+"\n"), 0o600); err != nil {
w.t.Fatal(err)
}
g["secret"] = secret
}
if given == nil {
given = []map[string]any{}
}
raw, _ := json.Marshal(map[string]any{"requirement": "postgres-database", "given": given})
if err := os.WriteFile(w.receives, raw, 0o600); err != nil {
w.t.Fatal(err)
}
}
func TestAddingExtensionsAppliesTheConsumerAgain(t *testing.T) {
w := newWorld(t)
w.give(map[string]any{"as": "mesh_ace_letta", "values": map[string]any{"name": "letta"}})
w.h.Reconcile(ctx)
w.give(map[string]any{"as": "mesh_ace_letta", "values": map[string]any{"name": "letta", "extensions": []any{"vector"}}})
w.h.Reconcile(ctx)
if len(w.a.created) != 2 {
t.Fatalf("created %d times", len(w.a.created))
}
if ext, _ := Extensions(w.a.created[1].Values); len(ext) != 1 || ext[0] != "vector" {
t.Fatal(ext)
}
}
type pgErr struct{ s string }
func (e *pgErr) Error() string { return e.s }
func TestProvisionerCreatesTheDatabaseThenItsExtensions(t *testing.T) {
f, c := newFake(admin)
f.answer(`FROM pg_available_extensions`, []string{"name"}, []string{"vector"})
var events []string
a := provisioner{pg: c, announce: func(e string, _ map[string]string) { events = append(events, e) }}
p := harness.Provision{As: "mesh_ace_letta", Password: "pw", Values: map[string]any{"name": "letta", "extensions": []any{"vector"}}}
if err := a.Create(ctx, p); err != nil {
t.Fatal(err)
}
sql := f.statements()
// The extension once the database exists, and last the active mark (novox/hq ADR 0230).
if !strings.HasPrefix(sql[len(sql)-2], `CREATE EXTENSION IF NOT EXISTS "vector"`) || !has(sql, `CREATE DATABASE "mesh_ace_letta"`) ||
sql[len(sql)-1] != `COMMENT ON ROLE "mesh_ace_letta" IS '{"mesh":"consumer"}'` {
t.Fatal(strings.Join(sql, "\n"))
}
if strings.Join(events, ",") != "database.provisioned" {
t.Fatal(events)
}
// An extension the server does not offer: refused, and no event says it was provisioned.
events = nil
p.Values = map[string]any{"extensions": []any{"nope"}}
if err := a.Create(ctx, p); err == nil || !strings.Contains(err.Error(), `"nope"`) || len(events) != 0 {
t.Fatal(err, events)
}
// A malformed list: refused before the server is asked anything.
f.reset()
p.Values = map[string]any{"extensions": "vector"}
if err := a.Create(ctx, p); err == nil || len(f.calls) != 0 {
t.Fatal(err, f.calls)
}
f.reset()
f.answer(`FROM pg_roles`, []string{"?column?"}, []string{"1"})
if err := a.Retire(ctx, "mesh_ace_letta", nil, "test", time.Now()); err != nil {
t.Fatal(err)
}
// On the operator's yes the login goes and the database stays (ADR 0570 clause 5).
if !has(f.statements(), `^DROP ROLE "mesh_ace_letta"$`) || has(f.statements(), `DROP DATABASE`) {
t.Fatal(f.statements())
}
}
func listHas(list []string, s string) bool {
for _, x := range list {
if x == s {
return true
}
}
return false
}