carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1// canary_region_test.go
2package main
3
4import (
5 "errors"
6 "testing"
7)
8
9// records is a fake single-record GET: a host it holds is found, any other
10// is a 404 (found false), and err fails every read.
11func records(err error, recs ...apiInstanceRecord) (func(string) (apiInstanceRecord, bool, error), *[]string) {
12 var asked []string
13 return func(host string) (apiInstanceRecord, bool, error) {
14 asked = append(asked, host)
15 if err != nil {
16 return apiInstanceRecord{}, false, err
17 }
18 for _, r := range recs {
19 if r.Host == host {
20 return r, true, nil
21 }
22 }
23 return apiInstanceRecord{}, false, nil
24 }, &asked
25}
26
27func TestCanaryRegionCheck(t *testing.T) {
28 names := []apiRegionEntry{{Code: "ie", Name: "P-ie"}, {Code: "uk", Name: "P-uk"}}
29 known := func(d apiAppDefault) *apiAppDefault {
30 d.RegionKnown, d.PlacementKnown, d.InstanceDomain = true, true, "go.tito.io"
31 return &d
32 }
33 plain := apiRegionsResult{Regions: names, Default: "ie", AppDefault: known(apiAppDefault{Region: "uk", Effective: "uk"})}
34 fleet := apiRegionsResult{Regions: names, Default: "ie", AppDefault: known(apiAppDefault{Region: "uk", Effective: "fleet/acme", Reason: "fleet"})}
35 older := apiRegionsResult{Regions: names, Default: "ie"} // no app_default
36 unread := apiRegionsResult{Regions: names, Default: "ie", AppDefault: &apiAppDefault{Region: "uk", Effective: "uk", RegionKnown: true, Reason: "policy-unreadable"}}
37 noDomain := apiRegionsResult{Regions: names, Default: "ie", AppDefault: &apiAppDefault{Region: "uk", Effective: "uk", RegionKnown: true, PlacementKnown: true}}
38 regionUnknownFleet := apiRegionsResult{Regions: names, Default: "ie", AppDefault: &apiAppDefault{PlacementKnown: true, Reason: "fleet", InstanceDomain: "go.tito.io"}}
39 regionUnknown := apiRegionsResult{Regions: names, Default: "ie", AppDefault: &apiAppDefault{PlacementKnown: true, InstanceDomain: "go.tito.io"}}
40 boom := errors.New("timeout")
41 const host = "c-blog.go.tito.io"
42 existingUK := apiInstanceRecord{Host: host, Region: "uk"}
43 existingHome := apiInstanceRecord{Host: host, Region: ""}
44 other := apiInstanceRecord{Host: "d-blog.go.tito.io", Region: "uk"}
45 cases := []struct {
46 name string
47 res apiRegionsResult
48 err error
49 recs []apiInstanceRecord
50 readErr error
51 asked string
52 want string
53 }{
54 {"no flag", fleet, boom, []apiInstanceRecord{existingUK}, nil, "", ""},
55 {"new canary", plain, nil, nil, nil, "uk", ""},
56 {"another canary is not this one", plain, nil, []apiInstanceRecord{other}, nil, "ie", ""},
57 {"existing, same", plain, nil, []apiInstanceRecord{existingUK}, nil, "uk", ""},
58 {"existing home read as its name", plain, nil, []apiInstanceRecord{existingHome}, nil, "ie", ""},
59 {"existing, different, named by place", plain, nil, []apiInstanceRecord{existingUK}, nil, "ie", canaryRegionMismatch(host, "P-uk")},
60 {"fleet, first run", fleet, nil, nil, nil, "uk", canaryRegionOnFleet("blog", "acme")},
61 {"fleet, repeat", fleet, nil, []apiInstanceRecord{existingUK}, nil, "uk", canaryRegionOnFleet("blog", "acme")},
62 {"older console, first run", older, nil, nil, nil, "uk", canaryFleetUnknown("blog")},
63 {"older console, repeat", older, nil, []apiInstanceRecord{existingUK}, nil, "uk", canaryFleetUnknown("blog")},
64 {"read failed", plain, boom, nil, nil, "uk", canaryFleetUnknown("blog")},
65 // codex plan-R2 3: a 200 whose placement the console could not read.
66 {"placement unknown", unread, nil, nil, nil, "uk", canaryFleetUnknown("blog")},
67 // codex plan-R3 1: the canary's own record is read, never inferred
68 // from a list; a failed read or an unknown domain refuses.
69 {"record read failed", plain, nil, []apiInstanceRecord{existingUK}, boom, "uk", canaryRegionUnconfirmed("c")},
70 {"no instance domain", noDomain, nil, nil, nil, "uk", canaryRegionUnconfirmed("c")},
71 // codex plan-R4 1, R9a: with the stored region unread, effective is
72 // empty, so a fleet cannot be seen; the flag is refused either way.
73 {"region unknown, fleet", regionUnknownFleet, nil, nil, nil, "uk", canaryFleetUnknown("blog")},
74 {"region unknown", regionUnknown, nil, nil, nil, "uk", canaryFleetUnknown("blog")},
75 }
76 for _, c := range cases {
77 get, asked := records(c.readErr, c.recs...)
78 pre, err := canaryRegionCheck(c.res, c.err, "blog", "c", c.asked, get)
79 got := ""
80 if err != nil {
81 got = err.Error()
82 }
83 if got != c.want {
84 t.Errorf("%s: %q, want %q", c.name, got, c.want)
85 }
86 if len(*asked) > 1 || (len(*asked) == 1 && (*asked)[0] != host) {
87 t.Errorf("%s: read %v, want at most one read of %s", c.name, *asked, host)
88 }
89 if c.want == "" && c.asked != "" && pre.Host != host {
90 t.Errorf("%s: checked %q, want %q", c.name, pre.Host, host)
91 }
92 if c.want == "" && c.asked != "" && pre.Found != (len(c.recs) > 0 && c.recs[0].Host == host) {
93 t.Errorf("%s: found = %v, want the read's own answer", c.name, pre.Found)
94 }
95 }
96}
97
98// codex plan-R5 1: with --region, the direct read decides the plan, even
99// when the capped list does not show the record at all.
100func TestCanaryPlanFor(t *testing.T) {
101 const host, ch = "c-blog.go.tito.io", "canary/c"
102 listed := []apiInstanceRecord{{Host: host, Channel: ch}}
103 cases := []struct {
104 name string
105 pre canaryPreflight
106 recs []apiInstanceRecord
107 want canaryPlan
108 }{
109 {"no --region: the list decides", canaryPreflight{}, listed, canaryPlanReady},
110 {"no --region, not listed", canaryPreflight{}, nil, canaryPlanCreate},
111 {"read found it, list did not, same channel", canaryPreflight{Host: host, Found: true, Rec: apiInstanceRecord{Host: host, Channel: ch}}, nil, canaryPlanReady},
112 {"read found it, list did not, other channel", canaryPreflight{Host: host, Found: true, Rec: apiInstanceRecord{Host: host, Channel: "canary/old"}}, nil, canaryPlanRechannel},
113 {"read found none", canaryPreflight{Host: host}, listed, canaryPlanCreate},
114 }
115 for _, c := range cases {
116 if got := canaryPlanFor(c.pre, c.recs, host, ch); got != c.want {
117 t.Errorf("%s: %v, want %v", c.name, got, c.want)
118 }
119 }
120}
121
122func TestInstanceCreatedLine(t *testing.T) {
123 r := apiInstanceRecord{Host: "a.go.tito.io", Channel: "stable", RegionName: "P-uk"}
124 if got := instanceCreatedLine(r, ""); got != "a.go.tito.io ("+instanceCreatedSuffix("stable", "P-uk")+")" {
125 t.Fatalf("got %q", got)
126 }
127 env := environmentSuffix("acme")
128 if got := instanceCreatedLine(r, env); got != "a.go.tito.io ("+instanceCreatedSuffix("stable", "P-uk")+env+")" {
129 t.Fatalf("with environment = %q", got)
130 }
131 r.RegionName = ""
132 if got := instanceCreatedLine(r, env); got != "a.go.tito.io (channel stable"+env+")" {
133 t.Fatalf("an old console's record = %q, want today's line byte for byte", got)
134 }
135}
136