Assigner: a build record is the builder's builds package's and a grant the grants part's grantsstate package's (ADR 0634 §5; issue 1966)

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-05 15:52:46 +01:00
parent a3e53e6f78
commit 7ff785978e
11 changed files with 76 additions and 61 deletions
@@ -10,6 +10,8 @@ import (
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
"io"
"maps"
"mesh-delivery-assigner/internal/buckets"
@@ -104,8 +106,8 @@ func startBed(t *testing.T, leaveOut string) *bed {
b.buckets[name] = kv
}
// The builder's module log, as the runtime raises it (ADR 0297): the running commits are read from it (ADR 0571 clause 1).
if _, err := js.CreateStream(ctx, jetstream.StreamConfig{Name: buscompose.LogStreamName(delivery.BuilderModule, delivery.BuilderLog),
Subjects: []string{buscompose.LogSubject(delivery.BuilderModule, delivery.BuilderLog) + ".>"}, AllowDirect: true}); err != nil {
if _, err := js.CreateStream(ctx, jetstream.StreamConfig{Name: buscompose.LogStreamName(builds.BuilderModule, builds.BuilderLog),
Subjects: []string{buscompose.LogSubject(builds.BuilderModule, builds.BuilderLog) + ".>"}, AllowDirect: true}); err != nil {
t.Fatal(err)
}
if _, err := js.CreateStream(ctx, jetstream.StreamConfig{Name: "EVENTS", Subjects: []string{"mesh.mod.*.event.>", "mesh.seat.*.event.>"}}); err != nil {
@@ -389,15 +391,15 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) {
digest := b.manifest(t, "web", `{"module":"web","version":"1"}`)
mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fNew, Manifest: digest, Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath})
b.putJSON(t, buckets.Modules, "web", mod)
built, err := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: digest})
built, err := builds.EncodeBuilderBuild(builds.BuilderBuild{State: builds.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: digest})
if err != nil {
t.Fatal(err)
}
bkey, _ := delivery.BuilderBuildKey("web", fNew)
bkey, _ := builds.BuilderBuildKey("web", fNew)
b.putJSON(t, buckets.Builds, bkey, built)
for _, fp := range []string{fNew, fOld} {
gkey, _ := delivery.PartGrantKey("web", fp)
grant, _ := delivery.EncodeGrant(delivery.Grant{})
gkey, _ := grantsstate.PartGrantKey("web", fp)
grant, _ := grantsstate.EncodeGrant(grantsstate.Grant{})
b.putJSON(t, buckets.Grants, gkey, grant)
}
runs := map[string]string{"ace": fOld, "g14": "build-9", "shanks": fOld}
@@ -540,11 +542,11 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) {
fps = append(fps, toolOld)
}
for _, fp := range fps {
built, _ := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: row.digest})
bkey, _ := delivery.BuilderBuildKey(module, fp)
built, _ := builds.EncodeBuilderBuild(builds.BuilderBuild{State: builds.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: row.digest})
bkey, _ := builds.BuilderBuildKey(module, fp)
b.putJSON(t, buckets.Builds, bkey, built)
gkey, _ := delivery.PartGrantKey(module, fp)
grant, _ := delivery.EncodeGrant(delivery.Grant{})
gkey, _ := grantsstate.PartGrantKey(module, fp)
grant, _ := grantsstate.EncodeGrant(grantsstate.Grant{})
b.putJSON(t, buckets.Grants, gkey, grant)
}
b.place(t, "ace", module)
@@ -596,18 +598,18 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) {
b.putJSON(t, buckets.Modules, "forms", mod)
}
for _, fp := range []string{formsOld, formsNew} {
build := delivery.BuilderBuild{State: delivery.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: formsDigest}
build := builds.BuilderBuild{State: builds.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: formsDigest}
if fp == formsNew {
build.Needs = []string{"form:new"}
}
built, err := delivery.EncodeBuilderBuild(build)
built, err := builds.EncodeBuilderBuild(build)
if err != nil {
t.Fatal(err)
}
bkey, _ := delivery.BuilderBuildKey("forms", fp)
bkey, _ := builds.BuilderBuildKey("forms", fp)
b.putJSON(t, buckets.Builds, bkey, built)
gkey, _ := delivery.PartGrantKey("forms", fp)
grant, _ := delivery.EncodeGrant(delivery.Grant{})
gkey, _ := grantsstate.PartGrantKey("forms", fp)
grant, _ := grantsstate.EncodeGrant(grantsstate.Grant{})
b.putJSON(t, buckets.Grants, gkey, grant)
}
runsFormsOld, _ := nodeengineclient.EncodeHave(nodeengine.HaveByNodeModuleValue{Fp: formsOld, Phase: nodeengineclient.PhaseRunning, Health: nodeengineclient.HealthOK})
@@ -793,14 +795,14 @@ func TestTheAssignerReplacedResumesWithNothingLostOrRepeated(t *testing.T) {
digest := b.manifest(t, name, fmt.Sprintf(`{"module":%q,"version":"1"}`, name))
mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fp, Manifest: digest, Repository: "novox/" + name, Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath})
b.putJSON(t, buckets.Modules, name, mod)
built, err := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: digest})
built, err := builds.EncodeBuilderBuild(builds.BuilderBuild{State: builds.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: digest})
if err != nil {
t.Fatal(err)
}
bkey, _ := delivery.BuilderBuildKey(name, fp)
bkey, _ := builds.BuilderBuildKey(name, fp)
b.putJSON(t, buckets.Builds, bkey, built)
gkey, _ := delivery.PartGrantKey(name, fp)
grant, _ := delivery.EncodeGrant(delivery.Grant{})
gkey, _ := grantsstate.PartGrantKey(name, fp)
grant, _ := grantsstate.EncodeGrant(grantsstate.Grant{})
b.putJSON(t, buckets.Grants, gkey, grant)
b.compose(t, "ace", 'c')
b.place(t, "ace", name)
@@ -839,11 +841,11 @@ func (b *bed) fixture(t *testing.T, name, fp, manifest string) {
digest := b.manifest(t, name, manifest)
mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fp, Manifest: digest, Repository: "novox/" + name, Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath})
b.putJSON(t, buckets.Modules, name, mod)
built, _ := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: digest})
bkey, _ := delivery.BuilderBuildKey(name, fp)
built, _ := builds.EncodeBuilderBuild(builds.BuilderBuild{State: builds.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: digest})
bkey, _ := builds.BuilderBuildKey(name, fp)
b.putJSON(t, buckets.Builds, bkey, built)
gkey, _ := delivery.PartGrantKey(name, fp)
grant, _ := delivery.EncodeGrant(delivery.Grant{})
gkey, _ := grantsstate.PartGrantKey(name, fp)
grant, _ := grantsstate.EncodeGrant(grantsstate.Grant{})
b.putJSON(t, buckets.Grants, gkey, grant)
on, _ := delivery.EncodePresence(delivery.Presence{Online: true})
b.putJSON(t, buckets.Presence, "ace", on)
@@ -7,6 +7,7 @@ import (
"errors"
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
"maps"
"mesh-delivery-assigner/internal/buckets"
"slices"
@@ -209,7 +210,7 @@ func (p *passer) wants(ctx context.Context) {
return p.w.composed(node, name, fp) // a placed node's own: the digest its own have names (ADR 0571 §6)
},
GrantedAt: func(fp string) bool {
key, err := delivery.PartGrantKey(name, fp)
key, err := grantsstate.PartGrantKey(name, fp)
return err == nil && p.w.has(grants, key)
},
Restored: func(node string) bool {
@@ -223,13 +224,13 @@ func (p *passer) wants(ctx context.Context) {
Release: func(fp string) (string, bool) { return p.w.release(name, fp) }}
if fp != "" {
held, _ := delivery.HeldKey(name, fp)
grant, _ := delivery.PartGrantKey(name, fp)
grant, _ := grantsstate.PartGrantKey(name, fp)
hold, _ := delivery.HoldAskKey(name, fp)
m.Released = p.answeredWith(hold, "release")
m.Kept = p.answeredWith(hold, "keep")
m.Built, m.Held, m.Granted = p.w.built(name, fp), p.w.has(buckets.Wants, held) && !m.Released, p.w.has(grants, grant)
if raw := p.w.value(grants, grant); raw != nil {
if g, err := delivery.DecodeGrant(raw); err == nil {
if g, err := grantsstate.DecodeGrant(raw); err == nil {
m.GrantedOn = func(node string) bool { return assign.GrantNamesNode(g, node, name) }
}
}
@@ -9,6 +9,8 @@ import (
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
"mesh-delivery-assigner/internal/buckets"
"slices"
"strings"
@@ -345,18 +347,18 @@ func putOfTheBus(t *testing.T) {
mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fp, Manifest: mdigest, Repository: "novox/mesh-catalog", Commit: strings.Repeat("c", 40)})
world(buckets.Modules, "nats", mod)
p.w.manifests[mdigest] = parsed{module: "nats", manifest: catalogue.Manifest{Module: "nats", Provides: []catalogue.Offer{{Name: "mesh-bus"}}}}
bkey, _ := delivery.BuilderBuildKey("nats", fp)
built, _ := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, Manifest: mdigest})
bkey, _ := builds.BuilderBuildKey("nats", fp)
built, _ := builds.EncodeBuilderBuild(builds.BuilderBuild{State: builds.BuildDone, Manifest: mdigest})
world(buckets.Builds, bkey, built)
hkey, _ := nodeengineclient.HaveKey("novox", "nats")
before, _ := nodeengineclient.EncodeHave(nodeengine.HaveByNodeModuleValue{Fp: meshcatalogclient.SourcePrefix2 + strings.Repeat("a", 64), Phase: nodeengineclient.PhaseRunning, Health: nodeengineclient.HealthOK})
world(buckets.Have, hkey, before)
builds := mem()
builds.values[bkey] = built
buildKV := mem()
buildKV.values[bkey] = built
modules := mem()
modules.values["nats"] = mod
s := newPutTools(memStore{putsState: puts, delivery.BuilderModule + ".builds": builds, delivery.IndexerModule + ".modules": modules})
s := newPutTools(memStore{putsState: puts, builds.BuilderModule + ".builds": buildKV, delivery.IndexerModule + ".modules": modules})
s.now = func() time.Time { return now }
was := answerWithin
answerWithin = 0
@@ -397,8 +399,8 @@ func putOfTheBus(t *testing.T) {
default:
}
composes(t, p.w, "novox", digest)
gkey, _ := delivery.PartGrantKey("nats", fp)
g, _ := delivery.EncodeGrant(delivery.Grant{})
gkey, _ := grantsstate.PartGrantKey("nats", fp)
g, _ := grantsstate.EncodeGrant(grantsstate.Grant{})
world(buckets.Grants, gkey, g)
got := step()
akey, _ := delivery.RecordAskKey("novox", "nats", digest)
@@ -909,7 +911,7 @@ func aReleasesApproveAnswersTheMoveOfItsBuildAlone(t *testing.T) {
alone bool
at string // the fingerprint the have runs
mergedAt string // the commit the release merged web at; "" for no merge of the release
fpSrc int64 // the source revision at which web's fingerprint last changed
fpSrc int64 // the source revision at which web's fingerprint last changed
yes, asked bool
}{
{"the build alone, its release approved", true, fpOld, commit, 7, true, false},
@@ -1137,8 +1139,8 @@ func aWantWaitsOnTheVerbEdgesTheGraphKeeps(t *testing.T) {
}
return nil, errNotThere
}
build, _ := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, Manifest: digest})
key, _ := delivery.BuilderBuildKey("server", fp("f"))
build, _ := builds.EncodeBuilderBuild(builds.BuilderBuild{State: builds.BuildDone, Manifest: digest})
key, _ := builds.BuilderBuildKey("server", fp("f"))
p.w.put(buckets.Builds, key, build)
running := nodeengine.HaveByNodeModuleValue{Phase: nodeengineclient.PhaseRunning, Health: nodeengineclient.HealthOK}
at := func(f string) nodeengine.HaveByNodeModuleValue { h := running; h.Fp = f; return h }
@@ -6,6 +6,8 @@ import (
"errors"
"fmt"
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
"mesh-delivery-assigner/internal/buckets"
"sort"
"strings"
@@ -176,9 +178,9 @@ func (p *passer) putWorld(node, module string, put delivery.Put, manifest catalo
w.Assigned = true
}
}
if bkey, err := delivery.BuilderBuildKey(module, put.FP); err == nil {
if bkey, err := builds.BuilderBuildKey(module, put.FP); err == nil {
if raw := p.w.value(buckets.Builds, bkey); raw != nil {
if b, err := delivery.DecodeBuilderBuild(raw); err == nil {
if b, err := builds.DecodeBuilderBuild(raw); err == nil {
w.Build, w.BuildWords = b.State, b.Error
} else {
w.Build = "unreadable: " + err.Error()
@@ -229,9 +231,9 @@ func (p *passer) composedFor(node, module, fp string) (*assign.ComposedDigest, b
out = &d
}
granted := false
if gkey, err := delivery.PartGrantKey(module, fp); err == nil {
if gkey, err := grantsstate.PartGrantKey(module, fp); err == nil {
if raw := p.w.value(p.w.grantsBucket(), gkey); raw != nil {
if g, err := delivery.DecodeGrant(raw); err == nil {
if g, err := grantsstate.DecodeGrant(raw); err == nil {
granted = g.NamesNode(node, module)
}
}
@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"os"
"regexp"
"slices"
@@ -94,13 +95,13 @@ func (s *putTools) version(module, version string) (string, error) {
return v, nil
case prefix.MatchString(v):
start := strings.TrimPrefix(v, meshcatalogclient.SourcePrefix2)
keys, err := s.st.keys(delivery.BuilderModule + ".builds")
keys, err := s.st.keys(builds.BuilderModule + ".builds")
if err != nil {
return "", fmt.Errorf("the builder's builds cannot be listed: %w", err)
}
var found []string
for _, k := range keys {
m, fp, err := delivery.ParseBuilderBuildKey(k)
m, fp, err := builds.ParseBuilderBuildKey(k)
if err == nil && m == module && strings.HasPrefix(strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2), start) {
found = append(found, fp)
}
@@ -4,6 +4,7 @@ import (
"context"
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"mesh-delivery-assigner/internal/buckets"
"slices"
@@ -111,7 +112,7 @@ func (p *passer) servesOf(ctx context.Context, get getter, module, fp string) ([
// manifestOf is the manifest of module's build at fp (the builder's build names its digest in the indexer's manifests),
// and whether it could be read.
func (p *passer) manifestOf(ctx context.Context, get getter, module, fp string) (catalogue.Manifest, bool) {
key, err := delivery.BuilderBuildKey(module, fp)
key, err := builds.BuilderBuildKey(module, fp)
if err != nil {
return catalogue.Manifest{}, false
}
@@ -119,7 +120,7 @@ func (p *passer) manifestOf(ctx context.Context, get getter, module, fp string)
if raw == nil {
return catalogue.Manifest{}, false
}
b, err := delivery.DecodeBuilderBuild(raw)
b, err := builds.DecodeBuilderBuild(raw)
if err != nil || b.Manifest == "" {
return catalogue.Manifest{}, false
}
@@ -7,6 +7,7 @@ import (
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-sdk/go/keys"
"maps"
"mesh-delivery-assigner/internal/buckets"
@@ -43,7 +44,7 @@ type world struct {
// meta is, by bucket and key, the revision and the time of the value held now, where the watch said them (putEntry).
meta map[string]entryMeta
// trunkBuilt is, by module, its newest done trunk build in the builder's log (putBuilt).
trunkBuilt map[string]delivery.BuildLogEntry
trunkBuilt map[string]builds.BuildLogEntry
// placement is the seat's state placement assembled node by node from its keys in either form (mesh-sdk
// mmac.Keys; research 072 row 37): the one reader of its keys in the assigner.
placement *mmac.Keys
@@ -67,7 +68,7 @@ type parsed struct {
func newWorld() *world {
return &world{values: map[string]map[string][]byte{}, manifests: map[string]parsed{}, healthy: map[string][]string{}, changes: map[string]uint64{},
meta: map[string]entryMeta{}, trunkBuilt: map[string]delivery.BuildLogEntry{}, placement: mmac.NewKeys(),
meta: map[string]entryMeta{}, trunkBuilt: map[string]builds.BuildLogEntry{}, placement: mmac.NewKeys(),
sourceGroups: map[uint64]string{}}
}
@@ -429,7 +430,7 @@ func (w *world) has(bucket, key string) bool {
// built says whether the builder's build of a module at a fingerprint is done.
func (w *world) built(module, fp string) bool {
key, err := delivery.BuilderBuildKey(module, fp)
key, err := builds.BuilderBuildKey(module, fp)
if err != nil {
return false
}
@@ -439,19 +440,19 @@ func (w *world) built(module, fp string) bool {
if !ok {
return false
}
b, err := delivery.DecodeBuilderBuild(value)
return err == nil && b.State == delivery.BuildDone
b, err := builds.DecodeBuilderBuild(value)
return err == nil && b.State == builds.BuildDone
}
// buildNeeds are the reference forms the builder's done build of module at fp is written in (the build key's needs, ADR
// 0618 §1): nil when it is not done or names none.
func (w *world) buildNeeds(module, fp string) []string {
key, err := delivery.BuilderBuildKey(module, fp)
key, err := builds.BuilderBuildKey(module, fp)
if err != nil {
return nil
}
b, err := delivery.DecodeBuilderBuild(w.value(buckets.Builds, key))
if err != nil || b.State != delivery.BuildDone {
b, err := builds.DecodeBuilderBuild(w.value(buckets.Builds, key))
if err != nil || b.State != builds.BuildDone {
return nil
}
return b.Needs
@@ -4,6 +4,7 @@ import (
"context"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
"mesh-delivery-assigner/internal/buckets"
"slices"
"strings"
@@ -59,8 +60,8 @@ func theWorldCountsTheValuesAKeyTakes(t *testing.T) {
}
// ADR 0571 clause 9: grants are read from the grants part's bucket, the one bucket of grants (ADR 0590).
fp := meshcatalogclient.SourcePrefix2 + strings.Repeat("d", 64)
gkey, _ := delivery.PartGrantKey("web", fp)
grant, _ := delivery.EncodeGrant(delivery.Grant{Accounts: []string{"ace.web"}})
gkey, _ := grantsstate.PartGrantKey("web", fp)
grant, _ := grantsstate.EncodeGrant(grantsstate.Grant{Accounts: []string{"ace.web"}})
for _, row := range []struct {
name string
inPart bool
@@ -4,6 +4,7 @@ import (
"fmt"
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"time"
occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient"
@@ -74,8 +75,8 @@ func StepPut(w PutWorld) PutNext {
return say(delivery.PutRefused, "%s is not assigned to %s: a put moves a module where it stands assigned (propose its placement first)", w.Module, w.Node)
}
switch w.Build {
case delivery.BuildDone:
case delivery.BuildFailed:
case builds.BuildDone:
case builds.BuildFailed:
return say(delivery.PutRefused, "the builder's build of %s at %s failed: %s", w.Module, fp, w.BuildWords)
case "":
if p.FP != w.Newest {
@@ -5,6 +5,7 @@ import (
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
"maps"
"slices"
"sort"
@@ -793,6 +794,6 @@ func (m Module) userListRevision(node string, before delivery.Want, had bool, n
// GrantNamesNode says whether a grant of module names its accounts on node (mesh-sdk's Grant.NamesNode, which a
// put reads by too).
func GrantNamesNode(g delivery.Grant, node, module string) bool {
func GrantNamesNode(g grantsstate.Grant, node, module string) bool {
return g.NamesNode(node, module)
}
@@ -4,6 +4,8 @@ import (
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
"slices"
"strings"
"testing"
@@ -433,7 +435,7 @@ func TestEachRuleHoldsTheWantBack(t *testing.T) {
// Rule 6 per node: a grant written for the module's other nodes does not grant a node whose account it does not name
// (issue 1945, live on 2026-10-25 at 20:04: ace's mesh-build-go was wanted with no account on the bus).
m, n := ready()
grant := delivery.Grant{Accounts: []string{"ace.mail", "ace.mail.send"}}
grant := grantsstate.Grant{Accounts: []string{"ace.mail", "ace.mail.send"}}
m.GrantedOn = func(node string) bool { return GrantNamesNode(grant, node, "mail") }
out := Wants(m, n, wantedOld(), nil)
if w := out.Wants["ace"]; w.FP != fNew {
@@ -452,7 +454,7 @@ func TestEachRuleHoldsTheWantBack(t *testing.T) {
{[]string{"g14.mailer"}, "g14", "mail", false},
{[]string{"ace.mail"}, "g14", "mail", false},
} {
if got := GrantNamesNode(delivery.Grant{Accounts: c.accounts}, c.node, c.module); got != c.named {
if got := GrantNamesNode(grantsstate.Grant{Accounts: c.accounts}, c.node, c.module); got != c.named {
t.Errorf("%v names %s of %s: %v, want %v", c.accounts, c.module, c.node, got, c.named)
}
}
@@ -850,7 +852,7 @@ func stepsOfAPut(t *testing.T) {
d := ComposedDigest{Digest: dig(fNew), Judgement: JudgedCannot, Words: "the have names no composition"}
running := nodeengine.HaveByNodeModuleValue{Fp: fOld, Phase: nodeengineclient.PhaseRunning, Health: nodeengineclient.HealthOK}
bus := func() PutWorld {
return PutWorld{Node: "novox", Module: "nats", Put: base, Assigned: true, Bus: true, Build: delivery.BuildDone, Newest: fNew,
return PutWorld{Node: "novox", Module: "nats", Put: base, Assigned: true, Bus: true, Build: builds.BuildDone, Newest: fNew,
Composed: &d, Granted: true, Have: &running, Now: now}
}
cases := []struct {
@@ -864,7 +866,7 @@ func stepsOfAPut(t *testing.T) {
{"not assigned", func() PutWorld { w := bus(); w.Assigned = false; return w }, delivery.PutRefused, "not assigned", false, false, false},
{"no build yet of the newest", func() PutWorld { w := bus(); w.Build = ""; return w }, delivery.PutBuild, "builds by itself", false, false, false},
{"no build of an older one", func() PutWorld { w := bus(); w.Build, w.Newest = "", fpOf('c'); return w }, delivery.PutRefused, "holds no build", false, false, false},
{"a failed build", func() PutWorld { w := bus(); w.Build, w.BuildWords = delivery.BuildFailed, "go vet"; return w }, delivery.PutRefused, "go vet", false, false, false},
{"a failed build", func() PutWorld { w := bus(); w.Build, w.BuildWords = builds.BuildFailed, "go vet"; return w }, delivery.PutRefused, "go vet", false, false, false},
{"no composition yet: waits", func() PutWorld { w := bus(); w.Composed = nil; return w }, delivery.PutCompose, "no composition of nats for novox", false, false, false},
{"composed, grant not naming the node", func() PutWorld { w := bus(); w.Granted = false; return w }, delivery.PutCompose, "does not name novox", false, false, false},
{"none within the bound: refused", func() PutWorld {