Files
mesh-sdk/go/catalogue/showcase_manifest_test.go
T
mesh-tools d1886bbd7b Move the catalogue tests that read mesh-catalog into go/catalogue, and lay the captured copy out once per process (issue 1379)
Imports rewritten to mesh-sdk's (beside, catalogue, overlay). Left in mesh-controller, which holds their modules: TestTheBuilderRequiresTheRegistryTheNpmSeatDelivers (foundation_manifests_test.go), TestGenesisAssignsTheBuildAgentWithNothingProvidingTheRegistry (genesis_registry_test.go, whole file), TestRouteProxyKeepsItsPublicAccountDirectory (public_issuer_test.go), TestEveryManifestInUseClaimsASeatTheMeshDefines (seats_test.go); with controller_is_a_process_test.go and genesis_image_test.go. moduleTree reads mesh-catalog only: mesh-sdk has no modules directory of its own. beside.Dir lays a repository's captured copy out once per process (a mutex and a map, os.MkdirTemp), new test TestTheCapturedCopyIsLaidOutOnce failed first (two directories). The captured copy is refreshed from the mains: mesh-catalog bb0fe93b, mesh-host cdcba9ca, only what these tests read; CAPTURED says how to move it. Unit level 1.16 s (bound 2 s).
2026-10-20 08:22:45 +00:00

87 lines
2.7 KiB
Go

package catalogue
import (
"os"
"path/filepath"
"testing"
"git.novox.be/novox/mesh-sdk/go/internal/beside"
)
// **The showcase module is parsed by the real parser, in the real test suite.**
//
// A module that exercises every capability is only worth having if something checks it still does.
// Written as a test rather than a script so it runs whenever anything about manifests changes —
// which is exactly when a module using all of it would quietly stop being valid.
func TestTheShowcaseModuleIsAValidManifest(t *testing.T) {
raw, err := os.ReadFile(filepath.Join(beside.Catalogue(t), "showcase", "module.json"))
if err != nil {
t.Fatal(err)
}
m, err := ParseManifest(raw)
if err != nil {
t.Fatalf("the module that exercises everything does not parse:\n%v", err)
}
// Every resource kind a MODULE may use, actually in it.
//
// Two of the host's eleven are deliberately absent, and the reasons are worth keeping:
//
// - `action` is refused to modules outright. The link may not carry a command to run (ADR
// 0005), so a module that needs something done ships a program that reads what the mesh
// delivered and reconciles — which is what a run-once `process` is.
// - `service` puts an EXISTING unit into a state and deliberately installs none, which is
// right for software that ships its own unit. A module whose code the mesh built has no
// such unit until the mesh writes one, and that is a `process`.
kinds := map[string]bool{}
for _, r := range m.Resources {
kind, _ := r["type"].(string)
kinds[kind] = true
}
for _, want := range []string{
"access", "archive", "container", "directory", "file", "network", "package",
"process", "user",
} {
if !kinds[want] {
t.Errorf("showcase no longer exercises %q", want)
}
}
// And all three ways a module's own code can run, which is the thing most easily lost.
var stays, once, scheduled bool
for _, r := range m.Resources {
if kind, _ := r["type"].(string); kind != "process" {
continue
}
switch {
case r["run-once"] == true:
once = true
case r["schedule"] != nil:
scheduled = true
default:
stays = true
}
}
if !stays || !once || !scheduled {
t.Errorf("showcase does not exercise all three process modes: stays=%v once=%v scheduled=%v",
stays, once, scheduled)
}
// And the artifact kinds, including the one that compiles.
var bundle, archive, upstream bool
for _, a := range m.Build.Artifacts {
switch a.Kind {
case ArtifactBundle:
bundle = true
case ArtifactArchive:
archive = true
case ArtifactUpstream:
upstream = true
}
}
if !bundle || !archive || !upstream {
t.Errorf("showcase does not exercise every artifact kind: bundle=%v archive=%v upstream=%v",
bundle, archive, upstream)
}
}