Grants read the have's build for memberships and holdings, and a failed read of it holds the pass back (issue 1966, review round 1)
Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
This commit is contained in:
@@ -4042,3 +4042,52 @@ func TestMembershipKeepsWhatTheRunningBuildReads(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// A pass reads each machine's have for the build it runs (issue 1966): its membership keeps what that older build reads, a
|
||||
// have or build that cannot be read holds the pass back, and the seats held are the ones that build claims (ADR 0660 §2).
|
||||
func TestPassComposesMembershipFromTheHaveBuild(t *testing.T) {
|
||||
const old = `{"module":"mod-y","version":"1","own-secrets":{"broker":"/var/lib/y/broker"},"reads":["mod-x.kept","mod-x.old"]}`
|
||||
runs := func(b *fakeBus) {
|
||||
b.manifestOf("mod-y", yManifest)
|
||||
digest := meshcatalogclient.ManifestDigest([]byte(old))
|
||||
b.put(grants.ReadManifests, digest, meshcatalog.ManifestsByDigestValue{V: keys.Version, Module: "mod-y", Manifest: old})
|
||||
fp := "src2:" + strings.Repeat("cd", 32)
|
||||
b.put(grants.ReadHave, "b.mod-y", nodeengine.HaveByNodeModuleValue{V: keys.Version, Phase: nodeengineclient.PhaseRunning, Health: nodeengineclient.HealthOK, Fp: fp})
|
||||
key, _ := builds.BuilderBuildKey("mod-y", fp)
|
||||
b.put(grants.ReadBuilds, key, map[string]any{"v": keys.Version, "state": "done", "manifest": digest})
|
||||
}
|
||||
t.Run("the published membership keeps a read of the build the have names", func(t *testing.T) {
|
||||
b := fixture()
|
||||
runs(b)
|
||||
partOn(b).Pass()
|
||||
if got := string(b.own[grants.StateMemberships]["b.mod-y"]); !strings.Contains(got, "mod-x.old") || !strings.Contains(got, "mod-x.kept") {
|
||||
t.Errorf("b.mod-y's membership lacks the running build's read: %s", got)
|
||||
}
|
||||
})
|
||||
t.Run("a build that cannot be read is a failed read", func(t *testing.T) {
|
||||
b := fixture()
|
||||
runs(b)
|
||||
b.refused[grants.ReadBuilds] = true
|
||||
if f := grants.ReadInputs(b, &grants.Manifests{}).ReadFailed(); !strings.Contains(strings.Join(f, "\n"), grants.ReadBuilds) {
|
||||
t.Errorf("a build read refused is not a failed read: %v", f)
|
||||
}
|
||||
})
|
||||
t.Run("the seats held are the have build's claims, then the want's, then the trunk's", func(t *testing.T) {
|
||||
claims := catalogue.Manifest{Module: "m", Version: "1", Claims: []catalogue.Claim{{Name: "mesh-catalog", Scope: catalogue.ScopeMesh}}}
|
||||
bare := catalogue.Manifest{Module: "m", Version: "1"}
|
||||
for name, row := range map[string]struct {
|
||||
had, running map[string]catalogue.Manifest
|
||||
held bool
|
||||
}{
|
||||
"trunk alone": {nil, nil, false},
|
||||
"have claims": {map[string]catalogue.Manifest{"a.m": claims}, map[string]catalogue.Manifest{"a.m": bare}, true},
|
||||
"want claims": {nil, map[string]catalogue.Manifest{"a.m": claims}, true},
|
||||
"have is bare": {map[string]catalogue.Manifest{"a.m": bare}, map[string]catalogue.Manifest{"a.m": claims}, false},
|
||||
} {
|
||||
in := grants.Inputs{Nodes: []string{"a"}, Assigned: map[string][]string{"a": {"m"}}, Manifests: map[string]catalogue.Manifest{"m": bare}, Had: row.had, Running: row.running}
|
||||
if got := len(grants.HoldingsOf(in).Claimed) > 0; got != row.held {
|
||||
t.Errorf("%s: claimed %v, want %v", name, got, row.held)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -754,6 +754,9 @@ func runningByHaves(r Reader, in *Inputs, cache *Manifests, into map[string]cata
|
||||
for node, modules := range in.Assigned {
|
||||
for _, module := range modules {
|
||||
raw, found, err := r.Get(ReadHave, node+"."+module)
|
||||
if err != nil {
|
||||
in.Gaps = append(in.Gaps, Gap{Input: ReadHave + " " + node + "." + module, Why: "cannot be read, so the build it runs is unknown: " + err.Error(), Failed: true})
|
||||
}
|
||||
if err != nil || !found {
|
||||
fromTrunk = append(fromTrunk, node+"."+module)
|
||||
continue
|
||||
@@ -769,6 +772,9 @@ func runningByHaves(r Reader, in *Inputs, cache *Manifests, into map[string]cata
|
||||
continue
|
||||
}
|
||||
braw, found, err := r.Get(ReadBuilds, bk)
|
||||
if err != nil {
|
||||
in.Gaps = append(in.Gaps, Gap{Input: ReadBuilds + " " + bk, Why: "cannot be read, so the manifest of the build " + node + "." + module + " runs is unknown: " + err.Error(), Failed: true})
|
||||
}
|
||||
if err != nil || !found {
|
||||
fromTrunk = append(fromTrunk, node+"."+module)
|
||||
continue
|
||||
|
||||
@@ -206,7 +206,10 @@ func HoldingsOf(in Inputs) Holdings {
|
||||
}
|
||||
for node, modules := range in.Assigned {
|
||||
for _, module := range modules {
|
||||
m, ok := in.Running[node+"."+module]
|
||||
m, ok := in.Had[node+"."+module]
|
||||
if !ok {
|
||||
m, ok = in.Running[node+"."+module]
|
||||
}
|
||||
if !ok {
|
||||
m, ok = in.Manifests[module]
|
||||
}
|
||||
|
||||
@@ -448,7 +448,10 @@ func holdersAfterPass(in Inputs) ([]catalogue.Held, []Gap) {
|
||||
var assignments []catalogue.Assignment
|
||||
for _, node := range slices.Sorted(maps.Keys(in.Assigned)) {
|
||||
for _, module := range in.Assigned[node] {
|
||||
m, ok := in.Running[node+"."+module]
|
||||
m, ok := in.Had[node+"."+module]
|
||||
if !ok {
|
||||
m, ok = in.Running[node+"."+module]
|
||||
}
|
||||
if !ok {
|
||||
m, ok = in.Manifests[module]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user