Make the copied catalogue stand in mesh-sdk: the SDK's validator, user-namespaces, two tests that read the controller's module.json left out (issue 1354). Unit level 1.05 s of 2 s with the package in (1162 tests, 3 skipped). Diff against the source: git diff --no-index <mesh-control 6c2a8d62 internal/catalogue> go/catalogue shows only doc.go, user_namespaces_test.go, three import lines, KnownCapabilities, and the two deleted test functions
This commit is contained in:
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-host/validate"
|
||||
"git.novox.be/novox/mesh-sdk/go/validate"
|
||||
)
|
||||
|
||||
// A long-running container may say it is busy (novox/hq ADR 0335 §1): `module check` holds the field to its
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copied from mesh-controller internal/catalogue at commit 6c2a8d62100cb7d491f8eb9a623e1eeea5ec0de1 (novox/hq ADR 0453
|
||||
// clause 3, ADR 0446 clause 4), so the builder, the checker and the assigner can read and resolve a manifest. The files
|
||||
// are unchanged but for import paths, this note and KnownCapabilities, which gains user-namespaces (issue 1308's name).
|
||||
// The test files that read mesh-controller's other packages or its own module.json stay in mesh-controller, as do two
|
||||
// tests of single files here that read its module.json (TestTheControllersOwnManifestClaimsItsSeat and
|
||||
// TestTheControlPlanesOwnAddressesFollowTheNodesPorts). mesh-controller keeps its own copy until release 4b.
|
||||
package catalogue
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-host/validate"
|
||||
"git.novox.be/novox/mesh-sdk/go/validate"
|
||||
)
|
||||
|
||||
// A module says how each long-running resource is ready (novox/hq ADR 0240 rule 2, to-be 48 §8): `module
|
||||
|
||||
@@ -2,8 +2,6 @@ package catalogue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -486,24 +484,3 @@ func TestSomethingOrdinaryAnsweredHereNeedsNothing(t *testing.T) {
|
||||
t.Fatalf("a shell answered on this machine produced %d need(s)", len(got.Needs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestTheControllersOwnManifestClaimsItsSeat(t *testing.T) {
|
||||
// The seat test above fabricates manifests, so deleting the claim from the real module.json
|
||||
// would fail nothing (novox/hq issue 059's review). This binds the one manifest this
|
||||
// repository owns: the controller claims the mesh-scoped seat named after its server
|
||||
// (ADR 0079), or the one-controller property is convention again.
|
||||
raw, err := os.ReadFile(filepath.Join("..", "..", "module.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("the controller's own manifest is unreadable: %v", err)
|
||||
}
|
||||
m, err := ParseManifest(raw)
|
||||
if err != nil {
|
||||
t.Fatalf("the controller's own manifest does not parse: %v", err)
|
||||
}
|
||||
for _, c := range m.Claims {
|
||||
if c.Name == "mesh-controller" && c.At() == ScopeMesh {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("module.json no longer claims the mesh-scoped mesh-controller seat: %+v", m.Claims)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-host/validate"
|
||||
"git.novox.be/novox/mesh-sdk/go/validate"
|
||||
)
|
||||
|
||||
// novox/hq ADR 0366: a module that runs as its own account declares its runtime's health under one manifest
|
||||
|
||||
@@ -68,7 +68,7 @@ var capabilityName = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`)
|
||||
var KnownCapabilities = []string{
|
||||
"battery", "container-runtime", "firewall", "graphical-session", "overlay", "package-manager",
|
||||
"power-meter", "privileged", "seat", "service-manager", "uplink-dhcpcd", "uplink-networkmanager",
|
||||
"uplink-systemd-networkd", "virtualisation",
|
||||
"uplink-systemd-networkd", "user-namespaces", "virtualisation",
|
||||
}
|
||||
|
||||
// renderFuncs are the functions a holder's template may call. `quote` writes a value as a JSON
|
||||
|
||||
@@ -2,7 +2,6 @@ package catalogue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -85,89 +84,6 @@ func TestFillingASeatLeavesTheManifestAlone(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// **The control plane's own manifest, composed through the whole path.**
|
||||
//
|
||||
// The store was given 6852 and the broker's plain port 5679 (the control-node's migration, novox/hq
|
||||
// 04-ISSUES/102). The control plane's own connections are sealed at genesis with the ports genesis
|
||||
// wrote; what its container is told beside them is where this machine put the store and the
|
||||
// broker now, read from the node's settings exactly as every consumer's binding is.
|
||||
func TestTheControlPlanesOwnAddressesFollowTheNodesPorts(t *testing.T) {
|
||||
raw, err := os.ReadFile("../../module.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m, err := ParseManifest(raw)
|
||||
if err != nil {
|
||||
t.Fatalf("the control plane's own manifest does not parse:\n%v", err)
|
||||
}
|
||||
// The manifest itself names them now; withSeatPorts is a no-op on it, and this holds it so.
|
||||
for _, r := range m.Resources {
|
||||
if r["type"] != "process" {
|
||||
continue
|
||||
}
|
||||
env, _ := r["env"].(map[string]any)
|
||||
for key, want := range SeatPorts {
|
||||
if env[key] != want {
|
||||
t.Errorf("module.json says %s=%v, not %q", key, env[key], want)
|
||||
}
|
||||
}
|
||||
}
|
||||
m = withSeatPorts(m)
|
||||
control, err := m.Resolve([]Built{{
|
||||
Name: "controller", Kind: ArtifactBundle,
|
||||
Reference: ArtifactStoreScheme + "mesh-controller/controller@sha256:" + strings.Repeat("c", 64),
|
||||
Digest: "sha256:" + strings.Repeat("c", 64),
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := Resolution{Node: "anchor", Modules: []Manifest{control}}
|
||||
needed := map[string]map[string]string{"mesh-controller": {}}
|
||||
for name := range m.OwnSecrets {
|
||||
needed["mesh-controller"][name] = "sealed-" + name
|
||||
}
|
||||
out, err := r.Declaration(Rendering{
|
||||
Needed: needed,
|
||||
ArtifactStore: "anchor.internal:5100",
|
||||
Seats: map[string]map[int]int{
|
||||
"mesh-store": {5432: 6852},
|
||||
"mesh-broker": {5671: 5671, 5672: 5679, 15672: 15673},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("the control plane does not compose: %v", err)
|
||||
}
|
||||
server := fileNamed(out, "mesh-controller.controller")
|
||||
if server == nil {
|
||||
t.Fatalf("the control plane's process is not in the declaration: %v", out)
|
||||
}
|
||||
env, _ := server["env"].(map[string]any)
|
||||
for key, want := range map[string]string{
|
||||
"MESH_STORE_INVENTORY_PORT": "6852",
|
||||
"MESH_STORE_IDENTITY_PORT": "6852",
|
||||
"MESH_STORE_LICENCES_PORT": "6852",
|
||||
"MESH_BROKER_MANAGEMENT_PORT": "15673",
|
||||
"MESH_BROKER_ADDRESS_PORT": "5671",
|
||||
} {
|
||||
if env[key] != want {
|
||||
t.Errorf("the control plane is told %s=%v; the node put it on %s", key, env[key], want)
|
||||
}
|
||||
}
|
||||
if got := server["source"]; got != "anchor.internal:5100/mesh-controller/controller@sha256:"+strings.Repeat("c", 64) {
|
||||
t.Errorf("the control plane's own bundle is fetched from %v, not routed through the store", got)
|
||||
}
|
||||
|
||||
// And on a mesh where the foundation is where genesis raised it, nothing is added.
|
||||
out, err = r.Declaration(Rendering{Needed: needed, ArtifactStore: "anchor.internal:5100"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
env, _ = fileNamed(out, "mesh-controller.controller")["env"].(map[string]any)
|
||||
if env["MESH_STORE_INVENTORY_PORT"] != "" {
|
||||
t.Errorf("with no settings, the control plane is told %v", env)
|
||||
}
|
||||
}
|
||||
|
||||
// SeatPorts is what the control plane's manifest says beside each sealed connection: the port
|
||||
// this machine put the seat's holder at (novox/hq 04-ISSUES/102).
|
||||
var SeatPorts = map[string]string{
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package catalogue
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// 1354/AC3: a contribution placed only where the machine reports the user namespaces capability (the name issue 1308 has
|
||||
// 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) {
|
||||
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)
|
||||
}
|
||||
for name, want := range map[string]string{
|
||||
"user-namespace": "which no machine reports",
|
||||
"userns": "which no machine reports",
|
||||
"user_namespaces": "is not a capability's name",
|
||||
} {
|
||||
_, err := ParseManifest([]byte(strings.Replace(piece, "%q", `"`+name+`"`, 1)))
|
||||
if err == nil || !strings.Contains(err.Error(), want) {
|
||||
t.Errorf("%s: accepted, or refused without today's words %q: %v", name, want, err)
|
||||
}
|
||||
}
|
||||
if !oneOf(KnownCapabilities, "user-namespaces") {
|
||||
t.Error("user-namespaces is not a known capability")
|
||||
}
|
||||
for _, name := range []string{"battery", "power-meter", "seat", "container-runtime"} {
|
||||
if !oneOf(KnownCapabilities, name) {
|
||||
t.Errorf("%s is no longer a known capability", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user