carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "context"
5 "net/http"
6 "strings"
7 "testing"
8)
9
10// edgesFor writes a fleet's edges files and returns the fixture's put helper
11// shape, so each door test states its fleet in one place.
12func putEdges(t *testing.T, fx *consoleFixture, files map[string]string) {
13 t.Helper()
14 for name, body := range files {
15 if _, err := fx.rel.Put(context.Background(), "control/edges/"+name+".json", []byte(body), ""); err != nil {
16 t.Fatal(err)
17 }
18 }
19}
20
21// Only a SOCKET-BACKED INSTANCE needs an armed activator on the target box.
22// A static route is served from bucket bytes by every armed edge with no
23// process at all, so refusing one for want of a hibernation bucket refuses a
24// site that would have served perfectly. The gate ran before the record's
25// kind was even read, so it applied to every kind alike.
26func TestCreateDoorLetsStaticIntoANonHostingRegion(t *testing.T) {
27 fx, token := instanceFixture(t, "code-inst-statictonohost")
28 m := titoManifest()
29 m.Regions = nil
30 m.Pool = ""
31 enableInstances(t, fx, "titogo", m)
32 // uk is reachable and explicitly cannot host; ie can.
33 putEdges(t, fx, map[string]string{
34 "uk-box": `{"v":1,"box":"uk-box","eip":"1.2.3.4","placement":"uk","hibernation_configured":false,"hosts":{}}`,
35 "ie-box": `{"v":1,"box":"ie-box","eip":"5.6.7.8","placement":"ie","data_bucket":"carlos-ie","hibernation_configured":true,"hosts":{}}`,
36 })
37 u := instancesURL(fx, "bab", "titogo")
38
39 // A static site into uk: allowed. It needs an edge, not an activator.
40 code, _, out := rawReq(t, http.MethodPost, u, token,
41 `{"host":"brochure.go.tito.io","region":"uk","kind":"static"}`)
42 if code != http.StatusCreated {
43 t.Fatalf("create static into a reachable non-hosting region = %d %s, want 201 — a static route runs no process", code, out)
44 }
45
46 // An instance into the same region: refused, and the refusal says why
47 // and lists somewhere that would work.
48 code, _, out = rawReq(t, http.MethodPost, u, token,
49 `{"host":"app.go.tito.io","region":"uk"}`)
50 if code != http.StatusBadRequest {
51 t.Fatalf("create instance into a non-hosting region = %d %s, want 400", code, out)
52 }
53 if !strings.Contains(out, "cannot host") || !strings.Contains(out, "ie") {
54 t.Errorf("refusal %q should say the region cannot host and name one that can", out)
55 }
56}
57
58// An addr-backed service proxies to a process the platform never spawns, so
59// it needs the region to exist, not to host.
60func TestCreateDoorLetsAddrBackedServiceIntoANonHostingRegion(t *testing.T) {
61 fx, token := instanceFixture(t, "code-inst-svctonohost")
62 letStateUpstreams(t, fx, "alice@keymail.dev")
63 m := titoManifest()
64 m.Regions = nil
65 m.Pool = ""
66 enableInstances(t, fx, "titogo", m)
67 putEdges(t, fx, map[string]string{
68 "uk-box": `{"v":1,"box":"uk-box","eip":"1.2.3.4","placement":"uk","hibernation_configured":false,"hosts":{}}`,
69 })
70 code, _, out := rawReq(t, http.MethodPost, instancesURL(fx, "bab", "titogo"), token,
71 `{"host":"svc.go.tito.io","region":"uk","kind":"service","addrs":["10.0.0.4:8080"]}`)
72 if code != http.StatusCreated {
73 t.Fatalf("create addr-backed service into a non-hosting region = %d %s, want 201", code, out)
74 }
75}
76
77// An UNREACHABLE region is refused for every kind — a box nothing can dial
78// homes nothing, static included.
79func TestCreateDoorRefusesEveryKindIntoAnUnreachableRegion(t *testing.T) {
80 fx, token := instanceFixture(t, "code-inst-unreachable")
81 m := titoManifest()
82 m.Regions = nil
83 m.Pool = ""
84 enableInstances(t, fx, "titogo", m)
85 putEdges(t, fx, map[string]string{
86 "se-box": `{"v":1,"box":"se-box","eip":"","placement":"se","hosts":{}}`,
87 "ie-box": `{"v":1,"box":"ie-box","eip":"5.6.7.8","placement":"ie","data_bucket":"carlos-ie","hibernation_configured":true,"hosts":{}}`,
88 })
89 code, _, out := rawReq(t, http.MethodPost, instancesURL(fx, "bab", "titogo"), token,
90 `{"host":"brochure.go.tito.io","region":"se","kind":"static"}`)
91 if code != http.StatusBadRequest || !strings.Contains(out, "not armed") {
92 t.Fatalf("create static into an unreachable region = %d %s, want 400 not-armed", code, out)
93 }
94}
95
96// The move door's bar is the target's published STAGING bucket, and it is
97// unconditional. internal/host's moveTargets drops any target whose edges
98// file carries no data_bucket, and runMoveRound then answers "publishes no
99// data bucket yet — waiting" forever, so a door that admitted the move would
100// wedge a LIVE instance's residence on a lane that does not exist.
101func TestMoveDoorRequiresAStagingBucket(t *testing.T) {
102 fx, token := instanceFixture(t, "code-inst-movestaging")
103 m := titoManifest()
104 m.Regions = nil
105 m.Pool = ""
106 enableInstances(t, fx, "titogo", m)
107 // uk is an old writer: reachable, eligible to HOST (unknown is not no),
108 // but it publishes no bucket coordinates, so it can take no move.
109 putEdges(t, fx, map[string]string{
110 "uk-box": `{"v":1,"box":"uk-box","eip":"1.2.3.4","placement":"uk","hosts":{}}`,
111 "ie-box": `{"v":1,"box":"ie-box","eip":"5.6.7.8","placement":"ie","data_bucket":"carlos-ie","hibernation_configured":true,"hosts":{}}`,
112 })
113 u := instancesURL(fx, "bab", "titogo")
114
115 // uk IS a legal create target — unknown hosting stays eligible. This
116 // instance is created in ie, though, so the move below is a genuine
117 // cross-region request and cannot be refused by the same-region conflict
118 // instead of by the bar under test.
119 if code, _, out := rawReq(t, http.MethodPost, u, token,
120 `{"host":"mover.go.tito.io","region":"ie"}`); code != http.StatusCreated {
121 t.Fatalf("create into ie = %d %s, want 201", code, out)
122 }
123 if code, _, out := rawReq(t, http.MethodPost, u, token,
124 `{"host":"stayer.go.tito.io","region":"uk"}`); code != http.StatusCreated {
125 t.Fatalf("create into an unknown-hosting region = %d %s, want 201 — unknown is not no", code, out)
126 }
127 // uk is NOT a legal move target: it publishes no staging bucket.
128 code, _, out := rawReq(t, http.MethodPost, u+"/mover.go.tito.io/move", token, `{"region":"uk"}`)
129 if code != http.StatusBadRequest {
130 t.Fatalf("move to a region with no staging bucket = %d %s, want 400", code, out)
131 }
132 if !strings.Contains(out, "staging bucket") {
133 t.Errorf("refusal %q should name the missing staging bucket — the worker's own reason", out)
134 }
135 if !strings.Contains(out, "ie") {
136 t.Errorf("refusal %q should list the regions that can take a move", out)
137 }
138}
139