From dba15eb4b15234d26297716de98fc35225664551 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 5 Nov 2026 17:11:58 +0100 Subject: [PATCH] The judge's rule tests are grouped by kind into subtests, each by its former name: unit count 900 to 671 (D-26, issue 1966) Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i --- .../mesh-delivery-indexer/judge/rules_test.go | 757 ++++++++++++------ 1 file changed, 518 insertions(+), 239 deletions(-) diff --git a/modules/mesh-delivery-indexer/judge/rules_test.go b/modules/mesh-delivery-indexer/judge/rules_test.go index 2d3a8074..d81283a3 100644 --- a/modules/mesh-delivery-indexer/judge/rules_test.go +++ b/modules/mesh-delivery-indexer/judge/rules_test.go @@ -29,7 +29,7 @@ import ( // declare is refused where it is written rather than reaching the holder as the literal text. (The // catalogue check refuses a hand-written backup line at all since ADR 0233; parsing still reads one, // because a module on the shelf was written before.) -func TestABackupNamingAnUndeclaredDirectoryIsRefused(t *testing.T) { +func caseABackupNamingAnUndeclaredDirectoryIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"pg","version":"1", "contributions":[{"seat":"node-backup","kind":"backup","content":"path ${dir:nowhere}"}]}`)) if err == nil || !strings.Contains(err.Error(), "nowhere") { @@ -42,7 +42,7 @@ func TestABackupNamingAnUndeclaredDirectoryIsRefused(t *testing.T) { // A binary is pinned to one operating system at link time, so a host refuses to touch a machine it // was not built for. An artifact that says nothing would be compiled for whatever the build machine // happened to be — which reads as portable and is not, and is the fault this check exists for. -func TestABinaryMustSayWhichSystemItIsFor(t *testing.T) { +func caseABinaryMustSayWhichSystemItIsFor(t *testing.T) { got := buildProblemsOf(t, bundleFor("go", "")) if !strings.Contains(got, "says no system") { t.Fatalf("a compiled bundle with no system was accepted:\n%s", got) @@ -55,7 +55,7 @@ func TestABinaryMustSayWhichSystemItIsFor(t *testing.T) { } } -func TestABlockOutsideTheShapeIsRefused(t *testing.T) { +func caseABlockOutsideTheShapeIsRefused(t *testing.T) { cases := map[string]string{ `{"seat":"node-bar","kind":"block","content":"[[block]]"}`: "has no data", `{"seat":"node-bar","kind":"block","content":"x","data":{"bar":"top","place":"status","shows":"battery"}}`: "has content", @@ -83,7 +83,7 @@ func TestABlockOutsideTheShapeIsRefused(t *testing.T) { } } -func TestABuildContextOnASeatNamesNoForge(t *testing.T) { +func caseABuildContextOnASeatNamesNoForge(t *testing.T) { m := catalogue.Manifest{Module: "packager", Build: &catalogue.Build{Artifacts: []catalogue.Artifact{ {Name: "server", Kind: "image", From: "Dockerfile", Context: &catalogue.ArtifactContext{Seat: "git", Repository: "org/controller", Ref: "main"}}, @@ -97,7 +97,7 @@ func TestABuildContextOnASeatNamesNoForge(t *testing.T) { } } -func TestABuildsBundlesAreCarriedOnTheResolvedManifest(t *testing.T) { +func caseABuildsBundlesAreCarriedOnTheResolvedManifest(t *testing.T) { m := aToolsModule(t, "nftables", "tools/index.js") if len(m.Bundles) != 1 { t.Fatalf("the resolved manifest carries %d bundle(s), not the one the build made", len(m.Bundles)) @@ -119,7 +119,7 @@ func TestABuildsBundlesAreCarriedOnTheResolvedManifest(t *testing.T) { // novox/hq ADR 0192: a tools bundle says what it is given, written with ${dir:…} and ${port:…}, and the judge takes // it; how the node-engine resolves the words per machine and hands them to the runtime is its own composition's to test // (ADR 0593 §7). -func TestABundleIsGivenItsWordsResolvedForThisMachine(t *testing.T) { +func caseABundleIsGivenItsWordsResolvedForThisMachine(t *testing.T) { dash := catalogue.Manifest{Module: "dash", Version: "1", Tools: []string{"status"}, Listens: []catalogue.Listening{{Name: "web", Port: 3000, Protocol: "tcp"}}, OwnSecrets: catalogue.OwnSecrets{"token": {Path: "${dir:mesh-state}/token"}}, @@ -143,7 +143,7 @@ func TestABundleIsGivenItsWordsResolvedForThisMachine(t *testing.T) { // novox/hq 04-ISSUES/216: a bundle nothing loads, runs or unpacks is refused at registration; saying // `loads`, listing `tools`, or a resource naming it admits it. -func TestABundleNothingDeliversIsRefused(t *testing.T) { +func caseABundleNothingDeliversIsRefused(t *testing.T) { base := func() catalogue.Manifest { return catalogue.Manifest{Module: "baserow", Version: "1", Build: &catalogue.Build{Artifacts: []catalogue.Artifact{ {Name: "tools", Kind: catalogue.ArtifactBundle, Language: "typescript", Entrypoints: []string{"tools/index.js"}}}}} @@ -172,7 +172,7 @@ func TestABundleNothingDeliversIsRefused(t *testing.T) { } } -func TestABundlesWordsAreRefusedWhenTheyAreNotPathsOrConstants(t *testing.T) { +func caseABundlesWordsAreRefusedWhenTheyAreNotPathsOrConstants(t *testing.T) { m := catalogue.Manifest{Module: "dash", Version: "1", Build: &catalogue.Build{Artifacts: []catalogue.Artifact{ {Name: "tools", Kind: catalogue.ArtifactBundle, Language: "typescript", Entrypoints: []string{"tools/index.js"}, Env: map[string]string{"DASH_TOKEN": "${secret:token}", catalogue.RuntimeBrokerFile: "/x", "DASH_PEER": "${bound:db:url}"}}, @@ -191,7 +191,7 @@ func TestABundlesWordsAreRefusedWhenTheyAreNotPathsOrConstants(t *testing.T) { } } -func TestABusyIsHeldToItsShape(t *testing.T) { +func caseABusyIsHeldToItsShape(t *testing.T) { if _, err := ParseManifest(busyManifest(t, "agent", map[string]any{"command": "mesh-builder busy"})); err != nil { t.Fatalf("a well-formed busy was refused: %v", err) } @@ -220,7 +220,7 @@ func TestABusyIsHeldToItsShape(t *testing.T) { // The claim may say what it serves for the role instead, when the module's own tools are not the // seat's verbs (ADR 0160). -func TestAClaimMayNameWhatItServesForTheSeat(t *testing.T) { +func caseAClaimMayNameWhatItServesForTheSeat(t *testing.T) { m := telegram() m.Tools = []string{"telegram_send"} m.Claims = append([]catalogue.Claim(nil), m.Claims...) @@ -235,7 +235,7 @@ func TestAClaimMayNameWhatItServesForTheSeat(t *testing.T) { } // A claim at the wrong scope is a different seat than the one declared. -func TestAClaimMustMatchTheDeclaredScope(t *testing.T) { +func caseAClaimMustMatchTheDeclaredScope(t *testing.T) { m := telegram() m.Claims = []catalogue.Claim{{Name: "telegram-sender", Scope: catalogue.ScopeNode}} got := problemsFor(t, catalogue.Shelf{"telegram": m}) @@ -246,7 +246,7 @@ func TestAClaimMustMatchTheDeclaredScope(t *testing.T) { // And the same claim is fine once something declares that seat, which is the case the parser // could not have distinguished. -func TestAClaimOnASeatAnotherModuleDeclaresIsAccepted(t *testing.T) { +func caseAClaimOnASeatAnotherModuleDeclaresIsAccepted(t *testing.T) { claimant, err := ParseManifest(claimed(`[{"name":"the-anything","scope":"node"}]`)) if err != nil { t.Fatal(err) @@ -277,7 +277,7 @@ func TestAClaimOnASeatAnotherModuleDeclaresIsAccepted(t *testing.T) { // is perfectly good, and the parser cannot tell the two cases apart. So the parser accepts it and // registration refuses it — the same guarantee, at the same moment work would otherwise start, // from a set nobody maintains by hand. -func TestAClaimOnASeatNobodyDeclaresIsRefusedAtRegistration(t *testing.T) { +func caseAClaimOnASeatNobodyDeclaresIsRefusedAtRegistration(t *testing.T) { m, err := ParseManifest(claimed(`[{"name":"the-anything","scope":"node"}]`)) if err != nil { t.Fatalf("the parser judged a claim it cannot judge alone: %v", err) @@ -293,7 +293,7 @@ func TestAClaimOnASeatNobodyDeclaresIsRefusedAtRegistration(t *testing.T) { } } -func TestAClaimThatIsMalformedIsRefusedOnceForThat(t *testing.T) { +func caseAClaimThatIsMalformedIsRefusedOnceForThat(t *testing.T) { // Not a second time for being unknown: one mistake, one line. _, err := ParseManifest(claimed(`[{"name":"Not A Name","scope":"node"}]`)) if err == nil { @@ -306,7 +306,7 @@ func TestAClaimThatIsMalformedIsRefusedOnceForThat(t *testing.T) { // A holder declares every path its seat names, as a resource or as a file the mesh renders for it, or // CanHold refuses it naming the seat and each missing path — the judgement registration and handover share. -func TestAClaimWithoutTheSeatsPathsIsRefused(t *testing.T) { +func caseAClaimWithoutTheSeatsPathsIsRefused(t *testing.T) { seat := hostnameSeat(t) hosts := map[string]any{"id": "hosts", "type": "file", "path": "/etc/hosts", "content": "x"} name := map[string]any{"id": "name", "type": "file", "path": "/etc/hostname", "content": "x"} @@ -341,7 +341,7 @@ func TestAClaimWithoutTheSeatsPathsIsRefused(t *testing.T) { } } -func TestACompiledBundleStillMustSayItsSystem(t *testing.T) { +func caseACompiledBundleStillMustSayItsSystem(t *testing.T) { b := &catalogue.Build{Artifacts: []catalogue.Artifact{{ Name: "host", Kind: catalogue.ArtifactBundle, Language: "go", From: "cmd/mesh-host", }}} @@ -350,7 +350,7 @@ func TestACompiledBundleStillMustSayItsSystem(t *testing.T) { } } -func TestAContainerCannotBeBothRunOnceAndScheduled(t *testing.T) { +func caseAContainerCannotBeBothRunOnceAndScheduled(t *testing.T) { // A container runs once and gates, or on a cadence, or stays up — never two (novox/hq ADR 0053). digest := "@sha256:" + strings.Repeat("a", 64) bad := []byte(`{"module":"m","resources":[ @@ -363,7 +363,7 @@ func TestAContainerCannotBeBothRunOnceAndScheduled(t *testing.T) { } } -func TestAContributionLocalNameMustBeUsable(t *testing.T) { +func caseAContributionLocalNameMustBeUsable(t *testing.T) { for _, bad := range []string{ // Not a usable name. `{"module":"minio","version":"1","requires":["route"], @@ -378,7 +378,7 @@ func TestAContributionLocalNameMustBeUsable(t *testing.T) { } } -func TestAContributionPlaceholderOutsideTheHolderIsRefused(t *testing.T) { +func caseAContributionPlaceholderOutsideTheHolderIsRefused(t *testing.T) { raw := `{"module":"laptop","resources":[{"id":"t","type":"file","path":"/etc/t","content":"${contribution:node-hotkeys:trigger}"}]}` if _, err := ParseManifest([]byte(raw)); err == nil || !strings.Contains(err.Error(), "laptop does not claim node-hotkeys") { t.Errorf("a placeholder outside the holder was accepted: %v", err) @@ -389,7 +389,7 @@ func TestAContributionPlaceholderOutsideTheHolderIsRefused(t *testing.T) { } } -func TestAContributionToASeatThatDoesNotReceiveItIsRefused(t *testing.T) { +func caseAContributionToASeatThatDoesNotReceiveItIsRefused(t *testing.T) { cases := map[string]string{ `{"seat":"node-hotkeys","kind":"config","content":"x"}`: "it receives trigger", `{"seat":"node-nothing","kind":"trigger","content":"x"}`: "the mesh does not define", @@ -404,7 +404,7 @@ func TestAContributionToASeatThatDoesNotReceiveItIsRefused(t *testing.T) { } } -func TestADeclaredStoreParsesAndPassesTheCheck(t *testing.T) { +func caseADeclaredStoreParsesAndPassesTheCheck(t *testing.T) { m := mustParse(t, declaredStore) if problems := DataProblems(catalogue.Shelf{"pg": m}); len(problems) > 0 { t.Fatalf("a store declaring its data was refused: %v", problems) @@ -421,7 +421,7 @@ func TestADeclaredStoreParsesAndPassesTheCheck(t *testing.T) { } // The node-engine's rules, for directories and — as the engine judges them since novox/hq issue 495 — files. -func TestADefinitionIsRefusedWhereTheNodeEngineRefusesItsPaths(t *testing.T) { +func caseADefinitionIsRefusedWhereTheNodeEngineRefusesItsPaths(t *testing.T) { refused := map[string]string{ "a stated directory in docker's data": `{"module": "sidecar", "version": "1", "resources": [ {"id": "volumes", "type": "directory", "path": "/var/lib/docker/volumes/x"}]}`, @@ -481,7 +481,7 @@ func TestADefinitionIsRefusedWhereTheNodeEngineRefusesItsPaths(t *testing.T) { // A definition names no installation (novox/hq ADR 0112, ADR 0155). What the mesh acts on is judged; // prose is not; the world's registries and resolvers are the world's; a declared exception is a // reason a reader sees. -func TestADefinitionNamingAnInstallationIsNamedBack(t *testing.T) { +func caseADefinitionNamingAnInstallationIsNamedBack(t *testing.T) { m := catalogue.Manifest{Module: "idp", Resources: []map[string]any{ {"id": "server", "type": "container", "image": "quay.io/keycloak/keycloak@sha256:aa", "env": map[string]any{"KC_HOSTNAME": "https://login.mesh-one.be"}}, @@ -503,7 +503,7 @@ func TestADefinitionNamingAnInstallationIsNamedBack(t *testing.T) { } } -func TestADeliveringSeatIsOnlyHeldByAModuleThatProvides(t *testing.T) { +func caseADeliveringSeatIsOnlyHeldByAModuleThatProvides(t *testing.T) { // Holding it makes the module the mesh's answer for the provision. A module that cannot answer // would be the answer anyway, and every consumer would be sent to it. // And refused at registration, where the seat set is the store's: what a seat delivers is @@ -519,7 +519,7 @@ func TestADeliveringSeatIsOnlyHeldByAModuleThatProvides(t *testing.T) { } } -func TestADirectoryBeneathAPlacedOneIsPlacedWithIt(t *testing.T) { +func caseADirectoryBeneathAPlacedOneIsPlacedWithIt(t *testing.T) { t.Run("anEnvironmentItemIsTypedAndNamesWhatItNeeds", anEnvironmentItemIsTypedAndNamesWhatItNeeds) t.Run("theMeshsDirectoryForAModuleIsAPlace", theMeshsDirectoryForAModuleIsAPlace) t.Run("anIdentityServedAsADNSLabelIsBoundedToOne", anIdentityServedAsADNSLabelIsBoundedToOne) @@ -542,7 +542,7 @@ func TestADirectoryBeneathAPlacedOneIsPlacedWithIt(t *testing.T) { } -func TestADirectoryPlacedInDockersDataIsRefusedWhereTheDefinitionIsJudged(t *testing.T) { +func caseADirectoryPlacedInDockersDataIsRefusedWhereTheDefinitionIsJudged(t *testing.T) { // The #205 shape, as it was merged. _, err := ParseManifest([]byte(`{"module": "docker", "version": "1", "resources": [{"id": "state", "type": "directory", "place": "."}]}`)) @@ -556,7 +556,7 @@ func TestADirectoryPlacedInDockersDataIsRefusedWhereTheDefinitionIsJudged(t *tes } } -func TestAFileNamingBothATemplateAndContentIsRefused(t *testing.T) { +func caseAFileNamingBothATemplateAndContentIsRefused(t *testing.T) { raw := strings.Replace(templatedTwin, `"template":"files/tidy.conf"`, `"template":"files/tidy.conf","content":"x"`, 1) _, err := ParseManifest([]byte(raw)) @@ -567,7 +567,7 @@ func TestAFileNamingBothATemplateAndContentIsRefused(t *testing.T) { // A file that asks for a setting says whether what it asks is trusted (novox/hq issue 339): `trusted` is a // boolean, on a file alone, and a file asking for a setting without it is named. -func TestAFileSaysWhetherItsSettingsAreTrusted(t *testing.T) { +func caseAFileSaysWhetherItsSettingsAreTrusted(t *testing.T) { m := catalogue.Manifest{Module: "power", Resources: []map[string]any{ {"id": "said", "type": "file", "path": "/etc/a", "trusted": true, "content": "${setting:a}"}, {"id": "unsaid", "type": "file", "path": "/etc/b", "content": "${setting:b}"}, @@ -592,7 +592,7 @@ func TestAFileSaysWhetherItsSettingsAreTrusted(t *testing.T) { } } -func TestAGoBundleMayNameItsCommand(t *testing.T) { +func caseAGoBundleMayNameItsCommand(t *testing.T) { b := &catalogue.Build{Artifacts: []catalogue.Artifact{{ Name: "host-arch", Kind: catalogue.ArtifactBundle, Language: "go", System: "arch", From: "cmd/mesh-host", @@ -604,7 +604,7 @@ func TestAGoBundleMayNameItsCommand(t *testing.T) { // novox/hq ADR 0193: a Go tools bundle is served — its binary is what the runtime starts, delivered // like any tools bundle, named to the runtime where a TypeScript bundle names its launcher. -func TestAGoToolsBundleIsServedByItsBinary(t *testing.T) { +func caseAGoToolsBundleIsServedByItsBinary(t *testing.T) { lamp := catalogue.Manifest{Module: "lamp", Version: "1", Tools: []string{"on"}, Build: &catalogue.Build{Artifacts: []catalogue.Artifact{{Name: "tools", Kind: catalogue.ArtifactBundle, Language: "go", System: "arch", From: "cmd/lamp-tools"}}}} @@ -632,7 +632,7 @@ func TestAGoToolsBundleIsServedByItsBinary(t *testing.T) { } } -func TestAGuardedPortMustBeAPort(t *testing.T) { +func caseAGuardedPortMustBeAPort(t *testing.T) { if _, err := ParseManifest([]byte(`{"module":"postgres","guards":[5432]}`)); err != nil { t.Fatalf("guards is refused: %v", err) } @@ -645,7 +645,7 @@ func TestAGuardedPortMustBeAPort(t *testing.T) { // the vault makes a first value in that form for a provider it holds no row of: one of its own secrets shared by // every consumer, a login per consumer when the offer says no credential, issued by its software, or given by a // person (the offer's own secret issued outside). -func TestAHandedModulesPlanNamesTheCredentialFormOfItsProvidersOffer(t *testing.T) { +func caseAHandedModulesPlanNamesTheCredentialFormOfItsProvidersOffer(t *testing.T) { storeOffering := func(credential string) catalogue.Manifest { raw := `{"module":"store","version":"1","provides":[{"name":"postgres-database","scope":"mesh"` + credential + `}],"serves":{"postgres-database":{"port":5432}}` @@ -696,7 +696,7 @@ func TestAHandedModulesPlanNamesTheCredentialFormOfItsProvidersOffer(t *testing. } // A holder that does not answer what the seat promises is a caller's timeout, found here instead. -func TestAHolderMustServeWhatItsSeatPromises(t *testing.T) { +func caseAHolderMustServeWhatItsSeatPromises(t *testing.T) { m := telegram() m.Tools = nil // declares the seat, serves none of it got := problemsFor(t, catalogue.Shelf{"telegram": m}) @@ -706,7 +706,7 @@ func TestAHolderMustServeWhatItsSeatPromises(t *testing.T) { } // issue 900, ADR 0394 §2: a holder of node-files runs as the tool runner's account, so it declares no runs-as. -func TestAHolderOfNodeFilesDeclaringRunsAsIsRefused(t *testing.T) { +func caseAHolderOfNodeFilesDeclaringRunsAsIsRefused(t *testing.T) { p := FilesHolderProblems(catalogue.Manifest{Module: "files", RunsAs: "mesh-files", Claims: []catalogue.Claim{{Name: catalogue.FilesSeat}}}) if len(p) != 1 || !strings.Contains(p[0], "0394") || !strings.Contains(p[0], "runs-as") { t.Errorf("a holder declaring runs-as was not refused: %v", p) @@ -721,7 +721,7 @@ func TestAHolderOfNodeFilesDeclaringRunsAsIsRefused(t *testing.T) { // novox/hq ADR 0310 §3: a holder of node-reads reads as an account of its own; one the machine's runtime would // carry — as the operator's account — is refused at parse. -func TestAHolderOfNodeReadsWithoutAnAccountOfItsOwnIsRefused(t *testing.T) { +func caseAHolderOfNodeReadsWithoutAnAccountOfItsOwnIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module": "reads", "version": "1", "claims": [{"name": "node-reads", "scope": "node"}]}`)) if err == nil || !strings.Contains(err.Error(), "runs-as") || !strings.Contains(err.Error(), "0310") { @@ -733,7 +733,7 @@ func TestAHolderOfNodeReadsWithoutAnAccountOfItsOwnIsRefused(t *testing.T) { } } -func TestAHolderPlacesEveryCombinationOnceWithATemplateThatRendersEveryExample(t *testing.T) { +func caseAHolderPlacesEveryCombinationOnceWithATemplateThatRendersEveryExample(t *testing.T) { holder := func(template string, contents ...string) string { var res []string for i, c := range contents { @@ -775,7 +775,7 @@ func TestAHolderPlacesEveryCombinationOnceWithATemplateThatRendersEveryExample(t } // A jail with no name, no pattern, or a name another jail of the same module already took is refused. -func TestAJailIsNamedOnceAndSaysWhatAFailureLooksLike(t *testing.T) { +func caseAJailIsNamedOnceAndSaysWhatAFailureLooksLike(t *testing.T) { m := catalogue.Manifest{Module: "mailu", Jails: []catalogue.Jail{ {Name: "", Failregex: "^.*rip=$"}, {Name: "mailu-front", Failregex: " "}, @@ -792,7 +792,7 @@ func TestAJailIsNamedOnceAndSaysWhatAFailureLooksLike(t *testing.T) { // A jail whose pattern names twice is refused by name: fail2ban would read it as a duplicate // capture group and refuse its whole configuration, leaving the machine with no bans at all — which // is what happened on the control node the day this was built (novox/hq ADR 0179). -func TestAJailsPatternNamesTheHostOncePerShape(t *testing.T) { +func caseAJailsPatternNamesTheHostOncePerShape(t *testing.T) { twice := catalogue.Manifest{Module: "route-proxy", Jails: []catalogue.Jail{{ Name: "route-proxy", Failregex: `^.*(?:refused for :\d+|asked from :\d+)$`, @@ -819,7 +819,7 @@ func TestAJailsPatternNamesTheHostOncePerShape(t *testing.T) { // The operator's own value is told by what a key's name is about: its last word, or its last two as // a known compound; a plural as its singular; and never a number or a switch. -func TestAKeyIsTheOperatorsByWhatItIsAbout(t *testing.T) { +func caseAKeyIsTheOperatorsByWhatItIsAbout(t *testing.T) { for _, key := range []string{"max-tokens", "show-hostname", "ghost-opacity", "users-per-page", "mailbox-size", "font-size", "width", "keyboard-delay", "ipv6-preferred", "client-width", "user-agent", "url-timeout", "site-title", "cert-renewal-days", "name", "font-name", "allow-resize", "use-gpu", "disable-sender-check", @@ -854,7 +854,7 @@ func TestAKeyIsTheOperatorsByWhatItIsAbout(t *testing.T) { } } -func TestAKindedBenchNeedsAKindAndNoOtherSeatTakesOne(t *testing.T) { +func caseAKindedBenchNeedsAKindAndNoOtherSeatTakesOne(t *testing.T) { got := problemsFor(t, catalogue.Shelf{"messenger": router(), "nameless": aChannel("nameless", "")}) if !strings.Contains(got, "claims the kinded bench channel and names no kind") { t.Fatalf("a claim without a kind stood: %s", got) @@ -871,7 +871,7 @@ func TestAKindedBenchNeedsAKindAndNoOtherSeatTakesOne(t *testing.T) { } // A local name names one credential: two requirements may not share it (review C2). -func TestALocalNameIsUniqueAcrossRequirements(t *testing.T) { +func caseALocalNameIsUniqueAcrossRequirements(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"x","version":"1","requires":["secret","postgres-database"], "secrets":{"secret":{"x":"/var/lib/x/a"},"postgres-database":{"x":"/var/lib/x/b"}}}`)) if err == nil || !strings.Contains(err.Error(), "both under") { @@ -879,7 +879,7 @@ func TestALocalNameIsUniqueAcrossRequirements(t *testing.T) { } } -func TestALocalNameMayNotCollideWithWhatTheModuleAlreadyCallsSomething(t *testing.T) { +func caseALocalNameMayNotCollideWithWhatTheModuleAlreadyCallsSomething(t *testing.T) { for _, bad := range []string{ // One of the module's own secrets. `{"module":"ca","version":"1","requires":["secret"],"own-secrets":{"root-key":"/var/lib/ca/own"}, @@ -900,7 +900,7 @@ func TestALocalNameMayNotCollideWithWhatTheModuleAlreadyCallsSomething(t *testin // The catalogue check refuses a log outside the caps, with a name that is not one plain token, with a // field the mesh does not know, or kept by a module whose own name is not one plain token. -func TestALogIsNamedLocallyAndCapped(t *testing.T) { +func caseALogIsNamedLocallyAndCapped(t *testing.T) { for _, c := range []struct{ manifest, says string }{ {`{"module":"a","version":"1","logs":["mesh.changes"]}`, `keeps log "mesh.changes": a log is named locally`}, {`{"module":"a","version":"1","logs":["my_changes"]}`, `keeps log "my_changes"`}, @@ -930,7 +930,7 @@ func TestALogIsNamedLocallyAndCapped(t *testing.T) { } } -func TestAMaintenanceWindowIsRefusedWhereTheDefinitionShowsItCannotMean(t *testing.T) { +func caseAMaintenanceWindowIsRefusedWhereTheDefinitionShowsItCannotMean(t *testing.T) { for _, c := range []struct { name string step map[string]any @@ -984,7 +984,7 @@ func TestAMaintenanceWindowIsRefusedWhereTheDefinitionShowsItCannotMean(t *testi } // What ADR 0203 §2 allows a contribution to say, refused at parse when it says anything else. -func TestAMalformedEnvironmentIsRefusedAtParse(t *testing.T) { +func caseAMalformedEnvironmentIsRefusedAtParse(t *testing.T) { for _, c := range []struct{ environment, want string }{ {`{"variables":{"1X":"a"}}`, `tool sets the variable "1X", which is not a name a shell accepts`}, {`{"variables":{"MY-VAR":"a"}}`, `tool sets the variable "MY-VAR", which is not a name a shell accepts`}, @@ -1017,7 +1017,7 @@ func TestAMalformedEnvironmentIsRefusedAtParse(t *testing.T) { } } -func TestAMalformedFamilyIsRefused(t *testing.T) { +func caseAMalformedFamilyIsRefused(t *testing.T) { for name, c := range map[string]struct{ own, says string }{ "made by the mesh": {`"smb-password-*":{"path":"/s/smb-password-*.secret","taken":"at-start"}`, "issued-by"}, "no star in its path": {`"smb-password-*":{"path":"/s/smb-password.secret","issued-by":"outside"}`, @@ -1035,7 +1035,7 @@ func TestAMalformedFamilyIsRefused(t *testing.T) { } // A prompt that is not one short line naming only {member} is refused by the module check (novox/hq issue 789). -func TestAMalformedPromptIsRefused(t *testing.T) { +func caseAMalformedPromptIsRefused(t *testing.T) { for name, c := range map[string]struct{ prompt, says string }{ "a newline": {"the password of\nthe mail account {member}", "one line"}, "over 120 characters": {"the password of the mail account {member}, which this mesh needs to log in to " + @@ -1052,7 +1052,7 @@ func TestAMalformedPromptIsRefused(t *testing.T) { } } -func TestAMalformedScheduleIsRefused(t *testing.T) { +func caseAMalformedScheduleIsRefused(t *testing.T) { digest := "@sha256:" + strings.Repeat("a", 64) bad := []byte(`{"module":"m","resources":[ {"id":"sync","type":"container","name":"sync","image":"registry.example/x` + digest + `","schedule":"every night"} @@ -1081,7 +1081,7 @@ func TestAMalformedScheduleIsRefused(t *testing.T) { // A manifest naming font-size registers against the list; one naming a key not on it, or of another type, is // refused — judged against the list given, whatever the mesh published. -func TestAManifestIsJudgedAgainstTheListOfItsTree(t *testing.T) { +func caseAManifestIsJudgedAgainstTheListOfItsTree(t *testing.T) { withPredefined(t, nil) list, err := catalogue.ParsePredefined([]byte(theFirstKeys)) if err != nil { @@ -1113,7 +1113,7 @@ func TestAManifestIsJudgedAgainstTheListOfItsTree(t *testing.T) { // A manifest key nothing reads is worse than a key that is refused: five HAL manifests carried // `scope:`, which read as a restriction and restricted nothing (novox/hq 04-ISSUES/003). The host's // declaration parser has always refused unknown keys; manifests never did. -func TestAManifestKeyNothingReadsIsRefused(t *testing.T) { +func caseAManifestKeyNothingReadsIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"web","scope":"mesh"}`)) if err == nil { t.Fatal("a manifest with a key nothing reads was accepted, which is how scope: survived") @@ -1125,7 +1125,7 @@ func TestAManifestKeyNothingReadsIsRefused(t *testing.T) { // `local-network` is a source a manifest may name (§1, changing ADR 0045 §3), and an unknown source is // still refused. -func TestAManifestMayListenFromTheLocalNetwork(t *testing.T) { +func caseAManifestMayListenFromTheLocalNetwork(t *testing.T) { if _, err := ParseManifest([]byte(`{"module":"mosquitto","version":"1", "listens":[{"port":1883,"from":"local-network"}]}`)); err != nil { t.Fatalf("a listen from the local network is refused: %v", err) @@ -1138,7 +1138,7 @@ func TestAManifestMayListenFromTheLocalNetwork(t *testing.T) { } // A module uses one form or the other, never both. -func TestAManifestMixingTheConfigAndSettingsFormsIsRefused(t *testing.T) { +func caseAManifestMixingTheConfigAndSettingsFormsIsRefused(t *testing.T) { m := inConfigForm() resourceOf(m, "configuration")["content"] = "font = ${config:font-size}\nwidth = ${setting:width}\nfrom = ${config:sender}\n" refused(t, m, "mixes", "${setting:", "config") @@ -1153,7 +1153,7 @@ func TestAManifestMixingTheConfigAndSettingsFormsIsRefused(t *testing.T) { refused(t, m, "mixes", "settings") } -func TestAManifestProvidingAmqpIsRefused(t *testing.T) { +func caseAManifestProvidingAmqpIsRefused(t *testing.T) { raw := []byte(`{"module":"old-broker","version":"1","provides":[{"name":"amqp","scope":"mesh"}]}`) _, err := ParseManifest(raw) if err == nil || !strings.Contains(err.Error(), `provides "amqp", which is not a provision`) { @@ -1161,7 +1161,7 @@ func TestAManifestProvidingAmqpIsRefused(t *testing.T) { } } -func TestAManifestRequiringAmqpIsRefused(t *testing.T) { +func caseAManifestRequiringAmqpIsRefused(t *testing.T) { raw := []byte(`{"module":"forwarder","version":"1","requires":["amqp"]}`) _, err := ParseManifest(raw) if err == nil || !strings.Contains(err.Error(), `requires "amqp", which is not a provision`) { @@ -1175,7 +1175,7 @@ func TestAManifestRequiringAmqpIsRefused(t *testing.T) { // reaching for the wrong one parsed cleanly and failed somewhere else entirely. Refusing the old // name with "unknown field" would be correct and unhelpful: whoever wrote it knew what they meant, // and the mesh knows what it is called now. -func TestAManifestUsingTheOldNameIsToldTheNewOne(t *testing.T) { +func caseAManifestUsingTheOldNameIsToldTheNewOne(t *testing.T) { _, err := ParseManifest([]byte( `{"module":"postgres","version":"1","needs":{"superuser":"/var/lib/superuser"}}`)) if err == nil { @@ -1190,7 +1190,7 @@ func TestAManifestUsingTheOldNameIsToldTheNewOne(t *testing.T) { // A manifest in the config form registers with the group a config value fills, and the value is placed (a container's // groups count as a place for it); a placeholder in any other shape is refused where the manifest is read. -func TestAManifestWhoseContainerTakesItsGroupFromConfigRegisters(t *testing.T) { +func caseAManifestWhoseContainerTakesItsGroupFromConfigRegisters(t *testing.T) { m := map[string]any{ "module": "n8n", "version": "1", "config": map[string]any{"media-gid": map[string]any{"type": "number", "minimum": 1, "required": true, @@ -1208,7 +1208,7 @@ func TestAManifestWhoseContainerTakesItsGroupFromConfigRegisters(t *testing.T) { } } -func TestAManifestWithoutUnhealthyIsNotUrgent(t *testing.T) { +func caseAManifestWithoutUnhealthyIsNotUrgent(t *testing.T) { m, err := ParseManifest([]byte(`{"module":"notes","version":"1"}`)) if err != nil { t.Fatal(err) @@ -1222,7 +1222,7 @@ func TestAManifestWithoutUnhealthyIsNotUrgent(t *testing.T) { } } -func TestAMapReferenceToNoDirectoryRefusesAtTheManifest(t *testing.T) { +func caseAMapReferenceToNoDirectoryRefusesAtTheManifest(t *testing.T) { m := catalogue.Manifest{ Module: "photos", Resources: []map[string]any{{"id": "state", "type": "directory", "place": "."}}, @@ -1236,7 +1236,7 @@ func TestAMapReferenceToNoDirectoryRefusesAtTheManifest(t *testing.T) { // The catalogue check — the strict parse registration runs too — refuses each by name, with the // module and the field it stands in, and says nothing about the shell's own syntax. -func TestAMisspelledPlaceholderIsRefusedAtTheCheck(t *testing.T) { +func caseAMisspelledPlaceholderIsRefusedAtTheCheck(t *testing.T) { raw := `{"module":"speller","version":"1","resources":[{"id":"rc","type":"file","path":"/etc/speller.rc",` + `"content":"a=` + misspelledShell + `\nb=` + undeclaredSetting + `\nc=` + misspelledMachine + `\nd=` + shellsOwn + `\n"}]}` @@ -1282,7 +1282,7 @@ func TestAMisspelledPlaceholderIsRefusedAtTheCheck(t *testing.T) { } // The prefix is the reservation rule, so there is no list to maintain and none to drift. -func TestAModuleCannotDeclareAMeshSeat(t *testing.T) { +func caseAModuleCannotDeclareAMeshSeat(t *testing.T) { for _, n := range []string{"mesh-broker", "mesh-anything", "mesh-store"} { m := catalogue.Manifest{Module: "impostor", DefinesSeats: []catalogue.SeatDeclaration{{Name: n, Accepts: []string{"x"}}}} got := strings.Join(declaredSeatProblems(m), "; ") @@ -1293,7 +1293,7 @@ func TestAModuleCannotDeclareAMeshSeat(t *testing.T) { } // The whole point: a module contributes a capability without the mesh being changed. -func TestAModuleDeclaresItsOwnSeatAndHoldsIt(t *testing.T) { +func caseAModuleDeclaresItsOwnSeatAndHoldsIt(t *testing.T) { shop := catalogue.Manifest{Module: "shop", Uses: []string{"telegram-sender"}} if got := problemsFor(t, catalogue.Shelf{"telegram": telegram(), "shop": shop}); got != "" { t.Fatalf("a declared seat and its caller were refused: %s", got) @@ -1302,7 +1302,7 @@ func TestAModuleDeclaresItsOwnSeatAndHoldsIt(t *testing.T) { // A module may define its own seat and claim it — the mesh enforces exclusivity without knowing // what it means (novox/hq ADR 0121). But it may not define one in the mesh's own namespace. -func TestAModuleDefinesAndClaimsItsOwnSeat(t *testing.T) { +func caseAModuleDefinesAndClaimsItsOwnSeat(t *testing.T) { ok := []byte(`{"module":"showcase","version":"1","seats":[{"name":"the-showcase","scope":"node"}],` + `"claims":[{"name":"the-showcase","scope":"node"}]}`) if _, err := ParseManifest(ok); err != nil { @@ -1327,7 +1327,7 @@ func TestAModuleDefinesAndClaimsItsOwnSeat(t *testing.T) { } } -func TestAModuleIsEitherWrittenOrComputedNotBoth(t *testing.T) { +func caseAModuleIsEitherWrittenOrComputedNotBoth(t *testing.T) { // Otherwise nobody could say where a given file on a machine came from. _, err := ParseManifest([]byte(`{"module":"mesh-network","version":"1", "computed":"mesh-network", @@ -1347,7 +1347,7 @@ func TestAModuleIsEitherWrittenOrComputedNotBoth(t *testing.T) { // a machine *over* the link, so a manifest carrying an action used to be accepted here, stored, // resolved and pushed — and then refused on the machine, in a log, with nothing tying it back to // the manifest. Enforced at the far end only is enforced and not usable. -func TestAModuleMayNotDeclareAnAction(t *testing.T) { +func caseAModuleMayNotDeclareAnAction(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"probe","version":"1","resources":[ {"id":"migrate","type":"action","command":["/bin/true"],"verify":["/bin/true"]}]}`)) if err == nil { @@ -1368,7 +1368,7 @@ func TestAModuleMayNotDeclareAnAction(t *testing.T) { // The fault this defends against does not look like a fault: resolution succeeds, the module // deploys, and the first query fails somewhere else entirely. Every earlier test had exactly one // provider of each name, so no mismatch was expressible and none was caught. -func TestAModuleMayNotProvideAGenericDatabase(t *testing.T) { +func caseAModuleMayNotProvideAGenericDatabase(t *testing.T) { for _, hidden := range []string{"database", "db", "sql", "sql-database"} { _, err := ParseManifest([]byte(`{"module":"postgres","version":"1", "provides":[{"name":"` + hidden + `","scope":"mesh"}]}`)) @@ -1384,14 +1384,14 @@ func TestAModuleMayNotProvideAGenericDatabase(t *testing.T) { } } -func TestAModuleNamedAfterADomainIsNamedBack(t *testing.T) { +func caseAModuleNamedAfterADomainIsNamedBack(t *testing.T) { got := InstallationProblems(catalogue.Manifest{Module: "mesh-one.be"}) if len(got) != 1 || !strings.Contains(got[0], "named after mesh-one.be") { t.Fatalf("got %v", got) } } -func TestAModuleOffersItsOwnStateOnly(t *testing.T) { +func caseAModuleOffersItsOwnStateOnly(t *testing.T) { block := `{"seat":"node-bar","kind":"block","data":{"bar":"bottom","place":"status","shows":"state","options":{"state":"%s"}}}` cases := map[string]string{ `{"module":"power","state":["draw"],"contributions":[` + fmt.Sprintf(block, "other.draw") + `]}`: "which power does not keep", @@ -1410,7 +1410,7 @@ func TestAModuleOffersItsOwnStateOnly(t *testing.T) { } // A module says what its own tools replace, and only for a tool it declares. -func TestAModuleSaysWhatItsOwnToolsReplace(t *testing.T) { +func caseAModuleSaysWhatItsOwnToolsReplace(t *testing.T) { m, err := ParseManifest([]byte(`{"module":"docker","version":"1","tools":["docker_logs","docker_list"],` + `"replaces":{"docker_logs":["docker logs"],"docker_list":["docker ps"]}}`)) if err != nil { @@ -1439,7 +1439,7 @@ func TestAModuleSaysWhatItsOwnToolsReplace(t *testing.T) { // A module's own seat names paths under the same rules: a node seat only, literal, and none another seat // names — the second declaration loses. Its holder declares them, as a mesh seat's does. -func TestAModulesOwnSeatNamesPathsUnderTheSameRules(t *testing.T) { +func caseAModulesOwnSeatNamesPathsUnderTheSameRules(t *testing.T) { meshScoped := catalogue.Manifest{Module: "a", Version: "1", DefinesSeats: []catalogue.SeatDeclaration{ {Name: "a-seat", Paths: []string{"/etc/a"}}}} if got := strings.Join(declaredSeatProblems(meshScoped), "; "); !strings.Contains(got, "only a node seat names paths") { @@ -1477,7 +1477,7 @@ func TestAModulesOwnSeatNamesPathsUnderTheSameRules(t *testing.T) { } } -func TestAModuleThatDeclaresASettingNamesItsFilesKeys(t *testing.T) { +func caseAModuleThatDeclaresASettingNamesItsFilesKeys(t *testing.T) { // ADR 0326 §3, ADR 0164 §15, novox/hq issue 574: only a module that declares no settings keeps // today's form. One that declares a preference and owns a silent mergeable file is refused where // a definition is written — and read and composed where a stored one is read again, so a build kept @@ -1522,7 +1522,7 @@ func TestAModuleThatDeclaresASettingNamesItsFilesKeys(t *testing.T) { // A module whose own code the mesh cannot find has nothing to ask, and saying so where the manifest // is read beats a declaration that quietly prepares nothing. -func TestAModuleThatPreparesAndRunsNoneOfItsOwnCodeIsRefused(t *testing.T) { +func caseAModuleThatPreparesAndRunsNoneOfItsOwnCodeIsRefused(t *testing.T) { m := catalogue.Manifest{ Module: "gitea", Prepares: true, @@ -1540,7 +1540,7 @@ func TestAModuleThatPreparesAndRunsNoneOfItsOwnCodeIsRefused(t *testing.T) { } } -func TestAMountNothingDeclaresIsRefused(t *testing.T) { +func caseAMountNothingDeclaresIsRefused(t *testing.T) { _, err := ParseManifest(manifestMounting("/services/store/data", "")) if err == nil { t.Fatal("a container mounting a path no resource declares was accepted; the runtime " + @@ -1551,7 +1551,7 @@ func TestAMountNothingDeclaresIsRefused(t *testing.T) { } } -func TestAMovedModulesMarkIsJudged(t *testing.T) { +func caseAMovedModulesMarkIsJudged(t *testing.T) { for name, raw := range map[string]string{ "marked moved and naming no template": `{"module":"bare","version":"1","moved":true, "resources":[{"id":"conf","type":"file","path":"/etc/bare","content":"x"}]}`, @@ -1571,7 +1571,7 @@ func TestAMovedModulesMarkIsJudged(t *testing.T) { // A manifest states an access's extent, the way a listening port states its source. An absolute // path and a mode of read or read-write; anything else is refused rather than acted on wrongly. -func TestAnAccessIsValidated(t *testing.T) { +func caseAnAccessIsValidated(t *testing.T) { good := []byte(`{"module":"m","accesses":[{"path":"/services/media","mode":"read-write"}]}`) if _, err := ParseManifest(good); err != nil { t.Fatalf("a valid access was refused: %v", err) @@ -1599,7 +1599,7 @@ func TestAnAccessIsValidated(t *testing.T) { } } -func TestANameMeantOnPurposeIsDeclaredWithItsReason(t *testing.T) { +func caseANameMeantOnPurposeIsDeclaredWithItsReason(t *testing.T) { // The federation's public directory in a homeserver's config: the world's, said so, and a name // the map does not cover is still reported. m := catalogue.Manifest{Module: "homeserver", Resources: []map[string]any{ @@ -1612,7 +1612,7 @@ func TestANameMeantOnPurposeIsDeclaredWithItsReason(t *testing.T) { } } -func TestAnArtifactBuiltFromOutsideItsRepositoryIsRefused(t *testing.T) { +func caseAnArtifactBuiltFromOutsideItsRepositoryIsRefused(t *testing.T) { // A build reads its own repository and nothing else. A path leaving it would make what gets // built depend on whatever happens to be on the machine doing the building. for _, from := range []string{"/etc/passwd", "../elsewhere"} { @@ -1631,7 +1631,7 @@ func TestAnArtifactBuiltFromOutsideItsRepositoryIsRefused(t *testing.T) { // language other than Go, may; a Go program's artifact, an archive, an image and an upstream artifact may not, and the // refusal names the artifact and its kind. Each path stays inside the module's directory: no `..`, no absolute path, // no pattern. -func TestAnArtifactNamesThePathsItIsBuiltFrom(t *testing.T) { +func caseAnArtifactNamesThePathsItIsBuiltFrom(t *testing.T) { m, err := ParseManifest([]byte(`{"module":"mesh-sdk","version":"1","slug":"sdk","build":{"artifacts":[ {"name":"lib","kind":"package","language":"typescript", "paths":["src","test","package.json","package-lock.json","tsconfig.json"]}]},"resources":[]}`)) @@ -1667,7 +1667,7 @@ func TestAnArtifactNamesThePathsItIsBuiltFrom(t *testing.T) { } } -func TestAnArtifactOfAnUnknownKindIsRefused(t *testing.T) { +func caseAnArtifactOfAnUnknownKindIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"a","version":"1","build":{"artifacts":[ {"name":"x","kind":"binary","from":"main.go"}]}}`)) if err == nil { @@ -1675,7 +1675,7 @@ func TestAnArtifactOfAnUnknownKindIsRefused(t *testing.T) { } } -func TestANeedIsAnAbsolutePath(t *testing.T) { +func caseANeedIsAnAbsolutePath(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"postgres","version":"1", "own-secrets":{"superuser":"superuser.txt"}}`)) if err == nil { @@ -1688,7 +1688,7 @@ func TestANeedIsAnAbsolutePath(t *testing.T) { // A need naming nothing node-scope — undeclared, or declared at another scope — is the whole // catalogue's to say (novox/hq ADR 0378 §8). -func TestANeedMustNameANodeSeatSomewhereInTheCatalogue(t *testing.T) { +func caseANeedMustNameANodeSeatSomewhereInTheCatalogue(t *testing.T) { mail := catalogue.Manifest{Module: "mail", DefinesSeats: []catalogue.SeatDeclaration{{ Name: "mail-notifier", Scope: catalogue.ScopeNode, Needs: []string{"desk-beeper"}}}} @@ -1712,7 +1712,7 @@ func TestANeedMustNameANodeSeatSomewhereInTheCatalogue(t *testing.T) { } } -func TestAnEmptyContributionIsRefused(t *testing.T) { +func caseAnEmptyContributionIsRefused(t *testing.T) { // Either a mistake or a requirement written the long way round, and both are better said. _, err := ParseManifest([]byte(`{"module":"board","version":"1", "contributes":{"reverse-proxy":{}}}`)) @@ -1725,7 +1725,7 @@ func TestAnEmptyContributionIsRefused(t *testing.T) { } // A name that is not a name is refused where it is written: it ends up in something a person types. -func TestAnEndpointNameIsHeldToItsShape(t *testing.T) { +func caseAnEndpointNameIsHeldToItsShape(t *testing.T) { for _, wrong := range []string{"Web", "web port", "3000", "-web", "web_surface"} { m := catalogue.Manifest{Module: "odd", Listens: []catalogue.Listening{{Name: wrong, Port: 80, From: catalogue.FromMesh}}} if got := strings.Join(endpointNameProblems(m), "\n"); !strings.Contains(got, "a name is lowercase") { @@ -1776,7 +1776,7 @@ func anIdentityServedAsADNSLabelIsBoundedToOne(t *testing.T) { } } -func TestAnImageFromAnInstallationsRegistryNeedsAReason(t *testing.T) { +func caseAnImageFromAnInstallationsRegistryNeedsAReason(t *testing.T) { bare := catalogue.Manifest{Module: "site", Resources: []map[string]any{ {"id": "server", "type": "container", "image": "registry.mesh-one.be/org/site@sha256:cc"}, }} @@ -1792,7 +1792,7 @@ func TestAnImageFromAnInstallationsRegistryNeedsAReason(t *testing.T) { } } -func TestAnInterpretedBundleStillMayNotNameASource(t *testing.T) { +func caseAnInterpretedBundleStillMayNotNameASource(t *testing.T) { b := &catalogue.Build{Artifacts: []catalogue.Artifact{{ Name: "tools", Kind: catalogue.ArtifactBundle, Language: "typescript", From: "src", }}} @@ -1803,7 +1803,7 @@ func TestAnInterpretedBundleStillMayNotNameASource(t *testing.T) { } // And an ordinary unknown key is still refused as one, rather than being guessed at. -func TestAnInventedKeyIsNotTreatedAsARename(t *testing.T) { +func caseAnInventedKeyIsNotTreatedAsARename(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"postgres","version":"1","nonsense":{}}`)) if err == nil { t.Fatal("an invented key was accepted") @@ -1815,7 +1815,7 @@ func TestAnInventedKeyIsNotTreatedAsARename(t *testing.T) { // An entry that names a module and no tool is refused at parse, in the manifest's words, rather than // at the composition of the bus's user list where it would stop the file for everybody. -func TestAnInvokeThatNamesNoToolIsRefusedAtParse(t *testing.T) { +func caseAnInvokeThatNamesNoToolIsRefusedAtParse(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"mesh-console","version":"1","invokes":["shop"]}`)) if err == nil { t.Fatal("an invoke naming no tool was accepted") @@ -1828,7 +1828,7 @@ func TestAnInvokeThatNamesNoToolIsRefusedAtParse(t *testing.T) { // A provider with one credential shares it (novox/hq ADR 0158): the offer names the own secret, the // secret says how it is taken, and a consumer's need carries the name so the plan mints its copy // from the provider's value. -func TestAnOfferMayNameAnOwnSecretAsItsCredential(t *testing.T) { +func caseAnOfferMayNameAnOwnSecretAsItsCredential(t *testing.T) { m, err := ParseManifest([]byte(`{"module":"downloader","version":"1", "own-secrets":{"password":{"path":"/var/lib/mesh/downloader/password","taken":"at-start"}}, "provides":[{"name":"downloader-api","credential":{"own":"password"}}], @@ -1858,7 +1858,7 @@ func TestAnOfferMayNameAnOwnSecretAsItsCredential(t *testing.T) { // A provision's credential may be one only a person outside the mesh can give (novox/hq ADR 0337 §1, issue 164): // the offer says `issued-by: outside` and names neither an own secret nor a tool, and the parser refuses it beside // either. An offer that says `software` keeps ADR 0305's shape. -func TestAnOfferMaySayAPersonOutsideTheMeshIssuesItsCredential(t *testing.T) { +func caseAnOfferMaySayAPersonOutsideTheMeshIssuesItsCredential(t *testing.T) { m, err := ParseManifest([]byte(`{"module":"tv","version":"1", "provides":[{"name":"tv-api","scope":"mesh","credential":{"issued-by":"outside"}}], "serves":{"tv-api":{"port":8989}}}`)) @@ -1894,7 +1894,7 @@ func TestAnOfferMaySayAPersonOutsideTheMeshIssuesItsCredential(t *testing.T) { // A provision's credential may be issued by its provider's software (novox/hq ADR 0305, issue 526): the offer // names the tool that answers it and no own secret, and every other shape is refused at parse. -func TestAnOfferMaySayItsSoftwareIssuesTheCredential(t *testing.T) { +func caseAnOfferMaySayItsSoftwareIssuesTheCredential(t *testing.T) { m, err := ParseManifest([]byte(`{"module":"media","version":"1", "provides":[{"name":"media-api","scope":"mesh","credential":{"issued-by":"software","tool":"media_issued_credential"}}], "serves":{"media-api":{"port":32400}}}`)) @@ -1929,7 +1929,7 @@ func TestAnOfferMaySayItsSoftwareIssuesTheCredential(t *testing.T) { } // The field reads as written and writes back the same, and refuses what says nothing. -func TestAnOffersIdentityIsParsedStrictly(t *testing.T) { +func caseAnOffersIdentityIsParsedStrictly(t *testing.T) { for _, raw := range []string{ `{"name":"s3-bucket","scope":"mesh","identity":{"max":20,"in":"an S3 access key"}}`, `{"name":"wildcard-resolution","scope":"mesh","identity":false}`, @@ -1972,7 +1972,7 @@ func TestAnOffersIdentityIsParsedStrictly(t *testing.T) { // it is unset; where a mergeable file takes it and no placeholder asks for it, the file's own content (or the // module's code reading the file) falls back, so it keeps a default and stays optional, as it is today: the // operator's decision on issue 664's second question (issue 735). -func TestAnOperatorNamedValueAFileFallsBackOnMayHaveADefault(t *testing.T) { +func caseAnOperatorNamedValueAFileFallsBackOnMayHaveADefault(t *testing.T) { m := inConfigForm() m["config"].(map[string]any)["url"] = map[string]any{"type": "string", "description": "the address the notifier posts to, a URL; empty for the one the file's software picks", @@ -2000,7 +2000,7 @@ func TestAnOperatorNamedValueAFileFallsBackOnMayHaveADefault(t *testing.T) { // A key asked only in a template is not refused while the manifest still names its templates (issue 817), and // is judged once they are filled: WithTemplatesFrom over a tree whose template does not ask for it refuses it. -func TestAnOwnerSettingAskedOnlyInATemplateIsJudgedOnceFilled(t *testing.T) { +func caseAnOwnerSettingAskedOnlyInATemplateIsJudgedOnceFilled(t *testing.T) { raw := `{"module":"sonarr","version":"1", "build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}, "resources":[{"id":"recycle-bin","type":"directory","path":"/srv/sonarr/recycle","mode":"0755","owner":"${setting:puid}:${setting:pgid}"}, @@ -2030,7 +2030,7 @@ func TestAnOwnerSettingAskedOnlyInATemplateIsJudgedOnceFilled(t *testing.T) { // Where the manifest is read: an owner holding a setting is a whole placeholder or a whole number on // each side of the colon, and every key is one the module asks for elsewhere or declares a default for. -func TestAnOwnerSettingIsJudgedWhereTheManifestIsRead(t *testing.T) { +func caseAnOwnerSettingIsJudgedWhereTheManifestIsRead(t *testing.T) { ok := []string{"${setting:puid}:${setting:pgid}", "${setting:puid}", "${setting:puid}:1000", "1000:${setting:pgid}", "1000:1000", "media:media"} bad := []string{ @@ -2076,7 +2076,7 @@ func TestAnOwnerSettingIsJudgedWhereTheManifestIsRead(t *testing.T) { // A secret an outside party issues says so (novox/hq ADR 0228), is written back as it was read, and // is the one at-start secret the mesh may not make; any other word for who issued it is refused. -func TestAnOwnSecretSaysWhenAnOutsidePartyIssuesIt(t *testing.T) { +func caseAnOwnSecretSaysWhenAnOutsidePartyIssuesIt(t *testing.T) { m, err := ParseManifest([]byte(`{"module":"letta","version":"1","own-secrets":{ "server-password":{"path":"/var/lib/letta/server-password","taken":"at-start"}, "openai-api-key":{"path":"/var/lib/letta/openai-api-key","taken":"at-start","issued-by":"outside"}, @@ -2115,7 +2115,7 @@ func TestAnOwnSecretSaysWhenAnOutsidePartyIssuesIt(t *testing.T) { // 1170/AC2: an owner naming an account the module does not make, root, or the operator account's placeholder is // refused, naming the secret and the account. -func TestAnOwnSecretsOwnerIsRefusedWhenItIsNotAnAccountTheModuleMakes(t *testing.T) { +func caseAnOwnSecretsOwnerIsRefusedWhenItIsNotAnAccountTheModuleMakes(t *testing.T) { for name, c := range map[string]struct{ owner, says string }{ "root": {"root", "root"}, "the operator account": {"${machine:account}", "operator account"}, @@ -2130,7 +2130,7 @@ func TestAnOwnSecretsOwnerIsRefusedWhenItIsNotAnAccountTheModuleMakes(t *testing } } -func TestAnOwnSecretTakenSomeOtherWayIsRefused(t *testing.T) { +func caseAnOwnSecretTakenSomeOtherWayIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"idp","version":"1","own-secrets":{ "admin":{"path":"/var/lib/idp/admin.secret","taken":"sometimes"}}}`)) if err == nil || !strings.Contains(err.Error(), `taken "sometimes"`) { @@ -2144,7 +2144,7 @@ func TestAnOwnSecretTakenSomeOtherWayIsRefused(t *testing.T) { } // A path is compared as the machine writes it: cleaned. Each spelling of /etc/hosts is /etc/hosts. -func TestAnUncleanSpellingOfASeatsPathIsTheSeatsPath(t *testing.T) { +func caseAnUncleanSpellingOfASeatsPathIsTheSeatsPath(t *testing.T) { for _, spelled := range []string{"/etc//hosts", "/etc/./hosts", "/etc/../etc/hosts", "/etc/hosts/"} { stranger := catalogue.Manifest{Module: "stranger", Version: "1", Resources: []map[string]any{ {"id": "hosts", "type": "file", "path": spelled, "content": "10.0.0.1 x\n"}}} @@ -2160,14 +2160,14 @@ func TestAnUncleanSpellingOfASeatsPathIsTheSeatsPath(t *testing.T) { } } -func TestAnUnhealthySeverityOtherThanUrgentOrWarningIsRefused(t *testing.T) { +func caseAnUnhealthySeverityOtherThanUrgentOrWarningIsRefused(t *testing.T) { if _, err := ParseManifest([]byte(`{"module":"mail","version":"1","unhealthy":{"severity":"loud","why":"mail stops"}}`)); err == nil || !strings.Contains(err.Error(), `not "loud"`) { t.Errorf("a manifest declaring its unhealthy loud parsed: %v", err) } } -func TestAnUnhealthyWithoutWhyIsRefused(t *testing.T) { +func caseAnUnhealthyWithoutWhyIsRefused(t *testing.T) { for _, why := range []string{"", " "} { if problems := manifestUnhealthyProblems((catalogue.Manifest{Module: "mail", Unhealthy: &catalogue.UnhealthyPolicy{Severity: catalogue.UnhealthyUrgent, Why: why}})); len(problems) == 0 { t.Errorf("urgent with why %q was accepted", why) @@ -2180,7 +2180,7 @@ func TestAnUnhealthyWithoutWhyIsRefused(t *testing.T) { } // A reference to an access the definition does not declare is refused where the author is. -func TestAnUnknownAccessReferenceIsRefusedAtParse(t *testing.T) { +func caseAnUnknownAccessReferenceIsRefusedAtParse(t *testing.T) { _, err := ParseManifest([]byte(`{ "module": "arr", "version": "1", "accesses": [{"id": "series", "mode": "read-write"}], @@ -2199,7 +2199,7 @@ func TestAnUnknownAccessReferenceIsRefusedAtParse(t *testing.T) { } // A key nobody renders is refused, not left in the file as a literal. -func TestAnUnknownPlaceholderKeyIsRefused(t *testing.T) { +func caseAnUnknownPlaceholderKeyIsRefused(t *testing.T) { for _, c := range []struct{ content, want string }{ {"${environment:foo}", "names ${environment:foo}; the environment is ${environment:posix} or ${environment:systemd}"}, {"${shell:zsh:middle}", "names ${shell:zsh:middle}; shell code is ${shell::}"}, @@ -2223,7 +2223,7 @@ func TestAnUnknownPlaceholderKeyIsRefused(t *testing.T) { // **Every endpoint in the catalogue is unnamed today, and must stay valid.** The word ships one // release before anything uses it. -func TestAnUnnamedEndpointIsStillValid(t *testing.T) { +func caseAnUnnamedEndpointIsStillValid(t *testing.T) { m := catalogue.Manifest{Module: "ordinary", Listens: []catalogue.Listening{{Port: 443, From: catalogue.FromEverywhere}}} if got := endpointNameProblems(m); len(got) != 0 { t.Fatalf("an unnamed endpoint was refused: %v", got) @@ -2233,7 +2233,7 @@ func TestAnUnnamedEndpointIsStillValid(t *testing.T) { } } -func TestAnUpstreamFileFromAnAddressOrAReservedNameIsRefused(t *testing.T) { +func caseAnUpstreamFileFromAnAddressOrAReservedNameIsRefused(t *testing.T) { for _, u := range []string{"https://git.novox.internal/r.tar.xz", "https://10.1.2.3/r.tar.xz", "https://203.0.113.9/r.tar.xz", "https://[2001:db8::1]/r.tar.xz", "https://nas.lan/r.tar.xz", "https://vendor/r.tar.xz"} { _, err := ParseManifest([]byte(upstreamManifest(`{"name":"x","kind":"archive","url":"` + u + `","sha256":"` + @@ -2244,7 +2244,7 @@ func TestAnUpstreamFileFromAnAddressOrAReservedNameIsRefused(t *testing.T) { } } -func TestAnUpstreamFilesVendorIsNamedOnPurposeAndAnInstallationsIsRefused(t *testing.T) { +func caseAnUpstreamFilesVendorIsNamedOnPurposeAndAnInstallationsIsRefused(t *testing.T) { // The vendor's host is judged like any name, and passes through names-on-purpose; a version of four dotted // numbers is not an address, and a name in it is still judged. m, err := ParseManifest([]byte(upstreamManifest(`{"name":"owl","kind":"archive","url":"https://vendor.be/owl/owl.xpi","sha256":"` + @@ -2269,7 +2269,7 @@ func TestAnUpstreamFilesVendorIsNamedOnPurposeAndAnInstallationsIsRefused(t *tes } } -func TestAnUpstreamFileThatIsNotPinnedIsRefused(t *testing.T) { +func caseAnUpstreamFileThatIsNotPinnedIsRefused(t *testing.T) { cases := map[string]string{ // No digest: what the address serves changes under the mesh. `{"name":"x","kind":"archive","url":"https://vendor.invalid/r.tar.xz","version":"1"}`: "without a pinned sha256", @@ -2306,7 +2306,7 @@ func TestAnUpstreamFileThatIsNotPinnedIsRefused(t *testing.T) { } } -func TestAPackageParsesLikeABundleAndNeedsALanguage(t *testing.T) { +func caseAPackageParsesLikeABundleAndNeedsALanguage(t *testing.T) { // The SDK's shape: a package built from the module's own directory, naming a language. m, err := ParseManifest([]byte(`{"module":"mesh-sdk","version":"1","slug":"sdk", "build":{"artifacts":[{"name":"lib","kind":"package","language":"typescript"}]}, @@ -2360,7 +2360,7 @@ func TestAPackageParsesLikeABundleAndNeedsALanguage(t *testing.T) { } } -func TestAPathThroughAnAccessIsJudgedWithTheAccessFilledIn(t *testing.T) { +func caseAPathThroughAnAccessIsJudgedWithTheAccessFilledIn(t *testing.T) { // A file's path may name an access; the access's default path is the definition's, so it is judged with it. _, err := ParseManifest([]byte(`{"module": "backup", "version": "1", "accesses": [{"id": "images", "path": "/var/lib/docker/volumes"}], @@ -2380,7 +2380,7 @@ func TestAPathThroughAnAccessIsJudgedWithTheAccessFilledIn(t *testing.T) { // ADR 0203 §5 and ADR 0204 §3: a placeholder outside the seat's holder is refused by the parser, which is what the // catalogue check and registration run (its refusal again at composition is the node-engine's, ADR 0593 §7). -func TestAPlaceholderOutsideTheHolderIsRefused(t *testing.T) { +func caseAPlaceholderOutsideTheHolderIsRefused(t *testing.T) { for _, c := range []struct{ content, want string }{ {"${environment:posix}", "toolchain's resource rc names ${environment:posix} and toolchain does not claim node-environment"}, {"${shell:zsh:normal}", "toolchain's resource rc names ${shell:zsh:normal} and toolchain does not claim node-login-shell"}, @@ -2395,7 +2395,7 @@ func TestAPlaceholderOutsideTheHolderIsRefused(t *testing.T) { // **A language that runs anywhere must not name a system.** A system that decides nothing reads as // though it did, which is the same fault as a restriction that restricts nothing (novox/hq ADR 0045); a compiled // bundle names one, and a portable bundle naming none is an ordinary one. -func TestABundleNamesASystemOnlyWhereItCompiles(t *testing.T) { +func caseABundleNamesASystemOnlyWhereItCompiles(t *testing.T) { for _, c := range []struct{ language, system, refused string }{ {"go", "arch", ""}, {"typescript", "", ""}, @@ -2409,7 +2409,7 @@ func TestABundleNamesASystemOnlyWhereItCompiles(t *testing.T) { } // A rule with no source is open, and must say so rather than appear to restrict something. -func TestAPortWithNoSourceIsRefused(t *testing.T) { +func caseAPortWithNoSourceIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"web","listens":[{"port":443}]}`)) if err == nil { t.Fatal("a port that never said who may reach it was accepted; it reads as a restriction") @@ -2421,7 +2421,7 @@ func TestAPortWithNoSourceIsRefused(t *testing.T) { // 1179/AC2: a bus on a process with no user, user root, or the operator account is refused naming the // process and the account rule. -func TestAProcessBusAccountMustBeTheModulesOwn(t *testing.T) { +func caseAProcessBusAccountMustBeTheModulesOwn(t *testing.T) { for name, c := range map[string]struct{ user, says string }{ "no user": {"", "send"}, "user root": {"root", "root"}, @@ -2444,7 +2444,7 @@ func TestAProcessBusAccountMustBeTheModulesOwn(t *testing.T) { // 1179/AC3: a bus naming a stream, state or event the module does not declare as its own is refused naming // it. -func TestAProcessBusNamesOnlyTheModulesOwn(t *testing.T) { +func caseAProcessBusNamesOnlyTheModulesOwn(t *testing.T) { for name, c := range map[string]struct{ bus, says string }{ "another module's event": {`{"emits":["billing.paid"]}`, "billing.paid"}, "another module's queue": {`{"queues":["other-queue"]}`, "other-queue"}, @@ -2459,7 +2459,7 @@ func TestAProcessBusNamesOnlyTheModulesOwn(t *testing.T) { // 1179/AC4: a bus declaring serves, holds, claims or a seat is refused naming the key; a bus with invokes of // a tool or a seat verb is accepted. -func TestAProcessBusNeverServesOrHoldsASeat(t *testing.T) { +func caseAProcessBusNeverServesOrHoldsASeat(t *testing.T) { for name, c := range map[string]struct{ bus, says string }{ "serves": {`{"emits":["mail.send.sent"],"serves":["send"]}`, "serves"}, "holds": {`{"emits":["mail.send.sent"],"holds":["mail-sender"]}`, "holds"}, @@ -2479,7 +2479,7 @@ func TestAProcessBusNeverServesOrHoldsASeat(t *testing.T) { // 1179/AC1: a well-formed bus on a process whose account the module makes is accepted, and the catalogue // gives it whole to the grant composition (ProcessBuses, which 1180 reads). -func TestAProcessDeclaresItsBusAndIsAccepted(t *testing.T) { +func caseAProcessDeclaresItsBusAndIsAccepted(t *testing.T) { m, err := ParseManifest([]byte(mailSenderProcessManifest(t, mailSenderBus))) if err != nil { t.Fatalf("a well-formed process bus was refused: %v", err) @@ -2552,7 +2552,7 @@ func TestAProcessDeclaresItsBusAndIsAccepted(t *testing.T) { } // {member} is replaced only for a family's member: a single secret's prompt may not hold it (novox/hq issue 789). -func TestAPromptHoldingMemberOnASingleSecretIsRefused(t *testing.T) { +func caseAPromptHoldingMemberOnASingleSecretIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"mesh-mail","version":"1","own-secrets":{ "smtp-relay-key":{"path":"/var/lib/mesh-mail/smtp-relay-key","taken":"at-start", "prompt":"For {member}"}}}`)) @@ -2563,7 +2563,7 @@ func TestAPromptHoldingMemberOnASingleSecretIsRefused(t *testing.T) { // What `module check` and the merge gate judge: the provider read from its tree, its text inline. Judged by the same // rules, a provider naming a provision it does not provide is refused there too, and one that does is taken. -func TestAProviderReadFromItsTreeIsJudgedByTheSameRules(t *testing.T) { +func caseAProviderReadFromItsTreeIsJudgedByTheSameRules(t *testing.T) { read := func(text string) (catalogue.Manifest, error) { dir := t.TempDir() if err := os.MkdirAll(filepath.Join(dir, "files"), 0o755); err != nil { @@ -2586,7 +2586,7 @@ func TestAProviderReadFromItsTreeIsJudgedByTheSameRules(t *testing.T) { } } -func TestAReferenceToNoDirectoryRefusesAtTheManifest(t *testing.T) { +func caseAReferenceToNoDirectoryRefusesAtTheManifest(t *testing.T) { m := placedModule() m.Resources[2]["volumes"] = []any{"${dir:date}:/data"} // a typo, the likely shape problems := manifestUnknownDirRefs(m) @@ -2598,7 +2598,7 @@ func TestAReferenceToNoDirectoryRefusesAtTheManifest(t *testing.T) { } } -func TestARenamedEntryIsRefusedWhereItCouldNotHold(t *testing.T) { +func caseARenamedEntryIsRefusedWhereItCouldNotHold(t *testing.T) { entry := func(m map[string]any, e any) map[string]any { resourceOf(m, "rules")["takes-config"] = []any{"position", "theme", e} return m @@ -2623,7 +2623,7 @@ func TestARenamedEntryIsRefusedWhereItCouldNotHold(t *testing.T) { refused(t, required, `"url"`, "only when it is set", "never required") } -func TestARenamedEntryIsTheConfigFormsOnly(t *testing.T) { +func caseARenamedEntryIsTheConfigFormsOnly(t *testing.T) { m := map[string]any{ "module": "notifier", "version": "1", "resources": []any{ @@ -2637,7 +2637,7 @@ func TestARenamedEntryIsTheConfigFormsOnly(t *testing.T) { // Tonight's case (issue 263): networkmanager, no slug, requiring the mesh's resolver provision on a // machine with a six-character name. Under ADR 0049's one bound it was refused, and its provider's // whole machine with it; the resolver keeps no name, so it is not refused at all. -func TestARequirementOnAKeylessProvisionComposesWithALongName(t *testing.T) { +func caseARequirementOnAKeylessProvisionComposesWithALongName(t *testing.T) { shelf := catalogue.Shelf{ "resolver": {Module: "resolver", Provides: []catalogue.Offer{{Name: "wildcard-resolution", Scope: catalogue.ScopeMesh}}}, "networkmanager": {Module: "networkmanager", Requires: []string{"wildcard-resolution"}}, @@ -2655,7 +2655,7 @@ func TestARequirementOnAKeylessProvisionComposesWithALongName(t *testing.T) { // address the builder reached the store by (novox/hq ADR 0155): on 2026-10-02 the first bundle // resolved on the mesh carried the store's host in bundles[0].source and registration refused it // as naming an installation. Archive resources are the same kind of reference and get the same. -func TestAResolvedReferenceIsKeptNotRouted(t *testing.T) { +func caseAResolvedReferenceIsKeptNotRouted(t *testing.T) { m, err := ParseManifest([]byte(`{ "module": "sample", "version": "1", "tools": ["one"], @@ -2689,7 +2689,7 @@ func TestAResolvedReferenceIsKeptNotRouted(t *testing.T) { // A route naming an endpoint the module does not declare reaches nothing, and is refused where it is // written rather than resolving to no port and serving nothing. -func TestARouteNamingAnEndpointTheModuleLacksIsRefused(t *testing.T) { +func caseARouteNamingAnEndpointTheModuleLacksIsRefused(t *testing.T) { m := aMediaServer() m.Contributes["route"][catalogue.RouteEndpoint] = "absent" got := strings.Join(RouteProblems(m), "\n") @@ -2698,7 +2698,7 @@ func TestARouteNamingAnEndpointTheModuleLacksIsRefused(t *testing.T) { } } -func TestARunOnceMustBeABoolean(t *testing.T) { +func caseARunOnceMustBeABoolean(t *testing.T) { // A value that is not true or false is refused here, not sent to a machine that would then have // to guess what a string means. digest := "@sha256:" + strings.Repeat("a", 64) @@ -2719,7 +2719,7 @@ func TestARunOnceMustBeABoolean(t *testing.T) { } } -func TestARuntimeHealthIsHeldToTheHealthRules(t *testing.T) { +func caseARuntimeHealthIsHeldToTheHealthRules(t *testing.T) { for _, c := range []struct { health any says string @@ -2737,7 +2737,7 @@ func TestARuntimeHealthIsHeldToTheHealthRules(t *testing.T) { } } -func TestAScheduleThatIsNotAStringIsRefused(t *testing.T) { +func caseAScheduleThatIsNotAStringIsRefused(t *testing.T) { digest := "@sha256:" + strings.Repeat("a", 64) bad := []byte(`{"module":"m","resources":[ {"id":"sync","type":"container","name":"sync","image":"registry.example/x` + digest + `","schedule":true} @@ -2750,7 +2750,7 @@ func TestAScheduleThatIsNotAStringIsRefused(t *testing.T) { } // A seat needing itself names nothing (novox/hq ADR 0378 §8). -func TestASeatCannotNeedItself(t *testing.T) { +func caseASeatCannotNeedItself(t *testing.T) { m := catalogue.Manifest{Module: "mail", DefinesSeats: []catalogue.SeatDeclaration{{ Name: "mail-notifier", Scope: catalogue.ScopeNode, Needs: []string{"mail-notifier"}}}} got := strings.Join(declaredSeatProblems(m), "; ") @@ -2761,7 +2761,7 @@ func TestASeatCannotNeedItself(t *testing.T) { // **At registration, not in the parser** (novox/hq ADR 0122): a seat's scope is a property of the // set, the set is the store's, and the parser also runs on a build machine that has no store. -func TestASeatClaimedAtAnotherScopeIsRefused(t *testing.T) { +func caseASeatClaimedAtAnotherScopeIsRefused(t *testing.T) { m, err := ParseManifest(claimed(`[{"name":"npm-package-registry","scope":"node"}]`)) if err != nil { t.Fatalf("the parser judged a scope it reads from data it may not have: %v", err) @@ -2773,7 +2773,7 @@ func TestASeatClaimedAtAnotherScopeIsRefused(t *testing.T) { } // A seat names a role's own path, never the root or a top-level directory. -func TestASeatNamesNoRootOrTopLevelDirectory(t *testing.T) { +func caseASeatNamesNoRootOrTopLevelDirectory(t *testing.T) { for _, p := range []string{"/", "/etc"} { m := catalogue.Manifest{Module: "a", Version: "1", DefinesSeats: []catalogue.SeatDeclaration{ {Name: "a-seat", Scope: catalogue.ScopeNode, Paths: []string{p}}}} @@ -2785,14 +2785,14 @@ func TestASeatNamesNoRootOrTopLevelDirectory(t *testing.T) { // A seat with no protocol is a marker: which module is this node's showcase, or its packet filter. // Most node-scoped seats are markers, so refusing one would refuse the majority of the set. -func TestASeatWithoutAProtocolIsAMarkerNotAMistake(t *testing.T) { +func caseASeatWithoutAProtocolIsAMarkerNotAMistake(t *testing.T) { m := catalogue.Manifest{Module: "vague", DefinesSeats: []catalogue.SeatDeclaration{{Name: "something", Scope: catalogue.ScopeNode}}} if got := strings.Join(declaredSeatProblems(m), "; "); got != "" { t.Fatalf("a marker seat was refused: %s", got) } } -func TestASecondClaimOfOneKindIsRefused(t *testing.T) { +func caseASecondClaimOfOneKindIsRefused(t *testing.T) { got := problemsFor(t, catalogue.Shelf{"messenger": router(), "telegram": aChannel("telegram", "telegram"), "telegram-two": aChannel("telegram-two", "telegram")}) if !strings.Contains(got, `of kind "telegram", which telegram already claims`) { @@ -2800,7 +2800,7 @@ func TestASecondClaimOfOneKindIsRefused(t *testing.T) { } } -func TestAServedNameIsCheckedWhenTheDefinitionIsRead(t *testing.T) { +func caseAServedNameIsCheckedWhenTheDefinitionIsRead(t *testing.T) { for bad, want := range map[string]string{ `"public-root":"https://${bound:route:name-api}/x"`: "what forge is called through route is name, internal-name, name-web, internal-name-web", `"public-root":"https://${bound:postgres-database:name}/x"`: `forge contributes to "route"`, @@ -2825,7 +2825,7 @@ func TestAServedNameIsCheckedWhenTheDefinitionIsRead(t *testing.T) { // A fact or an alphabet the mesh does not have is refused where the definition is, not where a // consumer happens to be resolved — and the refusal says what may be said instead. -func TestAServedValueNamingSomethingTheMeshDoesNotHaveIsRefused(t *testing.T) { +func caseAServedValueNamingSomethingTheMeshDoesNotHaveIsRefused(t *testing.T) { for _, c := range []struct{ value, says string }{ {"${consumer:node}", "as"}, {"${consumer:as:punycode}", "dns"}, @@ -2852,7 +2852,7 @@ func TestAServedValueNamingSomethingTheMeshDoesNotHaveIsRefused(t *testing.T) { // Third review: a setting may name only a template's instance — right after the `@`, before the final // suffix, and the whole instance — so a value can never make the unit another unit, nor another kind. // Refused where the manifest is read, near its author. -func TestASettingInAUnitNameIsOnlyATemplatesInstance(t *testing.T) { +func caseASettingInAUnitNameIsOnlyATemplatesInstance(t *testing.T) { ok := []string{"zfs-scrub-weekly@${setting:scrub-pool}.timer", "getty@${setting:tty}.service"} bad := []string{ "${setting:unit}", @@ -2878,7 +2878,7 @@ func TestASettingInAUnitNameIsOnlyATemplatesInstance(t *testing.T) { } } -func TestASiteScopedProvisionIsRefused(t *testing.T) { +func caseASiteScopedProvisionIsRefused(t *testing.T) { // Meaningful for a claim — one DHCP server per segment — and not yet meaningful for a // provision, because nothing knows how to reach "the one at my site". _, err := ParseManifest([]byte( @@ -2891,14 +2891,14 @@ func TestASiteScopedProvisionIsRefused(t *testing.T) { } } -func TestAskingForTheRuleSetWithNowhereToPutItIsRefused(t *testing.T) { +func caseAskingForTheRuleSetWithNowhereToPutItIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"firewall","filtering":{"into":""}}`)) if err == nil { t.Fatal("a module asked for the rule set and named no path; it would receive nothing") } } -func TestASoftwareSpelledKeyIsUsable(t *testing.T) { +func caseASoftwareSpelledKeyIsUsable(t *testing.T) { // A file's keys are its software's: nodered's timeZone is not lower case and is still a key. m := catalogue.Manifest{Module: "flows", Resources: []map[string]any{{"id": "settings", "type": "file", "path": "/x", "merge": catalogue.MergeJSON, "content": "{}", catalogue.TakesSettingsField: []any{"timeZone"}}}} @@ -2907,7 +2907,7 @@ func TestASoftwareSpelledKeyIsUsable(t *testing.T) { } } -func TestASourceNobodyDefinedIsRefused(t *testing.T) { +func caseASourceNobodyDefinedIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"web","listens":[{"port":443,"from":"lan"}]}`)) if err == nil { t.Fatal("a source the mesh cannot render was accepted, and would be silently dropped") @@ -2916,7 +2916,7 @@ func TestASourceNobodyDefinedIsRefused(t *testing.T) { // A name the bus could not hold, or that would let two modules derive one bucket, is refused at // registration in the manifest's words. -func TestAStateNameIsLocalAndOneToken(t *testing.T) { +func caseAStateNameIsLocalAndOneToken(t *testing.T) { for _, c := range []struct{ manifest, says string }{ {`{"module":"a","version":"1","state":["mesh.servers"]}`, `keeps state "mesh.servers": a state is named locally`}, {`{"module":"a","version":"1","state":["my_servers"]}`, `keeps state "my_servers"`}, @@ -2951,7 +2951,7 @@ func TestAStateNameIsLocalAndOneToken(t *testing.T) { // A stored manifest with a key this reader does not know, at the top or inside any block, is decoded with the key set // aside and named, and its module is composed, never left out (novox/hq ADR 0578 §6, which changes ADR 0262); the judge // refuses it. One case per block whose decoder wraps the decoder's words in its own. -func TestAStoredManifestWithAnUnknownKeyIsSetAsideAndTheJudgeRefusesIt(t *testing.T) { +func caseAStoredManifestWithAnUnknownKeyIsSetAsideAndTheJudgeRefusesIt(t *testing.T) { t.Run("it still provides what it provides", aModuleWithAFieldSetAsideStillProvidesWhatItProvides) for where, raw := range map[string]string{ "the top": `{"module": "later", "version": "2", "a-field-from-later": {"x": 1}}`, @@ -2990,7 +2990,7 @@ func TestAStoredManifestWithAnUnknownKeyIsSetAsideAndTheJudgeRefusesIt(t *testin } // Registration refuses a stream the mesh could not hold or would leave ambiguous (ADR 0363 §1, §2, §4). -func TestAStreamIsNamedBoundedAndGrantedByATrustedConfigValue(t *testing.T) { +func caseAStreamIsNamedBoundedAndGrantedByATrustedConfigValue(t *testing.T) { grants := `"grant":{"config":"grants","events":"mail.{key}.**"}` for _, c := range []struct{ manifest, says string }{ {mailManifest(t, `[{"name":"Mail","events":["mail.**"]}]`, ""), `a stream is named locally`}, @@ -3030,7 +3030,7 @@ func TestAStreamIsNamedBoundedAndGrantedByATrustedConfigValue(t *testing.T) { // A system the mesh does not build for is refused where it is written. These are the host's own // names, not a compiler's: the difference between two of them is a C library rather than a kernel, // so a value that looks like an operating system to a toolchain is still wrong here. -func TestASystemTheMeshDoesNotBuildForIsRefused(t *testing.T) { +func caseASystemTheMeshDoesNotBuildForIsRefused(t *testing.T) { for _, wrong := range []string{"linux", "debian", "darwin"} { got := buildProblemsOf(t, bundleFor("go", wrong)) if !strings.Contains(got, "and a system is") { @@ -3039,7 +3039,7 @@ func TestASystemTheMeshDoesNotBuildForIsRefused(t *testing.T) { } } -func TestATemplatedModuleWhoseBuildPacksNoFilesIsRefused(t *testing.T) { +func caseATemplatedModuleWhoseBuildPacksNoFilesIsRefused(t *testing.T) { for _, build := range []string{ ``, `"build":{"artifacts":[{"name":"look","kind":"archive","from":"theme"}]},`, @@ -3054,7 +3054,7 @@ func TestATemplatedModuleWhoseBuildPacksNoFilesIsRefused(t *testing.T) { } } -func TestATemplateOnAResourceThatIsNotAFileIsRefused(t *testing.T) { +func caseATemplateOnAResourceThatIsNotAFileIsRefused(t *testing.T) { raw := strings.Replace(templatedTwin, `{"id":"conf","type":"directory","path":"${dir:conf}"}`, `{"id":"conf","type":"directory","path":"${dir:conf}","template":"files/tidy.conf"}`, 1) _, err := ParseManifest([]byte(raw)) @@ -3063,7 +3063,7 @@ func TestATemplateOnAResourceThatIsNotAFileIsRefused(t *testing.T) { } } -func TestATemplateOutsideFilesIsRefusedByName(t *testing.T) { +func caseATemplateOutsideFilesIsRefusedByName(t *testing.T) { for _, bad := range []string{"../tidy.conf", "/etc/tidy.conf", "files", "files/", "files/../tidy.conf", "files/./tidy.conf", "other/tidy.conf", "tidy.conf", "files//tidy.conf", `files\\tidy.conf`} { raw := strings.Replace(templatedTwin, `"files/tidy.conf"`, `"`+bad+`"`, 1) @@ -3074,7 +3074,7 @@ func TestATemplateOutsideFilesIsRefusedByName(t *testing.T) { } } -func TestATemplateOutsideTheNamedTemplatesDirectoryIsRefused(t *testing.T) { +func caseATemplateOutsideTheNamedTemplatesDirectoryIsRefused(t *testing.T) { raw := strings.Replace(unpackingTemplated, `"template":"templates/tidy.conf"`, `"template":"files/tidy.conf"`, 1) if _, err := ParseManifest([]byte(raw)); err == nil || !strings.Contains(err.Error(), "files/tidy.conf") || !strings.Contains(err.Error(), "templates/") { @@ -3082,7 +3082,7 @@ func TestATemplateOutsideTheNamedTemplatesDirectoryIsRefused(t *testing.T) { } } -func TestATemplatesDirectoryNoArchiveIsBuiltFromIsRefused(t *testing.T) { +func caseATemplatesDirectoryNoArchiveIsBuiltFromIsRefused(t *testing.T) { raw := strings.Replace(unpackingTemplated, `, {"name":"templates","kind":"archive","from":"templates"}`, "", 1) if _, err := ParseManifest([]byte(raw)); err == nil || !strings.Contains(err.Error(), "no archive from templates/") { @@ -3090,14 +3090,14 @@ func TestATemplatesDirectoryNoArchiveIsBuiltFromIsRefused(t *testing.T) { } } -func TestATemplatesDirectoryOnAModuleNamingNoTemplateIsRefused(t *testing.T) { +func caseATemplatesDirectoryOnAModuleNamingNoTemplateIsRefused(t *testing.T) { raw := strings.Replace(unpackingInline, `"version":"1",`, `"version":"1","templates":"templates",`, 1) if _, err := ParseManifest([]byte(raw)); err == nil || !strings.Contains(err.Error(), "names no template") { t.Fatalf("a templates directory read by nothing was not refused: %v", err) } } -func TestATemplatesDirectoryThatIsNotAPlainRelativeDirectoryIsRefused(t *testing.T) { +func caseATemplatesDirectoryThatIsNotAPlainRelativeDirectoryIsRefused(t *testing.T) { for _, dir := range []string{"/etc", "../other", "..", "templates/../files", "./templates", ".", "a\\b", "templates/"} { raw := strings.Replace(unpackingTemplated, `"templates":"templates"`, `"templates":`+jsonString(dir), 1) if _, err := ParseManifest([]byte(raw)); err == nil || !strings.Contains(err.Error(), "templates directory") { @@ -3108,7 +3108,7 @@ func TestATemplatesDirectoryThatIsNotAPlainRelativeDirectoryIsRefused(t *testing // novox/hq ADR 0259 §8: a module saying warrants, or speaking for a kind that proves its sender, runs as an // account of its own — never carried by the machine's runtime, which runs as the operator's account. -func TestATrustedHolderMustRunAsAnAccountOfItsOwn(t *testing.T) { +func caseATrustedHolderMustRunAsAnAccountOfItsOwn(t *testing.T) { r := router() r.RunsAs = "" if got := problemsFor(t, catalogue.Shelf{"messenger": r}); !strings.Contains(got, "messenger must run as an account of its own") { @@ -3134,7 +3134,7 @@ func TestATrustedHolderMustRunAsAnAccountOfItsOwn(t *testing.T) { } // A misspelt key inside a verb's definition is refused, like one anywhere else in the manifest. -func TestAVerbWithAnUnknownKeyIsRefused(t *testing.T) { +func caseAVerbWithAnUnknownKeyIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"till","version":"1",` + `"seats":[{"name":"shop-till","serves":[{"name":"price","descripton":"typo"}]}]}`)) if err == nil || !strings.Contains(err.Error(), "descripton") { @@ -3144,7 +3144,7 @@ func TestAVerbWithAnUnknownKeyIsRefused(t *testing.T) { // A family is named one by one, never by a wildcard, and only by the tool runner's module (ADR 0367 §2, §6): // each refusal is said in the manifest's words, at parse, rather than at the composition of the bus's users. -func TestAWaitIsRefusedUnlessItNamesOneFamilyOfTheToolRunner(t *testing.T) { +func caseAWaitIsRefusedUnlessItNamesOneFamilyOfTheToolRunner(t *testing.T) { for manifest, want := range map[string]string{ `{"module":"shop","version":"1","waits":["mesh-knowledge.reviewed"]}`: "only the tool runner's module", `{"module":"node-tools","version":"1","waits":["mesh-knowledge.reviewed"]}`: "only the tool runner's module", // its name says nothing (issue 774) @@ -3170,7 +3170,7 @@ func TestAWaitIsRefusedUnlessItNamesOneFamilyOfTheToolRunner(t *testing.T) { // 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) { +func caseAWorkQueueStreamIsReadByExactlyOneProcessOfItsModule(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) } @@ -3194,7 +3194,7 @@ func TestAWorkQueueStreamIsReadByExactlyOneProcessOfItsModule(t *testing.T) { // 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) { +func caseAWorkQueueStreamsValuesAreBounded(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",` + `"max-deliveries":0,"duplicates":24}]`, "between 1 and 10"}, @@ -3229,7 +3229,7 @@ func TestAWorkQueueStreamsValuesAreBounded(t *testing.T) { } // A zone names the listen that answers it, or there is nothing to forward to (novox/hq ADR 0199). -func TestAZoneMustNameOneOfTheModulesListens(t *testing.T) { +func caseAZoneMustNameOneOfTheModulesListens(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"lab","version":"1", "listens":[{"name":"dns","port":5353,"protocol":"udp","from":"mesh","why":"the lab's names"}], "zone":{"name":"${setting:zone}","listen":"web"}}`)) @@ -3243,7 +3243,7 @@ func TestAZoneMustNameOneOfTheModulesListens(t *testing.T) { } } -func TestBindingWhatYouDoNotRequireIsRefused(t *testing.T) { +func caseBindingWhatYouDoNotRequireIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"app","version":"1", "binds":{"postgres-database":"/etc/app/db.json"}}`)) if err == nil { @@ -3255,7 +3255,7 @@ func TestBindingWhatYouDoNotRequireIsRefused(t *testing.T) { } // A channel's capabilities come from the fixed vocabulary, and only a kinded claim carries any. -func TestCapabilitiesAreTheVocabularysAndOnlyOnAKindedClaim(t *testing.T) { +func caseCapabilitiesAreTheVocabularysAndOnlyOnAKindedClaim(t *testing.T) { good := aChannel("telegram", "telegram") good.Claims[0].Capabilities = []string{"deliver", "choice", "verified-sender", "max-length:4096"} good.RunsAs = "telegram" @@ -3276,7 +3276,7 @@ func TestCapabilitiesAreTheVocabularysAndOnlyOnAKindedClaim(t *testing.T) { } } -func TestCodeForAPowerMomentDependsOnThePowerSeat(t *testing.T) { +func caseCodeForAPowerMomentDependsOnThePowerSeat(t *testing.T) { for _, moment := range powerMoments { m := mod("laptop", nil, nil, nil) m.Shell = []catalogue.ShellCode{{For: moment, Slot: "normal", Code: "true"}} @@ -3297,7 +3297,7 @@ func TestCodeForAPowerMomentDependsOnThePowerSeat(t *testing.T) { } } -func TestCollectionsAndItemsAreJudged(t *testing.T) { +func caseCollectionsAndItemsAreJudged(t *testing.T) { for name, c := range map[string]struct{ raw, says string }{ "an item of a module not moved": {`{"module":"m","version":"1", "items":[{"collection":"shell:zsh:normal","template":"files/x"}], @@ -3334,7 +3334,7 @@ func TestCollectionsAndItemsAreJudged(t *testing.T) { } // Rule 3: a default failing its validation. -func TestConfigRefusesADefaultFailingItsValidation(t *testing.T) { +func caseConfigRefusesADefaultFailingItsValidation(t *testing.T) { for _, c := range []struct { key string value any @@ -3353,7 +3353,7 @@ func TestConfigRefusesADefaultFailingItsValidation(t *testing.T) { } // Rule 10: a moved module's mergeable file not naming its keys under takes-config. -func TestConfigRefusesAMergeableFileNotNamingItsKeys(t *testing.T) { +func caseConfigRefusesAMergeableFileNotNamingItsKeys(t *testing.T) { m := inConfigForm() delete(resourceOf(m, "rules"), "takes-config") // position and theme are then placed nowhere; say they are read at runtime so only the file's rule speaks. @@ -3363,7 +3363,7 @@ func TestConfigRefusesAMergeableFileNotNamingItsKeys(t *testing.T) { } // Rule 11: a mesh word, puid or pgid in takes-config. -func TestConfigRefusesAMeshWordOrAnAccountFactInTakesConfig(t *testing.T) { +func caseConfigRefusesAMeshWordOrAnAccountFactInTakesConfig(t *testing.T) { for _, word := range []string{"ports", "expose", "reach", "endpoints", "places", "accesses", "networks", "puid", "pgid"} { m := inConfigForm() resourceOf(m, "rules")["takes-config"] = []any{"position", "theme", word} @@ -3372,7 +3372,7 @@ func TestConfigRefusesAMeshWordOrAnAccountFactInTakesConfig(t *testing.T) { } // Rule 4: an object or a list not trusted. -func TestConfigRefusesAnObjectOrListNotTrusted(t *testing.T) { +func caseConfigRefusesAnObjectOrListNotTrusted(t *testing.T) { for _, kind := range []string{"object", "list"} { m := inConfigForm() def := any(map[string]any{"a": 1}) @@ -3390,7 +3390,7 @@ func TestConfigRefusesAnObjectOrListNotTrusted(t *testing.T) { } // Rule 6: an untrusted value falling back to a trusted predefined key. -func TestConfigRefusesAnUntrustedValueFallingBackToATrustedKey(t *testing.T) { +func caseConfigRefusesAnUntrustedValueFallingBackToATrustedKey(t *testing.T) { withPredefined(t, nil) m := inConfigForm() declaration(m, "theme")["predefined"] = "theme" @@ -3434,7 +3434,7 @@ func TestConfigRefusesAnUntrustedValueFallingBackToATrustedKey(t *testing.T) { } // Rule 8: a placeholder naming an undeclared value. -func TestConfigRefusesAPlaceholderNamingAnUndeclaredValue(t *testing.T) { +func caseConfigRefusesAPlaceholderNamingAnUndeclaredValue(t *testing.T) { m := inConfigForm() resourceOf(m, "configuration")["content"] = "font = ${config:font-size}\nwidth = ${config:width}\n" + "from = ${config:sender}\ncolour = ${config:colour}\n" @@ -3443,7 +3443,7 @@ func TestConfigRefusesAPlaceholderNamingAnUndeclaredValue(t *testing.T) { // Rule 5: a predefined key not on the list, or of another type. Where no list is present, a value naming one is // refused saying so. -func TestConfigRefusesAPredefinedKeyNotOnTheListOrOfAnotherType(t *testing.T) { +func caseConfigRefusesAPredefinedKeyNotOnTheListOrOfAnotherType(t *testing.T) { withPredefined(t, nil) m := inConfigForm() declaration(m, "font-size")["predefined"] = "font-size" @@ -3462,7 +3462,7 @@ func TestConfigRefusesAPredefinedKeyNotOnTheListOrOfAnotherType(t *testing.T) { } // Rule 9: a reload-on or restart-on naming a file the module does not declare. -func TestConfigRefusesAReloadOrRestartOnNamingAnUndeclaredFile(t *testing.T) { +func caseConfigRefusesAReloadOrRestartOnNamingAnUndeclaredFile(t *testing.T) { m := inConfigForm() resourceOf(m, "notifier")["reload-on"] = []any{"configuration", "dunstrc"} refused(t, m, "reload-on", `"dunstrc"`, "declares no such") @@ -3479,14 +3479,14 @@ func TestConfigRefusesAReloadOrRestartOnNamingAnUndeclaredFile(t *testing.T) { // A key a mergeable file takes is a config value like every other: one not declared under config is refused by // name (ADR 0348 §4, review of mesh-controller#320). -func TestConfigRefusesATakesConfigKeyNotDeclared(t *testing.T) { +func caseConfigRefusesATakesConfigKeyNotDeclared(t *testing.T) { m := inConfigForm() resourceOf(m, "rules")["takes-config"] = []any{"position", "theme", "urgency"} refused(t, m, `"urgency"`, "takes-config", "declares no such value under config") } // Rule 7: a value neither placed in a template nor read at runtime. -func TestConfigRefusesAValueNeitherPlacedNorReadAtRuntime(t *testing.T) { +func caseConfigRefusesAValueNeitherPlacedNorReadAtRuntime(t *testing.T) { m := inConfigForm() delete(declaration(m, "history"), "runtime") refused(t, m, `"history"`, "${config:history}", `"runtime": true`) @@ -3498,7 +3498,7 @@ func TestConfigRefusesAValueNeitherPlacedNorReadAtRuntime(t *testing.T) { } // Rule 2: a value with neither a default nor required. -func TestConfigRefusesAValueWithNeitherDefaultNorRequired(t *testing.T) { +func caseConfigRefusesAValueWithNeitherDefaultNorRequired(t *testing.T) { m := inConfigForm() delete(declaration(m, "width"), "default") refused(t, m, `"width"`, "neither a default nor required") @@ -3508,7 +3508,7 @@ func TestConfigRefusesAValueWithNeitherDefaultNorRequired(t *testing.T) { } // Rule 1: a value without type or description. -func TestConfigRefusesAValueWithoutTypeOrDescription(t *testing.T) { +func caseConfigRefusesAValueWithoutTypeOrDescription(t *testing.T) { m := inConfigForm() delete(declaration(m, "width"), "type") refused(t, m, `notifier's config value "width"`, "no type") @@ -3521,7 +3521,7 @@ func TestConfigRefusesAValueWithoutTypeOrDescription(t *testing.T) { } // 1658/AC2: a declared value placed nowhere, with an item that does not say it, is still refused. -func TestConfigStillRefusesAValueNoItemPlaces(t *testing.T) { +func caseConfigStillRefusesAValueNoItemPlaces(t *testing.T) { m := map[string]any{ "module": "m", "version": "1", "config": map[string]any{ @@ -3534,7 +3534,7 @@ func TestConfigStillRefusesAValueNoItemPlaces(t *testing.T) { // Consumer data said to live in a provision the module requires is protected only as well as that // provision's provider protects its consumers' data. -func TestConsumerDataInARequiredProvisionIsJudgedAgainstItsProvider(t *testing.T) { +func caseConsumerDataInARequiredProvisionIsJudgedAgainstItsProvider(t *testing.T) { idp := mustParse(t, `{"module":"idp","version":"1","requires":["postgres-database"], "provides":[{"name":"oidc-client","scope":"mesh"}],"grants":{"oidc-client":"${dir:g}"}, "resources":[{"id":"g","type":"directory","mode":"0700"}], @@ -3550,7 +3550,7 @@ func TestConsumerDataInARequiredProvisionIsJudgedAgainstItsProvider(t *testing.T } // The settings form keeps its own declaration; the config form's has no kind or why. -func TestEachFormKeepsItsOwnDeclaration(t *testing.T) { +func caseEachFormKeepsItsOwnDeclaration(t *testing.T) { m := inConfigForm() declaration(m, "width")["why"] = "fits a title" refused(t, m, `"width"`, "why") @@ -3568,7 +3568,7 @@ func TestEachFormKeepsItsOwnDeclaration(t *testing.T) { // module's identity, on the longest machine name, fits the bound of every provision it wants. An // overflow fails here, in the pull request that introduces it, rather than on the provider's machine // the first time a real machine's name meets the module's (issue 263). -func TestEveryCatalogueIdentityFitsWhatItRequires(t *testing.T) { +func caseEveryCatalogueIdentityFitsWhatItRequires(t *testing.T) { _, found := catalogueManifests(t) shelf := catalogue.Shelf{} for _, r := range found { @@ -3598,7 +3598,7 @@ func TestEveryCatalogueIdentityFitsWhatItRequires(t *testing.T) { // 0214's store list): every provider that grants says what it keeps for its consumers, nothing writes a // backup line by hand, every directory a container writes is declared, and every irreplaceable item is // backed up — so a store added is a store backed up, without a list of stores to keep in step. -func TestEveryCatalogueModuleDeclaresItsData(t *testing.T) { +func caseEveryCatalogueModuleDeclaresItsData(t *testing.T) { _, found := catalogueManifests(t) shelf := catalogue.Shelf{} granting := 0 @@ -3626,7 +3626,7 @@ func TestEveryCatalogueModuleDeclaresItsData(t *testing.T) { // no subject, and every manifest in the catalogue still held the old bus's routing key, which // derives into a namespace nobody owns (novox/hq 04-ISSUES/127). Nothing failed — the services // started and none of them reacted. This is the check that was missing. -func TestEveryManifestsEventNamesAreLocal(t *testing.T) { +func caseEveryManifestsEventNamesAreLocal(t *testing.T) { manifests := theCatalogue(t) var problems []string @@ -3640,7 +3640,7 @@ func TestEveryManifestsEventNamesAreLocal(t *testing.T) { } // **Across the whole catalogue**: every log is named locally and capped within the mesh's caps. -func TestEveryManifestsLogsAreLocalAndCapped(t *testing.T) { +func caseEveryManifestsLogsAreLocalAndCapped(t *testing.T) { var problems []string for _, m := range theCatalogue(t) { problems = append(problems, LogProblems(m)...) @@ -3651,7 +3651,7 @@ func TestEveryManifestsLogsAreLocalAndCapped(t *testing.T) { } // **Across the whole catalogue**: every state name is local and every read names a module's state. -func TestEveryManifestsStateIsLocalAndEveryReadIsKept(t *testing.T) { +func caseEveryManifestsStateIsLocalAndEveryReadIsKept(t *testing.T) { manifests := theCatalogue(t) var problems []string for _, m := range manifests { @@ -3662,7 +3662,7 @@ func TestEveryManifestsStateIsLocalAndEveryReadIsKept(t *testing.T) { } } -func TestEveryOutOfBoundsHealthIsRefusedByName(t *testing.T) { +func caseEveryOutOfBoundsHealthIsRefusedByName(t *testing.T) { cases := []struct { name string on string @@ -3720,7 +3720,7 @@ func TestEveryOutOfBoundsHealthIsRefusedByName(t *testing.T) { // `consumes` naming a module and asking for events its restricted stream carries, unless the manifest declares // `runs-as`; a stream without a grant, an event the provider says on EVENTS, and a wildcard emitter stay as they // were, and a consumer whose provider is not on the shelf is judged once it is. -func TestHearingARestrictedStreamNeedsAnAccountOfItsOwn(t *testing.T) { +func caseHearingARestrictedStreamNeedsAnAccountOfItsOwn(t *testing.T) { provider, err := ParseManifest([]byte(mailManifest(t, mailStream, `"emits":["account.added"],`))) if err != nil { t.Fatal(err) @@ -3758,7 +3758,7 @@ func TestHearingARestrictedStreamNeedsAnAccountOfItsOwn(t *testing.T) { // the node-engine report) is accepted, and a misspelt name is still refused with today's words. The manifests are the // shape of TestIfACapabilityNamesOneTheNodeEngineDetectsOnAnOfferedKindOnly (mesh-control 6c2a8d62 // internal/catalogue/seat_data_test.go:105), which stays in mesh-controller with the tests that read its other packages. -func TestIfACapabilityMayNameUserNamespaces(t *testing.T) { +func caseIfACapabilityMayNameUserNamespaces(t *testing.T) { const piece = `{"module":"power","contributions":[{"seat":"node-bar","kind":"block","if-capability":%q,"data":{"bar":"top","place":"status","shows":"battery"}}]}` if _, err := ParseManifest([]byte(strings.Replace(piece, "%q", `"user-namespaces"`, 1))); err != nil { t.Fatalf("if-capability user-namespaces was refused: %v", err) @@ -3783,7 +3783,7 @@ func TestIfACapabilityMayNameUserNamespaces(t *testing.T) { } } -func TestIfACapabilityNamesOneTheNodeEngineDetectsOnAnOfferedKindOnly(t *testing.T) { +func caseIfACapabilityNamesOneTheNodeEngineDetectsOnAnOfferedKindOnly(t *testing.T) { cases := map[string]string{ // A name nothing detects would leave the piece out on every machine. `{"seat":"node-bar","kind":"block","if-capability":"batery","data":{"bar":"top","place":"status","shows":"battery"}}`: "which no machine reports", @@ -3806,7 +3806,7 @@ func TestIfACapabilityNamesOneTheNodeEngineDetectsOnAnOfferedKindOnly(t *testing // Data a consumer keeps with a provider as irreplaceable must be protected there: the check refuses a // provider that keeps its consumers' data as a cache, or in an item with no protection. -func TestIrreplaceableDataKeptWithAProviderMustBeProtectedThere(t *testing.T) { +func caseIrreplaceableDataKeptWithAProviderMustBeProtectedThere(t *testing.T) { photos := mustParse(t, `{"module":"photos","version":"1","requires":["s3-bucket"], "data":{"kept-by":{"s3-bucket":{"class":"irreplaceable"}}}}`) store := func(backup string) catalogue.Manifest { @@ -3824,7 +3824,7 @@ func TestIrreplaceableDataKeptWithAProviderMustBeProtectedThere(t *testing.T) { } } -func TestItemNamesAttributesAndCapabilitiesAreJudged(t *testing.T) { +func caseItemNamesAttributesAndCapabilitiesAreJudged(t *testing.T) { item := func(extra string) string { return `{"module":"p","moved":true,"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]},` + `"items":[` + extra + `]}` @@ -3851,7 +3851,7 @@ func TestItemNamesAttributesAndCapabilitiesAreJudged(t *testing.T) { } } -func TestKeepsMustBeAnAbsolutePath(t *testing.T) { +func caseKeepsMustBeAnAbsolutePath(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"mesh-vault","version":"1","keeps":"root"}`)) if err == nil || !strings.Contains(err.Error(), "keeps") { t.Fatalf("a relative keeps path was not refused: %v", err) @@ -3861,7 +3861,7 @@ func TestKeepsMustBeAnAbsolutePath(t *testing.T) { } } -func TestMalformedShellCodeIsRefusedAtParse(t *testing.T) { +func caseMalformedShellCodeIsRefusedAtParse(t *testing.T) { for _, c := range []struct{ shell, want string }{ {`[{"for":"tcsh","slot":"normal","code":"x"}]`, `tool's shell code 1 is for "tcsh"; the shells are zsh, bash, fish`}, {`[{"for":"zsh","slot":"middle","code":"x"}]`, `tool's shell code 1 goes in the slot "middle"; the slots are first, normal, last`}, @@ -3883,7 +3883,7 @@ func TestMalformedShellCodeIsRefusedAtParse(t *testing.T) { // TestNoCatalogueManifestNamesAnInstallation is ADR 0112's check, run over the real catalogue: no // definition names a domain or a public address the mesh acts on, and every value that must for now // carries its reason (novox/hq ADR 0155, issue 134). The list it prints is the one that shrinks. -func TestNoCatalogueManifestNamesAnInstallation(t *testing.T) { +func caseNoCatalogueManifestNamesAnInstallation(t *testing.T) { _, found := catalogueManifests(t) var named []string for _, r := range found { @@ -3901,7 +3901,7 @@ func TestNoCatalogueManifestNamesAnInstallation(t *testing.T) { // 1887/A9a: the catalogue defines no seat node-build-agent, and a manifest claiming it is refused naming its // replacement; the build modules' seats accept the three kinds in their pull order and serve current, pause, resume. -func TestNodeBuildAgentIsRetiredForTheBuildSeats(t *testing.T) { +func caseNodeBuildAgentIsRetiredForTheBuildSeats(t *testing.T) { for _, gone := range []string{"node-build-agent", "mesh-build-machine"} { if _, ok := catalogue.SeatNamed(gone); ok { t.Errorf("the mesh still defines %s", gone) @@ -3946,7 +3946,7 @@ func TestNodeBuildAgentIsRetiredForTheBuildSeats(t *testing.T) { } // §2: a module may claim one of them, and may not declare it as its own. -func TestNoModuleMayDeclareAGraphicalSessionSeat(t *testing.T) { +func caseNoModuleMayDeclareAGraphicalSessionSeat(t *testing.T) { raw := `{"module":"xorg","seats":[{"name":"node-display-server","scope":"node"}]}` if _, err := ParseManifest([]byte(raw)); err == nil || !strings.Contains(err.Error(), "mesh's own namespace") { t.Fatalf("a module declared node-display-server as its own: %v", err) @@ -3955,7 +3955,7 @@ func TestNoModuleMayDeclareAGraphicalSessionSeat(t *testing.T) { // ADR 0204 §1: the login shell is the mesh's, so no module declares it — neither under the mesh's // name nor under the name a module gave it before. -func TestNoModuleMayDeclareTheLoginShell(t *testing.T) { +func caseNoModuleMayDeclareTheLoginShell(t *testing.T) { for _, n := range []string{"login-shell", "node-login-shell", "node-environment"} { raw := `{"module":"zsh","seats":[{"name":"` + n + `","scope":"node","serves":["execute"]}],"tools":["execute"]}` _, err := ParseManifest([]byte(raw)) @@ -3982,7 +3982,7 @@ func TestNoModuleMayDeclareTheLoginShell(t *testing.T) { // One component, one artifact per system: the shape the mesh's own binaries are declared in, and the // reason the target is the artifact's rather than the recipe's. -func TestOneArtifactPerSystemIsAccepted(t *testing.T) { +func caseOneArtifactPerSystemIsAccepted(t *testing.T) { m := catalogue.Manifest{Module: "the-host", Build: &catalogue.Build{Artifacts: []catalogue.Artifact{ {Name: "arch", Kind: catalogue.ArtifactBundle, Language: "go", System: "arch"}, {Name: "alpine", Kind: catalogue.ArtifactBundle, Language: "go", System: "alpine"}, @@ -3993,7 +3993,7 @@ func TestOneArtifactPerSystemIsAccepted(t *testing.T) { } } -func TestOneNamingFileMakesEveryMergeableFileName(t *testing.T) { +func caseOneNamingFileMakesEveryMergeableFileName(t *testing.T) { // ADR 0326 §2: a module with one naming and one silent mergeable file is refused, naming the // silent one — the silent one would otherwise still take every key. m := twoFiles([]any{"server"}, nil) @@ -4013,7 +4013,7 @@ func TestOneNamingFileMakesEveryMergeableFileName(t *testing.T) { // Only a claimant declares a seat's path: a module claiming no seat that names /etc/hosts and declaring // it is refused at registration naming the seat; the uplink's holder and the resolver's both declaring // the resolver file are each a claimant of a seat naming it. Reading a seat's path is access, and allowed. -func TestOnlyAClaimantDeclaresASeatsPath(t *testing.T) { +func caseOnlyAClaimantDeclaresASeatsPath(t *testing.T) { stranger := catalogue.Manifest{Module: "stranger", Version: "1", Resources: []map[string]any{ {"id": "hosts", "type": "file", "path": "/etc/hosts", "into": "block", "content": "10.0.0.1 x\n"}}} got := strings.Join(CatalogueProblems(catalogue.Shelf{"stranger": stranger}), "; ") @@ -4041,7 +4041,7 @@ func TestOnlyAClaimantDeclaresASeatsPath(t *testing.T) { // An image names the Go package its recipe compiles (novox/hq ADR 0267): within the tree it is built in, // and only an image says one. -func TestOnlyAnImageNamesThePackageItCompilesWithinItsTree(t *testing.T) { +func caseOnlyAnImageNamesThePackageItCompilesWithinItsTree(t *testing.T) { m, err := ParseManifest([]byte(`{"module":"a","version":"1","build":{"artifacts":[ {"name":"x","kind":"image","from":"Dockerfile","compiles":"cmd/x"}]}}`)) if err != nil || m.Build.Artifacts[0].Compiles != "cmd/x" { @@ -4062,7 +4062,7 @@ func TestOnlyAnImageNamesThePackageItCompilesWithinItsTree(t *testing.T) { // Only a node seat may carry needs (novox/hq ADR 0378 §8): a per-mesh seat's holder is not on any // one node to depend on anything beside it there. -func TestOnlyANodeSeatMayCarryNeeds(t *testing.T) { +func caseOnlyANodeSeatMayCarryNeeds(t *testing.T) { m := catalogue.Manifest{Module: "mail", DefinesSeats: []catalogue.SeatDeclaration{{ Name: "mail-notifier", Scope: catalogue.ScopeMesh, Needs: []string{"node-notifier"}}}} got := strings.Join(declaredSeatProblems(m), "; ") @@ -4071,7 +4071,7 @@ func TestOnlyANodeSeatMayCarryNeeds(t *testing.T) { } } -func TestOnlyChannelAndIntakeAreKinded(t *testing.T) { +func caseOnlyChannelAndIntakeAreKinded(t *testing.T) { m := catalogue.Manifest{Module: "x", DefinesSeats: []catalogue.SeatDeclaration{{Name: "pager", Kinded: true, Accepts: []string{"page"}}}} if got := strings.Join(declaredSeatProblems(m), "; "); !strings.Contains(got, "only channel and intake are kinded") { t.Fatalf("another kinded bench was declared: %s", got) @@ -4081,7 +4081,7 @@ func TestOnlyChannelAndIntakeAreKinded(t *testing.T) { // The indexer and the builder hold no published list of predefined keys; a manifest whose config values fall back to // one (claude-code, dunst, xterm at mesh-catalog 835bf22b) is still read for its build's and fingerprint's inputs // (issue 1751). -func TestParseManifestForInputsReadsAValueFallingBackToAPredefinedKey(t *testing.T) { // issue 1751 +func caseParseManifestForInputsReadsAValueFallingBackToAPredefinedKey(t *testing.T) { // issue 1751 was := catalogue.ReplacePublished(nil) // the indexer's and the builder's case: no published list defer catalogue.ReplacePublished(was) for _, module := range []string{"claude-code", "dunst", "xterm"} { @@ -4098,7 +4098,7 @@ func TestParseManifestForInputsReadsAValueFallingBackToAPredefinedKey(t *testing } } -func TestPlaceIsValidatedAtTheManifest(t *testing.T) { +func casePlaceIsValidatedAtTheManifest(t *testing.T) { both := catalogue.Manifest{Module: "x", Resources: []map[string]any{ {"id": "d", "type": "directory", "place": ".", "path": "/somewhere"}, }} @@ -4119,7 +4119,7 @@ func TestPlaceIsValidatedAtTheManifest(t *testing.T) { } } -func TestReceivingWhatYouDoNotProvideIsRefused(t *testing.T) { +func caseReceivingWhatYouDoNotProvideIsRefused(t *testing.T) { // It would create a file nobody ever writes to, on a machine where nothing asked for it. _, err := ParseManifest([]byte(`{"module":"traefik","version":"1", "receives":{"reverse-proxy":"/etc/traefik/mesh.json"}}`)) @@ -4136,7 +4136,7 @@ func TestReceivingWhatYouDoNotProvideIsRefused(t *testing.T) { // /etc/hosts, and a module could claim node-hostname declaring none of its paths, and nothing refused either. // Written only with what the catalogue had before its fix (mesh-controller #267): CatalogueProblems, Shelf, // SeatNamed and CanHold, so it is laid over the commit before. -func TestReplay412(t *testing.T) { +func caseReplay412(t *testing.T) { stranger := catalogue.Manifest{Module: "stranger", Version: "1", Resources: []map[string]any{ {"id": "hosts", "type": "file", "path": "/etc/hosts", "into": "block", "content": "10.0.0.1 x\n"}}} got := strings.Join(CatalogueProblems(catalogue.Shelf{"stranger": stranger}), "; ") @@ -4161,7 +4161,7 @@ func TestReplay412(t *testing.T) { } } -func TestRunsAsIsAnAccountOfTheModulesOwn(t *testing.T) { +func caseRunsAsIsAnAccountOfTheModulesOwn(t *testing.T) { ok := catalogue.Manifest{Module: "telegram", RunsAs: "telegram", SecretsOwner: "telegram", OwnSecrets: catalogue.OwnSecrets{"broker": {Path: "/var/lib/telegram/broker"}}, Resources: []map[string]any{{"id": "account", "type": "user", "name": "telegram"}}} @@ -4185,14 +4185,14 @@ func TestRunsAsIsAnAccountOfTheModulesOwn(t *testing.T) { } } -func TestRuntimeHealthIsRefusedWithoutAnAccountOfItsOwn(t *testing.T) { +func caseRuntimeHealthIsRefusedWithoutAnAccountOfItsOwn(t *testing.T) { _, err := ParseManifest(ownAccountManifest(t, false, map[string]any{"kind": "tool", "tool": "keeper_health"})) if err == nil || !strings.Contains(err.Error(), "runtime-health") || !strings.Contains(err.Error(), "runs-as") { t.Errorf("runtime-health without runs-as: %v", err) } } -func TestServingWhatYouDoNotProvideIsRefused(t *testing.T) { +func caseServingWhatYouDoNotProvideIsRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"app","version":"1", "serves":{"postgres-database":{"port":5432}}}`)) if err == nil { @@ -4203,7 +4203,7 @@ func TestServingWhatYouDoNotProvideIsRefused(t *testing.T) { } } -func TestTakesSettingsIsRefusedWhereItCannotMeanAnything(t *testing.T) { +func caseTakesSettingsIsRefusedWhereItCannotMeanAnything(t *testing.T) { // ADR 0326 §4. cases := map[string]struct { resource map[string]any @@ -4245,7 +4245,7 @@ func TestTakesSettingsIsRefusedWhereItCannotMeanAnything(t *testing.T) { // A store holder that builds is not refused by its manifest (the operator, 2026-11-04, issue 1966). The fresh-mesh // circle the rule of novox/hq 04-ISSUES/029 refused, a holder whose build publishes through itself, is caught where a // fresh mesh starts (issue 1152), not here. -func TestAStoreHolderThatBuildsIsNotRefusedByItsManifest(t *testing.T) { +func caseAStoreHolderThatBuildsIsNotRefusedByItsManifest(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"registry","version":"1",` + `"provides":[{"name":"artifact-store","scope":"mesh"}],` + `"build":{"artifacts":[{"name":"registry","kind":"upstream","from":"registry:2"}]},` + @@ -4281,7 +4281,7 @@ func TestAStoreHolderThatBuildsIsNotRefusedByItsManifest(t *testing.T) { // The module holding mesh-broker is the bus, and its account is granted the bus's snapshot API and // nothing else (novox/hq ADR 0235). Anything it declared to say or hear on the bus would be granted // nothing, so it is refused at the parser rather than silently dropped. -func TestTheBussAccountSaysNothingOnTheBus(t *testing.T) { +func caseTheBussAccountSaysNothingOnTheBus(t *testing.T) { raw := []byte(`{"module":"bus","version":"1","provides":[{"name":"mesh-bus","scope":"mesh"}], "claims":[{"name":"mesh-broker","scope":"mesh"}],"own-secrets":{"broker":"/run/broker"}, "emits":["something.happened"]}`) @@ -4411,7 +4411,7 @@ func TestTheBussAccountSaysNothingOnTheBus(t *testing.T) { // The catalogue check: a granting provider says what it keeps, says it in one place, writes no backup // line by hand, and every directory a container writes is declared (novox/hq ADR 0233). -func TestTheCatalogueCheckAsksEveryModuleForItsData(t *testing.T) { +func caseTheCatalogueCheckAsksEveryModuleForItsData(t *testing.T) { unsaid := mustParse(t, `{"module":"q","version":"1","provides":[{"name":"queue","scope":"mesh"}], "grants":{"queue":"${dir:g}"},"resources":[{"id":"g","type":"directory","mode":"0700"}]}`) onTheOffer := mustParse(t, `{"module":"r","version":"1","provides":[{"name":"resolver","scope":"mesh","keeps-consumer-data":false}]}`) @@ -4445,7 +4445,7 @@ func TestTheCatalogueCheckAsksEveryModuleForItsData(t *testing.T) { // Refused before merge: the catalogue check judges each module's identity, on the longest machine // name, against the bound of every provision it wants — and names the module and the slug to set. -func TestTheCatalogueCheckRefusesAnIdentityThatOverflowsWhatItRequires(t *testing.T) { +func caseTheCatalogueCheckRefusesAnIdentityThatOverflowsWhatItRequires(t *testing.T) { shelf := catalogue.Shelf{ "objects": {Module: "objects", Provides: []catalogue.Offer{{Name: "s3-bucket", Scope: catalogue.ScopeMesh, Identity: &catalogue.OfferIdentity{Max: 20, In: "an S3 access key"}}}, @@ -4474,7 +4474,7 @@ func TestTheCatalogueCheckRefusesAnIdentityThatOverflowsWhatItRequires(t *testin // The catalogue as it is passes: no holder of a seat naming a path is missing one, and nobody else // declares one. -func TestTheCataloguePassesTheSeatPathRules(t *testing.T) { +func caseTheCataloguePassesTheSeatPathRules(t *testing.T) { shelf := catalogue.Shelf{} for _, m := range theCatalogue(t) { shelf[m.Module] = m @@ -4488,7 +4488,7 @@ func TestTheCataloguePassesTheSeatPathRules(t *testing.T) { // The catalogue pass no longer judges one module's reads against another's manifest (novox/hq ADR 0495 clauses 1 and 5, // issue 1790): what an owner keeps is what it announces on the bus, and each module's own announcement test holds that. -func TestTheCataloguePassJudgesNoReadAgainstTheOwnersManifest(t *testing.T) { +func caseTheCataloguePassJudgesNoReadAgainstTheOwnersManifest(t *testing.T) { shelf := catalogue.Shelf{ "licence-manager": {Module: "licence-manager", State: []catalogue.StateDeclaration{{Name: "bindings"}}}, "claude-code": {Module: "claude-code", Reads: []string{"licence-manager.tokens"}}, @@ -4504,7 +4504,7 @@ func TestTheCataloguePassJudgesNoReadAgainstTheOwnersManifest(t *testing.T) { // every example of the shape is no longer judged here (issue 915, which also covers placementProblems not reading the // collected form). What the controller still owns is that the bar's files place the blocks at all: a moved bar's // carry the collected placement, and one that stopped placing them fails here rather than being skipped (issue 432). -func TestTheCataloguesBarPlacesBlocksAndItsShapeCoversEveryShow(t *testing.T) { +func caseTheCataloguesBarPlacesBlocksAndItsShapeCoversEveryShow(t *testing.T) { holder := catalogueManifest(t, "i3status-rust") s, _ := catalogue.SeatNamed(catalogue.BarSeat) if holder.Moved { @@ -4548,7 +4548,7 @@ func TestTheCataloguesBarPlacesBlocksAndItsShapeCoversEveryShow(t *testing.T) { // The compiled set keeps the rules: node seats only, absolute and literal, one seat per path without // stepping back, and a stepping back that cannot cycle. -func TestTheCompiledSeatPathsKeepTheRules(t *testing.T) { +func caseTheCompiledSeatPathsKeepTheRules(t *testing.T) { if p := SeatPathProblems(catalogue.Seats()); len(p) != 0 { t.Fatalf("the compiled set breaks ADR 0287: %v", p) } @@ -4581,7 +4581,7 @@ func TestTheCompiledSeatPathsKeepTheRules(t *testing.T) { } // Every rule of the section itself, refused at parse in the words of the module. -func TestTheDataSectionIsRefusedWhereItIsWrong(t *testing.T) { +func caseTheDataSectionIsRefusedWhereItIsWrong(t *testing.T) { for _, c := range []struct{ name, data, want string }{ {"a class it does not know", `{"own":[{"id":"a","path":"${dir:d}","class":"precious"}]}`, "not one the mesh protects by"}, {"an access it does not have", `{"own":[{"id":"a","path":"${access:media}","class":"irreplaceable","redundancy":"an array"}]}`, "declares no access"}, @@ -4613,7 +4613,7 @@ func TestTheDataSectionIsRefusedWhereItIsWrong(t *testing.T) { // A default is a value the mesh writes, so the installation check reads it, even under a setting // called `description` or `why`; a setting's own why is prose and is not read. -func TestTheInstallationCheckReadsADefault(t *testing.T) { +func caseTheInstallationCheckReadsADefault(t *testing.T) { m := notifier() m.Settings["relay"] = catalogue.SettingDeclaration{Kind: catalogue.KindPreference, Default: "relay.acme.be", Why: "as at relay.acme.be"} m.Settings["description"] = catalogue.SettingDeclaration{Kind: catalogue.KindPreference, Default: "notes.acme.be", Why: "x"} @@ -4628,7 +4628,7 @@ func TestTheInstallationCheckReadsADefault(t *testing.T) { } } -func TestTheMachinesReachIsAProvisionsOnlyReachAndIsNodeScoped(t *testing.T) { +func caseTheMachinesReachIsAProvisionsOnlyReachAndIsNodeScoped(t *testing.T) { for _, c := range []struct{ provides, want string }{ {`{"name":"x11-display","reach":"internal"}`, `with reach "internal"; a provision's reach is "machine" or nothing`}, {`{"name":"x11-display","scope":"mesh","reach":"machine"}`, `at scope "mesh" with the machine's reach`}, @@ -4679,7 +4679,7 @@ func theMeshsDirectoryForAModuleIsAPlace(t *testing.T) { } // The mesh's own seats still work, and are not shadowed by the derived half. -func TestTheMeshsOwnSeatsAreStillClaimable(t *testing.T) { +func caseTheMeshsOwnSeatsAreStillClaimable(t *testing.T) { // It delivers the bus, so its holder provides the bus — the rule this check now enforces. m := catalogue.Manifest{Module: "nats", Provides: []catalogue.Offer{{Name: "mesh-bus", Scope: catalogue.ScopeMesh, Credential: &catalogue.OfferCredential{Form: catalogue.CredentialFormNone}}}, @@ -4689,7 +4689,7 @@ func TestTheMeshsOwnSeatsAreStillClaimable(t *testing.T) { } } -func TestTheModuleCheckRefusesAnOptionalPlaceholderThatCouldRenderEmpty(t *testing.T) { +func caseTheModuleCheckRefusesAnOptionalPlaceholderThatCouldRenderEmpty(t *testing.T) { refused := map[string]string{ "a placeholder without a default": `{"id":"ds","type":"file","path":"/a","mode":"0644", "content":"url: ${bound:influxdb-api:at}"}`, @@ -4725,7 +4725,7 @@ func TestTheModuleCheckRefusesAnOptionalPlaceholderThatCouldRenderEmpty(t *testi } } -func TestTheNewRulesAreHeldToWhatTheSeatSays(t *testing.T) { +func caseTheNewRulesAreHeldToWhatTheSeatSays(t *testing.T) { m := catalogue.Manifest{Module: "x", DefinesSeats: []catalogue.SeatDeclaration{{Name: "thing", Accepts: []string{"do"}, ByCaller: []string{"undo"}, Proofs: []string{"code"}, Records: []string{"nothing"}}}} got := strings.Join(declaredSeatProblems(m), "; ") @@ -4743,7 +4743,7 @@ func TestTheNewRulesAreHeldToWhatTheSeatSays(t *testing.T) { // mid-rollout — the compiled row said the seat delivered one provision, the store's row said // another, and the build failed on the copy rather than the truth. The parser judges the manifest; // the seat set judges the claim, where it is loaded. -func TestTheParserDoesNotJudgeWhatOnlyTheStoreKnows(t *testing.T) { +func caseTheParserDoesNotJudgeWhatOnlyTheStoreKnows(t *testing.T) { was := catalogue.Seats() t.Cleanup(func() { catalogue.UseSeats(was) }) @@ -4772,7 +4772,7 @@ func TestTheParserDoesNotJudgeWhatOnlyTheStoreKnows(t *testing.T) { } } -func TestTheParserTakesAPreferenceAndRefusesTheRest(t *testing.T) { +func caseTheParserTakesAPreferenceAndRefusesTheRest(t *testing.T) { if err := parsed(t, notifier()); err != nil { t.Fatalf("a preference with a default was refused: %v", err) } @@ -4807,7 +4807,7 @@ func TestTheParserTakesAPreferenceAndRefusesTheRest(t *testing.T) { } // A refusal that reorders itself between runs is a refusal nobody can diff. -func TestTheProblemsAreStable(t *testing.T) { +func caseTheProblemsAreStable(t *testing.T) { shelf := catalogue.Shelf{"telegram": telegram(), "shop": {Module: "shop", Uses: []string{"nope"}}, "other": {Module: "other", Uses: []string{"also-nope"}}} first, second := problemsFor(t, shelf), problemsFor(t, shelf) @@ -4817,7 +4817,7 @@ func TestTheProblemsAreStable(t *testing.T) { } // ADR 0310 §3: the account that reads is in no group beside its own; one put in a group is refused. -func TestTheReadsAccountIsInNoGroup(t *testing.T) { +func caseTheReadsAccountIsInNoGroup(t *testing.T) { m := catalogue.Manifest{Module: "reads", RunsAs: "mesh-reads", Claims: []catalogue.Claim{{Name: catalogue.ReadsSeat}}, Resources: []map[string]any{{"id": "account", "type": "user", "name": "mesh-reads", "groups": []any{"docker"}}}} if p := ReadsHolderProblems(m); len(p) != 1 || !strings.Contains(p[0], "docker") { @@ -4834,7 +4834,7 @@ func TestTheReadsAccountIsInNoGroup(t *testing.T) { // beside it at the commit the mesh runs, elsewhere the copy captured in testdata/beside. When the engine's lists // move, this fails until the controller's move with them, so the gate never refuses what the engine applies nor // passes what it refuses by path alone. -func TestTheResolvedPathRulesAreTheNodeEnginesOwn(t *testing.T) { +func caseTheResolvedPathRulesAreTheNodeEnginesOwn(t *testing.T) { file := filepath.Join(beside.Dir(t, "mesh-host"), "internal", "apply", "placement_guard.go") parsed, err := parser.ParseFile(token.NewFileSet(), file, nil, 0) if err != nil { @@ -4889,7 +4889,7 @@ func TestTheResolvedPathRulesAreTheNodeEnginesOwn(t *testing.T) { // Whom agents run as is the runtime's, told by the node-engine's composition (its own to test, ADR 0593 §7): a bundle // may not say it. -func TestTheRuntimeIsToldTheAgentAccount(t *testing.T) { +func caseTheRuntimeIsToldTheAgentAccount(t *testing.T) { if problems := bundleEnvProblems("x", catalogue.Artifact{Name: "b", Kind: catalogue.ArtifactBundle, Loads: []string{"x"}, Env: map[string]string{catalogue.RuntimeAgentAccount: "me"}}); len(problems) == 0 { t.Error("a bundle may tell the runtime whom agents run as") @@ -4899,7 +4899,7 @@ func TestTheRuntimeIsToldTheAgentAccount(t *testing.T) { // The machine's facility — the container runtime's socket — is granted by the capability that names // it, and declaring it as the module's own directory would be a lie the host would act on. This is // the case the first version of this check refused, and was withdrawn for: the builder. -func TestTheRuntimeSocketIsGrantedByTheCapabilityAndNotOtherwise(t *testing.T) { +func caseTheRuntimeSocketIsGrantedByTheCapabilityAndNotOtherwise(t *testing.T) { granted := `{"module":"builder","capabilities":["container-runtime"],"resources":[` + strings.Replace(aContainerMounting, "%s", "/var/run/docker.sock", 1) + `]}` if _, err := ParseManifest([]byte(granted)); err != nil { @@ -4916,7 +4916,7 @@ func TestTheRuntimeSocketIsGrantedByTheCapabilityAndNotOtherwise(t *testing.T) { // person changing the set finds the argument rather than a number to edit — the pattern the host's // vocabulary test follows. If this fails because a seat was added, the fix is a record in novox/hq // and a row in to-be 26, not a new number here. -func TestTheSeatsAreAClosedSetAndEachNamesItsDecision(t *testing.T) { +func caseTheSeatsAreAClosedSetAndEachNamesItsDecision(t *testing.T) { // A seat a later record extends names both, "novox/hq ADR 0166, ADR 0207": the one that defined // it and the one that seeded it. record := regexp.MustCompile(`^novox/hq ADR \d{4}(, ADR \d{4})*$`) @@ -4950,7 +4950,7 @@ func TestTheSeatsAreAClosedSetAndEachNamesItsDecision(t *testing.T) { // §4: xinitrc and xresources slots, placed by the display server's holder alone: the judge takes a session // contribution and refuses its placeholder outside the holder (the files the holder's composition places are the // node-engine's to test, ADR 0593 §7). -func TestTheSessionsFilesArePlacedByTheDisplayServersHolderAlone(t *testing.T) { +func caseTheSessionsFilesArePlacedByTheDisplayServersHolderAlone(t *testing.T) { // The contributions parse; the placeholders parse only in the holder. if _, err := ParseManifest([]byte(`{"module":"i3","shell":[{"for":"xinitrc","slot":"last","code":"exec i3"},` + `{"for":"xresources","slot":"normal","code":"i3.font: x"}]}`)); err != nil { @@ -4978,7 +4978,7 @@ func TestTheSessionsFilesArePlacedByTheDisplayServersHolderAlone(t *testing.T) { // #281). Inventory.Catalogue stops at the first manifest it cannot read, so a long-form entry inside // `requires` would have stopped every plan after a rollback. Stored, `requires` is plain names, as main's // manifest type reads it, and which are optional sits beside it in a key such a controller sets aside. -func TestTheStoredFormReadsWhereRequiresIsAListOfNames(t *testing.T) { +func caseTheStoredFormReadsWhereRequiresIsAListOfNames(t *testing.T) { m := mustParse(t, `{"module":"grafana","version":"1", "requires":["route",{"name":"influxdb-api","optional":true}]}`) raw, err := json.Marshal(m) @@ -5027,7 +5027,7 @@ func TestTheStoredFormReadsWhereRequiresIsAListOfNames(t *testing.T) { // **Nothing, because nothing may be required of it.** A holder only keeps its network manager from // contradicting the mesh; a requirement resolving to it would make the manager the mesh's answer // for something, and the manager's link is the one thing the mesh must never be able to break. -func TestTheUplinkIsANodeSeatThatDeliversNothing(t *testing.T) { +func caseTheUplinkIsANodeSeatThatDeliversNothing(t *testing.T) { seat, known := catalogue.SeatNamed("node-uplink") if !known { t.Fatalf("the uplink is not a seat; the seats are: %s", seatNames()) @@ -5042,7 +5042,7 @@ func TestTheUplinkIsANodeSeatThatDeliversNothing(t *testing.T) { } } -func TestTheWorldsNamesAreNotAnInstallations(t *testing.T) { +func caseTheWorldsNamesAreNotAnInstallations(t *testing.T) { m := catalogue.Manifest{Module: "resolver", Resources: []map[string]any{ {"id": "conf", "type": "file", "content": "server=1.1.1.1\nserver=8.8.8.8\nlisten=127.0.0.55\n"}, {"id": "proxy", "type": "container", "image": "docker.io/library/traefik@sha256:bb"}, @@ -5054,7 +5054,7 @@ func TestTheWorldsNamesAreNotAnInstallations(t *testing.T) { } } -func TestTwoArtifactsWithOneNameAreRefused(t *testing.T) { +func caseTwoArtifactsWithOneNameAreRefused(t *testing.T) { _, err := ParseManifest([]byte(`{"module":"a","version":"1","build":{"artifacts":[ {"name":"x","kind":"image","from":"Dockerfile"}, {"name":"x","kind":"archive","from":"files"}]}}`)) @@ -5066,7 +5066,7 @@ func TestTwoArtifactsWithOneNameAreRefused(t *testing.T) { } } -func TestTwoChannelsOfDifferentKindsHoldTheBenches(t *testing.T) { +func caseTwoChannelsOfDifferentKindsHoldTheBenches(t *testing.T) { shelf := catalogue.Shelf{"messenger": router(), "telegram": aChannel("telegram", "telegram"), "desk-channel": aChannel("desk-channel", "desktop")} if got := problemsFor(t, shelf); got != "" { @@ -5081,7 +5081,7 @@ func TestTwoChannelsOfDifferentKindsHoldTheBenches(t *testing.T) { // **Two endpoints called the same would make an assignment configure whichever was read last.** The // point of a name is that it identifies one thing. -func TestTwoEndpointsWithOneNameAreRefused(t *testing.T) { +func caseTwoEndpointsWithOneNameAreRefused(t *testing.T) { m := catalogue.Manifest{Module: "twice", Listens: []catalogue.Listening{ {Name: "web", Port: 80, From: catalogue.FromMesh}, {Name: "web", Port: 8080, From: catalogue.FromMesh}, @@ -5093,7 +5093,7 @@ func TestTwoEndpointsWithOneNameAreRefused(t *testing.T) { } // A stream name has one owner across the catalogue (ADR 0363 §1). -func TestTwoModulesCannotDeclareOneStream(t *testing.T) { +func caseTwoModulesCannotDeclareOneStream(t *testing.T) { a := catalogue.Manifest{Module: "a", Streams: []catalogue.StreamDeclaration{{Name: "mail", Events: []string{"x"}}}} b := catalogue.Manifest{Module: "b", Streams: []catalogue.StreamDeclaration{{Name: "mail", Events: []string{"y"}}}} got := strings.Join(CatalogueProblems(catalogue.Shelf{"a": a, "b": b}), "; ") @@ -5114,7 +5114,7 @@ func TestTwoModulesCannotDeclareOneStream(t *testing.T) { } // A seat name meaning two protocols is the failure nobody could diagnose afterwards. -func TestTwoModulesCannotDeclareTheSameSeat(t *testing.T) { +func caseTwoModulesCannotDeclareTheSameSeat(t *testing.T) { other := catalogue.Manifest{Module: "aardvark", DefinesSeats: []catalogue.SeatDeclaration{{ Name: "telegram-sender", Scope: catalogue.ScopeMesh, Accepts: []string{"something-else"}}}} got := problemsFor(t, catalogue.Shelf{"telegram": telegram(), "aardvark": other}) @@ -5130,7 +5130,7 @@ func TestTwoModulesCannotDeclareTheSameSeat(t *testing.T) { // Where ADR 0110's guarantee lands under a derived set: a typo is refused, not resolved to // nothing at runtime. And a seat verb a module invokes is one a holder serves (issue 774, sweep item 1: messenger // invoked a verb nothing answered, and Telegram held every ask silently). -func TestUsingASeatNobodyDeclaresIsRefused(t *testing.T) { +func caseUsingASeatNobodyDeclaresIsRefused(t *testing.T) { unclaimed := telegram() unclaimed.Claims = nil for _, row := range []struct { @@ -5171,7 +5171,7 @@ func TestUsingASeatNobodyDeclaresIsRefused(t *testing.T) { } } -func TestWhatAHandedModuleCannotHaveFromTheVaultIsRefused(t *testing.T) { +func caseWhatAHandedModuleCannotHaveFromTheVaultIsRefused(t *testing.T) { // A family and a secret issued outside the mesh are not handed by name yet: the mark is refused. for why, raw := range map[string]string{ "a family": strings.Replace(botMoved(), `"own-secrets":{"token":"${dir:state}/token"}`, `"own-secrets":{"token":"${dir:state}/token","key-*":"${dir:state}/keys"}`, 1), @@ -5183,7 +5183,7 @@ func TestWhatAHandedModuleCannotHaveFromTheVaultIsRefused(t *testing.T) { } } -func TestWhatReplacesMayNameIsRefusedNearItsAuthor(t *testing.T) { +func caseWhatReplacesMayNameIsRefusedNearItsAuthor(t *testing.T) { for what, resource := range map[string]string{ "a container": `{"id":"c","type":"container","name":"c","image":"x@` + aServiceDigest + `","replaces":["old"]}`, "a step": `{"id":"p","type":"process","name":"p","run":["./p"],"run-once":true,"replaces":["old"]}`, @@ -5204,7 +5204,7 @@ func TestWhatReplacesMayNameIsRefusedNearItsAuthor(t *testing.T) { // A module rolls out by default; it records where it says so with why, where it keeps irreplaceable // data, and always where it is the bus (novox/hq ADR 0236). -func TestWhereAModulesUpgradePolicyComesFrom(t *testing.T) { +func caseWhereAModulesUpgradePolicyComesFrom(t *testing.T) { cases := []struct { name string m catalogue.Manifest @@ -6101,3 +6101,282 @@ func (hub) Resources(string) ([]map[string]any, bool, error) { func (hub) Listens(string) ([]catalogue.Listening, error) { return []catalogue.Listening{{Port: 51820, Protocol: "udp", From: catalogue.FromEverywhere}}, nil } + +// TestRulesConfig runs the tests of one kind as subtests, each by its former name. +func TestRulesConfig(t *testing.T) { + t.Run("AManifestMixingTheConfigAndSettingsFormsIsRefused", caseAManifestMixingTheConfigAndSettingsFormsIsRefused) + t.Run("AManifestWhoseContainerTakesItsGroupFromConfigRegisters", caseAManifestWhoseContainerTakesItsGroupFromConfigRegisters) + t.Run("ARenamedEntryIsTheConfigFormsOnly", caseARenamedEntryIsTheConfigFormsOnly) + t.Run("AStreamIsNamedBoundedAndGrantedByATrustedConfigValue", caseAStreamIsNamedBoundedAndGrantedByATrustedConfigValue) + t.Run("ConfigRefusesADefaultFailingItsValidation", caseConfigRefusesADefaultFailingItsValidation) + t.Run("ConfigRefusesAMergeableFileNotNamingItsKeys", caseConfigRefusesAMergeableFileNotNamingItsKeys) + t.Run("ConfigRefusesAMeshWordOrAnAccountFactInTakesConfig", caseConfigRefusesAMeshWordOrAnAccountFactInTakesConfig) + t.Run("ConfigRefusesAnObjectOrListNotTrusted", caseConfigRefusesAnObjectOrListNotTrusted) + t.Run("ConfigRefusesAnUntrustedValueFallingBackToATrustedKey", caseConfigRefusesAnUntrustedValueFallingBackToATrustedKey) + t.Run("ConfigRefusesAPlaceholderNamingAnUndeclaredValue", caseConfigRefusesAPlaceholderNamingAnUndeclaredValue) + t.Run("ConfigRefusesAPredefinedKeyNotOnTheListOrOfAnotherType", caseConfigRefusesAPredefinedKeyNotOnTheListOrOfAnotherType) + t.Run("ConfigRefusesAReloadOrRestartOnNamingAnUndeclaredFile", caseConfigRefusesAReloadOrRestartOnNamingAnUndeclaredFile) + t.Run("ConfigRefusesATakesConfigKeyNotDeclared", caseConfigRefusesATakesConfigKeyNotDeclared) + t.Run("ConfigRefusesAValueNeitherPlacedNorReadAtRuntime", caseConfigRefusesAValueNeitherPlacedNorReadAtRuntime) + t.Run("ConfigRefusesAValueWithNeitherDefaultNorRequired", caseConfigRefusesAValueWithNeitherDefaultNorRequired) + t.Run("ConfigRefusesAValueWithoutTypeOrDescription", caseConfigRefusesAValueWithoutTypeOrDescription) + t.Run("ConfigStillRefusesAValueNoItemPlaces", caseConfigStillRefusesAValueNoItemPlaces) +} + +// TestRulesClaims runs the tests of one kind as subtests, each by its former name. +func TestRulesClaims(t *testing.T) { + t.Run("ABuildContextOnASeatNamesNoForge", caseABuildContextOnASeatNamesNoForge) + t.Run("AClaimMayNameWhatItServesForTheSeat", caseAClaimMayNameWhatItServesForTheSeat) + t.Run("AClaimMustMatchTheDeclaredScope", caseAClaimMustMatchTheDeclaredScope) + t.Run("AClaimOnASeatAnotherModuleDeclaresIsAccepted", caseAClaimOnASeatAnotherModuleDeclaresIsAccepted) + t.Run("AClaimOnASeatNobodyDeclaresIsRefusedAtRegistration", caseAClaimOnASeatNobodyDeclaresIsRefusedAtRegistration) + t.Run("AClaimThatIsMalformedIsRefusedOnceForThat", caseAClaimThatIsMalformedIsRefusedOnceForThat) + t.Run("AClaimWithoutTheSeatsPathsIsRefused", caseAClaimWithoutTheSeatsPathsIsRefused) + t.Run("AContributionPlaceholderOutsideTheHolderIsRefused", caseAContributionPlaceholderOutsideTheHolderIsRefused) + t.Run("AContributionToASeatThatDoesNotReceiveItIsRefused", caseAContributionToASeatThatDoesNotReceiveItIsRefused) + t.Run("ADeliveringSeatIsOnlyHeldByAModuleThatProvides", caseADeliveringSeatIsOnlyHeldByAModuleThatProvides) + t.Run("AFileSaysWhetherItsSettingsAreTrusted", caseAFileSaysWhetherItsSettingsAreTrusted) + t.Run("AHolderMustServeWhatItsSeatPromises", caseAHolderMustServeWhatItsSeatPromises) + t.Run("AHolderOfNodeFilesDeclaringRunsAsIsRefused", caseAHolderOfNodeFilesDeclaringRunsAsIsRefused) + t.Run("AHolderOfNodeReadsWithoutAnAccountOfItsOwnIsRefused", caseAHolderOfNodeReadsWithoutAnAccountOfItsOwnIsRefused) + t.Run("AHolderPlacesEveryCombinationOnceWithATemplateThatRendersEveryExample", caseAHolderPlacesEveryCombinationOnceWithATemplateThatRendersEveryExample) + t.Run("AKindedBenchNeedsAKindAndNoOtherSeatTakesOne", caseAKindedBenchNeedsAKindAndNoOtherSeatTakesOne) + t.Run("AModuleCannotDeclareAMeshSeat", caseAModuleCannotDeclareAMeshSeat) + t.Run("AModuleDeclaresItsOwnSeatAndHoldsIt", caseAModuleDeclaresItsOwnSeatAndHoldsIt) + t.Run("AModuleDefinesAndClaimsItsOwnSeat", caseAModuleDefinesAndClaimsItsOwnSeat) + t.Run("AModulesOwnSeatNamesPathsUnderTheSameRules", caseAModulesOwnSeatNamesPathsUnderTheSameRules) + t.Run("ANeedMustNameANodeSeatSomewhereInTheCatalogue", caseANeedMustNameANodeSeatSomewhereInTheCatalogue) + t.Run("AnUncleanSpellingOfASeatsPathIsTheSeatsPath", caseAnUncleanSpellingOfASeatsPathIsTheSeatsPath) + t.Run("APlaceholderOutsideTheHolderIsRefused", caseAPlaceholderOutsideTheHolderIsRefused) + t.Run("AProcessBusNeverServesOrHoldsASeat", caseAProcessBusNeverServesOrHoldsASeat) + t.Run("ASeatCannotNeedItself", caseASeatCannotNeedItself) + t.Run("ASeatClaimedAtAnotherScopeIsRefused", caseASeatClaimedAtAnotherScopeIsRefused) + t.Run("ASeatNamesNoRootOrTopLevelDirectory", caseASeatNamesNoRootOrTopLevelDirectory) + t.Run("ASeatWithoutAProtocolIsAMarkerNotAMistake", caseASeatWithoutAProtocolIsAMarkerNotAMistake) + t.Run("ASecondClaimOfOneKindIsRefused", caseASecondClaimOfOneKindIsRefused) + t.Run("ATrustedHolderMustRunAsAnAccountOfItsOwn", caseATrustedHolderMustRunAsAnAccountOfItsOwn) + t.Run("CapabilitiesAreTheVocabularysAndOnlyOnAKindedClaim", caseCapabilitiesAreTheVocabularysAndOnlyOnAKindedClaim) + t.Run("CodeForAPowerMomentDependsOnThePowerSeat", caseCodeForAPowerMomentDependsOnThePowerSeat) + t.Run("IfACapabilityMayNameUserNamespaces", caseIfACapabilityMayNameUserNamespaces) + t.Run("IfACapabilityNamesOneTheNodeEngineDetectsOnAnOfferedKindOnly", caseIfACapabilityNamesOneTheNodeEngineDetectsOnAnOfferedKindOnly) + t.Run("ItemNamesAttributesAndCapabilitiesAreJudged", caseItemNamesAttributesAndCapabilitiesAreJudged) + t.Run("NodeBuildAgentIsRetiredForTheBuildSeats", caseNodeBuildAgentIsRetiredForTheBuildSeats) + t.Run("NoModuleMayDeclareAGraphicalSessionSeat", caseNoModuleMayDeclareAGraphicalSessionSeat) + t.Run("OnlyAClaimantDeclaresASeatsPath", caseOnlyAClaimantDeclaresASeatsPath) + t.Run("OnlyANodeSeatMayCarryNeeds", caseOnlyANodeSeatMayCarryNeeds) + t.Run("OnlyChannelAndIntakeAreKinded", caseOnlyChannelAndIntakeAreKinded) + t.Run("AStoreHolderThatBuildsIsNotRefusedByItsManifest", caseAStoreHolderThatBuildsIsNotRefusedByItsManifest) + t.Run("TheCataloguePassesTheSeatPathRules", caseTheCataloguePassesTheSeatPathRules) + t.Run("TheCompiledSeatPathsKeepTheRules", caseTheCompiledSeatPathsKeepTheRules) + t.Run("TheMeshsOwnSeatsAreStillClaimable", caseTheMeshsOwnSeatsAreStillClaimable) + t.Run("TheNewRulesAreHeldToWhatTheSeatSays", caseTheNewRulesAreHeldToWhatTheSeatSays) + t.Run("TheRuntimeSocketIsGrantedByTheCapabilityAndNotOtherwise", caseTheRuntimeSocketIsGrantedByTheCapabilityAndNotOtherwise) + t.Run("TheSeatsAreAClosedSetAndEachNamesItsDecision", caseTheSeatsAreAClosedSetAndEachNamesItsDecision) + t.Run("TheSessionsFilesArePlacedByTheDisplayServersHolderAlone", caseTheSessionsFilesArePlacedByTheDisplayServersHolderAlone) + t.Run("TheUplinkIsANodeSeatThatDeliversNothing", caseTheUplinkIsANodeSeatThatDeliversNothing) + t.Run("TwoChannelsOfDifferentKindsHoldTheBenches", caseTwoChannelsOfDifferentKindsHoldTheBenches) + t.Run("TwoModulesCannotDeclareTheSameSeat", caseTwoModulesCannotDeclareTheSameSeat) + t.Run("UsingASeatNobodyDeclaresIsRefused", caseUsingASeatNobodyDeclaresIsRefused) +} + +// TestRulesBuilds runs the tests of one kind as subtests, each by its former name. +func TestRulesBuilds(t *testing.T) { + t.Run("ABinaryMustSayWhichSystemItIsFor", caseABinaryMustSayWhichSystemItIsFor) + t.Run("ABuildsBundlesAreCarriedOnTheResolvedManifest", caseABuildsBundlesAreCarriedOnTheResolvedManifest) + t.Run("ABundleIsGivenItsWordsResolvedForThisMachine", caseABundleIsGivenItsWordsResolvedForThisMachine) + t.Run("ABundleNothingDeliversIsRefused", caseABundleNothingDeliversIsRefused) + t.Run("ABundlesWordsAreRefusedWhenTheyAreNotPathsOrConstants", caseABundlesWordsAreRefusedWhenTheyAreNotPathsOrConstants) + t.Run("ACompiledBundleStillMustSayItsSystem", caseACompiledBundleStillMustSayItsSystem) + t.Run("AFileNamingBothATemplateAndContentIsRefused", caseAFileNamingBothATemplateAndContentIsRefused) + t.Run("AGoBundleMayNameItsCommand", caseAGoBundleMayNameItsCommand) + t.Run("AGoToolsBundleIsServedByItsBinary", caseAGoToolsBundleIsServedByItsBinary) + t.Run("AnArtifactBuiltFromOutsideItsRepositoryIsRefused", caseAnArtifactBuiltFromOutsideItsRepositoryIsRefused) + t.Run("AnArtifactNamesThePathsItIsBuiltFrom", caseAnArtifactNamesThePathsItIsBuiltFrom) + t.Run("AnArtifactOfAnUnknownKindIsRefused", caseAnArtifactOfAnUnknownKindIsRefused) + t.Run("AnImageFromAnInstallationsRegistryNeedsAReason", caseAnImageFromAnInstallationsRegistryNeedsAReason) + t.Run("AnInterpretedBundleStillMayNotNameASource", caseAnInterpretedBundleStillMayNotNameASource) + t.Run("AnOwnerSettingAskedOnlyInATemplateIsJudgedOnceFilled", caseAnOwnerSettingAskedOnlyInATemplateIsJudgedOnceFilled) + t.Run("AnUpstreamFileFromAnAddressOrAReservedNameIsRefused", caseAnUpstreamFileFromAnAddressOrAReservedNameIsRefused) + t.Run("AnUpstreamFilesVendorIsNamedOnPurposeAndAnInstallationsIsRefused", caseAnUpstreamFilesVendorIsNamedOnPurposeAndAnInstallationsIsRefused) + t.Run("AnUpstreamFileThatIsNotPinnedIsRefused", caseAnUpstreamFileThatIsNotPinnedIsRefused) + t.Run("APackageParsesLikeABundleAndNeedsALanguage", caseAPackageParsesLikeABundleAndNeedsALanguage) + t.Run("ABundleNamesASystemOnlyWhereItCompiles", caseABundleNamesASystemOnlyWhereItCompiles) + t.Run("APortWithNoSourceIsRefused", caseAPortWithNoSourceIsRefused) + t.Run("ASettingInAUnitNameIsOnlyATemplatesInstance", caseASettingInAUnitNameIsOnlyATemplatesInstance) + t.Run("ASourceNobodyDefinedIsRefused", caseASourceNobodyDefinedIsRefused) + t.Run("ASystemTheMeshDoesNotBuildForIsRefused", caseASystemTheMeshDoesNotBuildForIsRefused) + t.Run("ATemplatedModuleWhoseBuildPacksNoFilesIsRefused", caseATemplatedModuleWhoseBuildPacksNoFilesIsRefused) + t.Run("ATemplateOnAResourceThatIsNotAFileIsRefused", caseATemplateOnAResourceThatIsNotAFileIsRefused) + t.Run("ATemplateOutsideFilesIsRefusedByName", caseATemplateOutsideFilesIsRefusedByName) + t.Run("ATemplateOutsideTheNamedTemplatesDirectoryIsRefused", caseATemplateOutsideTheNamedTemplatesDirectoryIsRefused) + t.Run("ATemplatesDirectoryNoArchiveIsBuiltFromIsRefused", caseATemplatesDirectoryNoArchiveIsBuiltFromIsRefused) + t.Run("ATemplatesDirectoryOnAModuleNamingNoTemplateIsRefused", caseATemplatesDirectoryOnAModuleNamingNoTemplateIsRefused) + t.Run("ATemplatesDirectoryThatIsNotAPlainRelativeDirectoryIsRefused", caseATemplatesDirectoryThatIsNotAPlainRelativeDirectoryIsRefused) + t.Run("OneArtifactPerSystemIsAccepted", caseOneArtifactPerSystemIsAccepted) + t.Run("OnlyAnImageNamesThePackageItCompilesWithinItsTree", caseOnlyAnImageNamesThePackageItCompilesWithinItsTree) + t.Run("TwoArtifactsWithOneNameAreRefused", caseTwoArtifactsWithOneNameAreRefused) +} + +// TestRulesSecrets runs the tests of one kind as subtests, each by its former name. +func TestRulesSecrets(t *testing.T) { + t.Run("AHandedModulesPlanNamesTheCredentialFormOfItsProvidersOffer", caseAHandedModulesPlanNamesTheCredentialFormOfItsProvidersOffer) + t.Run("AJailIsNamedOnceAndSaysWhatAFailureLooksLike", caseAJailIsNamedOnceAndSaysWhatAFailureLooksLike) + t.Run("AJailsPatternNamesTheHostOncePerShape", caseAJailsPatternNamesTheHostOncePerShape) + t.Run("AKeyIsTheOperatorsByWhatItIsAbout", caseAKeyIsTheOperatorsByWhatItIsAbout) + t.Run("AManifestKeyNothingReadsIsRefused", caseAManifestKeyNothingReadsIsRefused) + t.Run("AModuleOffersItsOwnStateOnly", caseAModuleOffersItsOwnStateOnly) + t.Run("AModuleThatDeclaresASettingNamesItsFilesKeys", caseAModuleThatDeclaresASettingNamesItsFilesKeys) + t.Run("AnAccessIsValidated", caseAnAccessIsValidated) + t.Run("AnInventedKeyIsNotTreatedAsARename", caseAnInventedKeyIsNotTreatedAsARename) + t.Run("AnOfferMayNameAnOwnSecretAsItsCredential", caseAnOfferMayNameAnOwnSecretAsItsCredential) + t.Run("AnOfferMaySayAPersonOutsideTheMeshIssuesItsCredential", caseAnOfferMaySayAPersonOutsideTheMeshIssuesItsCredential) + t.Run("AnOfferMaySayItsSoftwareIssuesTheCredential", caseAnOfferMaySayItsSoftwareIssuesTheCredential) + t.Run("AnOffersIdentityIsParsedStrictly", caseAnOffersIdentityIsParsedStrictly) + t.Run("AnOwnSecretSaysWhenAnOutsidePartyIssuesIt", caseAnOwnSecretSaysWhenAnOutsidePartyIssuesIt) + t.Run("AnOwnSecretsOwnerIsRefusedWhenItIsNotAnAccountTheModuleMakes", caseAnOwnSecretsOwnerIsRefusedWhenItIsNotAnAccountTheModuleMakes) + t.Run("AnOwnSecretTakenSomeOtherWayIsRefused", caseAnOwnSecretTakenSomeOtherWayIsRefused) + t.Run("AnUnknownAccessReferenceIsRefusedAtParse", caseAnUnknownAccessReferenceIsRefusedAtParse) + t.Run("AnUnknownPlaceholderKeyIsRefused", caseAnUnknownPlaceholderKeyIsRefused) + t.Run("APathThroughAnAccessIsJudgedWithTheAccessFilledIn", caseAPathThroughAnAccessIsJudgedWithTheAccessFilledIn) + t.Run("AProcessBusAccountMustBeTheModulesOwn", caseAProcessBusAccountMustBeTheModulesOwn) + t.Run("APromptHoldingMemberOnASingleSecretIsRefused", caseAPromptHoldingMemberOnASingleSecretIsRefused) + t.Run("ARequirementOnAKeylessProvisionComposesWithALongName", caseARequirementOnAKeylessProvisionComposesWithALongName) + t.Run("ASoftwareSpelledKeyIsUsable", caseASoftwareSpelledKeyIsUsable) + t.Run("AStoredManifestWithAnUnknownKeyIsSetAsideAndTheJudgeRefusesIt", caseAStoredManifestWithAnUnknownKeyIsSetAsideAndTheJudgeRefusesIt) + t.Run("AVerbWithAnUnknownKeyIsRefused", caseAVerbWithAnUnknownKeyIsRefused) + t.Run("EveryCatalogueIdentityFitsWhatItRequires", caseEveryCatalogueIdentityFitsWhatItRequires) + t.Run("HearingARestrictedStreamNeedsAnAccountOfItsOwn", caseHearingARestrictedStreamNeedsAnAccountOfItsOwn) + t.Run("ParseManifestForInputsReadsAValueFallingBackToAPredefinedKey", caseParseManifestForInputsReadsAValueFallingBackToAPredefinedKey) + t.Run("RunsAsIsAnAccountOfTheModulesOwn", caseRunsAsIsAnAccountOfTheModulesOwn) + t.Run("RuntimeHealthIsRefusedWithoutAnAccountOfItsOwn", caseRuntimeHealthIsRefusedWithoutAnAccountOfItsOwn) + t.Run("TheBussAccountSaysNothingOnTheBus", caseTheBussAccountSaysNothingOnTheBus) + t.Run("TheCatalogueCheckRefusesAnIdentityThatOverflowsWhatItRequires", caseTheCatalogueCheckRefusesAnIdentityThatOverflowsWhatItRequires) + t.Run("TheReadsAccountIsInNoGroup", caseTheReadsAccountIsInNoGroup) + t.Run("TheRuntimeIsToldTheAgentAccount", caseTheRuntimeIsToldTheAgentAccount) + t.Run("WhatAHandedModuleCannotHaveFromTheVaultIsRefused", caseWhatAHandedModuleCannotHaveFromTheVaultIsRefused) +} + +// TestRulesHealth runs the tests of one kind as subtests, each by its former name. +func TestRulesHealth(t *testing.T) { + t.Run("AMaintenanceWindowIsRefusedWhereTheDefinitionShowsItCannotMean", caseAMaintenanceWindowIsRefusedWhereTheDefinitionShowsItCannotMean) + t.Run("AManifestWithoutUnhealthyIsNotUrgent", caseAManifestWithoutUnhealthyIsNotUrgent) + t.Run("AnUnhealthySeverityOtherThanUrgentOrWarningIsRefused", caseAnUnhealthySeverityOtherThanUrgentOrWarningIsRefused) + t.Run("AnUnhealthyWithoutWhyIsRefused", caseAnUnhealthyWithoutWhyIsRefused) + t.Run("ARuntimeHealthIsHeldToTheHealthRules", caseARuntimeHealthIsHeldToTheHealthRules) + t.Run("EveryOutOfBoundsHealthIsRefusedByName", caseEveryOutOfBoundsHealthIsRefusedByName) +} + +// TestRulesPlacement runs the tests of one kind as subtests, each by its former name. +func TestRulesPlacement(t *testing.T) { + t.Run("ABackupNamingAnUndeclaredDirectoryIsRefused", caseABackupNamingAnUndeclaredDirectoryIsRefused) + t.Run("ADefinitionIsRefusedWhereTheNodeEngineRefusesItsPaths", caseADefinitionIsRefusedWhereTheNodeEngineRefusesItsPaths) + t.Run("ADirectoryBeneathAPlacedOneIsPlacedWithIt", caseADirectoryBeneathAPlacedOneIsPlacedWithIt) + t.Run("ADirectoryPlacedInDockersDataIsRefusedWhereTheDefinitionIsJudged", caseADirectoryPlacedInDockersDataIsRefusedWhereTheDefinitionIsJudged) + t.Run("AMapReferenceToNoDirectoryRefusesAtTheManifest", caseAMapReferenceToNoDirectoryRefusesAtTheManifest) + t.Run("AMisspelledPlaceholderIsRefusedAtTheCheck", caseAMisspelledPlaceholderIsRefusedAtTheCheck) + t.Run("AMountNothingDeclaresIsRefused", caseAMountNothingDeclaresIsRefused) + t.Run("ANeedIsAnAbsolutePath", caseANeedIsAnAbsolutePath) + t.Run("AnOperatorNamedValueAFileFallsBackOnMayHaveADefault", caseAnOperatorNamedValueAFileFallsBackOnMayHaveADefault) + t.Run("AReferenceToNoDirectoryRefusesAtTheManifest", caseAReferenceToNoDirectoryRefusesAtTheManifest) + t.Run("AResolvedReferenceIsKeptNotRouted", caseAResolvedReferenceIsKeptNotRouted) + t.Run("EachFormKeepsItsOwnDeclaration", caseEachFormKeepsItsOwnDeclaration) + t.Run("KeepsMustBeAnAbsolutePath", caseKeepsMustBeAnAbsolutePath) + t.Run("OneNamingFileMakesEveryMergeableFileName", caseOneNamingFileMakesEveryMergeableFileName) + t.Run("PlaceIsValidatedAtTheManifest", casePlaceIsValidatedAtTheManifest) + t.Run("TheCataloguesBarPlacesBlocksAndItsShapeCoversEveryShow", caseTheCataloguesBarPlacesBlocksAndItsShapeCoversEveryShow) + t.Run("TheModuleCheckRefusesAnOptionalPlaceholderThatCouldRenderEmpty", caseTheModuleCheckRefusesAnOptionalPlaceholderThatCouldRenderEmpty) + t.Run("TheResolvedPathRulesAreTheNodeEnginesOwn", caseTheResolvedPathRulesAreTheNodeEnginesOwn) +} + +// TestRulesBus runs the tests of one kind as subtests, each by its former name. +func TestRulesBus(t *testing.T) { + t.Run("ABusyIsHeldToItsShape", caseABusyIsHeldToItsShape) + t.Run("AContainerCannotBeBothRunOnceAndScheduled", caseAContainerCannotBeBothRunOnceAndScheduled) + t.Run("AContributionLocalNameMustBeUsable", caseAContributionLocalNameMustBeUsable) + t.Run("ADeclaredStoreParsesAndPassesTheCheck", caseADeclaredStoreParsesAndPassesTheCheck) + t.Run("ADefinitionNamingAnInstallationIsNamedBack", caseADefinitionNamingAnInstallationIsNamedBack) + t.Run("AGuardedPortMustBeAPort", caseAGuardedPortMustBeAPort) + t.Run("ALocalNameIsUniqueAcrossRequirements", caseALocalNameIsUniqueAcrossRequirements) + t.Run("ALocalNameMayNotCollideWithWhatTheModuleAlreadyCallsSomething", caseALocalNameMayNotCollideWithWhatTheModuleAlreadyCallsSomething) + t.Run("ALogIsNamedLocallyAndCapped", caseALogIsNamedLocallyAndCapped) + t.Run("AMalformedScheduleIsRefused", caseAMalformedScheduleIsRefused) + t.Run("AManifestProvidingAmqpIsRefused", caseAManifestProvidingAmqpIsRefused) + t.Run("AManifestRequiringAmqpIsRefused", caseAManifestRequiringAmqpIsRefused) + t.Run("AManifestUsingTheOldNameIsToldTheNewOne", caseAManifestUsingTheOldNameIsToldTheNewOne) + t.Run("AModuleMayNotProvideAGenericDatabase", caseAModuleMayNotProvideAGenericDatabase) + t.Run("AModuleNamedAfterADomainIsNamedBack", caseAModuleNamedAfterADomainIsNamedBack) + t.Run("ANameMeantOnPurposeIsDeclaredWithItsReason", caseANameMeantOnPurposeIsDeclaredWithItsReason) + t.Run("AnEmptyContributionIsRefused", caseAnEmptyContributionIsRefused) + t.Run("AnEndpointNameIsHeldToItsShape", caseAnEndpointNameIsHeldToItsShape) + t.Run("AnInvokeThatNamesNoToolIsRefusedAtParse", caseAnInvokeThatNamesNoToolIsRefusedAtParse) + t.Run("AnUnnamedEndpointIsStillValid", caseAnUnnamedEndpointIsStillValid) + t.Run("AProcessBusNamesOnlyTheModulesOwn", caseAProcessBusNamesOnlyTheModulesOwn) + t.Run("AProcessDeclaresItsBusAndIsAccepted", caseAProcessDeclaresItsBusAndIsAccepted) + t.Run("AProviderReadFromItsTreeIsJudgedByTheSameRules", caseAProviderReadFromItsTreeIsJudgedByTheSameRules) + t.Run("ARouteNamingAnEndpointTheModuleLacksIsRefused", caseARouteNamingAnEndpointTheModuleLacksIsRefused) + t.Run("AScheduleThatIsNotAStringIsRefused", caseAScheduleThatIsNotAStringIsRefused) + t.Run("AServedNameIsCheckedWhenTheDefinitionIsRead", caseAServedNameIsCheckedWhenTheDefinitionIsRead) + t.Run("AServedValueNamingSomethingTheMeshDoesNotHaveIsRefused", caseAServedValueNamingSomethingTheMeshDoesNotHaveIsRefused) + t.Run("ASiteScopedProvisionIsRefused", caseASiteScopedProvisionIsRefused) + t.Run("AStateNameIsLocalAndOneToken", caseAStateNameIsLocalAndOneToken) + t.Run("AWaitIsRefusedUnlessItNamesOneFamilyOfTheToolRunner", caseAWaitIsRefusedUnlessItNamesOneFamilyOfTheToolRunner) + t.Run("AWorkQueueStreamIsReadByExactlyOneProcessOfItsModule", caseAWorkQueueStreamIsReadByExactlyOneProcessOfItsModule) + t.Run("AWorkQueueStreamsValuesAreBounded", caseAWorkQueueStreamsValuesAreBounded) + t.Run("AZoneMustNameOneOfTheModulesListens", caseAZoneMustNameOneOfTheModulesListens) + t.Run("BindingWhatYouDoNotRequireIsRefused", caseBindingWhatYouDoNotRequireIsRefused) + t.Run("ConsumerDataInARequiredProvisionIsJudgedAgainstItsProvider", caseConsumerDataInARequiredProvisionIsJudgedAgainstItsProvider) + t.Run("EveryCatalogueModuleDeclaresItsData", caseEveryCatalogueModuleDeclaresItsData) + t.Run("EveryManifestsEventNamesAreLocal", caseEveryManifestsEventNamesAreLocal) + t.Run("EveryManifestsLogsAreLocalAndCapped", caseEveryManifestsLogsAreLocalAndCapped) + t.Run("EveryManifestsStateIsLocalAndEveryReadIsKept", caseEveryManifestsStateIsLocalAndEveryReadIsKept) + t.Run("IrreplaceableDataKeptWithAProviderMustBeProtectedThere", caseIrreplaceableDataKeptWithAProviderMustBeProtectedThere) + t.Run("NoCatalogueManifestNamesAnInstallation", caseNoCatalogueManifestNamesAnInstallation) + t.Run("NoModuleMayDeclareTheLoginShell", caseNoModuleMayDeclareTheLoginShell) + t.Run("ReceivingWhatYouDoNotProvideIsRefused", caseReceivingWhatYouDoNotProvideIsRefused) + t.Run("ServingWhatYouDoNotProvideIsRefused", caseServingWhatYouDoNotProvideIsRefused) + t.Run("TheCatalogueCheckAsksEveryModuleForItsData", caseTheCatalogueCheckAsksEveryModuleForItsData) + t.Run("TheDataSectionIsRefusedWhereItIsWrong", caseTheDataSectionIsRefusedWhereItIsWrong) + t.Run("TheMachinesReachIsAProvisionsOnlyReachAndIsNodeScoped", caseTheMachinesReachIsAProvisionsOnlyReachAndIsNodeScoped) + t.Run("TheParserDoesNotJudgeWhatOnlyTheStoreKnows", caseTheParserDoesNotJudgeWhatOnlyTheStoreKnows) + t.Run("TheStoredFormReadsWhereRequiresIsAListOfNames", caseTheStoredFormReadsWhereRequiresIsAListOfNames) + t.Run("TheWorldsNamesAreNotAnInstallations", caseTheWorldsNamesAreNotAnInstallations) + t.Run("TwoEndpointsWithOneNameAreRefused", caseTwoEndpointsWithOneNameAreRefused) + t.Run("TwoModulesCannotDeclareOneStream", caseTwoModulesCannotDeclareOneStream) + t.Run("WhatReplacesMayNameIsRefusedNearItsAuthor", caseWhatReplacesMayNameIsRefusedNearItsAuthor) +} + +// TestRulesCatalogue runs the tests of one kind as subtests, each by its former name. +func TestRulesCatalogue(t *testing.T) { + t.Run("Replay412", caseReplay412) + t.Run("TheCataloguePassJudgesNoReadAgainstTheOwnersManifest", caseTheCataloguePassJudgesNoReadAgainstTheOwnersManifest) + t.Run("TheProblemsAreStable", caseTheProblemsAreStable) +} + +// TestRulesManifests runs the tests of one kind as subtests, each by its former name. +func TestRulesManifests(t *testing.T) { + t.Run("AMalformedEnvironmentIsRefusedAtParse", caseAMalformedEnvironmentIsRefusedAtParse) + t.Run("AMalformedFamilyIsRefused", caseAMalformedFamilyIsRefused) + t.Run("AMalformedPromptIsRefused", caseAMalformedPromptIsRefused) + t.Run("AManifestIsJudgedAgainstTheListOfItsTree", caseAManifestIsJudgedAgainstTheListOfItsTree) + t.Run("AManifestMayListenFromTheLocalNetwork", caseAManifestMayListenFromTheLocalNetwork) + t.Run("AModuleIsEitherWrittenOrComputedNotBoth", caseAModuleIsEitherWrittenOrComputedNotBoth) + t.Run("AModuleMayNotDeclareAnAction", caseAModuleMayNotDeclareAnAction) + t.Run("AModuleSaysWhatItsOwnToolsReplace", caseAModuleSaysWhatItsOwnToolsReplace) + t.Run("AModuleThatPreparesAndRunsNoneOfItsOwnCodeIsRefused", caseAModuleThatPreparesAndRunsNoneOfItsOwnCodeIsRefused) + t.Run("AMovedModulesMarkIsJudged", caseAMovedModulesMarkIsJudged) + t.Run("AnOwnerSettingIsJudgedWhereTheManifestIsRead", caseAnOwnerSettingIsJudgedWhereTheManifestIsRead) + t.Run("CollectionsAndItemsAreJudged", caseCollectionsAndItemsAreJudged) + t.Run("MalformedShellCodeIsRefusedAtParse", caseMalformedShellCodeIsRefusedAtParse) + t.Run("TheParserTakesAPreferenceAndRefusesTheRest", caseTheParserTakesAPreferenceAndRefusesTheRest) + t.Run("WhereAModulesUpgradePolicyComesFrom", caseWhereAModulesUpgradePolicyComesFrom) +} + +// TestRulesOther runs the tests of one kind as subtests, each by its former name. +func TestRulesOther(t *testing.T) { + t.Run("ABlockOutsideTheShapeIsRefused", caseABlockOutsideTheShapeIsRefused) + t.Run("ARenamedEntryIsRefusedWhereItCouldNotHold", caseARenamedEntryIsRefusedWhereItCouldNotHold) + t.Run("ARunOnceMustBeABoolean", caseARunOnceMustBeABoolean) + t.Run("AskingForTheRuleSetWithNowhereToPutItIsRefused", caseAskingForTheRuleSetWithNowhereToPutItIsRefused) + t.Run("TakesSettingsIsRefusedWhereItCannotMeanAnything", caseTakesSettingsIsRefusedWhereItCannotMeanAnything) + t.Run("TheInstallationCheckReadsADefault", caseTheInstallationCheckReadsADefault) +}