package catalogue import ( "strings" "testing" ) func configured(block map[string]any) SettingsBy { return SettingsBy{"media": {{From: "node anchor", Values: map[string]any{EndpointsSetting: block}}}} } // **One block per endpoint, saying all three things.** The machine port, the subdomain and the reach // were `ports`, the route's label and `reach`, each keyed by a port number, so configuring a module // with two endpoints of different shapes meant knowing which number was which. func TestAnEndpointsBlockSaysPortLabelAndReach(t *testing.T) { m := aMediaServer() // stream's reach NARROWS what the manifest says — the manifest has it from anywhere, the // assignment says internal. Chosen deliberately: a reach that agrees with the manifest proves // nothing about whether the block was read at all. settings := configured(map[string]any{ "web": map[string]any{"port": 20009, "label": "cinema", "reach": ReachBoth}, "stream": map[string]any{"reach": ReachInternal}, }) // The machine port, where the mapping is read. given, err := GivenPorts(m, settings["media"]) if err != nil { t.Fatal(err) } if given[80] != 20009 { t.Fatalf("the web endpoint is on machine port %d, want 20009: %v", given[80], given) } // The reach, where the filter reads it. r := Resolution{Node: "anchor", Modules: []Manifest{m}, PublicDomain: "example.test", At: "anchor.internal"} rules, err := r.Rules(Rendering{Settings: settings}) if err != nil { t.Fatal(err) } for _, rule := range rules { if rule.Port == 32400 && rule.From != FromMesh { t.Fatalf("the directly-dialled endpoint is %q; the assignment narrowed it to the private "+ "network and the manifest's 'anywhere' should not win", rule.From) } if rule.Port == 80 && rule.From != FromMesh { t.Fatalf("the routed endpoint's port opened to %q; the proxy is how it is reached", rule.From) } } // And the subdomain, where the name is composed — the assignment's, not the module's. nodes, err := r.contributions(settings, nil, nil) if err != nil { t.Fatal(err) } for _, c := range nodes["route"] { if got, _ := c.Values["name"].(string); got != "cinema.example.test" { t.Fatalf("the public name is %q, want the label the assignment gave", got) } if got, _ := c.Values["internal-name"].(string); got != "cinema.anchor.internal" { t.Fatalf("the internal name is %q, want the label the assignment gave", got) } } } // A block that says only a reach leaves the port to the mesh and the label to the module, which is the // ordinary case and must not require writing the other two. func TestABlockMaySayOnlyAReach(t *testing.T) { m := aMediaServer() settings := configured(map[string]any{"web": map[string]any{"reach": ReachInternal}}) r := Resolution{Node: "anchor", Modules: []Manifest{m}, PublicDomain: "example.test", At: "anchor.internal"} nodes, err := r.contributions(settings, nil, nil) if err != nil { t.Fatal(err) } for _, c := range nodes["route"] { if got, _ := c.Values["name"].(string); got != "" { t.Fatalf("an internal endpoint composed the public name %q", got) } // The module's own label, untouched. if got, _ := c.Values["internal-name"].(string); got != "media.anchor.internal" { t.Fatalf("the internal name is %q, want the module's own label", got) } } } // An endpoint the module does not declare reaches nothing, and the refusal says what it does declare. func TestConfiguringAnEndpointTheModuleLacksIsRefused(t *testing.T) { _, err := Endpoints(aMediaServer(), configured(map[string]any{ "admin": map[string]any{"reach": ReachInternal}})["media"]) if err == nil || !strings.Contains(err.Error(), "does not declare") { t.Fatalf("configuring an absent endpoint was accepted: %v", err) } if err != nil && !strings.Contains(err.Error(), "stream") { t.Fatalf("the refusal does not name what the module declares: %v", err) } } func TestAReachInABlockIsHeldToTheFourValues(t *testing.T) { _, err := Endpoints(aMediaServer(), configured(map[string]any{ "web": map[string]any{"reach": "mesh"}})["media"]) if err == nil || !strings.Contains(err.Error(), "a reach is") { t.Fatalf("a filter word was accepted as a reach: %v", err) } } // **Two places giving one endpoint a machine port is the confusion this key exists to end.** func TestAnEndpointGivenAPortTwiceIsRefused(t *testing.T) { m := aMediaServer() _, err := GivenPorts(m, []Layer{{From: "node anchor", Values: map[string]any{ EndpointsSetting: map[string]any{"web": map[string]any{"port": 20009}}, PortsSetting: map[string]any{"80": 30000}, }}}) if err == nil || !strings.Contains(err.Error(), "published once") { t.Fatalf("an endpoint given two machine ports was accepted: %v", err) } } // And the same for its reach, said once here and once through the older key. func TestAnEndpointWhoseReachIsAlsoExposedIsRefused(t *testing.T) { _, err := Endpoints(aMediaServer(), []Layer{{From: "node anchor", Values: map[string]any{ EndpointsSetting: map[string]any{"web": map[string]any{"reach": ReachInternal}}, ExposeSetting: map[string]any{"80": FromEverywhere}, }}}) if err == nil || !strings.Contains(err.Error(), "same thing in different words") { t.Fatalf("a reach said two ways was accepted: %v", err) } } // A module whose endpoints are unnamed cannot be configured this way, and is told so rather than // having a block silently reach nothing — which is every module in the catalogue today. func TestAModuleWithNoNamedEndpointsIsToldSo(t *testing.T) { m := Manifest{Module: "media", Listens: []Listening{{Port: 80, From: FromMesh}}} _, err := Endpoints(m, configured(map[string]any{"web": map[string]any{"reach": ReachBoth}})["media"]) if err == nil || !strings.Contains(err.Error(), "no endpoints by name") { t.Fatalf("a module with no named endpoints accepted a block: %v", err) } }