Keep every column and table the controller of before reads: no migration 0108-0110, and a test that its queries still run (release 6, issue 1945 review H1)
This commit is contained in:
@@ -3,25 +3,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
)
|
||||
|
||||
// **The controller opens on a store whose plan tables are gone** (novox/hq ADR 0539 §17, issue 1945 B9): migration 0108 has
|
||||
// dropped the record of sends, the assignment generation, the gate's verdicts and the durations, and the controller still
|
||||
// assigns a module, reads where it runs, takes it off and reads the nodes.
|
||||
func TestTheControllerOpensOnAStoreWithoutThePlanTables(t *testing.T) {
|
||||
// **The controller opens on a store after release 6's migrations, which drop nothing the controller of before reads** (issue
|
||||
// 1945, review round 1): it assigns a module, reads where it runs and the nodes. Release 6 reads none of the plans' tables.
|
||||
func TestTheControllerOpensOnTheStoreAfterReleaseSix(t *testing.T) {
|
||||
open := aMesh(t)
|
||||
ctx := t.Context()
|
||||
inv := open.inventory
|
||||
for _, row := range inv.QueryForTest(t, `select table_name::text from information_schema.tables where table_schema = 'public'`) {
|
||||
switch name := strings.Trim(row[0], `"`); name {
|
||||
case "declaration_send", "assignment_generation", "build_gate", "duration":
|
||||
t.Errorf("the table %s is in the store", name)
|
||||
}
|
||||
}
|
||||
register(t, open, catalogue.Manifest{Module: "notes", Version: "1"})
|
||||
if _, err := assign(ctx, open, "anchor", "notes"); err != nil {
|
||||
t.Fatalf("assign on the migrated store: %v", err)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//go:build integration
|
||||
|
||||
package inventory
|
||||
|
||||
import "testing"
|
||||
|
||||
// **The store after release 6's migrations is still one today's controller (C5) can read** (issue 1945, review round 1): the
|
||||
// revert path puts C5 back, either by the witness or by the operator's want, and it reads the columns of the node row that
|
||||
// recorded a send (sent, sent_at, sent_bus_users, sent_builds, sent_epoch, sent_summary, sent_generation, sent_provisioning)
|
||||
// and the tables of the plans' machinery (build_gate, declaration_send, assignment_generation, duration). Release 6 reads
|
||||
// none of them any more and drops none: they go in a later milestone, once C5 has left the controller's five newest
|
||||
// fingerprints. Each query below is one C5 ran.
|
||||
func TestTheStoreAfterReleaseSixIsStillOneTheControllerOfBeforeCanRead(t *testing.T) {
|
||||
inv := ForTest(t)
|
||||
ctx := t.Context()
|
||||
if _, err := inv.AddNode(ctx, "anchor"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, q := range []string{
|
||||
`select sent, sequence, sent_at, sent_provisioning from node`,
|
||||
`select sent_bus_users, sent_builds, sent_epoch, sent_summary, sent_generation from node`,
|
||||
`select name, sent, sent_at from node order by name`,
|
||||
`select build from build_gate where verdict = 'failed'`,
|
||||
`select count(*) from declaration_send`,
|
||||
`select generation from assignment_generation`,
|
||||
`select kind, subject, ref, took_ms from duration`,
|
||||
} {
|
||||
if _, err := inv.store.Pool().Exec(ctx, q); err != nil {
|
||||
t.Errorf("a query of the controller of before no longer runs on the store: %s: %v", q, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
-- The tables of the delivery plans' machinery leave the store (novox/hq ADR 0539 §17, design 47 release 6, issue 1945).
|
||||
--
|
||||
-- A machine follows its wants and applies a module from the composition the controller writes for it (ADR 0539 §1, §2), so
|
||||
-- the controller keeps no record of what it sent, no counter of the assignments a send was composed from, no verdict of a
|
||||
-- gate that judged a build on its first machine and no measure of how long a plan's tier or a machine's apply took. This
|
||||
-- drops the four tables that kept them: declaration_send (0094), assignment_generation (0094), build_gate (0073) and duration
|
||||
-- (0066, 0075).
|
||||
--
|
||||
-- **It is one-way**: a controller older than this schema is refused by the put-back gate (the highest migration it carries is
|
||||
-- recorded by its version, issue 352). What stays: the node row and its columns (the digest of the last send, which the old
|
||||
-- reads of `status` still name until they go with their verbs), the bus step, the core box and the refused registrations.
|
||||
-- The function raise_assignment_generation and its triggers went with 0105.
|
||||
drop table if exists declaration_send;
|
||||
drop table if exists assignment_generation;
|
||||
drop table if exists build_gate;
|
||||
drop table if exists duration;
|
||||
@@ -1,11 +0,0 @@
|
||||
-- The node row keeps no record of a send's builds, epoch, summary or generation (novox/hq ADR 0539 §5, §17, issue 1945).
|
||||
--
|
||||
-- Nothing sends a declaration any more, so nothing writes what a send carried: the commit of each module (sent_builds, which
|
||||
-- 0105 kept only as the source of the one-time copy onto the assignments, long done), the lease epoch (sent_epoch, 0068), the
|
||||
-- summary `plan --diff` compared (sent_summary, 0078) and the assignment generation (sent_generation, 0094). **It is one-way**,
|
||||
-- as 0108. What stays: sent and sent_at (the digest and time of the last send), sent_bus_users and sent_provisioning, which holds the
|
||||
-- provisioner's plans of each composition (inventory.RecordComposedPlans); 0110 drops the first three.
|
||||
alter table node drop column if exists sent_builds;
|
||||
alter table node drop column if exists sent_epoch;
|
||||
alter table node drop column if exists sent_summary;
|
||||
alter table node drop column if exists sent_generation;
|
||||
@@ -1,11 +0,0 @@
|
||||
-- The node row keeps no digest of a send, nor when it was made (novox/hq ADR 0539 §5, §9, §17, issue 1945).
|
||||
--
|
||||
-- A machine is not sent a declaration, so nothing records one: whether a machine has what is wanted of it is read from its
|
||||
-- haves beside the assigner's wants, a given value is replaced when a have of its module is first running and healthy, and the
|
||||
-- bus's user list is part of the bus module's composition, which the bus machine's have names or does not. This drops what
|
||||
-- the last readers of a send's record read: node.sent and node.sent_at (0014), and node.sent_bus_users (0058). **It is
|
||||
-- one-way**, as 0108 and 0109. node.sent_provisioning stays: it holds the provisioner's plans of each composition
|
||||
-- (inventory.RecordComposedPlans).
|
||||
alter table node drop column if exists sent;
|
||||
alter table node drop column if exists sent_at;
|
||||
alter table node drop column if exists sent_bus_users;
|
||||
@@ -1,111 +0,0 @@
|
||||
//go:build integration
|
||||
|
||||
package inventory
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// **Migration 0108 drops the tables of the delivery plans' machinery** (novox/hq ADR 0539 §17, design 47 release 6, issue 1945):
|
||||
// the record of each send, the assignment generation, the gate's verdicts and the measured durations. The store is built as
|
||||
// the mesh holds it before the migration, with a row in each, and after it the four are gone and what the controller still
|
||||
// keeps stays: the node and its columns, the module, the bus step, the core box and the refused registrations.
|
||||
func TestMigration0108DropsTheTablesOfThePlansMachineryAndKeepsWhatTheControllerStillKeeps(t *testing.T) {
|
||||
inv, migrate := ForTestBefore(t, 108)
|
||||
tables := func() map[string]bool {
|
||||
t.Helper()
|
||||
out := map[string]bool{}
|
||||
for _, row := range inv.QueryForTest(t, `select table_name::text from information_schema.tables where table_schema = 'public'`) {
|
||||
out[strings.Trim(row[0], `"`)] = true
|
||||
}
|
||||
return out
|
||||
}
|
||||
gone := []string{"declaration_send", "assignment_generation", "build_gate", "duration"}
|
||||
before := tables()
|
||||
for _, name := range gone {
|
||||
if !before[name] {
|
||||
t.Fatalf("the table %s is not in the store before the migration", name)
|
||||
}
|
||||
}
|
||||
migrate()
|
||||
after := tables()
|
||||
for _, name := range gone {
|
||||
if after[name] {
|
||||
t.Errorf("the table %s is still in the store", name)
|
||||
}
|
||||
}
|
||||
for _, stays := range []string{"node", "module", "bus_step", "core_box", "build_refused", "controller_schema"} {
|
||||
if !after[stays] {
|
||||
t.Errorf("the table %s is gone", stays)
|
||||
}
|
||||
}
|
||||
// The functions and triggers the tables carried go with them.
|
||||
if rows := inv.QueryForTest(t, `select count(*) from pg_proc where proname = 'raise_assignment_generation'`); rows[0][0] != "0" {
|
||||
t.Errorf("the function raise_assignment_generation is still in the store")
|
||||
}
|
||||
}
|
||||
|
||||
// **Migration 0109 drops the columns of the node row that kept what a send carried** (ADR 0539 §17, issue 1945): the builds,
|
||||
// the epoch, the summary and the generation. The provisioner's plans stay (0110 drops the rest).
|
||||
func TestMigration0109DropsWhatASendCarriedFromTheNodeRow(t *testing.T) {
|
||||
inv, migrate := ForTestBefore(t, 109)
|
||||
columns := func() map[string]bool {
|
||||
t.Helper()
|
||||
out := map[string]bool{}
|
||||
for _, row := range inv.QueryForTest(t, `select column_name::text from information_schema.columns where table_name = 'node'`) {
|
||||
out[strings.Trim(row[0], `"`)] = true
|
||||
}
|
||||
return out
|
||||
}
|
||||
gone := []string{"sent_builds", "sent_epoch", "sent_summary", "sent_generation"}
|
||||
before := columns()
|
||||
for _, name := range gone {
|
||||
if !before[name] {
|
||||
t.Fatalf("node.%s is not in the store before the migration", name)
|
||||
}
|
||||
}
|
||||
migrate()
|
||||
after := columns()
|
||||
for _, name := range gone {
|
||||
if after[name] {
|
||||
t.Errorf("node.%s is still in the store", name)
|
||||
}
|
||||
}
|
||||
for _, stays := range []string{"sent_provisioning"} {
|
||||
if !after[stays] {
|
||||
t.Errorf("node.%s is gone", stays)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// **Migration 0110 drops the digest and time of a send, and the bus users' digest, from the node row** (ADR 0539 §17, issue
|
||||
// 1945): the haves answer what a machine has. The provisioner's plans stay.
|
||||
func TestMigration0110DropsTheDigestOfASendFromTheNodeRow(t *testing.T) {
|
||||
inv, migrate := ForTestBefore(t, 110)
|
||||
columns := func() map[string]bool {
|
||||
t.Helper()
|
||||
out := map[string]bool{}
|
||||
for _, row := range inv.QueryForTest(t, `select column_name::text from information_schema.columns where table_name = 'node'`) {
|
||||
out[strings.Trim(row[0], `"`)] = true
|
||||
}
|
||||
return out
|
||||
}
|
||||
gone := []string{"sent", "sent_at", "sent_bus_users"}
|
||||
before := columns()
|
||||
for _, name := range gone {
|
||||
if !before[name] {
|
||||
t.Fatalf("node.%s is not in the store before the migration", name)
|
||||
}
|
||||
}
|
||||
migrate()
|
||||
after := columns()
|
||||
for _, name := range gone {
|
||||
if after[name] {
|
||||
t.Errorf("node.%s is still in the store", name)
|
||||
}
|
||||
}
|
||||
if !after["sent_provisioning"] {
|
||||
t.Errorf("node.sent_provisioning is gone")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user