carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "context"
5 "encoding/json"
6 "errors"
7 "slices"
8 "testing"
9
10 "github.com/carlosframework/platform/internal/hostbox"
11 "github.com/carlosframework/platform/internal/hostclaim"
12 "github.com/carlosframework/platform/internal/park"
13 "github.com/carlosframework/platform/internal/provision"
14 "github.com/carlosframework/platform/internal/release"
15)
16
17// Moves into the home region, part 2, Task 2: the fixtures for a home
18// target box. intoHome mirrors fromHome for the target: the source is
19// ca-box in ca, the target home-box with placement "", whose roster name is
20// ie and whose fleet designates ie the home. The witnesses of Tasks 3 to 5
21// stand on these fixtures, so this test pins what each one is.
22
23var _ release.Store = p1FilesStore{}
24
25// TestIntoHomeFixtureIsAHomeTarget: the record's move names the home's
26// code, the target's edges file publishes no placement, the claim's op
27// names the placement-derived @home with home_region ie, the target's held
28// environment sets no CARLOS_REGION, and the close harness's production
29// probe mode admits on home-box in the claim engine's region ie.
30func TestIntoHomeFixtureIsAHomeTarget(t *testing.T) {
31 ctx := context.Background()
32
33 t.Run("the move, the edges file, the claim and the held env", func(t *testing.T) {
34 h := newPhase1Harness(t, intoHome)
35 rec := h.start(t, "manual")
36 if rec.Move == nil || rec.Move.To != "" || rec.Move.From != "ca" || rec.Region != "ca" {
37 t.Fatalf("the record: region %q move %+v", rec.Region, rec.Move)
38 }
39 body, _, err := h.s.Get(ctx, "control/edges/home-box.json")
40 if err != nil {
41 t.Fatal(err)
42 }
43 var edges map[string]any
44 if err := json.Unmarshal(body, &edges); err != nil {
45 t.Fatal(err)
46 }
47 if _, ok := edges["placement"]; ok || edges["data_bucket"] != "data-home" || edges["box"] != "home-box" {
48 t.Fatalf("the home box's edges file: %s", body)
49 }
50 if _, _, err := h.s.Get(ctx, "control/edges/uk-box.json"); err == nil {
51 t.Fatal("a uk-box edges file is still published beside the home box")
52 }
53 c := h.claim(t)
54 if c.Op.Kind != hostclaim.KindMoving || c.Op.Intent["to"] != park.HomeRegion || c.Op.Intent["home_region"] != "ie" ||
55 c.Op.Intent["source"] != "ca-box" || c.Op.Intent["target"] != "home-box" || c.Op.Exec != "ca-box" {
56 t.Fatalf("the claim's op: %+v", c.Op)
57 }
58 if c.Op.Intent["source_enrollment"] != p1SrcEnrollment || c.Op.Intent["target_enrollment"] != p1DstEnrollment || c.Op.Intent["admission_id"] != p1ID {
59 t.Fatalf("the op was not begun as the claim-mode door begins it: %+v", c.Op.Intent)
60 }
61 a := h.roster[h.dstBox]
62 if a.Region != "ie" || a.FleetHomeRegion != "ie" || a.HomeRegion != "ie" || h.roster[h.srcBox].Region != "ca" || h.roster[h.srcBox].HomeRegion != "" {
63 t.Fatalf("the roster: %+v", h.roster)
64 }
65 tc := h.targetCfg()
66 if tc.Region != "" || tc.Box != "home-box" || tc.OwnBucket != "data-home" || tc.OwnBucketRegion != "eu-west-1" || tc.ParkHomeRegion != "ie" {
67 t.Fatalf("the target's configuration: region %q box %q bucket %q/%q park home %q", tc.Region, tc.Box, tc.OwnBucket, tc.OwnBucketRegion, tc.ParkHomeRegion)
68 }
69 env, _, _, _, err := tc.ComposeHeldEnv(ctx, h.s, rec, nil)
70 if err != nil {
71 t.Fatal(err)
72 }
73 if _, ok := env["CARLOS_REGION"]; ok {
74 t.Fatal("the home target's held env sets CARLOS_REGION")
75 }
76 ch := newCutHarness(t, intoHome)
77 env, _, _, _, err = ch.target().ComposeHeldEnv(ctx, ch.s, rec, nil)
78 if err != nil {
79 t.Fatal(err)
80 }
81 if _, ok := env["CARLOS_REGION"]; ok {
82 t.Fatal("the cut harness's home target sets CARLOS_REGION")
83 }
84 // The default fixture is unchanged: uk sets its own region.
85 named := newPhase1Harness(t)
86 env, _, _, _, err = named.targetCfg().ComposeHeldEnv(ctx, named.s, rec, nil)
87 if err != nil || env["CARLOS_REGION"] != "uk" {
88 t.Fatalf("the named target's held env: %v %q", err, env["CARLOS_REGION"])
89 }
90 })
91
92 t.Run("retained state in either spelling", func(t *testing.T) {
93 for _, spelling := range []string{"ie", park.HomeRegion} {
94 h := newPhase1Harness(t, intoHome, retainTouched(spelling), retainQuiet(spelling), retainChore("ie"))
95 h.start(t, "manual")
96 c := h.claim(t)
97 if !containsString(c.Touched.Regions, spelling) || !containsString(c.Touched.Regions, "ca") {
98 t.Fatalf("%s: touched %+v", spelling, c.Touched)
99 }
100 if _, ok := c.QuietAfter[spelling]; !ok || len(c.QuietAfter) != 1 {
101 t.Fatalf("%s: quiet_after %v", spelling, c.QuietAfter)
102 }
103 var chore *hostclaim.Obligation
104 for _, o := range c.Obligations {
105 if o.Op == retainedChoreOp {
106 chore = &o
107 }
108 }
109 if chore == nil || chore.Region != "ie" || chore.Owner != "region:ie" || chore.Kind != "park-generation" || chore.Generation != retainedChoreGeneration ||
110 chore.Park == nil || chore.Park.Location != c.Holder.Location || chore.Park.Incarnation != h.inc {
111 t.Fatalf("%s: the earlier residue chore: %+v", spelling, c.Obligations)
112 }
113 if c.Op.Intent["to"] != park.HomeRegion {
114 t.Fatalf("%s: the op's to: %+v", spelling, c.Op.Intent)
115 }
116 }
117 })
118
119 t.Run("the production probe admits on home-box in ie", func(t *testing.T) {
120 h := newCloseHarness(t, intoHome, realLaunchEnv)
121 if m := h.read(t, p1Host).Move; m.To != "" || m.State != provision.MoveLanding || m.LandingPhase != provision.LandRestored {
122 t.Fatalf("the close harness: %+v", m)
123 }
124 p := h.productionProbe(t)
125 h.land(t)
126 if len(p.admissions) != 1 {
127 t.Fatalf("admissions through the claim runtime: %+v", p.admissions)
128 }
129 a := p.admissions[0]
130 if a.Box != "home-box" || a.Region != "ie" || a.PredecessorRegion != "ca" || a.Mode != "cold" || a.Generation != p1ID || a.Coverage != "sealed" {
131 t.Fatalf("the probe's admission: %+v", a)
132 }
133 if p.owners.Box != "home-box" || p.owners.Region != "ie" || p.owners.HomeRegion != "ie" || p.owners.FleetHomeRegion != "ie" {
134 t.Fatalf("the owners' identity: box %q region %q home %q fleet %q", p.owners.Box, p.owners.Region, p.owners.HomeRegion, p.owners.FleetHomeRegion)
135 }
136 c := h.claim(t)
137 if c.Holder.WriterBox != "home-box" || c.Op.Intent["to"] != park.HomeRegion {
138 t.Fatalf("the claim after the probe: writer %q to %q", c.Holder.WriterBox, c.Op.Intent["to"])
139 }
140 // The writer's evidence was the owners': asked once, for the one
141 // admission.
142 if p.evidence != 1 {
143 t.Fatalf("the writer's admission evidence ran %d times, want 1", p.evidence)
144 }
145 // Materialize ran the production owners' held steps, in order.
146 if want := []string{"render", "select:held-config", "select:held-release", "release:v7"}; len(p.order) < len(want) || !slices.Equal(p.order[:len(want)], want) {
147 t.Fatalf("the owners' held steps: %v", p.order)
148 }
149 h.committedAndOpen(t)
150 })
151
152 t.Run("rejected admission evidence admits nothing", func(t *testing.T) {
153 h := newCloseHarness(t, intoHome, realLaunchEnv)
154 p := h.productionProbe(t)
155 before := h.claim(t).Holder
156 p.rejectEvidence = hostbox.ErrChanged
157 h.land(t)
158 if p.evidence == 0 {
159 t.Fatal("the writer never asked for admission evidence")
160 }
161 after := h.claim(t).Holder
162 if len(p.admissions) != 0 || len(after.Admissions) != len(before.Admissions) || after.Session != before.Session || after.WriterBox == "home-box" {
163 t.Fatalf("an admission went through rejected evidence: %+v (before %+v)", after, before)
164 }
165 if m := h.read(t, p1Host).Move; m.State != provision.MoveLanding || m.LandingPhase != provision.LandProbing {
166 t.Fatalf("the landing moved past probing: %+v", m)
167 }
168 // The owners' own evidence refuses an admission Select never made:
169 // the dispatch the writer calls is the owners'.
170 p.rejectEvidence = nil
171 o, err := hostclaim.Read(t.Context(), h.s, p1Host)
172 if err != nil {
173 t.Fatal(err)
174 }
175 in, err := p.owners.Select(t.Context(), h.route, o, poProbe)
176 if err != nil {
177 t.Fatal(err)
178 }
179 if err := p.writerEvidence(t.Context(), o, in.Admission, in.Baseline); err != nil {
180 t.Fatalf("the writer's evidence refused the owners' own admission: %v", err)
181 }
182 bad := in.Admission
183 bad.Box = "ca-box"
184 if err := p.writerEvidence(t.Context(), o, bad, in.Baseline); !errors.Is(err, hostbox.ErrChanged) {
185 t.Fatalf("the writer's evidence accepted an admission on %s: %v", bad.Box, err)
186 }
187 })
188
189 t.Run("the probe and recovery owners' fixtures", func(t *testing.T) {
190 f := newPOFixture(t, poIntoHome)
191 in, err := f.owners.Select(t.Context(), f.route, f.read(), poProbe)
192 if err != nil {
193 t.Fatal(err)
194 }
195 if a := in.Admission; a.Box != "home-box" || a.Region != "ie" || a.PredecessorRegion != "ca" || a.Mode != "cold" {
196 t.Fatalf("the probe owners' admission: %+v", a)
197 }
198 if err := f.owners.AdmissionEvidence(t.Context(), f.read(), in.Admission, in.Baseline); err != nil {
199 t.Fatal(err)
200 }
201 if o := f.read(); o.Claim.Op.Intent["to"] != park.HomeRegion || o.Claim.Op.Intent["home_region"] != "ie" || f.rec.Move.To != "" {
202 t.Fatalf("the probe owners' fixture: %+v %+v", o.Claim.Op.Intent, f.rec.Move)
203 }
204 for _, kind := range []string{rcClean, rcDirty, rcRevert} {
205 f := newRCFixture(t, kind, poIntoHome)
206 o := f.read()
207 in := f.selectAdmission(o)
208 if a := in.Admission; a.Box != "ca-box" || a.Region != "ca" {
209 t.Fatalf("%s: the recovery owners' admission: %+v", kind, a)
210 }
211 if err := f.owners.AdmissionEvidence(t.Context(), o, in.Admission, in.Baseline); err != nil {
212 t.Fatalf("%s: %v", kind, err)
213 }
214 if o.Claim.Op.Intent["to"] != park.HomeRegion || o.Claim.Op.Intent["target"] != "home-box" {
215 t.Fatalf("%s: the recovery claim: %+v", kind, o.Claim.Op)
216 }
217 }
218 })
219
220 t.Run("the revert fixture", func(t *testing.T) {
221 for _, from := range []string{"stopping", "stopped"} {
222 h := newRevertHarness(t, intoHome)
223 if from == "stopping" {
224 h.fromStopping(t)
225 h.ev.stopped = true
226 } else {
227 h.fromStopped(t)
228 }
229 h.arm(t)
230 h.drive(t)
231 h.closed(t)
232 if rec := h.read(t, p1Host); rec.Region != "ca" || rec.LastMove == nil || rec.LastMove.Outcome != "rolled_back" {
233 t.Fatalf("%s: the record: %+v", from, rec)
234 }
235 if keys := h.laneKeys(); len(keys) != 0 {
236 t.Fatalf("%s: the home bucket's lane still holds %v", from, keys)
237 }
238 }
239 })
240}
241