package steering import ( "bytes" "log" "reflect" "strings" "testing" "github.com/carlosframework/platform/internal/registry" ) func captureLog(t *testing.T) *bytes.Buffer { t.Helper() var buf bytes.Buffer prev := log.Writer() flags := log.Flags() log.SetOutput(&buf) log.SetFlags(0) t.Cleanup(func() { log.SetOutput(prev); log.SetFlags(flags) }) return &buf } func steeredRoute(host string) registry.Route { return registry.Route{Host: host, Steering: "latency"} } // TestDesiredStateReplicasDoNotSteer pins the #162 half of the fold: an // account whose replica box publishes the host marked replica gets records // from EVERY armed edge EXCEPT that one — the pre-#162 rule is any-edge- // any-app (far edges backhaul), so the ONLY entries a replica mark removes // are its own. The synthetic edge. records keep ALL armed // edges regardless (every edge is a cache front). func TestDesiredStateReplicasDoNotSteer(t *testing.T) { dublin := edgeHomes("dublin", "1.2.3.4", "eu-west-1", "app.example.com") oregon := edge("oregon", "5.6.7.8", "us-west-2") oregon.Hosts = map[string]edgeHostView{ "app.example.com": {Replica: true}, } got := desiredState([]registry.Route{steeredRoute("app.example.com")}, []edgesFileView{dublin, oregon}, "example.com") want := []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "edge.example.com.", EIP: "5.6.7.8", Box: "oregon", Region: "us-west-2"}, {Name: "app.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, } if !reflect.DeepEqual(got, want) { t.Fatalf("desiredState() =\n%#v\nwant\n%#v", got, want) } // A host named by NO box still earns records from every armed edge: // steering is any-edge-any-app, and the far edge backhauls to the home // whether or not this box holds a row for the host. got = desiredState([]registry.Route{steeredRoute("never-published.example.com")}, []edgesFileView{dublin, oregon}, "example.com") want = []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "edge.example.com.", EIP: "5.6.7.8", Box: "oregon", Region: "us-west-2"}, {Name: "never-published.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "never-published.example.com.", EIP: "5.6.7.8", Box: "oregon", Region: "us-west-2"}, } if !reflect.DeepEqual(got, want) { t.Fatalf("unpublished-host desiredState() =\n%#v\nwant\n%#v", got, want) } } func edge(box, eip, region string) edgesFileView { return edgesFileView{V: 1, Box: box, EIP: eip, Region: region} } // edgeHomes is edge() with the homed-host set filled in: the tests that // drive desiredState's per-host fold need Hosts, which pre-#162 was // deliberately absent (the fold never asked who served what) and which the // replica-aware fold now reads. Hosts uses the writer's own key shape; // every entry is home-marked (Replica clear) unless a test says otherwise. func edgeHomes(box, eip, region string, homes ...string) edgesFileView { e := edge(box, eip, region) e.Hosts = map[string]edgeHostView{} for _, h := range homes { e.Hosts[h] = edgeHostView{} } return e } // TestDesiredState is the brief's table: one steered host x two armed // edges = two records; unsteered host absent; edge. present // whenever >=1 edge is armed, absent at zero. func TestDesiredState(t *testing.T) { dublin := edgeHomes("dublin", "1.2.3.4", "eu-west-1", "app.example.com", "steered.example.com", "example.com") oregon := edgeHomes("oregon", "5.6.7.8", "us-west-2", "app.example.com", "steered.example.com") tests := []struct { name string routes []registry.Route edges []edgesFileView appsDomain string want []desiredRecord }{ { name: "one steered host x two armed edges", routes: []registry.Route{steeredRoute("app.example.com")}, edges: []edgesFileView{dublin, oregon}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "edge.example.com.", EIP: "5.6.7.8", Box: "oregon", Region: "us-west-2"}, {Name: "app.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "app.example.com.", EIP: "5.6.7.8", Box: "oregon", Region: "us-west-2"}, }, }, { name: "unsteered host absent", routes: []registry.Route{ {Host: "app.example.com", Steering: ""}, steeredRoute("steered.example.com"), }, edges: []edgesFileView{dublin}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "steered.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "zero armed edges yields nothing, no edge.", routes: []registry.Route{steeredRoute("app.example.com")}, edges: nil, appsDomain: "example.com", want: nil, }, { name: "edge with empty EIP skipped", routes: []registry.Route{steeredRoute("app.example.com")}, edges: []edgesFileView{dublin, edge("noeip", "", "us-west-2")}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "app.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "edge with empty region skipped", routes: []registry.Route{steeredRoute("app.example.com")}, edges: []edgesFileView{dublin, edge("noregion", "9.9.9.9", "")}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "app.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "edge region carrying a placement code (not an AWS region) skipped", routes: []registry.Route{steeredRoute("app.example.com")}, edges: []edgesFileView{dublin, edge("tito", "9.9.9.9", "ie")}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "app.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "pool-carrying steered route excluded", routes: []registry.Route{ {Host: "pooled.example.com", Steering: "latency", Pool: "reserved"}, }, edges: []edgesFileView{dublin}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "wildcard registry row with steering set never produces a record", routes: []registry.Route{ {Host: "*.example.com", Steering: "latency"}, }, edges: []edgesFileView{dublin}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "invalid steering value skipped, never guessed", routes: []registry.Route{ {Host: "hand-written.example.com", Steering: "geo"}, }, edges: []edgesFileView{dublin}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "trailing-dot input normalizes to a single trailing dot", routes: []registry.Route{steeredRoute("app.example.com.")}, edges: []edgesFileView{dublin}, appsDomain: "example.com.", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "app.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "mixed-case host folds to one lowercase Name", routes: []registry.Route{steeredRoute("App.Example.COM")}, edges: []edgesFileView{dublin}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "app.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "blank apps domain skips the synthetic edge hostname AND every per-host record", routes: []registry.Route{steeredRoute("app.example.com")}, edges: []edgesFileView{dublin}, appsDomain: "", want: nil, }, { name: "out-of-zone steered host excluded, in-zone host still lands", routes: []registry.Route{ steeredRoute("app.example.com"), steeredRoute("console.carloku.com"), }, edges: []edgesFileView{dublin}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "app.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "steered host equal to the apps domain itself (apex) lands", routes: []registry.Route{steeredRoute("example.com")}, edges: []edgesFileView{dublin}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, {Name: "example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, { name: "steered host merely sharing a suffix (not a subdomain) is excluded", routes: []registry.Route{steeredRoute("notexample.com")}, edges: []edgesFileView{dublin}, appsDomain: "example.com", want: []desiredRecord{ {Name: "edge.example.com.", EIP: "1.2.3.4", Box: "dublin", Region: "eu-west-1"}, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { captureLog(t) // silence + isolate log output from test noise got := desiredState(tt.routes, tt.edges, tt.appsDomain) if !reflect.DeepEqual(got, tt.want) { t.Fatalf("desiredState() =\n%#v\nwant\n%#v", got, tt.want) } }) } } func TestDesiredStateLogsEachSkipReason(t *testing.T) { dublin := edge("dublin", "1.2.3.4", "eu-west-1") tests := []struct { name string routes []registry.Route edges []edgesFileView wantLog string }{ { name: "edge with no EIP is named in the log", edges: []edgesFileView{edge("noeip", "", "eu-west-1")}, wantLog: "steering: edge noeip unarmed: no EIP", }, { name: "edge with a placement code names the bad value", edges: []edgesFileView{edge("tito", "9.9.9.9", "ie")}, wantLog: `steering: edge tito unarmed: region "ie" is not an AWS region`, }, { name: "pool-carrying route is named", edges: []edgesFileView{dublin}, routes: []registry.Route{{Host: "pooled.example.com", Steering: "latency", Pool: "reserved"}}, wantLog: `steering: route pooled.example.com excluded: pool "reserved" set`, }, { name: "wildcard route is named", edges: []edgesFileView{dublin}, routes: []registry.Route{{Host: "*.example.com", Steering: "latency"}}, wantLog: "steering: route *.example.com excluded: wildcard host", }, { name: "invalid steering value is named verbatim", edges: []edgesFileView{dublin}, routes: []registry.Route{{Host: "hand.example.com", Steering: "geo"}}, wantLog: `steering: route hand.example.com excluded: invalid steering value "geo"`, }, { name: "out-of-zone steered host is named, with the CNAME guidance", edges: []edgesFileView{dublin}, routes: []registry.Route{steeredRoute("console.carloku.com")}, wantLog: `steering: route console.carloku.com excluded: host is not under the apps domain "example.com" — custom domains steer via CNAME to edge.`, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { buf := captureLog(t) desiredState(tt.routes, tt.edges, "example.com") if !strings.Contains(buf.String(), tt.wantLog) { t.Fatalf("log output =\n%s\nwant substring %q", buf.String(), tt.wantLog) } }) } } // TestDesiredStateBlankAppsDomainExcludesEveryPerHostRecord pins the second // half of the Important review finding: appsDomain == "" is not just "no // synthetic edge. record" — with no domain there is no zone a // per-host route can be proven to lie under, so EVERY steered route is // excluded too (steeredHosts' own appsDomain == "" branch), loudly, one // line per route, same log family as the out-of-zone case. func TestDesiredStateBlankAppsDomainExcludesEveryPerHostRecord(t *testing.T) { dublin := edge("dublin", "1.2.3.4", "eu-west-1") buf := captureLog(t) got := desiredState( []registry.Route{steeredRoute("app.example.com"), steeredRoute("other.example.com")}, []edgesFileView{dublin}, "", ) if got != nil { t.Fatalf("desiredState() = %#v, want nil (no domain, no synthetic hostname, no per-host record)", got) } logged := buf.String() for _, want := range []string{ `steering: route app.example.com excluded: no apps domain configured`, `steering: route other.example.com excluded: no apps domain configured`, "custom domains steer via CNAME to edge.", } { if !strings.Contains(logged, want) { t.Fatalf("log output =\n%s\nwant substring %q", logged, want) } } } // TestDesiredStateCaseFoldDedupe pins the case-collision half of the // review's Important finding: two registry rows differing only by case // are two legitimate primary-key rows right up until fqdn folds them onto // one Route53 name, at which point desiredState must produce exactly ONE // record per armed edge for that name, not two — and the log must name // BOTH original (still mixed-case) Host values, not the already-folded // Name, because that is the only information an operator can act on: // which two registry rows to go fix. That naming has to happen where the // originals still exist — steeredHosts, via dedupeCaseCollisions — not // later at the desiredRecord level, where a same-edge collision has // identical Box/EIP on both sides and the log would just repeat the one // folded Name. func TestDesiredStateCaseFoldDedupe(t *testing.T) { dublin := edgeHomes("dublin", "1.2.3.4", "eu-west-1", "app.example.com") buf := captureLog(t) routes := []registry.Route{ steeredRoute("App.example.com"), steeredRoute("app.example.com"), } got := desiredState(routes, []edgesFileView{dublin}, "example.com") var matches int for _, rec := range got { if rec.Name == "app.example.com." { matches++ } } if matches != 1 { t.Fatalf("desiredState() produced %d records for the case-colliding name, want exactly 1 (got %#v)", matches, got) } // Total should be the edge. record plus the ONE surviving // per-host record — not two. if len(got) != 2 { t.Fatalf("desiredState() = %#v, want 2 records (1 synthetic + 1 deduped)", got) } logged := buf.String() // Sorted-Host order (ASCII, uppercase < lowercase) keeps // "App.example.com" and drops "app.example.com" — both original // strings, plus the folded DNS name, must appear verbatim. for _, want := range []string{`"App.example.com"`, `"app.example.com"`, `"app.example.com."`} { if !strings.Contains(logged, want) { t.Fatalf("log output =\n%s\nwant substring %s naming the original colliding host/DNS name", logged, want) } } if !strings.Contains(logged, "steering: case-collision:") { t.Fatalf("log output =\n%s\nwant a case-collision line", logged) } // The record-level backstop (dedupeRecords) must NOT be the one that // fired — the collision was already resolved at the route level, one // layer earlier, where the log could still name both original hosts. if strings.Contains(logged, "steering: record ") { t.Fatalf("log output =\n%s\nwant no dedupeRecords line — the collision should be caught earlier, in steeredHosts", logged) } } func TestDesiredStateBlankAppsDomainLogged(t *testing.T) { dublin := edge("dublin", "1.2.3.4", "eu-west-1") buf := captureLog(t) desiredState([]registry.Route{steeredRoute("app.example.com")}, []edgesFileView{dublin}, "") want := "steering: no apps domain configured" if !strings.Contains(buf.String(), want) { t.Fatalf("log output =\n%s\nwant substring %q", buf.String(), want) } } func TestParseEdgesFileView(t *testing.T) { tests := []struct { name string body string want edgesFileView wantErr bool }{ { name: "v1 body with region", body: `{"v":1,"box":"dublin","eip":"1.2.3.4","region":"eu-west-1","generation":"2026-08-22T09:00:00Z","hosts":{"app.example.com":{"role":"home"}}}`, want: edgesFileView{V: 1, Box: "dublin", EIP: "1.2.3.4", Region: "eu-west-1"}, }, { name: "v1 body without region (pre-region writer)", body: `{"v":1,"box":"dublin","eip":"1.2.3.4","generation":"2026-08-22T09:00:00Z","hosts":{}}`, want: edgesFileView{V: 1, Box: "dublin", EIP: "1.2.3.4", Region: ""}, }, { name: "unversioned body refused", body: `{"box":"dublin","eip":"1.2.3.4"}`, wantErr: true, }, { name: "garbage body refused", body: `not json`, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := parseEdgesFileView([]byte(tt.body)) if tt.wantErr { if err == nil { t.Fatalf("parseEdgesFileView(%q) = %+v, nil; want error", tt.body, got) } return } if err != nil { t.Fatalf("parseEdgesFileView(%q) unexpected error: %v", tt.body, err) } // Field-by-field, not struct equality: Hosts is a map, and a // comparable-struct check died the day #162 added it. The // scalar fields are the ones this test pins; Hosts is read // only for the replica mark in desiredState, pinned there. if got.V != tt.want.V || got.Box != tt.want.Box || got.EIP != tt.want.EIP || got.Region != tt.want.Region { t.Fatalf("parseEdgesFileView(%q) = %+v, want %+v", tt.body, got, tt.want) } }) } } func TestArmedEdgesSortedByBox(t *testing.T) { edges := []edgesFileView{ edge("oregon", "5.6.7.8", "us-west-2"), edge("dublin", "1.2.3.4", "eu-west-1"), } got := armedEdges(edges) if len(got) != 2 || got[0].Box != "dublin" || got[1].Box != "oregon" { t.Fatalf("armedEdges() = %+v, want dublin then oregon", got) } }