Test route-proxy without composing: its manifest's own facts and a plan entry's port, since the composition left mesh-sdk

The composer's proof that the manifest composes, and that a port is the placement's, is the node-engine's now (ADR 0593 §7).

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 19:06:37 +01:00
parent 9c9d03691b
commit a74f9db508
2 changed files with 24 additions and 86 deletions
@@ -54,40 +54,16 @@ func TestRouteProxyKeepsItsPublicAccountDirectory(t *testing.T) {
if slices.Contains(m.Requires, "acme-ca") {
t.Fatal("route-proxy still asks for acme-ca; the public issuer is its own fact (ADR 0226)")
}
// As a build would leave it: each artifact a container names resolved to an image. Which image does not matter to
// the file checked here. An archive resource carries no image: it unpacks a bundle.
for _, res := range m.Resources {
if res["type"] == "archive" {
continue
}
if artifact, ok := res["artifact"].(string); ok {
delete(res, "artifact")
res["image"] = "registry.invalid/route-proxy/" + artifact +
"@sha256:1111111111111111111111111111111111111111111111111111111111111111"
}
}
r := catalogue.Resolution{
Node: "anchor",
Modules: []catalogue.Manifest{m},
Needs: []catalogue.Needed{{
Name: "internal-acme-ca", From: "home", At: "home.internal", For: "route-proxy",
Serves: map[string]any{"port": float64(9000), "path": "/acme/acme/directory", "roots": "/roots.pem"},
}},
}
// Its own broker credential, sealed as the mesh would; what it is does not matter here.
out, err := r.Declaration(catalogue.Rendering{Needed: map[string]map[string]string{"route-proxy": {"broker": "sealed"}}})
if err != nil {
t.Fatalf("route-proxy could not be composed for a machine: %v", err)
}
env := resourceNamed(out, "route-proxy.acme-env")
// The tree read inlines the template the manifest names, a literal with nothing to fill, so this is what it writes.
env := resourceNamed(m.Resources, "acme-env")
if env == nil {
t.Fatalf("nothing writes the public issuer's environment: %v", out)
t.Fatalf("nothing writes the public issuer's environment: %v", m.Resources)
}
if got, _ := env["content"].(string); got != renderedBeforeTheFold {
t.Fatalf("acme.env changed, which moves the proxy's account and reorders every certificate:\ngot %q\nwant %q",
got, renderedBeforeTheFold)
}
if resourceNamed(out, "route-proxy.bound-acme-ca") != nil {
if resourceNamed(m.Resources, "bound-acme-ca") != nil {
t.Error("a binding to acme-ca is still written")
}
var trust string
@@ -154,70 +154,32 @@ func TestARouteWithNoInternalNameGetsNoAlias(t *testing.T) {
}
}
// A route is dialled where the machine publishes its module's endpoint, as the module's declaration publishes it (issue
// 774, research 072 row 34; 2026-10-31: gitea's 3000, published at 20000, and grafana's 3000 on another machine,
// published at 20012, answered 502): over loopback beside the proxy, which is the only thing that works without a
// private network, and at its machine's address otherwise. Each plan is composed by the SDK as the seat
// mesh-provisioner composes it, its ports as compose's portsFor gives them (the placement's for a port the mesh may
// move, the manifest's own otherwise), and read as this proxy reads it: the live shapes the old proxy served alike.
func TestAComposedPlanIsDialledWhereTheMachinePublishesIt(t *testing.T) {
proxy := catalogue.Manifest{Module: "route-proxy", Version: "1",
Provides: []catalogue.Offer{{Name: "route", Scope: catalogue.ScopeMesh, AnsweredBy: catalogue.AnsweredByHelper}}}
world := catalogue.World{Offered: map[string][]catalogue.Provider{
"route": {{Node: "anchor", At: "anchor.internal", Module: "route-proxy"}}}}
// A route is dialled at the machine port its plan entry carries (issue 774, research 072 row 34; 2026-10-31: gitea's
// 3000, published at 20000, and grafana's 3000 on another machine, published at 20012, answered 502): over loopback
// when the plan is the one of this proxy's own node, which is the only thing that works without a private network, and
// at the address the entry gives for its machine otherwise. The plans here are written as the seat mesh-provisioner
// carries them; that the port is the placement's and not the software's own is the composition's, proved by the
// node-engine's composer, not here.
func TestAPlanEntryIsDialledAtTheMachinePortItCarries(t *testing.T) {
for _, c := range []struct {
name, node, module string
port int // the endpoint's port, as listens says it
published []any // the container's ports; nil for the host's network
placed map[int]int // what mesh-placement holds for the module
target string
name, node, module, at string
port int
target string
}{
{"beside the proxy, moved by the placement (gitea)", "anchor", "gitea", 3000, []any{"3000"}, map[int]int{3000: 20000},
"http://127.0.0.1:20000"},
{"on another machine, moved by the placement (grafana)", "home", "grafana", 3000, []any{"3000"},
map[int]int{3000: 20012}, "http://home.internal:20012"},
{"a bare port the placement holds none for (influxdb)", "home", "influxdb", 8086, []any{"8086"}, nil,
"http://home.internal:8086"},
{"a fixed mapping (mailu 7080:80)", "anchor", "mailu", 7080, []any{"25", "7080:80"}, nil, "http://127.0.0.1:7080"},
{"a fixed mapping the placement names another port of (photos 9102:9000)", "anchor", "photos", 9102,
[]any{"9102:9000"}, map[int]int{9000: 20011}, "http://127.0.0.1:9102"},
{"the host's network (home-assistant)", "anchor", "home-assistant", 8123, nil, nil, "http://127.0.0.1:8123"},
{"beside the proxy (gitea)", "anchor", "gitea", "", 20000, "http://127.0.0.1:20000"},
{"beside the proxy, though the entry says an address (mailu)", "anchor", "mailu", "anchor.internal", 7080, "http://127.0.0.1:7080"},
{"on another machine (grafana)", "home", "grafana", "home.internal", 20012, "http://home.internal:20012"},
{"on another machine, a bare port (influxdb)", "home", "influxdb", "home.internal", 8086, "http://home.internal:8086"},
} {
container := map[string]any{"type": "container", "name": c.module, "image": "x"}
if c.published != nil {
container["ports"] = c.published
} else {
container["network"] = "host"
}
module := catalogue.Manifest{Module: c.module, Version: "1", Requires: []string{"route"},
Listens: []catalogue.Listening{{Name: "web", Port: c.port, Protocol: "tcp", From: "mesh"}},
Contributes: map[string]map[string]any{"route": {"label": c.module, "endpoint": "web"}},
Resources: []map[string]any{container}}
node := catalogue.Node{Name: c.node, At: c.node + ".internal", PublicDomain: "example.org",
Capabilities: map[string]bool{"container-runtime": true}}
r, err := catalogue.Resolve(map[string]catalogue.Manifest{module.Module: module, proxy.Module: proxy},
[]string{module.Module}, node, world)
values, _ := json.Marshal(map[string]any{"name": c.module + ".example.org", "port": c.port})
contributed, err := catalogue.EncodeContributed(catalogue.ContributedForm{At: c.at,
Each: []catalogue.ContributedOne{{Values: values}}})
if err != nil {
t.Fatalf("%s: %v", c.name, err)
}
r.Account = "op"
for i, n := range r.Needs {
r.Needs[i].AnsweredByHelper = n.Name == "route" // as the plan sets it (compose's answeredByHelper)
}
ports := map[int]int{}
for _, l := range module.Listens { // compose's portsFor
where, mayAssign := module.MachineSide(l.Port)
if at, known := c.placed[l.Port]; mayAssign && known {
where = at
}
ports[l.Port] = where
}
composed, err := r.Compose(catalogue.Rendering{Hands: true, Provisioner: "mesh-provisioner-client",
ArtifactStore: "store:5000", Planned: true, Ports: map[string]map[int]int{c.module: ports}})
if err != nil {
t.Fatalf("%s: %v", c.name, err)
}
value, err := provisions.EncodePlan(provisions.Plan{Node: c.node, Module: c.module, Plan: composed.Plans[c.module]})
value, err := provisions.EncodePlan(provisions.Plan{Node: c.node, Module: c.module, Plan: catalogue.Plan{
Provisions: []catalogue.PlanProvision{{Provision: contract.Provision, Provider: "anchor",
ProviderModule: contract.Module, Contributed: contributed}}}})
if err != nil {
t.Fatalf("%s: %v", c.name, err)
}