From b317dfef45b63884e2ba2216738a0b9f0cc54c62 Mon Sep 17 00:00:00 2001 From: mesh-tools Date: Tue, 20 Oct 2026 09:54:06 +0000 Subject: [PATCH] Name only the differing entries of what two sends made, and leave a refused machine out (issue 1384) The live try cut the lists of the ports allocated and the own secrets made at 2.5 KB, so no difference showed. madeDiffer now says, per kind, the entries made only by the controller, only by mesh-sdk, and by both with a different value; the entries of a machine refused on either side are left out of both, since it sends nothing. --- cmd/mesh-controller/compose_equal_test.go | 119 +++++++++++++++++++--- 1 file changed, 107 insertions(+), 12 deletions(-) diff --git a/cmd/mesh-controller/compose_equal_test.go b/cmd/mesh-controller/compose_equal_test.go index 2b782992..5ac92d7c 100644 --- a/cmd/mesh-controller/compose_equal_test.go +++ b/cmd/mesh-controller/compose_equal_test.go @@ -180,20 +180,103 @@ type made struct { OwnSecrets []string } -// madeDiffer says how what two sends made differs. -func madeDiffer(comparison string, old, sdk made) []string { +// madeDiffer says how what two sends made differs, by entry: for each kind, the entries only the controller made, the ones only +// mesh-sdk made, and the ones both made with a different value. Never a whole list. The entries of a machine in refused (a +// machine whose send is refused on either side, which sends nothing) are left out of both. +func madeDiffer(comparison string, old, sdk made, refused map[string]bool) []string { var out []string for _, f := range []struct { name string old, sdk []string + split func(string) (key, value string) + nodes func(string) []string }{ - {"the ports allocated", old.Ports, sdk.Ports}, - {"the pair credentials made", old.Pairs, sdk.Pairs}, - {"the own secrets made", old.OwnSecrets, sdk.OwnSecrets}, + {"the ports allocated", old.Ports, sdk.Ports, splitAt("->"), firstWord}, + {"the pair credentials made", old.Pairs, sdk.Pairs, func(l string) (string, string) { return l, "" }, pairNodes}, + {"the own secrets made", old.OwnSecrets, sdk.OwnSecrets, splitAtLast(" ("), firstWord}, } { - if !sameStrings(f.old, f.sdk) { - out = append(out, fmt.Sprintf("%s: %s differ: the controller's %s, mesh-sdk's %s", comparison, f.name, - strings.Join(f.old, ", "), strings.Join(f.sdk, ", "))) + left, right := entriesOf(f.old, f.split, f.nodes, refused), entriesOf(f.sdk, f.split, f.nodes, refused) + var onlyOld, onlySDK, different []string + for key, v := range left { + if w, both := right[key]; !both { + onlyOld = append(onlyOld, key) + } else if w != v { + different = append(different, fmt.Sprintf("%s (the controller's %s, mesh-sdk's %s)", key, v, w)) + } + } + for key := range right { + if _, both := left[key]; !both { + onlySDK = append(onlySDK, key) + } + } + sort.Strings(onlyOld) + sort.Strings(onlySDK) + sort.Strings(different) + var said []string + if len(onlyOld) > 0 { + said = append(said, "made only by the controller: "+strings.Join(onlyOld, ", ")) + } + if len(onlySDK) > 0 { + said = append(said, "made only by mesh-sdk: "+strings.Join(onlySDK, ", ")) + } + if len(different) > 0 { + said = append(said, "made by both with a different value: "+strings.Join(different, ", ")) + } + if len(said) > 0 { + out = append(out, fmt.Sprintf("%s: %s differ: %s", comparison, f.name, strings.Join(said, "; "))) + } + } + return out +} + +// entriesOf is the entries of a list by key, those of a machine in skip left out. +func entriesOf(lines []string, split func(string) (string, string), nodes func(string) []string, skip map[string]bool) map[string]string { + out := map[string]string{} + for _, l := range lines { + skipped := false + for _, n := range nodes(l) { + skipped = skipped || skip[n] + } + if skipped { + continue + } + k, v := split(l) + out[k] = v + } + return out +} + +func splitAt(sep string) func(string) (string, string) { + return func(l string) (string, string) { + k, v, _ := strings.Cut(l, sep) + return k, v + } +} + +func splitAtLast(sep string) func(string) (string, string) { + return func(l string) (string, string) { + if i := strings.LastIndex(l, sep); i >= 0 { + return l[:i], l[i+1:] + } + return l, "" + } +} + +func firstWord(l string) []string { + f := strings.Fields(l) + if len(f) == 0 { + return nil + } + return f[:1] +} + +// pairNodes are the consumer and the provider of a pair credential line ("name module on consumer from provider local=..."). +func pairNodes(l string) []string { + f := strings.Fields(l) + var out []string + for i := 0; i+1 < len(f); i++ { + if f[i] == "on" || f[i] == "from" { + out = append(out, f[i+1]) } } return out @@ -238,9 +321,21 @@ func TestTheComparisonNamesTheMachineWhoseCompositionDiffers(t *testing.T) { !strings.Contains(got[0], "the refusal differs") { t.Fatalf("a machine one path refuses and the other composes is not named: %v", got) } - // And what a send made. - if got := madeDiffer("the send", made{Ports: []string{"anchor files:80->8080"}}, made{}); len(got) != 1 || - !strings.Contains(got[0], "the ports allocated differ") { - t.Fatalf("a port allocated on one path alone is not named: %v", got) + // And what a send made: only the entries that differ, per machine, never the whole lists. + long := made{Ports: []string{"anchor files:80->8080", "anchor web:81->8081", "laptop db:5432->5432"}, + OwnSecrets: []string{"anchor files/admin (made)", "laptop db/root (made)"}} + other2 := made{Ports: []string{"anchor files:80->8080", "anchor web:81->9091", "laptop db:5432->5432", "laptop cache:6379->6379"}, + OwnSecrets: []string{"anchor files/admin (made)", "laptop db/root (accepted)"}} + got = madeDiffer("the send", long, other2, nil) + if len(got) != 2 || !strings.Contains(got[0], "made only by mesh-sdk: laptop cache:6379") || + !strings.Contains(got[0], "anchor web:81 (the controller's 8081, mesh-sdk's 9091)") || + strings.Contains(got[0], "anchor files:80") || strings.Contains(got[0], "laptop db:5432") || + !strings.Contains(got[1], "laptop db/root (the controller's (made), mesh-sdk's (accepted))") || + strings.Contains(got[1], "anchor files/admin") { + t.Fatalf("the send's differences are not only the differing entries: %v", got) + } + // A machine refused on either side is left out of both. + if got := madeDiffer("the send", long, other2, map[string]bool{"anchor": true, "laptop": true}); len(got) != 0 { + t.Fatalf("a refused machine is compared: %v", got) } }