package manifest import ( "bytes" "encoding/json" "os" "reflect" "slices" "strings" "testing" ) // The controller's manifest reader is mesh-controller internal/catalogue (ParseManifest), an internal package of another // repository, which this module cannot import. These tests therefore decode the manifest strictly into the fields the // controller's Manifest, Build and Artifact types name (internal/catalogue/manifest.go:475, :602, :659, :667, :737, // :809, :821, :892, :1010, :1065-:1090), as its parseManifest does (DisallowUnknownFields, manifest.go:1744), and check // the rules the issue names, and two rules of the controller's module check (a module with templates packs a files // archive; a module contributing an item is moved). **The merge gate's module check is what proves the controller // takes this manifest (1134/AC7); these tests hold the rules so a unit run catches a refusal early.** type artifact struct { Name string `json:"name"` Kind string `json:"kind"` Language string `json:"language"` System string `json:"system"` From string `json:"from"` Binary string `json:"binary"` Context *struct { Repository string `json:"repository"` } `json:"context"` } type item struct { Collection string `json:"collection"` Template string `json:"template"` } type manifest struct { Module string `json:"module"` Moved bool `json:"moved"` Version string `json:"version"` Slug string `json:"slug"` Reads []string `json:"reads"` OwnSecrets map[string]string `json:"own-secrets"` SecretsOwner string `json:"secrets-owner"` Resources []map[string]any `json:"resources"` Items []item `json:"items"` Build struct { Artifacts []artifact `json:"artifacts"` } `json:"build"` } func load(t *testing.T) (manifest, map[string]json.RawMessage) { t.Helper() raw, err := os.ReadFile("module.json") if err != nil { t.Fatal(err) } var m manifest dec := json.NewDecoder(bytes.NewReader(raw)) dec.DisallowUnknownFields() if err := dec.Decode(&m); err != nil { t.Fatalf("the controller's reader refuses a key this manifest has: %v", err) } var top map[string]json.RawMessage if err := json.Unmarshal(raw, &top); err != nil { t.Fatal(err) } return m, top } func TestManifestIsTakenAndReadsOnly(t *testing.T) { // 1134/AC7 m, top := load(t) if m.Module != "mesh-delivery-view" { t.Errorf("module = %q", m.Module) } want := []string{"mesh-controller.assignments", "mesh-controller.builds", "mesh-delivery-watchman.presence", "mesh-delivery-watchman.stuck", "node-engine.have"} // 1168/AC1 got := slices.Clone(m.Reads) slices.Sort(got) if !reflect.DeepEqual(got, want) { t.Errorf("reads = %v, want exactly %v", got, want) } for _, k := range []string{"state", "emits", "consumes", "provides", "claims"} { if _, ok := top[k]; ok { t.Errorf("the manifest declares %q: the view writes nothing", k) } } if _, ok := m.OwnSecrets["broker"]; !ok || len(m.OwnSecrets) != 1 { t.Errorf("own-secrets = %v, want exactly broker (or no credential is issued)", m.OwnSecrets) } if m.SecretsOwner != "mesh-delivery-view" { t.Errorf("secrets-owner = %q", m.SecretsOwner) } } func TestManifestIsWholeInItsRepository(t *testing.T) { // 1134/AC7 m, _ := load(t) if len(m.Build.Artifacts) != 3 { t.Fatalf("artifacts = %+v", m.Build.Artifacts) } for _, a := range m.Build.Artifacts { if a.Name == "files" { continue } if a.Context != nil { t.Errorf("artifact %s names a context of another repository", a.Name) } if a.Kind != "bundle" || a.Language != "go" || a.System != "arch" { t.Errorf("artifact %s = %+v, want a go bundle for arch", a.Name, a) } if st, err := os.Stat(a.From); err != nil || !st.IsDir() { t.Errorf("artifact %s builds from %q, which is not a directory of this module", a.Name, a.From) } if a.Binary == "" || !strings.HasSuffix(a.From, a.Binary) { t.Errorf("artifact %s binary %q does not match %q", a.Name, a.Binary, a.From) } } names := map[string]string{} for _, a := range m.Build.Artifacts { names[a.Name] = a.Binary } if names["program"] != "mesh-delivery-view" || names["cli"] != "mesh-delivery-cli" { t.Errorf("artifacts = %v", names) } } func TestManifestResources(t *testing.T) { // 1134/AC7 m, _ := load(t) byType := map[string][]map[string]any{} for _, r := range m.Resources { byType[r["type"].(string)] = append(byType[r["type"].(string)], r) } for _, ty := range []string{"user", "directory", "process", "archive"} { if len(byType[ty]) == 0 { t.Fatalf("no %s resource", ty) } } user := byType["user"][0]["name"] if user != "mesh-delivery-view" { t.Errorf("user = %v", user) } p := byType["process"][0] if p["user"] != user || p["artifact"] != "program" { t.Errorf("process = %v", p) } env, _ := p["env"].(map[string]any) if env["MESH_BROKER_FILE"] != "${dir:state}/broker" || m.OwnSecrets["broker"] != "${dir:state}/broker" { t.Errorf("the process reads %v, the own-secret is written at %v", env["MESH_BROKER_FILE"], m.OwnSecrets["broker"]) } if h, _ := p["health"].(map[string]any); h["kind"] != "unit" { t.Errorf("health = %v", p["health"]) } var state, run bool for _, d := range byType["directory"] { if d["id"] == "state" && d["mode"] == "0700" && d["owner"] == user { state = true } if d["path"] == "/var/lib/mesh-delivery-view-cli" && d["mode"] == "0755" && d["owner"] == user { run = true } } if !state || !run { t.Errorf("state directory 0700 owned by the user: %v; run directory for the socket 0755: %v", state, run) } a := byType["archive"][0] if a["artifact"] != "cli" || a["path"] != "/usr/local/lib/mesh-delivery-view" { t.Errorf("archive = %v, want the cli unpacked into its own directory", a) } } func TestModuleCheckRules(t *testing.T) { // 1134/AC7 m, _ := load(t) if len(m.Items) > 0 && !m.Moved { t.Error("a module contributing an item is marked moved: true") } var files bool for _, a := range m.Build.Artifacts { files = files || (a.Name == "files" && a.Kind == "archive" && a.From == "files") } if len(m.Items) > 0 && !files { t.Error("a module naming templates packs a files archive from files/") } } func TestAliasItem(t *testing.T) { // 1137/AC1 m, _ := load(t) if !reflect.DeepEqual(m.Items, []item{{Collection: "shell:zsh:normal", Template: "files/zsh-normal"}}) { t.Fatalf("items = %+v", m.Items) } raw, err := os.ReadFile("files/zsh-normal") if err != nil { t.Fatal(err) } if string(raw) != "alias nox-delivery=mesh-delivery-cli\n" { t.Fatalf("files/zsh-normal = %q, want the one line", raw) } } // The controller refuses two modules declaring one path (internal/catalogue/resolve.go:1160-1168). mesh-cli (mesh-catalog // modules/mesh-cli/module.json) declares /usr/local/bin whole, so this module may place only a file below a shared // directory, never the directory itself. func TestNoSharedDirectoryIsClaimed(t *testing.T) { // 1134/AC7 m, _ := load(t) shared := map[string]bool{"/usr/local/bin": true, "/usr/local/lib": true, "/usr/bin": true, "/usr/local": true, "/usr/lib": true, "/etc": true, "/opt": true} var binary bool for _, r := range m.Resources { p, _ := r["path"].(string) if shared[strings.TrimRight(p, "/")] { t.Errorf("resource %v declares the shared directory %s, which mesh-cli and others declare too", r["id"], p) } if p == "/usr/local/bin/mesh-delivery-cli" && r["type"] == "file" && r["template"] == "files/mesh-delivery-cli" { binary = true } } if !binary { t.Error("the command is placed as the file /usr/local/bin/mesh-delivery-cli") } raw, err := os.ReadFile("files/mesh-delivery-cli") if err != nil || !strings.Contains(string(raw), "exec /usr/local/lib/mesh-delivery-view/mesh-delivery-cli") { t.Errorf("files/mesh-delivery-cli = %q, %v", raw, err) } } // The node-engine never places a module-owned directory below /etc, /usr, /run or /var/run: they are root's // (mesh-host internal/apply/placement_guard.go:80, rootsOnly; novox/hq issue 339). func TestNoDirectoryBelowRootsTrees(t *testing.T) { // 1134/AC10 m, _ := load(t) for _, r := range m.Resources { if r["type"] != "directory" { continue } p, _ := r["path"].(string) for _, root := range []string{"/etc", "/usr", "/run", "/var/run"} { if p == root || strings.HasPrefix(p, root+"/") { t.Errorf("directory %v at %s is below %s, which is root's", r["id"], p, root) } } } var socketDir bool for _, r := range m.Resources { if r["path"] == "/var/lib/mesh-delivery-view-cli" && r["type"] == "directory" && r["mode"] == "0755" && r["owner"] == "mesh-delivery-view" { socketDir = true } } if !socketDir { t.Error("the socket's directory is /var/lib/mesh-delivery-view-cli, 0755, owned by mesh-delivery-view") } }