package resolution import ( "strings" "testing" mcat "git.novox.be/novox/mesh-sdk/go/catalogue" ) func configured(block map[string]any) mcat.SettingsBy { return mcat.SettingsBy{"media": {{From: "node anchor", Placement: map[string]any{mcat.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": mcat.ReachBoth}, "stream": map[string]any{"reach": mcat.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 := mcat.Resolution{Node: "anchor", Modules: []mcat.Manifest{m}, PublicDomain: "example.test", At: "anchor.internal"} rules, err := Rules(r, mcat.Rendering{Settings: settings}) if err != nil { t.Fatal(err) } for _, rule := range rules { if rule.Port == 32400 && rule.From != mcat.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 != mcat.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 := resolutionContributions(r, 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": mcat.ReachInternal}}) r := mcat.Resolution{Node: "anchor", Modules: []mcat.Manifest{m}, PublicDomain: "example.test", At: "anchor.internal"} nodes, err := resolutionContributions(r, 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) } } } // **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, []mcat.Layer{{From: "node anchor", Placement: map[string]any{mcat.EndpointsSetting: map[string]any{"web": map[string]any{"port": 20009}}, mcat.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) } }