Fold the release's new tests into existing ones to stay within the test budget
mesh-delivery is over its budget (810 unit, 73 integration on main), so this branch adds none net: its new cases are subtests, the three work-queue process tests and the consumes test become one, the history stream bounds join the stream values table, and the go/-only mesh-sdk merge check joins the one new integration test. buildrun's 20 unit and 1 integration tests moved in from mesh-sdk with it. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.<digest> holds and the running SDK reads; the go toolchain is reported. Within 5 s of the start
|
||||
|
||||
+21
-2
@@ -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) {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user