From 198be8217c67d834b205bb893e74a4cfac79de24 Mon Sep 17 00:00:00 2001 From: mesh-tools Date: Tue, 20 Oct 2026 11:17:16 +0000 Subject: [PATCH] stage 8 of 8 for issue 1389: the equality test's integration part goes --- .../compose_equal_integration_test.go | 310 ------------------ 1 file changed, 310 deletions(-) delete mode 100644 cmd/mesh-controller/compose_equal_integration_test.go diff --git a/cmd/mesh-controller/compose_equal_integration_test.go b/cmd/mesh-controller/compose_equal_integration_test.go deleted file mode 100644 index 335645ca..00000000 --- a/cmd/mesh-controller/compose_equal_integration_test.go +++ /dev/null @@ -1,310 +0,0 @@ -//go:build integration - -package main - -import ( - "context" - "flag" - "fmt" - "os" - "sort" - "strings" - "testing" - "time" - - "git.novox.be/novox/mesh-sdk/go/compose" - snapshot "git.novox.be/novox/mesh-sdk/go/facts" -) - -// 1384: nothing shows the controller's composition and mesh-sdk's compose every node alike on the live facts. This test is -// that proof (novox/hq ADR 0453 clause 3): it reads the facts snapshot MESH_FACTS names (the live one in every check and -// every try, the build seat gives it), else one captured in testdata/facts-equal.json (taken with `facts show` and -// scrubbed as the snapshot is), else the snapshot of a small mesh of its own; raises it into throwaway stores as the merge -// gate does; and composes every machine both ways. -// -// It runs only when named (a try with this test's name as the tests pattern); a whole-suite run skips it. -// -// (a) Foreseeing on the fresh store: the same error or none, the same validator problems, LeftOut and its reasons, Withheld, -// Unbound, Unplaced, HandedOnly and the own secrets named foreseen; and the ports mesh-sdk names foreseen are the ones the -// controller allocates when it sends. -// (b) the send: on two stores raised from the same snapshot, the controller's Allocating composition of every machine, and the -// adapter's compose, perform and compose again; the same ports, pair credentials and own secrets were made, by key. -// (c) after (b), Reading on one store, both ways: the declaration byte for byte. -// -// It sends nothing and opens no store but the throwaway ones. A difference names the machine, the comparison and the first -// field that differs; a machine both paths refuse alike is said, not failed. The test is deleted with the controller's -// composition (issue 1389). -func TestEveryMachineComposesAlikeBothWays(t *testing.T) { - // It is slow (it composes every machine of the live mesh several times each way) and is deleted with the controller's - // composition (issue 1389), so it runs only when asked for by name: a try or a `go test -run` that names it. A merge check - // runs every test and does not. - if run := flag.Lookup("test.run"); run == nil || !strings.Contains(run.Value.String(), "TestEveryMachineComposesAlikeBothWays") { - t.Skip("runs only when named: a try with the tests pattern TestEveryMachineComposesAlikeBothWays") - } - ctx := t.Context() - admin := os.Getenv("MESH_TEST_POSTGRES") - if admin == "" { - t.Skip("no throwaway PostgreSQL (MESH_TEST_POSTGRES) to raise the mesh in") - } - started := time.Now() - phase := func(what string) { t.Logf("[%s] %s", time.Since(started).Round(time.Second), what) } - f, source := equalityFacts(t) - if len(f.Machines) < 1 { - t.Fatalf("the facts (%s) hold no machine, so nothing was composed and nothing is proved", source) - } - t.Logf("the facts of %s (%s): %d machine(s)", f.Taken.Format("2006-01-02 15:04:05"), source, len(f.Machines)) - shelf, err := shelfOfFacts(f) - if err != nil { - t.Fatal(err) - } - sources := sourcesOfFacts(f) - - // Three stores, raised from the same snapshot, one after the other: (a) both ways on a fresh store, (b) and (c) the - // controller's sends and readings, (b) mesh-sdk's sends. They cannot run together: throwawayStores finds its databases by - // the process environment (and a store opened later finds them there too), so a second one raised at the same time takes - // the first one's connection from under it (the live try: database gate_inventory_... does not exist). - var ( - oldForeseen, sdkForeseen = map[string]composedBoth{}, map[string]composedBoth{} - foreseenPorts = map[string][]string{} - readOld, readSDK = map[string]composedBoth{}, map[string]composedBoth{} - oldMade, sdkMade made - oldRefused = map[string]string{} - sendRefused = map[string]string{} - errA, errOld, errSDK error - ) - func() { // (a) Foreseeing on the fresh store. - phase("(a) starts: raising a fresh store") - fresh, drop, err := throwawayStores(ctx, admin) - if err != nil { - errA = err - return - } - defer drop() - if _, err := raiseFromFacts(ctx, fresh, f, shelf, sources); err != nil { - errA = err - return - } - // mesh-sdk's composition first: it writes nothing, where the controller's makes every pair credential on the way. The - // Input is read once for all of its machines. - phase("(a) the store is raised; mesh-sdk's Foreseeing starts") - cached := withInputCache(ctx) - for _, m := range f.Machines { - in, err := inputFor(cached, fresh) - if err != nil { - errA = fmt.Errorf("%s: the adapter cannot read the mesh: %w", m.Name, err) - return - } - d, problems, cerr := compose.ComposeIn(in.Input, m.Name, compose.Foreseeing) - if cerr == nil { - foreseenPorts[m.Name] = append([]string(nil), d.ForeseenPorts...) - sort.Strings(foreseenPorts[m.Name]) - } - sdkForeseen[m.Name] = capturedFrom(sendableOf(d), problems, cerr) - } - phase("(a) mesh-sdk's Foreseeing of every machine") - gens, gensErr := generators(ctx, fresh) - for _, m := range f.Machines { - if gensErr != nil { - oldForeseen[m.Name] = composedBoth{Err: gensErr.Error()} - continue - } - d, problems, err := composedAndValidated(ctx, fresh, m.Name, gens, Foreseeing) - oldForeseen[m.Name] = capturedFrom(d, problems, err) - } - phase("(a) the controller's Foreseeing of every machine") - }() - if errA != nil { - t.Fatal(errA) - } - func() { // (b) and (c): the controller's send of every machine, then both ways of reading. - phase("(b) starts: the controller's send, raising a store") - oldStore, drop, err := throwawayStores(ctx, admin) - if err != nil { - errOld = err - return - } - defer drop() - if _, err := raiseFromFacts(ctx, oldStore, f, shelf, sources); err != nil { - errOld = err - return - } - oldGens, oldGensErr := generators(ctx, oldStore) - for _, m := range f.Machines { - if oldGensErr != nil { - oldRefused[m.Name] = oldGensErr.Error() - continue - } - if _, _, err := composedAndValidated(ctx, oldStore, m.Name, oldGens, Allocating); err != nil { - oldRefused[m.Name] = err.Error() - } - } - phase("(b) the controller's send of every machine") - if oldMade, err = madeIn(ctx, oldStore); err != nil { - errOld = err - return - } - cached := withInputCache(ctx) - for _, m := range f.Machines { - if oldGensErr != nil { - readOld[m.Name] = composedBoth{Err: oldGensErr.Error()} - } else { - d, problems, err := composedAndValidated(ctx, oldStore, m.Name, oldGens, Reading) - readOld[m.Name] = capturedFrom(d, problems, err) - } - d, problems, err := composeQuestion(cached, oldStore, m.Name, compose.Reading, true) - readSDK[m.Name] = capturedFrom(d, problems, err) - } - phase("(c) both ways of reading every machine after the controller's send") - }() - if errOld != nil { - t.Fatal(errOld) - } - func() { // (b) mesh-sdk's send of every machine. - phase("(b) starts: mesh-sdk's send, raising a store") - sdkStore, drop, err := throwawayStores(ctx, admin) - if err != nil { - errSDK = err - return - } - defer drop() - if _, err := raiseFromFacts(ctx, sdkStore, f, shelf, sources); err != nil { - errSDK = err - return - } - for _, m := range f.Machines { - if _, err := composeSend(ctx, sdkStore, m.Name); err != nil { - sendRefused[m.Name] = err.Error() - } - } - phase("(b) mesh-sdk's send of every machine") - sdkMade, errSDK = madeIn(ctx, sdkStore) - }() - if errSDK != nil { - t.Fatal(errSDK) - } - - var failures []string - for _, m := range f.Machines { - failures = append(failures, bothWaysDiffer(m.Name, "(a) Foreseeing", oldForeseen[m.Name], sdkForeseen[m.Name], false)...) - failures = append(failures, bothWaysDiffer(m.Name, "(c) Reading after the send", readOld[m.Name], readSDK[m.Name], true)...) - } - // **The send must compose every machine both ways.** A machine either send refuses is no proof of anything: what the - // controller made on the way to refusing it is no send's, and a refusal alike says nothing about what a send of it makes. - // So it fails here, naming the machine and both refusals (a refusal alike in (a), the Foreseeing on a store that holds no - // secret a send made, is said and stays). A pass proves that every machine of the facts was sent and compared. - refused := map[string]bool{} - for _, m := range f.Machines { - why, oldNo := oldRefused[m.Name] - sdkWhy, sdkNo := sendRefused[m.Name] - if !oldNo && !sdkNo { - continue - } - refused[m.Name] = true - failures = append(failures, fmt.Sprintf("%s, (b) the send: it is not composed both ways, so nothing of it is compared: "+ - "the controller's refusal %s, mesh-sdk's %s", m.Name, quoted(oneLine(why)), quoted(oneLine(sdkWhy)))) - } - failures = append(failures, madeDiffer("(b) the send", oldMade, sdkMade, refused)...) - - // (a)'s ports: those mesh-sdk names foreseen, for each machine, are the ones the controller's send allocated to it. - for _, m := range f.Machines { - if refused[m.Name] { - continue - } - var allocated []string - for _, p := range oldMade.Ports { - if node, rest, ok := strings.Cut(p, " "); ok && node == m.Name { - module, port, _ := strings.Cut(strings.SplitN(rest, "->", 2)[0], ":") - allocated = append(allocated, module+":"+port) - } - } - sort.Strings(allocated) - // A port the snapshot already holds is not allocated by a send, and one a module is given is not allocated either: the - // ones mesh-sdk names must all be among those the send allocated. - for _, want := range foreseenPorts[m.Name] { - found := false - for _, got := range allocated { - found = found || got == want - } - if !found { - failures = append(failures, fmt.Sprintf("%s, (a) Foreseeing: mesh-sdk names the port %s foreseen and the "+ - "controller's send allocates none for it", m.Name, want)) - } - } - } - for machine, why := range sendRefused { - t.Logf("%s: mesh-sdk's send of it is refused: %s", machine, why) - } - for machine, c := range oldForeseen { - if c.Err != "" { - t.Logf("%s: the controller refuses it, and mesh-sdk alike: %s", machine, oneLine(c.Err)) - } - } - if len(failures) > 0 { - t.Fatalf("the two compositions differ on %d point(s):\n %s", len(failures), strings.Join(failures, "\n ")) - } - t.Logf("%d machine(s) were sent and compose alike both ways", len(f.Machines)) -} - -// equalityFacts is the snapshot the comparison composes: MESH_FACTS, else the one captured in testdata, else the facts of a -// mesh of its own (the same shape, small). Source says which. -func equalityFacts(t *testing.T) (snapshot.Facts, string) { - t.Helper() - ctx := t.Context() - if path := os.Getenv("MESH_FACTS"); path != "" { - f, err := readFacts(ctx, path) - if err != nil { - t.Fatalf("MESH_FACTS names %s and it is not a snapshot: %v", path, err) - } - return f, "MESH_FACTS " + path - } - if _, err := os.Stat("testdata/facts-equal.json"); err == nil { - f, err := readFacts(ctx, "testdata/facts-equal.json") - if err != nil { - t.Fatal(err) - } - return f, "captured in testdata/facts-equal.json" - } - open, _ := aMeshWithSecrets(t) - f, err := gatherFacts(ctx, open, "2.11.17") - if err != nil { - t.Fatal(err) - } - return f, "gathered from a mesh of the test's own" -} - -// madeIn is what a store holds that a send makes, by key and never by value. -func madeIn(ctx context.Context, open *stores) (made, error) { - var out made - inv := open.inventory - nodes, err := inv.Nodes(ctx) - if err != nil { - return out, err - } - for _, n := range nodes { - ports, err := inv.PortsFor(ctx, n.Name) - if err != nil { - return out, err - } - for _, p := range ports { - out.Ports = append(out.Ports, fmt.Sprintf("%s %s:%d->%d", n.Name, p.Module, p.Wanted, p.Machine)) - } - rows, err := inv.SecretsFrom(ctx, n.Name) - if err != nil { - return out, err - } - for _, s := range rows { - out.Pairs = append(out.Pairs, fmt.Sprintf("%s %s on %s from %s local=%s", s.Name, s.ConsumerModule, s.Consumer, n.Name, s.Local)) - } - } - own, err := inv.OwnSecretRows(ctx) - if err != nil { - return out, err - } - for _, r := range own { - out.OwnSecrets = append(out.OwnSecrets, fmt.Sprintf("%s %s/%s (%s)", r.Node, r.Module, r.Name, r.Origin)) - } - sort.Strings(out.Ports) - sort.Strings(out.Pairs) - sort.Strings(out.OwnSecrets) - return out, nil -}