carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package hostops
2
3import (
4 "context"
5 "testing"
6
7 "github.com/carlosframework/platform/internal/hostclaim"
8 "github.com/carlosframework/platform/internal/moves"
9 "github.com/carlosframework/platform/internal/park"
10 "github.com/carlosframework/platform/internal/provision"
11)
12
13func TestMoveRecoveryCommitUsesSharedSealValidation(t *testing.T) {
14 for _, unknownField := range []bool{false, true} {
15 t.Run(map[bool]string{false: "valid", true: "unknown-seal-field"}[unknownField], func(t *testing.T) {
16 w := newLossWorld(t, "landing", func(c *hostclaim.Claim, r *provision.Record, _ *AppAdmission) {
17 c.Op.Phase = hostclaim.PhaseLandingProbed
18 r.Move.State = provision.MoveCommitted
19 r.Move.CommittedAt = r.Move.FlippedAt
20 if unknownField {
21 raw := c.Op.Journal[hostclaim.JournalSeal]
22 c.Op.Journal[hostclaim.JournalSeal] = `{"unknown":true,` + raw[1:]
23 }
24 })
25 before := w.claim(t)
26 rec, tag := w.record(t)
27 err := w.control.RunRecovery(context.Background(), func(ctx context.Context) error {
28 return runMoveRecovery(ctx, before, func(ctx context.Context, g *MoveRecoveryGrant) error {
29 return g.Claim(ctx, RecoveryMoveCommit)
30 })
31 })
32 after := w.claim(t)
33 if unknownField {
34 if err == nil || after.ETag != before.ETag {
35 t.Fatalf("unsupported seal changed claim: err=%v, before=%s, after=%s", err, before.ETag, after.ETag)
36 }
37 return
38 }
39 if err != nil || after.Claim.Op.Phase != hostclaim.PhaseCommitted {
40 t.Fatalf("commit: %v, claim=%+v", err, after.Claim)
41 }
42 source, staging, err := moves.CommitScopes(before.Claim, rec.Move.FlippedAt)
43 if err != nil {
44 t.Fatal(err)
45 }
46 found := map[string]bool{}
47 for _, chore := range after.Claim.Obligations {
48 if chore.Kind == "park-replica" && chore.Park != nil {
49 if *chore.Park == source || *chore.Park == staging {
50 found[chore.Park.Location] = true
51 }
52 }
53 }
54 if !found[source.Location] || !found[staging.Location] {
55 t.Fatalf("commit parks differ from shared scopes: %+v", after.Claim.Obligations)
56 }
57 if _, nextTag := w.record(t); nextTag != tag {
58 t.Fatal("claim commit wrote the record")
59 }
60 })
61 }
62}
63
64// Home-region parks, part 1: the console's commit of a move out of home
65// queues the source's location park in park.HomeRegion, exactly as the
66// box's commit does (K9), and covers the home generation's admission. The
67// record names home by its code, "", which the claim would refuse.
68func TestMoveRecoveryCommitFromHome(t *testing.T) {
69 w := newLossWorld(t, "landing", func(c *hostclaim.Claim, r *provision.Record, _ *AppAdmission) {
70 c.Op.Phase = hostclaim.PhaseLandingProbed
71 r.Move.State = provision.MoveCommitted
72 r.Move.CommittedAt = r.Move.FlippedAt
73 r.Move.From = ""
74 for i := range c.Holder.Admissions {
75 a := &c.Holder.Admissions[i]
76 if a.Region == "ie" {
77 a.Region = park.HomeRegion
78 }
79 if a.PredecessorRegion == "ie" {
80 a.PredecessorRegion = park.HomeRegion
81 }
82 }
83 })
84 before := w.claim(t)
85 err := w.control.RunRecovery(context.Background(), func(ctx context.Context) error {
86 return runMoveRecovery(ctx, before, func(ctx context.Context, g *MoveRecoveryGrant) error {
87 return g.Claim(ctx, RecoveryMoveCommit)
88 })
89 })
90 after := w.claim(t)
91 if err != nil || after.Claim.Op.Phase != hostclaim.PhaseCommitted {
92 t.Fatalf("commit: %v, claim=%+v", err, after.Claim.Op)
93 }
94 found := false
95 for _, o := range after.Claim.Obligations {
96 if o.Region == "" {
97 t.Fatalf("a chore in the unset region: %+v", o)
98 }
99 if o.Kind == "park-replica" && o.Park != nil && o.Park.Location == "instances/"+lossHost {
100 if o.Region != park.HomeRegion || o.Owner != "region:"+park.HomeRegion {
101 t.Fatalf("the source's location park %+v, want it in %s", o, park.HomeRegion)
102 }
103 found = true
104 }
105 }
106 if !found {
107 t.Fatalf("no location park: %+v", after.Claim.Obligations)
108 }
109 for _, a := range after.Claim.Holder.Admissions {
110 if a.PredecessorRegion == park.HomeRegion && !a.Covered {
111 t.Fatalf("the home generation's admission is not covered: %+v", a)
112 }
113 }
114}
115
116// Home part 2, Task 3 (the inventory's witness for this Commit site): the
117// console's commit of a move into home, from clean claim state. The record
118// names the target by the home's code, ""; the start CAS wrote the op's to
119// as @home with home_region uk, the roster name of uk-box, whose admissions
120// keep their engine region uk. The commit queues the lane park in @home,
121// owned by region:@home, and the source's location park in ie; nothing is
122// queued under uk or "".
123func TestMoveRecoveryCommitIntoHome(t *testing.T) {
124 w := newLossWorld(t, "landing", func(c *hostclaim.Claim, r *provision.Record, _ *AppAdmission) {
125 c.Op.Phase = hostclaim.PhaseLandingProbed
126 c.Op.Intent["to"], c.Op.Intent["home_region"] = park.HomeRegion, "uk"
127 r.Move.State = provision.MoveCommitted
128 r.Move.CommittedAt = r.Move.FlippedAt
129 r.Move.To, r.Region = "", ""
130 })
131 // The console names the same home (CONSOLE_HOME_REGION), as the
132 // operation's binding requires.
133 w.control.homeRegion = "uk"
134 before := w.claim(t)
135 if len(before.Claim.Obligations) != 0 {
136 t.Fatalf("fixture: the claim already owes %+v", before.Claim.Obligations)
137 }
138 rec, _ := w.record(t)
139 err := w.control.RunRecovery(context.Background(), func(ctx context.Context) error {
140 return runMoveRecovery(ctx, before, func(ctx context.Context, g *MoveRecoveryGrant) error {
141 return g.Claim(ctx, RecoveryMoveCommit)
142 })
143 })
144 after := w.claim(t)
145 if err != nil || after.Claim.Op.Phase != hostclaim.PhaseCommitted {
146 t.Fatalf("commit: %v, claim=%+v", err, after.Claim.Op)
147 }
148 source, staging, err := moves.CommitScopes(before.Claim, rec.Move.FlippedAt)
149 if err != nil {
150 t.Fatal(err)
151 }
152 var lane, loc bool
153 for _, o := range after.Claim.Obligations {
154 if o.Region == "" || o.Region == "uk" {
155 t.Fatalf("a chore named %q: %+v", o.Region, o)
156 }
157 switch {
158 case o.Kind == "park-replica" && o.Park != nil && *o.Park == staging:
159 if o.Region != park.HomeRegion || o.Owner != "region:"+park.HomeRegion {
160 t.Fatalf("the lane park %+v, want it in %s", o, park.HomeRegion)
161 }
162 lane = true
163 case o.Kind == "park-replica" && o.Park != nil && *o.Park == source:
164 if o.Region != "ie" || o.Owner != "region:ie" {
165 t.Fatalf("the source's location park %+v, want it in ie", o)
166 }
167 loc = true
168 }
169 }
170 if !lane || !loc {
171 t.Fatalf("the commit's parks: lane %v location %v in %+v", lane, loc, after.Claim.Obligations)
172 }
173 if after.Claim.Op.Intent["to"] != park.HomeRegion {
174 t.Fatalf("the op's to after the commit: %+v", after.Claim.Op.Intent)
175 }
176}
177