carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package hostclaim
2
3import (
4 "errors"
5 "strings"
6 "testing"
7 "time"
8
9 "github.com/carlosframework/platform/internal/release"
10)
11
12func TestParkScopeAndHolderlessSweep(t *testing.T) {
13 c := &Claim{V: 2, Host: "shop.bab.example.com", Gen: 1, Op: Op{Kind: KindParking, ID: "sweep", Intent: map[string]string{"park_sweep": "v1"}}}
14 c.Obligations = []Obligation{{ID: "ob", Op: "sweep", Kind: "park-replica", Region: "ie", Retirement: "rt", Owner: "region:ie", Park: &ParkScope{Location: "instances/" + c.Host + "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", Incarnation: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", EvidenceAt: time.Now(), RequestLimit: time.Second}}}
15 if err := c.Validate(); err != nil {
16 t.Fatal(err)
17 }
18 for _, change := range []func(*Claim){
19 func(c *Claim) { c.Obligations[0].Park = nil },
20 func(c *Claim) { c.Op.Exec = "box" },
21 func(c *Claim) { c.Obligations[0].Op = "another" },
22 func(c *Claim) { c.Op.Intent = nil },
23 func(c *Claim) { c.Obligations[0].Park.RequestLimit = 0 },
24 func(c *Claim) { c.Obligations[0].Park.EvidenceAt = time.Time{} },
25 func(c *Claim) { c.Obligations[0].Park.Location = "instances/other.example" },
26 } {
27 copy := *c
28 copy.Obligations = append([]Obligation(nil), c.Obligations...)
29 scope := *c.Obligations[0].Park
30 copy.Obligations[0].Park = &scope
31 change(&copy)
32 if err := copy.Validate(); err == nil {
33 t.Fatal("invalid sweep admitted")
34 }
35 }
36}
37
38func TestParkScopeLocationGrammar(t *testing.T) {
39 host := "shop.bab.example.com"
40 inc := strings.Repeat("a", 64)
41 instances, moves := "instances/"+host, "moves/"+host
42 for _, tc := range []struct {
43 location string
44 valid bool
45 }{
46 {instances, true},
47 {instances + "/" + inc, true},
48 {moves, true},
49 {moves + "/move-1", true},
50 {moves + "/" + strings.Repeat("b", 64), true},
51 {instances + "/", false},
52 {instances + "/" + inc + "/", false},
53 {instances + "/" + inc + "/x", false},
54 {instances + "/" + strings.Repeat("b", 64), false},
55 {moves + "/", false},
56 {moves + "/move-1/", false},
57 {moves + "/move-1/x", false},
58 {moves + "/.", false},
59 {moves + "/..", false},
60 {moves + "//move-1", false},
61 {"moves/other.example/move-1", false},
62 {"instances/other.example", false},
63 {"other/" + host, false},
64 } {
65 t.Run(tc.location, func(t *testing.T) {
66 c := &Claim{V: 2, Host: host, Gen: 1, Op: Op{Kind: KindParking, ID: "sweep", Intent: map[string]string{"park_sweep": "v1"}}}
67 c.Obligations = []Obligation{{ID: "ob", Op: "sweep", Kind: "park-replica", Region: "ie", Retirement: "rt", Owner: "region:ie", Park: &ParkScope{Location: tc.location, Incarnation: inc, EvidenceAt: time.Now(), RequestLimit: time.Second}}}
68 err := c.Validate()
69 if tc.valid && err != nil {
70 t.Fatalf("valid scope rejected: %v", err)
71 }
72 if !tc.valid && !errors.Is(err, ErrMalformed) {
73 t.Fatalf("invalid scope: %v", err)
74 }
75 })
76 }
77 for _, location := range []string{instances, instances + "/" + strings.ToUpper(inc), moves, moves + "/move-1"} {
78 t.Run("uppercase-archive/"+location, func(t *testing.T) {
79 c := &Claim{V: 2, Host: host, Gen: 1, Op: Op{Kind: KindParking, ID: "sweep", Intent: map[string]string{"park_sweep": "v1"}}}
80 c.Obligations = []Obligation{{ID: "ob", Op: "sweep", Kind: "park-replica", Region: "ie", Retirement: "rt", Owner: "region:ie", Park: &ParkScope{Location: location, Incarnation: strings.ToUpper(inc), EvidenceAt: time.Now(), RequestLimit: time.Second}}}
81 if err := c.Validate(); !errors.Is(err, ErrMalformed) {
82 t.Fatalf("uppercase archive incarnation accepted: %v", err)
83 }
84 })
85 }
86}
87
88func TestHolderlessSweepJoinsRegion(t *testing.T) {
89 host := "shop.bab.example.com"
90 st := release.NewDirStore(t.TempDir())
91 chore := Obligation{ID: "ie-ob", Op: "sweep", Kind: "park-replica", Region: "ie", Retirement: "ie-rt", Owner: "region:ie", Park: &ParkScope{Location: "moves/" + host, Incarnation: strings.Repeat("a", 64), EvidenceAt: time.Now(), RequestLimit: time.Second}}
92 obs, err := Update(t.Context(), st, Observed{Host: host, Absent: true}, func(c *Claim) error {
93 c.Op = Op{Kind: KindParking, ID: "sweep", Intent: map[string]string{"park_sweep": "v1"}}
94 c.Obligations = []Obligation{chore}
95 return nil
96 })
97 if err != nil {
98 t.Fatal(err)
99 }
100 joined := chore
101 joined.ID, joined.Region, joined.Retirement, joined.Owner = "uk-ob", "uk", "uk-rt", "region:uk"
102 obs, err = Update(t.Context(), st, obs, func(c *Claim) error {
103 c.Obligations = append(c.Obligations, joined)
104 return nil
105 })
106 if err != nil {
107 t.Fatal(err)
108 }
109 if obs.Claim.Free() || obs.Claim.Holder != nil || obs.Claim.Op.ID != "sweep" || len(obs.Claim.Obligations) != 2 {
110 t.Fatalf("invalid joined sweep: %+v", obs.Claim)
111 }
112 _, err = Update(t.Context(), st, obs, func(c *Claim) error {
113 c.Obligations[1].Op = "other-sweep"
114 return nil
115 })
116 if !errors.Is(err, ErrMalformed) {
117 t.Fatalf("joined region with a different op accepted: %v", err)
118 }
119}
120