diff --git a/modules/mesh-delivery-builder/internal/build/imports_test.go b/modules/mesh-delivery-builder/internal/build/imports_test.go index 58f6342..4b7d27e 100644 --- a/modules/mesh-delivery-builder/internal/build/imports_test.go +++ b/modules/mesh-delivery-builder/internal/build/imports_test.go @@ -11,7 +11,7 @@ import ( // ADR 0593 §2 (F3): the imports a Go build module answers at a build's end reach the done key and the log's end entry, // where the indexer keeps them on the module. -func TestTheImportsABuildAnswersReachTheDoneKeyAndTheLog(t *testing.T) { +func importsABuildAnswersReachTheDoneKeyAndTheLog(t *testing.T) { r := newRig(t, goBundle) imports := []string{"git.novox.be/novox/mesh-sdk/go", "git.novox.be/novox/mesh-sdk/go/announce"} r.asks.Answer = func(a delivery.StepAsk) delivery.Step { diff --git a/modules/mesh-delivery-builder/internal/build/run_test.go b/modules/mesh-delivery-builder/internal/build/run_test.go index 181b4ee..e2ecd62 100644 --- a/modules/mesh-delivery-builder/internal/build/run_test.go +++ b/modules/mesh-delivery-builder/internal/build/run_test.go @@ -221,6 +221,7 @@ var ( ) func TestABundleAndAnArchiveAreBuiltOnOneNodeAndDone(t *testing.T) { // 1607/AC7, ADR 0478 clauses 1, 4 + t.Run("the imports a build answers reach the done key and the log", importsABuildAnswersReachTheDoneKeyAndTheLog) r := newRig(t, goBundle, archiveA, tsBundle) // ADR 0584: a third node agrees with novox and ace's typescript is the odd one; the build is done and its step says ace sits out. r.tools.Put(buildrun.NodeBuildModule, "g14.typescript", tcValue(t, "typescript", "tsc5"), false) diff --git a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/integration_test.go b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/integration_test.go index c35ebf9..0aae898 100644 --- a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/integration_test.go +++ b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/integration_test.go @@ -10,10 +10,8 @@ import ( "encoding/json" "fmt" "io" - "maps" "os" "path/filepath" - "slices" "strings" "testing" "time" @@ -603,74 +601,6 @@ func TestIndexerGivesACandidateItsFingerprintWhenTheCheckerCreatesThePreviewsBuc } } -// TestAMergeOfMeshSDKChangingOnlyGoLeavesItsNamedTreeEqual: two merged messages of mesh-sdk (its module.json at 9cb4d59, -// whose lib names its paths) differ in the root tree, as a change to go/ alone makes them, and carry the same objects of the -// named paths; the module's kept tree, and so its fingerprint's tree input, is the same after both, its new form -// (fingerprint or reason) does not move, and so the second writes no value at all (issue 1758, I9, ADR 0499 check clause 6 -// in miniature; the operator, 2026-10-25: a module's value moves only with the module). -func TestAMergeOfMeshSDKChangingOnlyGoLeavesItsNamedTreeEqual(t *testing.T) { - manifest, err := os.ReadFile("../../internal/index/testdata/sdk-9cb4d59-mesh-sdk.module.json") - if err != nil { - t.Fatal(err) - } - objects := map[string]string{"src": "1111111111111111111111111111111111111111", "test": "2222222222222222222222222222222222222222", - "package.json": "3333333333333333333333333333333333333333", "package-lock.json": "4444444444444444444444444444444444444444", "tsconfig.json": "5555555555555555555555555555555555555555"} - js, ctx, _, modules := startIndexer(t, func(context.Context, buildLog) {}) - publish := func(merge, root string, objects map[string]string) { - data, err := delivery.EncodeForge(delivery.Forge{Kind: delivery.ForgeMerged, Repository: "novox/mesh-sdk", Branch: "feat/x", Number: 70, - Head: "0123456789abcdef0123456789abcdef01234567", Merge: merge, Root: root, Trees: map[string]string{"": root}, - Manifests: map[string]string{"": string(manifest)}, Paths: map[string]map[string]string{"": objects}}) - if err != nil { - t.Fatal(err) - } - if _, err := js.Publish(ctx, "mesh.stream.mesh-delivery-forge-bridge.event.forge.novox.mesh-sdk.merged", data); err != nil { - t.Fatal(err) - } - } - at := func(merge string) delivery.Module { - var m delivery.Module - for deadline := time.Now().Add(5 * time.Second); time.Now().Before(deadline); time.Sleep(50 * time.Millisecond) { - if e, err := modules.Get(ctx, "mesh-sdk"); err == nil { - if m, err = delivery.DecodeModule(e.Value()); err == nil && m.Commit == merge { - return m - } - } - } - t.Fatalf("modules.mesh-sdk = %+v within 5 s, want the merge %s", m, merge) - return m - } - const firstMerge, secondMerge, thirdMerge = "89abcdef0123456789abcdef0123456789abcdef", "99abcdef0123456789abcdef0123456789abcdef", "a9abcdef0123456789abcdef0123456789abcdef" - publish(firstMerge, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", objects) - first := at(firstMerge) - if first.Inputs2 == nil || !strings.HasPrefix(first.Inputs2.Tree, delivery.NamedTreePrefix) { - t.Fatalf("kept inputs %+v, want a named tree", first.Inputs2) - } - // The go/-only merge, then one that changes src/: the stream is taken in order, so once the third is written the second - // was heard, and it wrote nothing: the module's value stays at the commit its fingerprint first appeared at (the - // operator, 2026-10-25). - publish(secondMerge, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", objects) - changed := maps.Clone(objects) - changed["src"] = "6666666666666666666666666666666666666666" - publish(thirdMerge, "cccccccccccccccccccccccccccccccccccccccc", changed) - at(thirdMerge) - history, err := modules.History(ctx, "mesh-sdk") - if err != nil { - t.Fatal(err) - } - var commits []string - for _, e := range history { - if m, err := delivery.DecodeModule(e.Value()); err == nil { - commits = append(commits, m.Commit) - if m.Commit == firstMerge && (m.Inputs2 == nil || m.Inputs2.Tree != first.Inputs2.Tree || m.FP2 != first.FP2 || m.None2 != first.None2) { - t.Errorf("the value at the first merge moved: %+v, was %+v", m, first) - } - } - } - if slices.Contains(commits, secondMerge) { - t.Errorf("the go/-only merge wrote a value: the commits written are %v", commits) - } -} - // TestIndexerJudgesAnUnreadableVerdictAgainAtStart: the modules bucket holds avahi as an older SDK wrote it, with the reason // 'the manifest cannot be read', the inputs the merge carried (the tree, the lock hash by file name) and the digest of its // manifest, which manifests. holds and the running SDK reads; the go toolchain is reported. Within 5 s of the start diff --git a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/packages_integration_test.go b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/packages_integration_test.go index 2829604..11192c9 100644 --- a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/packages_integration_test.go +++ b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/packages_integration_test.go @@ -22,7 +22,7 @@ import ( // buildstep; plain: announce); then mesh-sdk merges a change of buildstep alone, which moves mesh-sdk's version. Within // 5 s the packages key of mesh-sdk/go names the merge with a digest per package, importer gets a new fingerprint, and // plain keeps the one it had, though the version line would have moved it. The forge's tools answer on the bus as the -// gitea module's do. +// gitea module's do. A merge of go/ alone before it writes no value of mesh-sdk, whose tree is its named paths'. func TestAMeshSDKMergeMovesOnlyTheModulesImportingAChangedPackage(t *testing.T) { const ( sdkGo = "git.novox.be/novox/mesh-sdk/go" @@ -136,10 +136,29 @@ func TestAMeshSDKMergeMovesOnlyTheModulesImportingAChangedPackage(t *testing.T) module(b.name, func(m delivery.Module) bool { return m.Inputs2 != nil && m.Inputs2.ImportForm != "" && m.FP2 == fp }) } + // mesh-sdk merges a change of go/ alone that leaves its own named paths' objects: its value, a TypeScript package's + // over its named tree, is not written (issue 1758, ADR 0499 clause 6; the operator, 2026-10-25: a module's value moves + // only with the module). + const goOnly = "4444444444444444444444444444444444444444" + merged("novox/mesh-sdk", 72, goOnly, delivery.Forge{Root: "cccccccccccccccccccccccccccccccccccccccc", + Trees: map[string]string{"": "cccccccccccccccccccccccccccccccccccccccc"}, Manifests: map[string]string{"": string(sdkManifest)}, + Paths: sdkObjects("6666666666666666666666666666666666666666")}) // mesh-sdk merges a change of buildstep alone (its version moves: src changed too). merged("novox/mesh-sdk", 71, m2, delivery.Forge{Root: sdk2, Trees: map[string]string{"": sdk2}, Manifests: map[string]string{"": string(sdkManifest)}, Paths: sdkObjects("7777777777777777777777777777777777777777")}) - module("mesh-sdk", func(m delivery.Module) bool { return m.Commit == m2 }) + sdkAt2 := module("mesh-sdk", func(m delivery.Module) bool { return m.Commit == m2 }) + if sdkAt2.Inputs2 == nil || !strings.HasPrefix(sdkAt2.Inputs2.Tree, delivery.NamedTreePrefix) { + t.Errorf("mesh-sdk's kept inputs %+v, want a named tree", sdkAt2.Inputs2) + } + history, err := modules.History(ctx, "mesh-sdk") + if err != nil { + t.Fatal(err) + } + for _, e := range history { + if m, err := delivery.DecodeModule(e.Value()); err == nil && m.Commit == goOnly { + t.Errorf("the go/-only merge wrote mesh-sdk's value: %+v", m) + } + } key, _ := delivery.PackagesKey(sdkGo) var pub delivery.PublishedPackages for deadline := time.Now().Add(5 * time.Second); time.Now().Before(deadline); time.Sleep(50 * time.Millisecond) { diff --git a/modules/mesh-delivery-indexer/internal/fingerprint/fingerprint_test.go b/modules/mesh-delivery-indexer/internal/fingerprint/fingerprint_test.go index c63ab1b..ddad203 100644 --- a/modules/mesh-delivery-indexer/internal/fingerprint/fingerprint_test.go +++ b/modules/mesh-delivery-indexer/internal/fingerprint/fingerprint_test.go @@ -9,6 +9,14 @@ import ( const sdk = "git.novox.be/novox/mesh-sdk/go" +// The indexer's one computation (ADR 0593 §2): what moved out of mesh-sdk computes what it computed, the import form +// moves only with what a module imports, and a package's digest is its own files. +func TestTheFingerprintComputation(t *testing.T) { + t.Run("the moved computation gives the values it gave in mesh-sdk", movedComputationGivesTheValuesItGaveInMeshSDK) + t.Run("the import form moves only with what the module imports", importFormMovesOnlyWithWhatTheModuleImports) + t.Run("a package's digest is its own files", packageDigestIsItsOwnFiles) +} + func base() Inputs { return Inputs{Module: "netcheck", Tree: "t1", Bases: []string{"src2:b"}, Contexts: map[string]string{"c": "x"}, Locks: map[string]string{"bin": "l1"}, Toolchains: map[string]delivery.Toolchain2{"bin": {Language: "go", Version: "1.26.0", Recipe: "7"}}} @@ -16,7 +24,7 @@ func base() Inputs { // The form moved out of mesh-sdk computes what mesh-sdk's SourceFingerprint2 and NamedTree computed for the same // inputs (golden values taken from mesh-sdk 3d87ddc), so the move itself rebuilds nothing. -func TestTheMovedComputationGivesTheValuesItGaveInMeshSDK(t *testing.T) { +func movedComputationGivesTheValuesItGaveInMeshSDK(t *testing.T) { in := base() in.Packages = map[string]string{sdk: "abc"} if fp, none := Of(in); fp != "src2:0f96be10d19712c94ea0ece8125a45cbb658ec06b705b28e747332cc94500e41" || none != "" { @@ -45,7 +53,7 @@ func published(module, repo, dir, commit, requires string, digests map[string]st // ADR 0593 §2, §3: the fingerprint takes the digest of each package a module imports, and of each mesh Go module's // requirements; a package it does not import moves nothing, an imported one or a sibling one moves it. -func TestTheImportFormMovesOnlyWithWhatTheModuleImports(t *testing.T) { +func importFormMovesOnlyWithWhatTheModuleImports(t *testing.T) { const sibling = "git.novox.be/novox/mesh-catalog/modules/mesh-build-go/buildstep" imports := []string{sdk, sdk + "/announce", sibling} pubs := func(announce, buildstep, sib, requires string) map[string]delivery.PublishedPackages { @@ -93,7 +101,7 @@ func TestTheImportFormMovesOnlyWithWhatTheModuleImports(t *testing.T) { // A package's digest is its own files: a test file, a sub-package or a nested module changes nothing of it; a file // of it, or of a sub-directory that is no package (testdata), changes only it. -func TestAPackageDigestIsItsOwnFiles(t *testing.T) { +func packageDigestIsItsOwnFiles(t *testing.T) { files := map[string]string{ "go.mod": "m1", "go.sum": "s1", "stdio.go": "a", "stdio_test.go": "t", "announce/announce.go": "b", "announce/testdata/x.json": "d", diff --git a/modules/mesh-delivery-indexer/internal/index/imports_test.go b/modules/mesh-delivery-indexer/internal/index/imports_test.go index 9d0a3bc..ba8e703 100644 --- a/modules/mesh-delivery-indexer/internal/index/imports_test.go +++ b/modules/mesh-delivery-indexer/internal/index/imports_test.go @@ -47,6 +47,7 @@ func (m *missingDir) Error() string { return "no directory " + m.dir } // a package the module does not import leaves it; one that changes an imported package moves it to the import form; // and the packages state holds one key with a digest per package. func TestImportsReportedMoveTheFingerprintOnlyWithAnImportedPackage(t *testing.T) { + t.Run("a build of an older fingerprint keeps no imports", buildOfAnOlderFingerprintKeepsNoImports) ctx := context.Background() ix, mods := newFormIndexer(t, mod{"avahi", catalogueManifest(t, "avahi")}) reportToolchain(t, ix, "mesh-build-go", "novox", "go", "go1.27.1") @@ -117,7 +118,7 @@ func TestImportsReportedMoveTheFingerprintOnlyWithAnImportedPackage(t *testing.T } // A build of a fingerprint the module no longer holds says nothing of its inputs now: its imports are not kept. -func TestABuildOfAnOlderFingerprintKeepsNoImports(t *testing.T) { +func buildOfAnOlderFingerprintKeepsNoImports(t *testing.T) { ctx := context.Background() ix, mods := newFormIndexer(t, mod{"avahi", catalogueManifest(t, "avahi")}) reportToolchain(t, ix, "mesh-build-go", "novox", "go", "go1.27.1") diff --git a/modules/mesh-delivery-indexer/judge/objects_test.go b/modules/mesh-delivery-indexer/judge/objects_test.go index f651619..a74bfe5 100644 --- a/modules/mesh-delivery-indexer/judge/objects_test.go +++ b/modules/mesh-delivery-indexer/judge/objects_test.go @@ -18,9 +18,10 @@ const knowledge = `{"module":"mesh-knowledge","version":"1", "streams":[{"name":"versions","retention":"history","max-mib":4096,"events":["version.stored"]}, {"name":"reviews","retention":"history","events":["review.stored"]}]}` -// ADR 0592 §5, §6, §25: a module's own object bucket and a stream that keeps its history are taken as declared; each -// bound and form the record names is refused, saying which. -func TestObjectBucketsAndHistoryStreamsAreJudgedAsADR0592Says(t *testing.T) { +// ADR 0592 §5, §6, §9, §25: a module's own object bucket and a stream that keeps its history are taken as declared (the +// history stream's bounds are in TestAWorkQueueStreamsValuesAreBounded); each bound and form of a bucket is refused, a +// bucket's name has one owner on the bus, and a module reads another's bucket only where the owner grants it. +func TestObjectBucketsAreJudgedAsADR0592Says(t *testing.T) { if _, err := ParseManifest([]byte(knowledge)); err != nil { t.Fatalf("mesh-knowledge's manifest was refused: %v", err) } @@ -30,11 +31,6 @@ func TestObjectBucketsAndHistoryStreamsAreJudgedAsADR0592Says(t *testing.T) { {`"name":"sections"`, `"name":"Sections"`}, // not a plain local name {`"name":"sections"`, `"name":"sections"},{"name":"sections","max-mib":1`}, // one bucket per name {`"grant":{"config":"readers"}`, `"grant":{"config":"nobody"}`}, // a grant not by a trusted value - {`"retention":"history","max-mib":4096`, `"retention":"history","max-age-days":30`}, - {`"retention":"history","max-mib":4096`, `"retention":"history","max-deliveries":3`}, - {`"retention":"history","max-mib":4096`, `"retention":"history","duplicates":2`}, - {`"retention":"history","max-mib":4096`, `"retention":"history","max-mib":8193`}, - {`"retention":"history","max-mib":4096`, `"retention":"forever"`}, } { raw := strings.Replace(knowledge, c.change, c.want, 1) if raw == knowledge { @@ -49,11 +45,6 @@ func TestObjectBucketsAndHistoryStreamsAreJudgedAsADR0592Says(t *testing.T) { !strings.Contains(err.Error(), "KV_") { t.Errorf("a bucket kv_x was taken: %v", err) } -} - -// ADR 0592 §5, §9: a bucket name has one owner on the bus, and a module reads another's bucket only where the owner -// grants it; a history stream is one of the bus's predefined forms. -func TestAnObjectBucketIsReadOnlyThroughItsOwnersGrant(t *testing.T) { parse := func(raw string) catalogue.Manifest { t.Helper() m, err := ParseManifest([]byte(raw)) diff --git a/modules/mesh-delivery-indexer/judge/rules_test.go b/modules/mesh-delivery-indexer/judge/rules_test.go index 76cbab5..424a0de 100644 --- a/modules/mesh-delivery-indexer/judge/rules_test.go +++ b/modules/mesh-delivery-indexer/judge/rules_test.go @@ -3247,35 +3247,32 @@ func TestAWaitIsRefusedUnlessItNamesOneFamilyOfTheToolRunner(t *testing.T) { } } -// 1178/AC2 (another module's consumes): a work-queue stream another module's consumes asks for is refused. -func TestAWorkQueueStreamAnotherModulesConsumesIsRefused(t *testing.T) { - sender := mailSenderManifestWithQueue("mail-sends") - reader := catalogue.Manifest{Module: "reader", Version: "1", Consumes: []string{"mesh-mail.mail.send.approved"}} - got := strings.Join(WorkQueueConsumedElsewhereProblems(catalogue.Shelf{"mesh-mail": sender, "reader": reader}), "; ") - if !strings.Contains(got, "reader") || !strings.Contains(got, "MAIL_SENDS") { - t.Fatalf("another module's consumes of a work-queue stream: %q", got) - } -} - -// 1178/AC2 (named): a work-queue stream no process names is refused. -func TestAWorkQueueStreamNoProcessNamesIsRefused(t *testing.T) { - m := mailSenderManifestWithQueue("") - got := strings.Join(WorkQueueStreamProblems(m), "; ") - if !strings.Contains(got, "mail-sends") || !strings.Contains(got, "no process names it") { - t.Fatalf("an unnamed work-queue stream: %q", got) - } -} - -// 1178/AC2 (named once): a work-queue stream exactly one process names is accepted. -func TestAWorkQueueStreamOneProcessNamesIsAccepted(t *testing.T) { - m := mailSenderManifestWithQueue("mail-sends") - if got := WorkQueueStreamProblems(m); len(got) != 0 { +// 1178/AC2: a work-queue stream is read by exactly one process of its module and by no other module's consumes: one +// process naming it is accepted; none, two, or another module's consumes is refused, naming it. +func TestAWorkQueueStreamIsReadByExactlyOneProcessOfItsModule(t *testing.T) { + if got := WorkQueueStreamProblems(mailSenderManifestWithQueue("mail-sends")); len(got) != 0 { t.Fatalf("a work-queue stream one process names was refused: %v", got) } + if got := strings.Join(WorkQueueStreamProblems(mailSenderManifestWithQueue("")), "; "); !strings.Contains(got, "mail-sends") || + !strings.Contains(got, "no process names it") { + t.Errorf("an unnamed work-queue stream: %q", got) + } + two := mailSenderManifestWithQueue("mail-sends") + two.Resources = append(two.Resources, map[string]any{"id": "resend", "type": "process", + "run": []any{"./mesh-mail", "send"}, "user": "mesh-mail-send", + "bus": map[string]any{"emits": []any{"mail.send.sent"}, "queues": []any{"mail-sends"}}}) + if got := strings.Join(WorkQueueStreamProblems(two), "; "); !strings.Contains(got, "mail-sends") || !strings.Contains(got, "2 processes name") { + t.Errorf("a work-queue stream two processes name: %q", got) + } + reader := catalogue.Manifest{Module: "reader", Version: "1", Consumes: []string{"mesh-mail.mail.send.approved"}} + got := strings.Join(WorkQueueConsumedElsewhereProblems(catalogue.Shelf{"mesh-mail": mailSenderManifestWithQueue("mail-sends"), "reader": reader}), "; ") + if !strings.Contains(got, "reader") || !strings.Contains(got, "MAIL_SENDS") { + t.Errorf("another module's consumes of a work-queue stream: %q", got) + } } -// 1177/AC2: a stream whose work-queue values are out of range, contradictory, or carries a grant is refused -// naming the stream and the rule. +// 1177/AC2, ADR 0592 §6: a stream whose work-queue or history values are out of range, contradictory, or carries a grant +// where it may not is refused naming the stream and the rule. func TestAWorkQueueStreamsValuesAreBounded(t *testing.T) { for name, c := range map[string]struct{ streams, says string }{ "max-deliveries 0": {`[{"name":"mail-sends","events":["mail.send.approved"],"retention":"work-queue",` + @@ -3293,6 +3290,15 @@ func TestAWorkQueueStreamsValuesAreBounded(t *testing.T) { "a work-queue stream carrying a grant": {`[{"name":"mail-sends","events":["mail.send.approved"],` + `"retention":"work-queue","max-deliveries":5,` + `"grant":{"config":"grants","events":"mail-sends.{key}.**"}}]`, "carrying a grant"}, + // ADR 0592 §6: a stream that keeps its history has no maximum age, deliveries or duplicate window. + "a history stream with a maximum age": {`[{"name":"mail-sends","events":["mail.send.approved"],` + + `"retention":"history","max-age-days":30}]`, "no maximum age"}, + "a history stream with max-deliveries": {`[{"name":"mail-sends","events":["mail.send.approved"],` + + `"retention":"history","max-deliveries":3}]`, "without retention"}, + "a history stream with duplicates": {`[{"name":"mail-sends","events":["mail.send.approved"],` + + `"retention":"history","duplicates":2}]`, "without retention"}, + "a history stream over its bound": {`[{"name":"mail-sends","events":["mail.send.approved"],` + + `"retention":"history","max-mib":8193}]`, "between"}, } { _, err := ParseManifest([]byte(mailManifest(t, c.streams, ""))) if err == nil || !strings.Contains(err.Error(), "mail-sends") || !strings.Contains(err.Error(), c.says) { @@ -3301,18 +3307,6 @@ func TestAWorkQueueStreamsValuesAreBounded(t *testing.T) { } } -// 1178/AC2 (named twice): a work-queue stream two processes name is refused. -func TestAWorkQueueStreamTwoProcessesNameIsRefused(t *testing.T) { - m := mailSenderManifestWithQueue("mail-sends") - m.Resources = append(m.Resources, map[string]any{"id": "resend", "type": "process", - "run": []any{"./mesh-mail", "send"}, "user": "mesh-mail-send", - "bus": map[string]any{"emits": []any{"mail.send.sent"}, "queues": []any{"mail-sends"}}}) - got := strings.Join(WorkQueueStreamProblems(m), "; ") - if !strings.Contains(got, "mail-sends") || !strings.Contains(got, "2 processes name") { - t.Fatalf("a work-queue stream two processes name: %q", got) - } -} - // A zone names the listen that answers it, or there is nothing to forward to (novox/hq ADR 0199). func TestAZoneMustNameOneOfTheModulesListens(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"lab","version":"1", diff --git a/modules/mesh-delivery-view/cmd/mesh-delivery-view-tools/main_test.go b/modules/mesh-delivery-view/cmd/mesh-delivery-view-tools/main_test.go index 43364b3..4d54278 100644 --- a/modules/mesh-delivery-view/cmd/mesh-delivery-view-tools/main_test.go +++ b/modules/mesh-delivery-view/cmd/mesh-delivery-view-tools/main_test.go @@ -54,6 +54,7 @@ const ( // 1562/AC1: indexer_module answers the key's value as stored: FP, FP2, None2, Inputs2, Path and Toolchains are all there. func TestModuleToolAnswersTheStoredValue(t *testing.T) { + t.Run("indexer_packages answers the published modules", packagesToolAnswersThePublishedModules) r := fake{"a": withFP2, "b": withNone}.reader() for key, want := range map[string]string{"a": withFP2, "b": withNone} { out, err := run(t, r, view.ModuleReadTool, map[string]any{"module": key}) @@ -550,7 +551,7 @@ func TestAssignerDifferencesAndNodeHavesToolsAnswerAsStored(t *testing.T) { } // ADR 0593 §2 (D2): indexer_packages answers the indexer's published packages, one Go module by its path or all. -func TestPackagesToolAnswersThePublishedModules(t *testing.T) { +func packagesToolAnswersThePublishedModules(t *testing.T) { key, err := delivery.PackagesKey("git.novox.be/novox/mesh-sdk/go") if err != nil { t.Fatal(err)