From 67964cae3fc1ad09e7741eb56e1fab76e1d5c552 Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 18 Oct 2026 19:36:03 +0200 Subject: [PATCH] Show a pulled-in module as running with what pulled it in (issue 1134, AC3 revised) --- .../mesh-delivery-view/internal/view/view.go | 28 +++++++++++-------- .../internal/view/view_test.go | 13 ++++++++- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/modules/mesh-delivery-view/internal/view/view.go b/modules/mesh-delivery-view/internal/view/view.go index be6ad54..945fd36 100644 --- a/modules/mesh-delivery-view/internal/view/view.go +++ b/modules/mesh-delivery-view/internal/view/view.go @@ -32,7 +32,9 @@ type Row struct { Since time.Time `json:"since,omitzero"` Detail string `json:"detail,omitempty"` Waits string `json:"waits,omitempty"` - Error string `json:"error,omitempty"` + // RequiredBy is what pulled the module onto the node, for an assignment that is pulled in. + RequiredBy string `json:"required-by,omitempty"` + Error string `json:"error,omitempty"` } // NodeRow is a node's own facts as counts. @@ -63,19 +65,20 @@ type Model struct { // assignment holds only the fields of the controller's Assignment the view reads. type assignment struct { - Node string `json:"node"` - Module string `json:"module"` - Build string `json:"build"` - Commit string `json:"commit"` - Since time.Time `json:"since"` - Ended time.Time `json:"ended"` - State string `json:"state"` - PulledIn bool `json:"pulled-in"` + Node string `json:"node"` + Module string `json:"module"` + Build string `json:"build"` + Commit string `json:"commit"` + Since time.Time `json:"since"` + Ended time.Time `json:"ended"` + State string `json:"state"` + PulledIn bool `json:"pulled-in"` + RequiredBy string `json:"required-by"` } // open says whether the value is an assignment that stands for the module on its node, as the controller's -// Assignment.Stands does, and is not a module pulled in by another. -func (a assignment) open() bool { return a.Ended.IsZero() && a.State == "" && !a.PulledIn } +// Assignment.Stands does. A module pulled in by another stands too. +func (a assignment) open() bool { return a.Ended.IsZero() && a.State == "" } // build holds only the fields of the controller's Build record the view reads. A record with no state and no failure // is a done build. @@ -187,6 +190,9 @@ func (m *Model) Snapshot() Snapshot { continue } r := Row{Node: a.Node, Module: a.Module, Status: StatusAssigned, Assigned: a.Build} + if a.PulledIn { + r.RequiredBy = a.RequiredBy + } var waits []string h, has := m.haves[key] switch { diff --git a/modules/mesh-delivery-view/internal/view/view_test.go b/modules/mesh-delivery-view/internal/view/view_test.go index 9ebe1e3..29f3a63 100644 --- a/modules/mesh-delivery-view/internal/view/view_test.go +++ b/modules/mesh-delivery-view/internal/view/view_test.go @@ -111,7 +111,7 @@ func TestWaitsForTheNodeAndForANewerBuild(t *testing.T) { // 1134/AC2 } func TestLeftBehindIsNotRunning(t *testing.T) { // 1134/AC3 - for name, extra := range map[string]string{"ended": `,"ended":"2026-10-18T11:30:00Z"`, "state": `,"state":"pending"`, "pulled-in": `,"pulled-in":true`} { + for name, extra := range map[string]string{"ended": `,"ended":"2026-10-18T11:30:00Z"`, "state": `,"state":"pending"`} { m := New() fill(m, base(t)...) fill(m, assign("b", "z", "b3", extra)) @@ -133,6 +133,17 @@ func TestLeftBehindIsNotRunning(t *testing.T) { // 1134/AC3 } } +func TestPulledInIsRunning(t *testing.T) { // 1134/AC3 + m := New() + fill(m, base(t)...) + fill(m, assign("b", "z", "b3", `,"pulled-in":true,"required-by":"x"`)) + s := m.Snapshot() + r := find(t, s, "b", "z") + if r.Status != StatusAssigned || r.RequiredBy != "x" || r.Have != "b3" || s.Counted() != 4 { + t.Fatalf("pulled-in row = %+v counted %d, want shown and counted with required-by x", r, s.Counted()) + } +} + func TestUnknownVersionSaysSo(t *testing.T) { // 1134/AC4 m := New() fill(m, base(t)...)