Files
mesh-controller/internal/inventory/fortest.go
T
jochen 8adb7f1a05
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery-group group fix/assign-says-why-a-module-is-not-there delivering: 1 of 2 delivered
mesh/delivery superseded: a newer delivery to the same trunk took over its walk
Give each pending assignment its own condition, and keep a raised row until it clears
Second review of #150: one key per machine and module let a newer failure
be cleared in the tick that raised it, pruning could orphan an open
condition, and a build no longer waited for read as never asked although it
may still run.
2026-10-08 16:45:43 +02:00

81 lines
2.2 KiB
Go

package inventory
import (
"context"
"fmt"
"os"
"strings"
"testing"
"time"
"github.com/jackc/pgx/v5"
"github.com/novox/mesh-controller/internal/store"
)
// ForTest is a fresh inventory in a database of its own, dropped when the test ends.
//
// Exported because the check that this mesh reads what a node sends lives beside the link, and a
// second copy of this would be a second thing to keep true. It takes a *testing.T, so it cannot
// be called from anything that is not a test.
func ForTest(t *testing.T) *Inventory {
t.Helper()
admin := os.Getenv("MESH_TEST_POSTGRES")
if admin == "" {
t.Skip("no MESH_TEST_POSTGRES; run `make check` to raise one")
}
name := fmt.Sprintf("inv_%d_%s", time.Now().UnixNano()%1_000_000,
strings.ToLower(strings.NewReplacer("/", "", "-", "").Replace(t.Name())))
if len(name) > 60 {
name = name[:60]
}
conn, err := pgx.Connect(t.Context(), admin)
if err != nil {
t.Fatalf("cannot reach the test PostgreSQL: %v", err)
}
if _, err := conn.Exec(t.Context(), "create database "+name); err != nil {
t.Fatalf("cannot create %s: %v", name, err)
}
conn.Close(t.Context())
cut := strings.LastIndex(admin, "/")
t.Setenv(store.Variable(Name), admin[:cut]+"/"+name+"?sslmode=disable")
inv, err := Open(t.Context())
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
inv.Close()
c, err := pgx.Connect(context.Background(), admin)
if err != nil {
return
}
defer c.Close(context.Background())
_, _ = c.Exec(context.Background(), "drop database if exists "+name+" with (force)")
})
if err := inv.Ready(t.Context(), 20*time.Second); err != nil {
t.Fatal(err)
}
migrations, err := Migrations()
if err != nil {
t.Fatal(err)
}
if _, err := inv.store.Migrate(t.Context(), migrations); err != nil {
t.Fatal(err)
}
return inv
}
// RemoveNodeForTest removes a machine's record as a person removing it from the store would: no verb of the
// mesh removes one yet, and what hangs off it must go with it.
func (i *Inventory) RemoveNodeForTest(ctx context.Context, name string) (bool, error) {
tag, err := i.store.Pool().Exec(ctx, `delete from node where name = $1`, name)
if err != nil {
return false, err
}
return tag.RowsAffected() == 1, nil
}