From 25fdf9920e58ef0cad1e6da2c84052aefc6fd393 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 22 Oct 2026 18:21:47 +0200 Subject: [PATCH] Read a commit as the same as itself however short, and fit the pending assignments' tests to a mesh that asks no build (issue 1851, A9, A10) --- .../pending_integration_test.go | 59 +------------------ cmd/mesh-controller/plan_keys.go | 3 + cmd/mesh-controller/replay325_test.go | 9 +-- cmd/mesh-controller/same_commit_test.go | 17 ++++++ 4 files changed, 24 insertions(+), 64 deletions(-) create mode 100644 cmd/mesh-controller/same_commit_test.go diff --git a/cmd/mesh-controller/pending_integration_test.go b/cmd/mesh-controller/pending_integration_test.go index e45d5207..3e1b4780 100644 --- a/cmd/mesh-controller/pending_integration_test.go +++ b/cmd/mesh-controller/pending_integration_test.go @@ -3,7 +3,6 @@ package main import ( - "context" "encoding/json" "errors" "fmt" @@ -178,7 +177,7 @@ func TestAPendingAssignmentExpiresWhenItsBuildFails(t *testing.T) { t.Fatalf("a module whose build failed: %v", err) } for _, want := range []string{"sensors is known and not registered", "its last build, b-modules/sensors", - "failed: go build: undefined: sensorsRead", "build \"true\"", "repository novox/mesh-catalog, path modules/sensors"} { + "failed: go build: undefined: sensorsRead", "registered from the builder's done key", "novox/mesh-catalog (path modules/sensors)"} { if !strings.Contains(err.Error(), want) { t.Fatalf("the refusal does not say %q:\n%v", want, err) } @@ -308,7 +307,7 @@ func TestAnUnknownModuleIsRefusedWithTheClosestNames(t *testing.T) { } for _, want := range []string{"no module of that name: sensors", "the catalogue holds no module of that name", "no build request the controller kept (the last 30 days)", "the closest names it holds: sensord", - "asks for nothing here"} { + "asks for nothing: the controller asks no build"} { if !strings.Contains(err.Error(), want) { t.Fatalf("the refusal does not say %q:\n%v", want, err) } @@ -478,60 +477,6 @@ func TestAPendingAssignmentNeverWaitsSilently(t *testing.T) { } } -func TestASecondAssignmentNotMadeKeepsItsCondition(t *testing.T) { - open := aCatalogueMesh(t) - ctx := t.Context() - asked := 0 - asksOfEveryModule(t) // the one ask left is the builder's own (ADR 0453 §5): this test is of what a walk does around it - was := askABuild - askABuild = func(context.Context, buildSource, string, string) (string, error) { - asked++ - return fmt.Sprintf("b-%d", asked), nil - } - t.Cleanup(func() { askABuild = was }) - mergeAdding(t, open, "modules/sensors", "3da80a4b00aa") - if _, err := assign(ctx, open, "laptop", "sensors"); err != nil { - t.Fatal(err) - } - failedBuild(t, open, "b-1") - settlePending(ctx, open, time.Now()) - first := pendingOf(t, open)[0] - if !conditionOpen(t, first) { - t.Fatal("the first assignment not made raised nothing") - } - - if _, err := assignWith(ctx, open, "laptop", assignOptions{Build: true}, "sensors"); err != nil { - t.Fatal(err) - } - failedBuild(t, open, "b-2") - settlePending(ctx, open, time.Now()) - - var second inventory.PendingAssignment - for _, p := range pendingOf(t, open) { - if p.Build == "b-2" { - second = p - } - } - if second.State != inventory.PendingExpired { - t.Fatalf("the second: %+v", second) - } - if !conditionOpen(t, second) { - t.Fatal("the second assignment's condition was cleared in the tick that raised it") - } - if !conditionOpen(t, rowOf(t, open, first.ID)) { - t.Fatal("the first was judged answered by a second that itself was not made") - } - // unassign takes both back, and the next tick clears both. - if said, err := unassign(ctx, open, "laptop", "sensors"); err != nil || !strings.Contains(said, "b-1") || - !strings.Contains(said, "b-2") { - t.Fatalf("unassign: %q %v", said, err) - } - settlePending(ctx, open, time.Now()) - if conditionOpen(t, first) || conditionOpen(t, second) { - t.Fatal("a condition stayed open after both were taken back") - } -} - func TestARaisedRowIsKeptUntilItsConditionClears(t *testing.T) { open := aCatalogueMesh(t) ctx := t.Context() diff --git a/cmd/mesh-controller/plan_keys.go b/cmd/mesh-controller/plan_keys.go index e3c48291..16cecbf1 100644 --- a/cmd/mesh-controller/plan_keys.go +++ b/cmd/mesh-controller/plan_keys.go @@ -209,6 +209,9 @@ func sameCommitID(a, b string) bool { if a == "" || b == "" { return false } + if a == b { + return true + } n := min(len(a), len(b)) return n >= 7 && a[:n] == b[:n] } diff --git a/cmd/mesh-controller/replay325_test.go b/cmd/mesh-controller/replay325_test.go index 2ca214b8..b4dacb4f 100644 --- a/cmd/mesh-controller/replay325_test.go +++ b/cmd/mesh-controller/replay325_test.go @@ -27,13 +27,8 @@ func TestReplay325(t *testing.T) { BuiltFrom: "c0", Head: "c0"}); err != nil { t.Fatal(err) } - asksWithPaths(t) - m := link.SourceMoved{Owner: "novox", Repo: "mesh-catalog", Base: "main", Commit: "5e450125aa", - Paths: []string{"modules/sensors/module.json", "modules/sensors/cmd/sensors/main.go"}, - ModuleDirs: []string{"modules/sensors"}, ModuleDirsSaid: true} - if err := (following{open: open}).SourceMoved(ctx, m); err != nil { - t.Fatal(err) - } + // The build the merge asked before R4e (nothing asks one since, ADR 0501 §6), kept as it was. + mergeAdding(t, open, "modules/sensors", "5e450125aa") said, err := assign(ctx, open, "laptop", "sensors") if err != nil { diff --git a/cmd/mesh-controller/same_commit_test.go b/cmd/mesh-controller/same_commit_test.go new file mode 100644 index 00000000..2e33b719 --- /dev/null +++ b/cmd/mesh-controller/same_commit_test.go @@ -0,0 +1,17 @@ +package main + +import "testing" + +// A held build's commit as recorded and as registered name one commit however each is abbreviated, a short name +// included (the fault the try of R4e's controller found: "c0" was never the same as "c0"). +func TestACommitIsTheSameAsItselfHoweverShort(t *testing.T) { + for _, c := range []struct { + a, b string + same bool + }{{"c0", "c0", true}, {"c0ffee0123456789", "c0ffee0", true}, {"c0ffee0123", "c0ffee0999", false}, {"", "", false}, + {"c0", "c1", false}} { + if got := sameCommitID(c.a, c.b); got != c.same { + t.Errorf("%q %q: %v", c.a, c.b, got) + } + } +}