diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go index 1ab80af8..74678cc6 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go @@ -10,11 +10,13 @@ import ( "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + mdcc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliverycheckerclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" "git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate" + "git.novox.be/novox/mesh-delivery/sdk/buildstep" "io" "maps" "mesh-delivery-assigner/internal/buckets" @@ -39,7 +41,6 @@ import ( "git.novox.be/novox/mesh-sdk/go/announce" "git.novox.be/novox/mesh-sdk/go/buscompose" "git.novox.be/novox/mesh-sdk/go/catalogue" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/process" "git.novox.be/novox/mesh-sdk/go/provisions" @@ -121,7 +122,7 @@ func startBed(t *testing.T, leaveOut string) *bed { // event names the engine's machine last, so the filter is the event with every machine (mesh-grants buscompose // machineEvent; the grants part's own test holds the derivation). if _, err := js.CreateOrUpdateConsumer(ctx, "EVENTS", jetstream.ConsumerConfig{Durable: "n1_mesh-delivery-assigner", - FilterSubjects: []string{enginereads.SubjectPrefix + "*", "mesh.mod." + delivery.IndexerModule + ".event.views.>"}, AckPolicy: jetstream.AckExplicitPolicy}); err != nil { + FilterSubjects: []string{enginereads.SubjectPrefix + "*", "mesh.mod." + meshcatalogclient.Module + ".event.views.>"}, AckPolicy: jetstream.AckExplicitPolicy}); err != nil { t.Fatal(err) } // The operator-channel seat's stream of conditions, which the assigner says its conditions on. @@ -137,7 +138,7 @@ func startBed(t *testing.T, leaveOut string) *bed { b.buckets[marksBucket] = kv } // The Go build seat's work queue, as the broker derives it from the seat's accepted kinds (delivery.AskStream). - seat, _ := delivery.AskStream(delivery.AskGo) + seat, _ := buildstep.AskStream(buildstep.AskGo) if _, err := js.CreateStream(ctx, jetstream.StreamConfig{Name: seat, Subjects: []string{"mesh.seat.node-build-go.accept.>"}, Retention: jetstream.WorkQueuePolicy}); err != nil { t.Fatal(err) @@ -386,7 +387,7 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) { firstViewBound, firstViewWait = 300*time.Millisecond, 50*time.Millisecond t.Cleanup(func() { indexerLate, firstViewBound, firstViewWait = nil, 0, 0 }) for _, name := range append(append([]string{}, readBuckets...), watched...) { - if strings.HasPrefix(name, delivery.IndexerModule+"_") { + if strings.HasPrefix(name, meshcatalogclient.Module+"_") { t.Errorf("the assigner reads the indexer's state %s itself", name) } } @@ -426,10 +427,10 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) { "seat-holders": {"n1.node-tools"}, "wants": {"n1.mesh-grants"}, }) - graphKey := meshconditionsclient.Key(meshconditionsclient.ScopeModule, delivery.AssignerModule+"."+delivery.IndexerModule+"."+graph.State, views.UnansweredKind) + graphKey := meshconditionsclient.Key(meshconditionsclient.ScopeModule, mmac.Module+"."+meshcatalogclient.Module+"."+graph.State, views.UnansweredKind) graphRaised := func() bool { e, err := b.buckets[assign.FindingsBucket].Get(b.ctx, graphKey) - return err == nil && strings.Contains(string(e.Value()), delivery.IndexerModule+".graph") + return err == nil && strings.Contains(string(e.Value()), meshcatalogclient.Module+".graph") } for deadline := time.Now().Add(10 * time.Second); !graphRaised(); time.Sleep(50 * time.Millisecond) { if time.Now().After(deadline) { @@ -898,7 +899,7 @@ func (b *bed) answer(t *testing.T, key, option string) { // answerTo is answer to the ask with this id (the router's warrant names it). func (b *bed) answerTo(t *testing.T, key, option, askID string) { t.Helper() - v, err := delivery.EncodeAnswer(delivery.Answer{Option: option, Warrant: askID + "@2026-10-24T12:00:00Z", Words: "the operator"}) + v, err := meshdeliveryclient.EncodeAnswer(meshdeliveryclient.Answer{Option: option, Warrant: askID + "@2026-10-24T12:00:00Z", Words: "the operator"}) if err != nil { t.Fatal(err) } @@ -1091,7 +1092,7 @@ func (s bedStore) kv(state string) jetstream.KeyValue { if strings.Contains(state, ".") { return s.b.buckets[strings.Replace(state, ".", "_", 1)] } - return s.b.buckets[delivery.AssignerModule+"_"+state] + return s.b.buckets[mmac.Module+"_"+state] } func (s bedStore) get(state, key string) ([]byte, uint64, bool, error) { @@ -1126,7 +1127,7 @@ func (s bedStore) history(string, string) ([]stdio.StateRevision, error) { retur // and declined, writes nothing and is withdrawn. func TestAProposalIsAnsweredApprovedAndWritten(t *testing.T) { b := startBed(t, "") - if _, err := b.js.CreateStream(b.ctx, jetstream.StreamConfig{Name: "MOD_" + delivery.AssignerModule + "_placement", + if _, err := b.js.CreateStream(b.ctx, jetstream.StreamConfig{Name: "MOD_" + mmac.Module + "_placement", Subjects: placementSubjects()}); err != nil { // the seat's four events: the views family has a stream of its own t.Fatal(err) } @@ -1136,7 +1137,7 @@ func TestAProposalIsAnsweredApprovedAndWritten(t *testing.T) { t.Fatal(err) } t.Cleanup(nc.Close) - if _, err := nc.Subscribe(process.ModuleStreamSubject(delivery.AssignerModule, mma.EventPlacementChanged), func(m *nats.Msg) { + if _, err := nc.Subscribe(process.ModuleStreamSubject(mmac.Module, mma.EventPlacementChanged), func(m *nats.Msg) { var e mma.PlacementEvent if json.Unmarshal(m.Data, &e) == nil { heard <- e @@ -1310,7 +1311,7 @@ func TestAProposalIsAnsweredApprovedAndWritten(t *testing.T) { } silent := q.(proposed).Proposal decided := proposalNow(silent.ID, "decided without its silent nodes", func(p mma.Proposal) bool { return p.State == mmac.ProposalAsked }) - if decided.Verdict == nil || decided.Verdict.State != delivery.VerdictPass || + if decided.Verdict == nil || decided.Verdict.State != mdcc.VerdictPass || !strings.Contains(strings.Join(decided.Verdict.Notes, "; "), "no answer from") || !strings.Contains(strings.Join(decided.Verdict.Notes, "; "), "laptop (offline)") { t.Errorf("the silent node's verdict = %+v", decided.Verdict) } @@ -1378,8 +1379,8 @@ func (b *bed) viewsHold(t *testing.T, state, key string) { t.Fatal(err) } for deadline := time.Now().Add(20 * time.Second); ; time.Sleep(50 * time.Millisecond) { - f := &views.Follower{Owner: delivery.AssignerModule, Tool: state, State: state, Ask: func(context.Context, string) (views.Answer, error) { - return views.FirstView(delivery.AssignerModule, state, src(kv), src(marks), "", time.Now()) + f := &views.Follower{Owner: mmac.Module, Tool: state, State: state, Ask: func(context.Context, string) (views.Answer, error) { + return views.FirstView(mmac.Module, state, src(kv), src(marks), "", time.Now()) }} if err := f.Start(b.ctx); err != nil { t.Fatal(err) @@ -1388,7 +1389,7 @@ func (b *bed) viewsHold(t *testing.T, state, key string) { gap := false for seq := info.State.FirstSeq; seq > 0 && seq <= info.State.LastSeq; seq++ { m, err := st.GetMsg(b.ctx, seq) - if owner, _ := views.OwnerOfEvent(m.Subject); err != nil || owner != delivery.AssignerModule || views.StateOfEvent(m.Subject) != state { + if owner, _ := views.OwnerOfEvent(m.Subject); err != nil || owner != mmac.Module || views.StateOfEvent(m.Subject) != state { continue } e, err := views.DecodeEvent(m.Data) @@ -1446,7 +1447,7 @@ func (s bedSource) Get(key string) (*views.Entry, bool, error) { func placementSubjects() []string { var out []string for _, e := range mma.Events() { - out = append(out, process.ModuleStreamSubject(delivery.AssignerModule, e)) + out = append(out, process.ModuleStreamSubject(mmac.Module, e)) } return out } @@ -1460,11 +1461,11 @@ var indexerLate chan struct{} // read by the assigner's durable consumer; and its first-view tools of the three answered from the buckets at their marks. func serveIndexer(t *testing.T, b *bed, nc *nats.Conn) { t.Helper() - marks, err := b.js.CreateKeyValue(b.ctx, jetstream.KeyValueConfig{Bucket: delivery.IndexerModule + "_" + views.MarksState, History: 1}) + marks, err := b.js.CreateKeyValue(b.ctx, jetstream.KeyValueConfig{Bucket: meshcatalogclient.Module + "_" + views.MarksState, History: 1}) if err != nil { t.Fatal(err) } - em := views.Emitter{Owner: delivery.IndexerModule, Subject: process.Account{Node: "n1", Module: delivery.IndexerModule}.EventSubject, + em := views.Emitter{Owner: meshcatalogclient.Module, Subject: process.Account{Node: "n1", Module: meshcatalogclient.Module}.EventSubject, Publish: views.JetStreamPublish(b.js), Marks: marks} for state, bucket := range indexerFirstViews { kv, err := b.js.CreateKeyValue(b.ctx, jetstream.KeyValueConfig{Bucket: bucket, History: 5}) @@ -1489,7 +1490,7 @@ func serveIndexer(t *testing.T, b *bed, nc *nats.Conn) { After string `json:"after"` } _ = json.Unmarshal(m.Data, &args) - a, err := views.FirstView(delivery.IndexerModule, state, bedSource{b.ctx, kv}, bedSource{b.ctx, marks}, args.After, time.Now()) + a, err := views.FirstView(meshcatalogclient.Module, state, bedSource{b.ctx, kv}, bedSource{b.ctx, marks}, args.After, time.Now()) out := map[string]any{"result": a, "node": "n0"} if err != nil { out = map[string]any{"error": err.Error()} @@ -1549,7 +1550,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][] outR, outW := io.Pipe() t.Cleanup(func() { inW.Close(); outW.Close() }) go func() { - _ = stdio.ServeOn(delivery.AssignerModule, viewTools(func(k string) string { return env[k] }, state, time.Now), inR, outW) + _ = stdio.ServeOn(mmac.Module, viewTools(func(k string) string { return env[k] }, state, time.Now), inR, outW) }() answers := make(chan map[string]any, 16) go func() { @@ -1570,7 +1571,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][] t.Fatal(err) } t.Cleanup(nc.Close) - sub, err := nc.Subscribe("mesh.mod."+delivery.AssignerModule+".call.*.*", func(msg *nats.Msg) { + sub, err := nc.Subscribe("mesh.mod."+mmac.Module+".call.*.*", func(msg *nats.Msg) { one <- struct{}{} defer func() { <-one }() tokens := strings.Split(msg.Subject, ".") @@ -1602,7 +1603,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][] ask := func(user, tool string) (views.Answer, error) { return views.AskVia(func(key string, body any) (json.RawMessage, error) { data, _ := json.Marshal(body) - msg, err := nc.Request("mesh.mod."+delivery.AssignerModule+".call."+tool+"."+strings.ReplaceAll(user, ".", "~"), data, 5*time.Second) + msg, err := nc.Request("mesh.mod."+mmac.Module+".call."+tool+"."+strings.ReplaceAll(user, ".", "~"), data, 5*time.Second) if err != nil { return nil, err } @@ -1618,7 +1619,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][] t.Errorf("%s's first view of %s before any new-form state: %v", user, tool, err) case slices.Contains(allowed, user): keys, _ := b.buckets[viewedStates[tool]].Keys(b.ctx) - if a.Owner != delivery.AssignerModule || a.State != tool || len(a.Values) != len(keys) { + if a.Owner != mmac.Module || a.State != tool || len(a.Values) != len(keys) { t.Errorf("%s's first view of %s = %+v, the state holds %v", user, tool, a, keys) } case err == nil || !strings.Contains(err.Error(), "refused"): diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/main.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/main.go index 42d3725a..c1f7d5f3 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/main.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/main.go @@ -10,6 +10,7 @@ import ( "context" "errors" "fmt" + mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" "io" "log" "mesh-delivery-assigner/internal/buckets" @@ -26,7 +27,6 @@ import ( oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" "git.novox.be/novox/mesh-sdk/go/announce" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/process" "git.novox.be/novox/mesh-sdk/go/provisions" @@ -85,7 +85,7 @@ var ownBuckets = []string{buckets.Asks, buckets.Differences, const engineReadsState = "engine-reads" // engineReadsBucket is that state's bucket. -const engineReadsBucket = delivery.AssignerModule + "_" + engineReadsState +const engineReadsBucket = mmac.Module + "_" + engineReadsState // seatBuckets are the seat's states, new with it: until the controller has made them from the manifest and the bus grants // them, the assigner starts without them and binds each once the bus says it was created (issue 1790's kind). @@ -512,7 +512,7 @@ var PutsReopenEvery = time.Minute // (ADR 0437 clause 9). func sayVia(ctx context.Context, js jetstream.JetStream) func(oc.Condition) error { return func(c oc.Condition) error { - subject, err := occ.ConditionSubject(delivery.AssignerModule) + subject, err := occ.ConditionSubject(mmac.Module) if err != nil { return err } @@ -529,7 +529,7 @@ func sayVia(ctx context.Context, js jetstream.JetStream) func(oc.Condition) erro // consumer on EVENTS, and asks the node it names again; the hub also hands the indexer's views to the followers of // indexerViews, and starts once both are registered. func hearReadsChanged(ctx context.Context, js jetstream.JetStream, hub *process.EventHub, reads *enginereads.Keeper, findings assign.Findings, logf func(string, ...any)) { - account := process.Account{Node: thisNode, Module: delivery.AssignerModule} + account := process.Account{Node: thisNode, Module: mmac.Module} w := notHeardWriter(findings, logf) handle := func(m jetstream.Msg) { if err := m.Ack(); err != nil { diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass.go index 90437261..00840a56 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass.go @@ -10,6 +10,8 @@ import ( "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" "git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate" + "git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go/overlay" + "git.novox.be/novox/mesh-sdk/go/motion" "maps" "mesh-delivery-assigner/internal/buckets" "slices" @@ -18,7 +20,6 @@ import ( oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" "git.novox.be/novox/mesh-sdk/go/catalogue" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/provisions" "git.novox.be/novox/mesh-delivery/sdk/enginereads" @@ -1008,7 +1009,7 @@ func (p *passer) provisionFindings(failed map[string]provisions.Provision) { // MissingBound is how long a required provision may have no key before it is said: a module's delivery bound, the default // when its manifest names none (ADR 0564 clause 13 (d)). -var MissingBound = delivery.DefaultDeliveryBound +var MissingBound = motion.DefaultDeliveryBound // missingPulse is the pulse key of a provision with no key, `provision-missing...`. func missingPulse(key string) string { return "provision-missing." + key } @@ -1150,8 +1151,8 @@ func offered(manifests map[string]catalogue.Manifest) func(string) bool { for _, m := range manifests { add(m) } - for _, module := range delivery.ProvidedModules() { - if m, _, err := delivery.ProvidedManifest(module); err == nil { + for _, module := range overlay.ProvidedModules() { + if m, _, err := overlay.ProvidedManifest(module); err == nil { add(m) } } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go index 0140f36b..5664b66b 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go @@ -10,7 +10,9 @@ import ( watchdogs "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshwatchdogs" mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + mdc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" + mdseat "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshdelivery" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" "git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate" @@ -29,7 +31,6 @@ import ( mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" "git.novox.be/novox/mesh-sdk/go/busretry" "git.novox.be/novox/mesh-sdk/go/catalogue" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" "git.novox.be/novox/mesh-delivery/sdk/enginereads" @@ -150,7 +151,7 @@ func TestAnAnswerCountsOnlyForTheAskingItAnswered(t *testing.T) { return mustAskID(a) } first := put(100) - v, _ := delivery.EncodeAnswer(delivery.Answer{Option: "release", Warrant: first + "@2026-10-25T01:00:00Z", Words: "the operator"}) + v, _ := mdc.EncodeAnswer(mdc.Answer{Option: "release", Warrant: first + "@2026-10-25T01:00:00Z", Words: "the operator"}) p.w.put(buckets.Answers, key, v) if !p.answeredWith(key, "release") { t.Fatal("the answer to the ask that stands is not taken") @@ -362,7 +363,7 @@ func putOfTheBus(t *testing.T) { buildKV.values[bkey] = built modules := mem() modules.values["nats"] = mod - s := newPutTools(memStore{putsState: putsKV, builds.BuilderModule + ".builds": buildKV, delivery.IndexerModule + ".modules": modules}) + s := newPutTools(memStore{putsState: putsKV, builds.BuilderModule + ".builds": buildKV, meshcatalogclient.Module + ".modules": modules}) s.now = func() time.Time { return now } was := answerWithin answerWithin = 0 @@ -419,7 +420,7 @@ func putOfTheBus(t *testing.T) { t.Fatal("the bus's want was written before the operator's warrant") } world(buckets.Asks, akey, asksKV.values[akey]) - yes, _ := delivery.EncodeAnswer(delivery.Answer{Option: assign.OptionYes, Warrant: a.Ask.ID + "@2026-10-25T22:01:00Z", Words: "the operator, verified"}) + yes, _ := mdc.EncodeAnswer(mdc.Answer{Option: assign.OptionYes, Warrant: a.Ask.ID + "@2026-10-25T22:01:00Z", Words: "the operator, verified"}) world(buckets.Answers, akey, yes) if got := step(); got.Step != puts.Snapshot { t.Fatalf("on the warrant the put stands at %s: %s", got.Step, got.Words) @@ -465,7 +466,7 @@ func putOfTheBus(t *testing.T) { t.Fatalf("put again, it stands at %s (%s); its ask %q, %v; the first ask was %q", again.Step, again.Words, a2.Ask.ID, err, a.Ask.ID) } world(buckets.Asks, akey, asksKV.values[akey]) - yes2, _ := delivery.EncodeAnswer(delivery.Answer{Option: assign.OptionYes, Warrant: a2.Ask.ID + "@2026-10-25T22:03:00Z", Words: "the operator, verified"}) + yes2, _ := mdc.EncodeAnswer(mdc.Answer{Option: assign.OptionYes, Warrant: a2.Ask.ID + "@2026-10-25T22:03:00Z", Words: "the operator, verified"}) world(buckets.Answers, akey, yes2) if got := step(); got.Step != puts.Snapshot { t.Fatalf("on the second warrant the put stands at %s: %s", got.Step, got.Words) @@ -934,19 +935,19 @@ func aReleasesApproveAnswersTheMoveOfItsBuildAlone(t *testing.T) { p.logf = t.Logf mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fpTest, Repository: "novox/web", Commit: commit, Src: 7, FpSrc: c.fpSrc, Path: meshcatalogclient.RootPath}) p.w.put(buckets.Modules, "web", mod) - src, _ := delivery.EncodeSource(delivery.Source{Group: "feat/web", Heads: map[string]string{"novox/web": commit}}) - p.w.putEntry(buckets.Source, delivery.SourceMainKey, src, 7, time.Now()) - later, _ := delivery.EncodeSource(delivery.Source{Group: "feat/other", Heads: map[string]string{"novox/web": commit, "novox/x": commit}}) - p.w.putEntry(buckets.Source, delivery.SourceMainKey, later, 8, time.Now()) // a later merge leaves revision 7's release + src, _ := mdc.EncodeSource(mdseat.SourceByMainValue{Group: "feat/web", Heads: map[string]string{"novox/web": commit}}) + p.w.putEntry(buckets.Source, mdc.SourceMainKey, src, 7, time.Now()) + later, _ := mdc.EncodeSource(mdseat.SourceByMainValue{Group: "feat/other", Heads: map[string]string{"novox/web": commit, "novox/x": commit}}) + p.w.putEntry(buckets.Source, mdc.SourceMainKey, later, 8, time.Now()) // a later merge leaves revision 7's release if c.mergedAt != "" { - merge, err := delivery.EncodeMerge(delivery.Merge{Group: "feat/web", Ask: "merge.feat_web.0123456789ab", Pulls: []delivery.MergePull{ - {Head: delivery.Head{Repository: "novox/web", Number: 3, Head: strings.Repeat("3", 40)}, State: delivery.MergeMerged, Commit: c.mergedAt}}}) + merge, err := mdc.EncodeMerge(mdseat.MergesByGroupValue{Group: "feat/web", Ask: "merge.feat_web.0123456789ab", Pulls: []mdseat.MergesByGroupValuePullsItem{ + {Repository: "novox/web", Number: 3, Head: strings.Repeat("3", 40), State: string(mdc.MergeMerged), Commit: c.mergedAt}}}) if err != nil { t.Fatal(err) } p.w.put(buckets.Merges, "feat/web", merge) - other, err := delivery.EncodeMerge(delivery.Merge{Group: "feat/other", Ask: "merge.feat_other.0123456789ab", Pulls: []delivery.MergePull{ - {Head: delivery.Head{Repository: "novox/x", Number: 4, Head: strings.Repeat("4", 40)}, State: delivery.MergeMerged, Commit: commit}}}) + other, err := mdc.EncodeMerge(mdseat.MergesByGroupValue{Group: "feat/other", Ask: "merge.feat_other.0123456789ab", Pulls: []mdseat.MergesByGroupValuePullsItem{ + {Repository: "novox/x", Number: 4, Head: strings.Repeat("4", 40), State: string(mdc.MergeMerged), Commit: commit}}}) if err != nil { t.Fatal(err) } @@ -1058,7 +1059,7 @@ func aPlacedNodesWantsNameTheBuildAloneAndItsYesComesFromItsHave(t *testing.T) { t.Fatal(err) } put(buckets.Asks, akey, asksKV.values[akey]) - yes, _ := delivery.EncodeAnswer(delivery.Answer{Option: assign.OptionYes, Warrant: a.Ask.ID + "@2026-10-26T19:00:00Z", Words: "the operator"}) + yes, _ := mdc.EncodeAnswer(mdc.Answer{Option: assign.OptionYes, Warrant: a.Ask.ID + "@2026-10-26T19:00:00Z", Words: "the operator"}) put(buckets.Answers, akey, yes) p.wants(context.Background()) sync() @@ -1085,7 +1086,7 @@ func TestAnApprovedPlacementCallsNoControllerVerb(t *testing.T) { p.publish = func(event string, _ any, _ string) error { said = append(said, event); return nil } prop := mma.Proposal{ID: "p-one", By: "operator@laptop", Why: "move web"} change := plc.ChangeOf(mma.Placement{Node: "anchor"}, mma.Placement{Node: "anchor", Modules: []mma.PlacedModule{{Module: "web"}}}) - p.followWrite(prop, delivery.Answer{}, []plc.Change{change}) + p.followWrite(prop, mdc.Answer{}, []plc.Change{change}) if len(bus.calls) != 0 || !slices.Equal(said, []string{mma.EventPlacementChanged}) { t.Fatalf("calls = %d, said = %v", len(bus.calls), said) } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/puts.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/puts.go index 9bf9d77b..b6c0236f 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/puts.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/puts.go @@ -21,7 +21,6 @@ import ( "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" "git.novox.be/novox/mesh-sdk/go/catalogue" - "git.novox.be/novox/mesh-sdk/go/delivery" "mesh-delivery-assigner/internal/assign" ) @@ -408,7 +407,7 @@ func (a *putActs) warrant(id, ask string) { a.warranted[id] = true a.mu.Unlock() go func() { - if _, err := a.rec.RecordWarrant(delivery.TellerModule, ask); err != nil { + if _, err := a.rec.RecordWarrant(buckets.TellerModule, ask); err != nil { a.logf("the put's warrant %s is not recorded in the hand-act log: %v", ask, err) a.mu.Lock() a.warrantNo[id] = fmt.Sprintf("the warrant %s is not recorded in the hand-act log: %v", ask, err) diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go index 587e6608..add29071 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go @@ -8,6 +8,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" + mdcc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliverycheckerclient" + mdc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" "maps" "mesh-delivery-assigner/internal/buckets" @@ -24,7 +26,6 @@ import ( occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/process" "mesh-delivery-assigner/internal/assign" @@ -51,9 +52,9 @@ func streamPublisher(ctx context.Context, js jetstream.JetStream, node string) p if err != nil { return err } - msg := nats.NewMsg(process.ModuleStreamSubject(delivery.AssignerModule, event)) + msg := nats.NewMsg(process.ModuleStreamSubject(mmac.Module, event)) msg.Header.Set("x-event-id", id) - msg.Header.Set("x-source", delivery.AssignerModule) + msg.Header.Set("x-source", mmac.Module) msg.Header.Set("x-node", node) msg.Header.Set("x-time", time.Now().UTC().Format(time.RFC3339Nano)) msg.Header.Set("content-type", "application/json") @@ -86,7 +87,7 @@ func (a *seatActs) record(warrant string) { } ask, _, _ := strings.Cut(warrant, "@") go func() { - if taken, err := a.rec.RecordWarrant(delivery.TellerModule, ask); err != nil { + if taken, err := a.rec.RecordWarrant(buckets.TellerModule, ask); err != nil { a.logf("the placement's warrant %s is not recorded in the hand-act log: %v", ask, err) } else { a.logf("the placement's warrant %s is recorded in the log of %s", ask, taken.Log) @@ -328,11 +329,11 @@ func (p *passer) stepProposal(ctx context.Context, prop mma.Proposal, rev uint64 } prop.Verdict = &v switch v.State { - case delivery.VerdictFail: + case mdcc.VerdictFail: prop.State, prop.Ask = mmac.ProposalFailed, "" case plc.VerdictWaits: prop.State, prop.Ask = mmac.ProposalAnswering, "" - case delivery.VerdictPass: + case mdcc.VerdictPass: if prop.State != mmac.ProposalAsked || again { var ok bool if prop, ok = p.ask(ctx, prop, akey, judge.Brief(prop, v)); !ok { @@ -558,7 +559,7 @@ func (p *passer) addNode(ctx context.Context, prop mma.Proposal, revs map[string _ = p.kvs[plc.ProposalsBucket].Delete(ctx, prop.ID) p.w.put(plc.ProposalsBucket, prop.ID, nil) w := prop.Warrant - p.sayChanged(prop, delivery.Answer{Option: assign.OptionYes, Warrant: w.Warrant, + p.sayChanged(prop, mdc.Answer{Option: assign.OptionYes, Warrant: w.Warrant, Words: fmt.Sprintf("the operator approved the machine %s at %s through the enrolment's ask %s", w.Node, w.Address, w.Ask)}, []plc.Change{c}) } @@ -585,14 +586,14 @@ func (p *passer) removeNode(ctx context.Context, prop mma.Proposal, current map[ _ = p.kvs[plc.ProposalsBucket].Delete(ctx, prop.ID) p.w.put(plc.ProposalsBucket, prop.ID, nil) w := prop.Warrant - p.sayChanged(prop, delivery.Answer{Option: assign.OptionYes, Warrant: w.Warrant, + p.sayChanged(prop, mdc.Answer{Option: assign.OptionYes, Warrant: w.Warrant, Words: fmt.Sprintf("the machine %s left placement: its enrolment (ask %s) ended before it confirmed", w.Node, w.Ask)}, []plc.Change{c}) } // followWrite follows the keys a warrant wrote: the warrant recorded and placement-changed said. No verb of the // controller is called: the placement is the one source of where modules run (ADR 0567 §8, issue 774). -func (p *passer) followWrite(prop mma.Proposal, answer delivery.Answer, changes []plc.Change) { +func (p *passer) followWrite(prop mma.Proposal, answer mdc.Answer, changes []plc.Change) { if len(changes) == 0 { return } @@ -610,7 +611,7 @@ func sortedNodes(m map[string]*mma.Placement) []string { } // sayChanged says placement-changed for the keys written. -func (p *passer) sayChanged(prop mma.Proposal, answer delivery.Answer, changes []plc.Change) { +func (p *passer) sayChanged(prop mma.Proposal, answer mdc.Answer, changes []plc.Change) { if len(changes) == 0 { return } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go index 74d44e61..c6535858 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go @@ -15,7 +15,6 @@ import ( mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/delivery" "mesh-delivery-assigner/internal/assign" plc "mesh-delivery-assigner/internal/placement" @@ -43,7 +42,7 @@ func (runtimeStore) history(state, key string) ([]stdio.StateRevision, error) { // The states the verbs read, as the runtime names them: the seat's own by their local names, the others' // `.`. const ( - modulesState = delivery.IndexerModule + ".modules" + modulesState = meshcatalogclient.Module + ".modules" haveState = "node-engine.have" ) diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go index 94219f87..899a82e1 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go @@ -16,7 +16,6 @@ import ( "time" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-delivery/sdk/enginereads" ) @@ -77,7 +76,7 @@ func (s *putTools) version(module, version string) (string, error) { v := strings.ToLower(strings.TrimSpace(version)) switch { case v == "newest": - raw, _, found, err := s.st.get(delivery.IndexerModule+".modules", module) + raw, _, found, err := s.st.get(meshcatalogclient.ModulesRead, module) if err != nil { return "", fmt.Errorf("the indexer's modules cannot be read: %w", err) } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/verbs.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/verbs.go index 3951f82e..c3607709 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/verbs.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/verbs.go @@ -3,13 +3,11 @@ package main 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" "git.novox.be/novox/mesh-sdk/go/catalogue" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-delivery/sdk/graph" @@ -66,7 +64,7 @@ func (p *passer) served(ctx context.Context, get getter, g graph.Graph, n assign if len(g) == 0 { return nil } - served, unread := graph.Served(graphHaves(n.Haves), func(module, fp string) ([]string, bool) { return p.servesOf(ctx, get, module, fp) }, + served, unread := graph.Served(n.Haves, func(module, fp string) ([]string, bool) { return p.servesOf(ctx, get, module, fp) }, func(module string) []string { return g[module].Serves }) if len(unread) > 0 { p.logf("the manifest of the running build of %v cannot be read, so what the module graph says they serve is counted as served", unread) @@ -130,16 +128,3 @@ func (p *passer) manifestOf(ctx context.Context, get getter, module, fp string) } return got.manifest, true } - -// graphHaves is the haves as the module graph's Served reads them, which keeps the earlier have form for what it reads: the -// build, the phase and the health of each module on each node. -func graphHaves(haves map[string]map[string]nodeengine.HaveByNodeModuleValue) map[string]map[string]delivery.Have { - out := map[string]map[string]delivery.Have{} - for node, modules := range haves { - out[node] = map[string]delivery.Have{} - for module, h := range modules { - out[node][module] = delivery.Have{FP: h.Fp, Build: h.Build, Phase: delivery.Phase(h.Phase), Health: delivery.Health(h.Health)} - } - } - return out -} diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/views.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/views.go index 986a7ead..8102e70d 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/views.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/views.go @@ -3,6 +3,8 @@ package main import ( "context" "encoding/json" + mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "mesh-delivery-assigner/internal/buckets" "slices" "time" @@ -12,7 +14,6 @@ import ( "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" stdio "git.novox.be/novox/mesh-sdk/go" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/process" @@ -27,7 +28,7 @@ import ( ) // marksBucket is the assigner's state of what its views family said each state up to. -var marksBucket = delivery.AssignerModule + "_" + views.MarksState +var marksBucket = mmac.Module + "_" + views.MarksState // viewedTool is one tool over one state of the assigner's. type viewedTool struct{ tool, state, words string } @@ -66,13 +67,13 @@ func viewTools(getenv func(string) string, state func(string) views.Source, now marks := state(views.MarksState) var out []stdio.Tool for _, t := range firstViewTools { - out = append(out, views.FirstViewTool(delivery.AssignerModule, t.tool, t.state, t.words, views.ParseCallers(getenv(views.CallersEnv(t.tool))), state(t.state), marks, now)) + out = append(out, views.FirstViewTool(mmac.Module, t.tool, t.state, t.words, views.ParseCallers(getenv(views.CallersEnv(t.tool))), state(t.state), marks, now)) } for _, t := range readTools { - out = append(out, views.ReadTool(delivery.AssignerModule, t.tool, t.state, t.words, state(t.state), marks, now)) + out = append(out, views.ReadTool(mmac.Module, t.tool, t.state, t.words, state(t.state), marks, now)) } // Its own first views, of the indexer's manifests, modules and graph (DLV-F3r, ADR 0631 §2): read, and asked again by hand. - return append(out, views.StatusTools(delivery.AssignerModule, "assigner_first_views", "assigner_first_view_again", stdio.State(views.StatusState), meshhandactsclient.Recorder{Ask: stdio.Ask}, now)...) + return append(out, views.StatusTools(mmac.Module, "assigner_first_views", "assigner_first_view_again", stdio.State(views.StatusState), meshhandactsclient.Recorder{Ask: stdio.Ask}, now)...) } func keptSource(name string) views.Source { return views.KeptSource{State: stdio.State(name)} } @@ -84,7 +85,7 @@ func startViews(ctx context.Context, js jetstream.JetStream, nc process.Subscrib if findings.Put == nil { return } - if err := viewFindings(findings).Put(views.TooLargeFinding(delivery.AssignerModule, state, key, size, time.Now())); err != nil { + if err := viewFindings(findings).Put(views.TooLargeFinding(mmac.Module, state, key, size, time.Now())); err != nil { logf("views: the finding of %s.%s too large is not written: %v", state, key, err) } } @@ -109,7 +110,7 @@ func startViews(ctx context.Context, js jetstream.JetStream, nc process.Subscrib // viewsEmitter is the assigner's emitter of its views family: a change not said past views.Bound is its finding // view-unsaid, in its findings (review round 2); with no findings state it is said in the log only. func viewsEmitter(js jetstream.JetStream, account process.Account, mk jetstream.KeyValue, findings assign.Findings, tooLarge func(string, string, int), logf func(string, ...any)) views.Emitter { - em := views.Emitter{Owner: delivery.AssignerModule, Subject: account.EventSubject, Publish: views.JetStreamPublish(js), Marks: mk, TooLarge: tooLarge, Logf: logf} + em := views.Emitter{Owner: mmac.Module, Subject: account.EventSubject, Publish: views.JetStreamPublish(js), Marks: mk, TooLarge: tooLarge, Logf: logf} if findings.Put != nil && findings.Delete != nil { em.Findings = viewFindings(findings) } @@ -122,7 +123,7 @@ func viewFindings(f assign.Findings) views.FindingWriter { } // firstViewsBucket is the assigner's own state of its first views (views.StatusState). -var firstViewsBucket = delivery.AssignerModule + "_" + views.StatusState +var firstViewsBucket = mmac.Module + "_" + views.StatusState // indexerViews are the assigner's first views of the indexer's manifests, modules and module graph (ADR 0615 §1, // ADR 0621 §2, ADR 0631; DLV-F2r): asked at the start through the indexer's tools, then followed on indexer-views, asking once more on a gap; @@ -154,7 +155,7 @@ func (iv *indexerViews) start(ctx context.Context, w *world, wake func(), settle if iv.findings.Put == nil { return } - f := views.UnansweredFinding(delivery.AssignerModule, s, time.Now()) + f := views.UnansweredFinding(mmac.Module, s, time.Now()) var err error if raised { err = viewFindings(iv.findings).Put(f) @@ -169,8 +170,8 @@ func (iv *indexerViews) start(ctx context.Context, w *world, wake func(), settle var all []*views.Follower for state, bucket := range indexerFirstViews { bucket := bucket - tool := delivery.IndexerModule + "." + state - f := &views.Follower{Owner: delivery.IndexerModule, Tool: tool, State: state, Ask: views.AskVia(iv.call, tool), Logf: iv.logf, + tool := meshcatalogclient.Module + "." + state + f := &views.Follower{Owner: meshcatalogclient.Module, Tool: tool, State: state, Ask: views.AskVia(iv.call, tool), Logf: iv.logf, Bound: firstViewBound, Wait: firstViewWait, Raise: func(s views.Status) { finding(s, true) }, Clear: func(s views.Status) { finding(s, false) }, Changed: func(key string, value json.RawMessage, deleted bool, at time.Time) { @@ -201,7 +202,7 @@ func (iv *indexerViews) start(ctx context.Context, w *world, wake func(), settle // Not heard, the indexer's views family is the finding family-not-heard until it binds (ADR 0615 §5): the handler is // registered on the module's hub, which the assigner starts once every handler is. _ = notHeardWriter(iv.findings, iv.logf).Bind(process.EventsStream, "the indexer's manifests, modules and graph are the first views' alone until the assigner starts again", func() error { - return iv.hub.Handle("mesh.mod."+delivery.IndexerModule+".event."+views.EventPrefix+"*", views.Hear(ctx, followers, iv.logf)) + return iv.hub.Handle("mesh.mod."+meshcatalogclient.Module+".event."+views.EventPrefix+"*", views.Hear(ctx, followers, iv.logf)) }) return len(all) } @@ -209,7 +210,7 @@ func (iv *indexerViews) start(ctx context.Context, w *world, wake func(), settle // notHeardWriter writes the assigner's finding of a family it does not hear into its findings (heard.Writer); with no // findings state it is said in the log alone. func notHeardWriter(findings assign.Findings, logf func(string, ...any)) heard.Writer { - w := heard.Writer{Observer: delivery.AssignerModule, Logf: logf, Put: findings.Put} + w := heard.Writer{Observer: mmac.Module, Logf: logf, Put: findings.Put} if findings.Delete != nil { w.Delete = func(key string) error { if keys, err := findings.Keys(); err == nil && !slices.Contains(keys, key) { diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go index 6376020e..b18447bf 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go @@ -18,7 +18,6 @@ import ( "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-sdk/go/catalogue" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/health" "mesh-delivery-assigner/internal/assign" @@ -33,7 +32,7 @@ import ( // The states the verbs read, as the runtime names them. const ( policiesState = buckets.PoliciesState - manifestsState = delivery.IndexerModule + ".manifests" + manifestsState = meshcatalogclient.Module + ".manifests" // PolicyChangedEvent is the seat's event of a person's policy set or taken back. PolicyChangedEvent = "policy-changed" // busStepCause is the cause the bus's step is recorded under in the hand-act log. diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go index 0b216c04..4e225851 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go @@ -8,8 +8,10 @@ import ( watchdogs "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshwatchdogs" mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + mdc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" "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/sdk/trunk" "git.novox.be/novox/mesh-sdk/go/keys" "maps" "mesh-delivery-assigner/internal/buckets" @@ -24,16 +26,11 @@ import ( mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" "git.novox.be/novox/mesh-sdk/go/catalogue" - "git.novox.be/novox/mesh-sdk/go/delivery" "mesh-delivery-assigner/internal/assign" plc "mesh-delivery-assigner/internal/placement" ) -// noModuleWords is the indexer's reason for a module of a candidate whose directory the merge preview holds no manifest -// for (mesh-sdk delivery.CandidateNoneNoModule, which the indexer writes): the change removes the module. -const noModuleWords = delivery.CandidateNoneNoModule - // world is what the assigner watched, as it stands now: every value by bucket and key, and the manifests read by // digest. The watches write it; a pass reads it. type world struct { @@ -88,8 +85,8 @@ func (w *world) putEntry(bucket, key string, value []byte, revision uint64, at t if bucket == plc.PlacementBucket { _, _ = w.placement.Put(key, value, revision, false) // put took it already; this is its revision } - if bucket == buckets.Source && key == delivery.SourceMainKey { - if s, err := delivery.DecodeSource(value); err == nil && s.Group != "" { + if bucket == buckets.Source && key == mdc.SourceMainKey { + if s, err := mdc.DecodeSource(value); err == nil && s.Group != "" { w.sourceGroups[revision] = s.Group } } @@ -108,7 +105,7 @@ func (w *world) release(module, fp string) (string, bool) { w.mu.Lock() group := w.sourceGroups[uint64(t.FpSrc)] w.mu.Unlock() - key, err := delivery.MergesKey(group) + key, err := mdc.MergesKey(group) if group == "" || err != nil { return "", false } @@ -116,12 +113,12 @@ func (w *world) release(module, fp string) (string, bool) { if raw == nil { return "", false } - merge, err := delivery.DecodeMerge(raw) + merge, err := mdc.DecodeMerge(raw) if err != nil { return "", false } for _, pull := range merge.Pulls { - if pull.State == delivery.MergeMerged && pull.Commit == t.Commit && delivery.SameRepository(pull.Repository, t.Repository) { + if pull.State == string(mdc.MergeMerged) && pull.Commit == t.Commit && trunk.SameRepository(pull.Repository, t.Repository) { return group, true } } @@ -503,14 +500,14 @@ func (w *world) composed(node, module, fp string) (assign.ComposedDigest, bool) } // answer is the teller's answer to the ask at key (mesh-delivery-teller_answers, the same key), and whether there is one. -func (w *world) answer(key string) (delivery.Answer, bool) { +func (w *world) answer(key string) (mdc.Answer, bool) { w.mu.Lock() value, ok := w.values[buckets.Answers][key] w.mu.Unlock() if !ok { - return delivery.Answer{}, false + return mdc.Answer{}, false } - a, err := delivery.DecodeAnswer(value) + a, err := mdc.DecodeAnswer(value) return a, err == nil } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go index e784333f..cd70b04f 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go @@ -6,12 +6,9 @@ import ( "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" "testing" "time" - - "git.novox.be/novox/mesh-sdk/go/delivery" ) // fakeManifests is the indexer's manifests bucket in memory. @@ -37,15 +34,6 @@ func (f fakeManifests) get(_ context.Context, key string) ([]byte, error) { func fp(c byte) string { return meshcatalogclient.SourcePrefix2 + strings.Repeat(string(c), 64) } -func pull(repo string, number int, modules map[string]delivery.CandidateModule) delivery.CandidatePull { - p := delivery.CandidatePull{Head: delivery.Head{Repository: repo, Number: number, Head: strings.Repeat("3", 40)}, Fps: modules} - for m := range modules { - p.Modules = append(p.Modules, m) - } - slices.Sort(p.Modules) - return p -} - // Review round 1 (items 3 and 4): the world counts the values a key takes, so a have written again after an answer is seen. func theWorldCountsTheValuesAKeyTakes(t *testing.T) { w := newWorld() diff --git a/modules/mesh-delivery-assigner/go.mod b/modules/mesh-delivery-assigner/go.mod index 2161515c..4b0ad299 100644 --- a/modules/mesh-delivery-assigner/go.mod +++ b/modules/mesh-delivery-assigner/go.mod @@ -64,3 +64,8 @@ require git.novox.be/novox/mesh-delivery/modules/mesh-delivery-view/viewstate v0 replace git.novox.be/novox/mesh-delivery/modules/mesh-delivery-view/viewstate => ../mesh-delivery-view/viewstate require git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient v0.0.0-00010101000000-000000000000 + +require git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliverycheckerclient v0.0.0-00010101000000-000000000000 +replace git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliverycheckerclient => ../../contracts/go/clients/meshdeliverycheckerclient + +require git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go v0.0.0-20261105000000-000000000000 diff --git a/modules/mesh-delivery-assigner/internal/assign/asks.go b/modules/mesh-delivery-assigner/internal/assign/asks.go index 5fbbeea1..064a5049 100644 --- a/modules/mesh-delivery-assigner/internal/assign/asks.go +++ b/modules/mesh-delivery-assigner/internal/assign/asks.go @@ -2,6 +2,7 @@ package assign import ( "fmt" + mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" @@ -12,7 +13,6 @@ import ( occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" - "git.novox.be/novox/mesh-sdk/go/delivery" ) // HoldAsk is the ask about a module's fingerprint the assigner holds, at its key (asks.HoldAskKey): keep it held or @@ -68,7 +68,7 @@ func RestoreAsk(key, node, module, fp, words string, now time.Time) asks.Ask { // words, under the assigner's own name (ADR 0437 clause 9), keyed by the held fingerprint. needsYou is true for a module holding // data, whose restore ask waits for the operator. func HeldCondition(module, fp, node, words string, raised, needsYou bool) oc.Condition { - key := delivery.AssignerModule + ".held." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) + key := mmac.Module + ".held." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared} @@ -91,7 +91,7 @@ func HeldCondition(module, fp, node, words string, raised, needsYou bool) oc.Con // the node keeps its want. It names the node, the module, fp and the have's words, keyed by node and module, and is cleared // (raised false) once the node no longer fails alone. func NodeFailedCondition(node, module, fp string, f NodeFailure, raised bool) oc.Condition { - key := delivery.AssignerModule + ".failed-alone." + node + "." + module + key := mmac.Module + ".failed-alone." + node + "." + module subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared, @@ -114,7 +114,7 @@ func NodeFailedCondition(node, module, fp string, f NodeFailure, raised bool) oc // naming the module, the node and the rule holding its first want back with the rule's words, under the assigner's own name keyed by // node and module, and cleared (raised false) when the node has a want for it again. func NeitherCondition(node, module string, h Holding, raised bool) oc.Condition { - key := delivery.AssignerModule + ".neither." + node + "." + module + key := mmac.Module + ".neither." + node + "." + module subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared, @@ -236,7 +236,7 @@ func BackupAsk(key, node, module, fp, digest, words string, asking int, now time // BackupCondition is the condition raised when a backup before an apply fails and the module is held on the node (ADR 0539 §16), // naming the node, the module and the backup's words; cleared under the same key. func BackupCondition(node, module, fp, words string, raised bool) oc.Condition { - key := delivery.AssignerModule + ".backup." + node + "." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) + key := mmac.Module + ".backup." + node + "." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared} diff --git a/modules/mesh-delivery-assigner/internal/assign/asks_test.go b/modules/mesh-delivery-assigner/internal/assign/asks_test.go index 888ce7ec..865e4b85 100644 --- a/modules/mesh-delivery-assigner/internal/assign/asks_test.go +++ b/modules/mesh-delivery-assigner/internal/assign/asks_test.go @@ -2,6 +2,7 @@ package assign import ( "fmt" + mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" @@ -15,7 +16,6 @@ import ( occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/health" ) @@ -160,7 +160,7 @@ func saidConditionsAreFindings(t *testing.T) { t.Fatalf("%s: %v", c.key, err) } got, ok := puts[c.key] - if !ok || got.Severity != health.Severity(c.raised.Severity) || got.Headline != c.raised.Headline || got.Observer != delivery.AssignerModule || + if !ok || got.Severity != health.Severity(c.raised.Severity) || got.Headline != c.raised.Headline || got.Observer != mmac.Module || got.Subject.Machine != c.raised.Subject.Machine || said != 0 { t.Fatalf("%s: finding %+v (written %v), said %d", c.key, got, puts, said) } diff --git a/modules/mesh-delivery-assigner/internal/assign/findings.go b/modules/mesh-delivery-assigner/internal/assign/findings.go index 254c38e8..65b2ec11 100644 --- a/modules/mesh-delivery-assigner/internal/assign/findings.go +++ b/modules/mesh-delivery-assigner/internal/assign/findings.go @@ -3,12 +3,12 @@ package assign import ( "errors" "fmt" + mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" "strings" "time" occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/health" ) @@ -20,13 +20,13 @@ import ( // assigner no longer says it straight (never both). // FindingsBucket is the assigner's findings. -var FindingsBucket = health.FindingsBucket(delivery.AssignerModule) +var FindingsBucket = health.FindingsBucket(mmac.Module) // FindingOf is a said condition as a finding: its key `..`, from the condition's own key // `mesh-delivery-assigner..` (the subject's id when the key names none), its words unchanged. raised is false for // a clear, whose key is to be deleted; value is nil then. func FindingOf(c oc.Condition, at time.Time) (key string, value []byte, raised bool, err error) { - rest, ok := strings.CutPrefix(c.Key, delivery.AssignerModule+".") + rest, ok := strings.CutPrefix(c.Key, mmac.Module+".") if !ok || rest == "" { return "", nil, false, fmt.Errorf("the condition %q is not the assigner's", c.Key) } @@ -56,7 +56,7 @@ func FindingOf(c oc.Condition, at time.Time) (key string, value []byte, raised b value, err = health.EncodeFinding(health.Finding{Key: key, Kind: kind, Subject: health.Subject{Scope: scope, ID: id, Machine: c.Subject.Machine}, Severity: health.Severity(c.Severity), Summary: summary, Headline: c.Headline, Explanation: c.Explanation, Resolved: c.Resolved, Needs: c.Needs, Actions: actions, Evidence: []health.Evidence{{At: at.UTC(), Said: summary}}, Source: "assigner." + kind, - Observer: delivery.AssignerModule, At: at.UTC()}) + Observer: mmac.Module, At: at.UTC()}) return key, value, true, err } diff --git a/modules/mesh-delivery-assigner/internal/assign/placement.go b/modules/mesh-delivery-assigner/internal/assign/placement.go index d0f920da..523fb446 100644 --- a/modules/mesh-delivery-assigner/internal/assign/placement.go +++ b/modules/mesh-delivery-assigner/internal/assign/placement.go @@ -1,18 +1,18 @@ package assign import ( + mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" "strings" occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" - "git.novox.be/novox/mesh-sdk/go/delivery" ) // SeatWaitsCondition is the assigner's word on the seat mesh-placement while a state of the seat is not bound (ADR 0567 // §1): raised naming each, cleared when none is left. func SeatWaitsCondition(unbound []string) oc.Condition { - key := delivery.AssignerModule + ".seat-states" - subject := oc.ConditionSubject{Scope: "module", ID: delivery.AssignerModule} + key := mmac.Module + ".seat-states" + subject := oc.ConditionSubject{Scope: "module", ID: mmac.Module} if len(unbound) == 0 { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared, Resolved: "the seat mesh-placement holds all its states."} } diff --git a/modules/mesh-delivery-assigner/internal/assign/policy.go b/modules/mesh-delivery-assigner/internal/assign/policy.go index c5b872ff..f4a5921c 100644 --- a/modules/mesh-delivery-assigner/internal/assign/policy.go +++ b/modules/mesh-delivery-assigner/internal/assign/policy.go @@ -3,6 +3,7 @@ package assign import ( "encoding/json" "fmt" + mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" "mesh-delivery-assigner/internal/buckets" "sort" "strings" @@ -10,7 +11,6 @@ import ( occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" "git.novox.be/novox/mesh-sdk/go/catalogue" - "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-sdk/go/provisions" ) @@ -20,7 +20,7 @@ import ( // catalogue.Upgrade: a person's choice over the module's word, its irreplaceable data and the default, the bus as any module (ADR 0601 §1). // PoliciesBucket is the assigner's state `policies`. -var PoliciesBucket = delivery.AssignerModule + "_" + buckets.PoliciesState +var PoliciesBucket = mmac.Module + "_" + buckets.PoliciesState // DecodePolicies reads the policies state's values by key (the module); a value that cannot be read is left out, named. func DecodePolicies(values map[string][]byte) (map[string]catalogue.PersonPolicy, []string) { @@ -73,7 +73,7 @@ func ProvisionFailedFinding(key string, p provisions.Provision, at time.Time) ([ Severity: health.Warning, Summary: summary, Headline: clipHeadline(p.Consumer.Module + " waits for a provision that failed"), Explanation: occ.NothingToDo + " " + summary + ". It clears once the provider provides it.", Resolved: p.Provision + " for " + p.Consumer.Module + " is provided", Evidence: []health.Evidence{{At: at.UTC(), Said: p.Why}}, - Source: "assigner." + KindProvisionFailed, Observer: delivery.AssignerModule, At: at.UTC()}) + Source: "assigner." + KindProvisionFailed, Observer: mmac.Module, At: at.UTC()}) } func also(provider, consumer string) []string { @@ -105,7 +105,7 @@ func ProvisionMissingFinding(key string, bound time.Duration, at time.Time) ([]b Severity: health.Warning, Summary: summary, Headline: clipHeadline(module + " on " + node + " lacks " + provision), Explanation: occ.NothingToDo + " " + summary + ". It clears once the provision has its key.", Resolved: provision + " for " + module + " on " + node + " has its key", Evidence: []health.Evidence{{At: at.UTC(), Said: summary}}, - Source: "assigner." + KindProvisionMissing, Observer: delivery.AssignerModule, At: at.UTC()}) + Source: "assigner." + KindProvisionMissing, Observer: mmac.Module, At: at.UTC()}) } // KindUnplaced is, from the lease write, a node that runs but no placement names (ADR 0571 §6). @@ -125,7 +125,7 @@ func UnplacedFinding(node string, at time.Time) ([]byte, error) { Headline: clipHeadline(node + " has no placement"), Needs: "place it with mesh-placement.propose.", Explanation: occ.NeedsYou + "place it with mesh-placement.propose. " + summary + ".", Resolved: node + " is placed", Evidence: []health.Evidence{{At: at.UTC(), Said: summary}}, - Source: "assigner." + KindUnplaced, Observer: delivery.AssignerModule, At: at.UTC()}) + Source: "assigner." + KindUnplaced, Observer: mmac.Module, At: at.UTC()}) } func clipHeadline(s string) string { diff --git a/modules/mesh-delivery-assigner/internal/assign/seat.go b/modules/mesh-delivery-assigner/internal/assign/seat.go index 5b968ae3..056980bc 100644 --- a/modules/mesh-delivery-assigner/internal/assign/seat.go +++ b/modules/mesh-delivery-assigner/internal/assign/seat.go @@ -13,7 +13,6 @@ import ( oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" - "git.novox.be/novox/mesh-sdk/go/delivery" plc "mesh-delivery-assigner/internal/placement" ) @@ -178,7 +177,7 @@ const ( // CallClearedCondition clears the condition of a refused controller call a previous process raised, for its pair (node and // module, or node and provision for a pin). func CallClearedCondition(kind, node, module string) oc.Condition { - return oc.Condition{Key: delivery.AssignerModule + "." + kind + "." + node + "." + module, + return oc.Condition{Key: mmac.Module + "." + kind + "." + node + "." + module, Subject: oc.ConditionSubject{Scope: "module", ID: module, Machine: node}, State: occ.StateCleared, Resolved: "the assigner calls no verb of the controller any more: placement is the one source."} } diff --git a/modules/mesh-delivery-assigner/internal/buckets/buckets.go b/modules/mesh-delivery-assigner/internal/buckets/buckets.go index 4317d794..c0fe39eb 100644 --- a/modules/mesh-delivery-assigner/internal/buckets/buckets.go +++ b/modules/mesh-delivery-assigner/internal/buckets/buckets.go @@ -44,8 +44,11 @@ const ( // Source and Merges are the gate's. Source = "mesh-delivery-gate_" + delivery.StateSource Merges = "mesh-delivery-gate_" + delivery.StateMerges + // TellerModule is the module whose hand the operator's answers pass: the one that holds each ask's answer, and the + // name the hand-act log records a warrant under. Held equal to the manifest's reads by its test. + TellerModule = "mesh-delivery-teller" // Answers holds the teller's answer to each ask. - Answers = "mesh-delivery-teller_answers" + Answers = TellerModule + "_answers" // Builds is the builder's. Builds = builds.BuilderBuildsBucket // Grants is the grants part's. diff --git a/modules/mesh-delivery-assigner/internal/buckets/buckets_test.go b/modules/mesh-delivery-assigner/internal/buckets/buckets_test.go index e39f55ec..70a0fa96 100644 --- a/modules/mesh-delivery-assigner/internal/buckets/buckets_test.go +++ b/modules/mesh-delivery-assigner/internal/buckets/buckets_test.go @@ -13,7 +13,7 @@ func TestBucketsAreTheEarlierNames(t *testing.T) { "Builds": {Builds, "mesh-delivery-builder_builds"}, "Grants": {Grants, "mesh-grants_grants"}, "Wants": {Wants, "mesh-delivery-assigner_wants"}, "Differences": {Differences, "mesh-delivery-assigner_differences"}, "Asks": {Asks, "mesh-delivery-assigner_asks"}, "Puts": {Puts, "mesh-delivery-assigner_puts"}, - "Policies": {Policies, "mesh-delivery-assigner_policies"}, + "Policies": {Policies, "mesh-delivery-assigner_policies"}, "TellerModule": {TellerModule, "mesh-delivery-teller"}, } { if c[0] != c[1] { t.Errorf("%s = %q, want %q", name, c[0], c[1]) diff --git a/modules/mesh-delivery-assigner/internal/judge/judge.go b/modules/mesh-delivery-assigner/internal/judge/judge.go index 6440e77b..4f4ccc84 100644 --- a/modules/mesh-delivery-assigner/internal/judge/judge.go +++ b/modules/mesh-delivery-assigner/internal/judge/judge.go @@ -9,6 +9,7 @@ import ( "encoding/json" "fmt" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + mdcc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliverycheckerclient" "reflect" "sort" "strconv" @@ -17,7 +18,6 @@ import ( nec "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" - "git.novox.be/novox/mesh-sdk/go/delivery" plc "mesh-delivery-assigner/internal/placement" ) @@ -169,11 +169,11 @@ func JudgeAnswers(p mma.Proposal, intended map[string]map[string]bool, answers m } switch { case len(v.Fails) > 0: - v.State = delivery.VerdictFail + v.State = mdcc.VerdictFail case len(waiting) > 0: v.State = plc.VerdictWaits default: - v.State = delivery.VerdictPass + v.State = mdcc.VerdictPass } return v } @@ -259,7 +259,7 @@ func differenceWords(d nodeengine.CandidateDiffers) string { // shownValue bounds a value named in a brief. const shownValue = 60 -// walk follows a differing path (delivery.DifferingPaths: keys joined by dots, a key may hold dots, and a JSON value +// walk follows a differing path (the node-engine's DifferingPaths: keys joined by dots, a key may hold dots, and a JSON value // written in a string is read as JSON) through a body, answering the keys it passed and the value at its end. func walk(body, path string) (keys []string, value any, ok bool) { var v any diff --git a/modules/mesh-delivery-assigner/internal/judge/judge_test.go b/modules/mesh-delivery-assigner/internal/judge/judge_test.go index c7c45c5e..5c077346 100644 --- a/modules/mesh-delivery-assigner/internal/judge/judge_test.go +++ b/modules/mesh-delivery-assigner/internal/judge/judge_test.go @@ -2,13 +2,13 @@ package judge import ( "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + mdcc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliverycheckerclient" "slices" "strings" "testing" "time" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" - "git.novox.be/novox/mesh-sdk/go/delivery" plc "mesh-delivery-assigner/internal/placement" ) @@ -49,22 +49,22 @@ func TestJudge(t *testing.T) { words string marked string }{ - {"all the same", false, map[string]*nodeengine.CandidateAnswer{"anchor": same(7), "laptop": same(8)}, nil, delivery.VerdictPass, "", ""}, + {"all the same", false, map[string]*nodeengine.CandidateAnswer{"anchor": same(7), "laptop": same(8)}, nil, mdcc.VerdictPass, "", ""}, {"a module added where intended", false, map[string]*nodeengine.CandidateAnswer{"anchor": {Proposal: "p-one", Revision: 7, Verdict: nodeengine.CandidateAnswerVerdictDiffers, - Added: []nodeengine.CandidateAdded{{Module: "web", Unissued: []string{"its own secret"}}}}, "laptop": same(8)}, nil, delivery.VerdictPass, "", ""}, - {"a difference not computed passes, marked", false, map[string]*nodeengine.CandidateAnswer{"anchor": differs(7, "mail"), "laptop": same(8)}, nil, delivery.VerdictPass, "", "mail"}, + Added: []nodeengine.CandidateAdded{{Module: "web", Unissued: []string{"its own secret"}}}}, "laptop": same(8)}, nil, mdcc.VerdictPass, "", ""}, + {"a difference not computed passes, marked", false, map[string]*nodeengine.CandidateAnswer{"anchor": differs(7, "mail"), "laptop": same(8)}, nil, mdcc.VerdictPass, "", "mail"}, {"the seed carries a difference, named", true, map[string]*nodeengine.CandidateAnswer{"anchor": same(7), "laptop": {Proposal: "p-one", Revision: 8, Verdict: nodeengine.CandidateAnswerVerdictDiffers, Differs: []nodeengine.CandidateDiffers{{Module: "node-tools", Resource: "node-tools.runtime", Why: "the resource differs", Bodies: []nodeengine.CandidateBodies{{ID: "node-tools.runtime", Paths: []string{"env.MESH_OWNED_PATHS./etc/resolv.conf", "env.MESH_TOOL_MODULES"}, Running: `{"env":{"MESH_OWNED_PATHS":"{\"/etc/hosts\":\"hostname\",\"/etc/resolv.conf\":\"networkmanager (node-uplink)\"}"}}`, - Composed: `{"env":{"MESH_OWNED_PATHS":"{\"/etc/hosts\":\"hostname\",\"/etc/resolv.conf\":\"systemd-resolved (node-resolver)\"}","MESH_TOOL_MODULES":"… (cut at 8192 bytes)`}}}}}}, nil, delivery.VerdictPass, "", ""}, + Composed: `{"env":{"MESH_OWNED_PATHS":"{\"/etc/hosts\":\"hostname\",\"/etc/resolv.conf\":\"systemd-resolved (node-resolver)\"}","MESH_TOOL_MODULES":"… (cut at 8192 bytes)`}}}}}}, nil, mdcc.VerdictPass, "", ""}, {"a refusal", false, map[string]*nodeengine.CandidateAnswer{"anchor": same(7), "laptop": {Proposal: "p-one", Revision: 8, Verdict: nodeengine.CandidateAnswerVerdictRefused, - Refusals: []nodeengine.CandidateRefusal{{Module: "web", Why: "no own secret"}}}}, nil, delivery.VerdictFail, "laptop refuses", ""}, + Refusals: []nodeengine.CandidateRefusal{{Module: "web", Why: "no own secret"}}}}, nil, mdcc.VerdictFail, "laptop refuses", ""}, {"a node not answering, within its bound", false, map[string]*nodeengine.CandidateAnswer{"anchor": same(7)}, map[string]bool{"laptop": true}, plc.VerdictWaits, "laptop (offline)", ""}, - {"an answer of an earlier revision, past its bound, is no answer and decided without it", false, map[string]*nodeengine.CandidateAnswer{"anchor": same(6), "laptop": same(8)}, nil, delivery.VerdictPass, "no answer from anchor", ""}, + {"an answer of an earlier revision, past its bound, is no answer and decided without it", false, map[string]*nodeengine.CandidateAnswer{"anchor": same(6), "laptop": same(8)}, nil, mdcc.VerdictPass, "no answer from anchor", ""}, {"a module held as today passes, shown in the brief", false, map[string]*nodeengine.CandidateAnswer{"anchor": same(7), "laptop": {Proposal: "p-one", Revision: 8, - Verdict: nodeengine.CandidateAnswerVerdictSame, Held: []nodeengine.CandidateRefusal{{Module: "spiegel", Why: "a required value is unset"}}}}, nil, delivery.VerdictPass, "", ""}, - {"its later answer", false, map[string]*nodeengine.CandidateAnswer{"anchor": same(7), "laptop": same(8)}, nil, delivery.VerdictPass, "", ""}, + Verdict: nodeengine.CandidateAnswerVerdictSame, Held: []nodeengine.CandidateRefusal{{Module: "spiegel", Why: "a required value is unset"}}}}, nil, mdcc.VerdictPass, "", ""}, + {"its later answer", false, map[string]*nodeengine.CandidateAnswer{"anchor": same(7), "laptop": same(8)}, nil, mdcc.VerdictPass, "", ""}, } { q := p q.Seed = row.seed @@ -73,10 +73,10 @@ func TestJudge(t *testing.T) { if v.State != row.state || !strings.Contains(all, row.words) { t.Errorf("%s: %s, %q", row.name, v.State, all) } - if row.seed && row.state == delivery.VerdictPass && !strings.Contains(Brief(q, v), "the seed carries: node-tools: MESH_OWNED_PATHS[/etc/resolv.conf] networkmanager (node-uplink) → (value cut) (and 1 more fields)") { + if row.seed && row.state == mdcc.VerdictPass && !strings.Contains(Brief(q, v), "the seed carries: node-tools: MESH_OWNED_PATHS[/etc/resolv.conf] networkmanager (node-uplink) → (value cut) (and 1 more fields)") { t.Errorf("%s: the brief does not name it: %s", row.name, Brief(q, v)) } - if row.seed && row.state == delivery.VerdictPass { + if row.seed && row.state == mdcc.VerdictPass { whole := row.answers["laptop"].Differs[0] whole.Bodies = []nodeengine.CandidateBodies{{ID: "r", Paths: []string{"env.MESH_OWNED_PATHS./etc/resolv.conf"}, Running: `{"env":{"MESH_OWNED_PATHS":"{\"/etc/resolv.conf\":\"networkmanager (node-uplink)\"}"}}`,