carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package park
2
3import (
4 "reflect"
5 "strings"
6 "testing"
7
8 "github.com/carlosframework/platform/internal/hostclaim"
9)
10
11func TestInstanceParkPreservesStaging(t *testing.T) {
12 for _, legacy := range []bool{true, false} {
13 name := "incarnation"
14 if legacy {
15 name = "legacy"
16 }
17 t.Run(name, func(t *testing.T) {
18 f := newFixture(t)
19 if legacy {
20 f.ob.Park.Location = "instances/" + f.w.Host
21 }
22 obs, err := hostclaim.Read(t.Context(), f.e.Claims, f.w.Host)
23 if err != nil {
24 t.Fatal(err)
25 }
26 _, err = hostclaim.Update(t.Context(), f.e.Claims, obs, func(c *hostclaim.Claim) error {
27 c.Holder.Location = f.ob.Park.Location
28 c.Op = hostclaim.Op{Kind: hostclaim.KindLanding, ID: "move-1", Phase: "parking", Exec: "target"}
29 c.Obligations = []hostclaim.Obligation{f.ob}
30 return nil
31 })
32 if err != nil {
33 t.Fatal(err)
34 }
35 source := f.seed()
36 for _, op := range []string{"move-1", f.ob.Park.Incarnation} {
37 p := "moves/" + f.w.Host + "/" + op + "/"
38 for _, key := range []string{"replica/0000/data", "seal.json"} {
39 f.b.Put("data", p+key, []byte("old"))
40 f.b.Put("data", p+key, []byte("sealed"))
41 }
42 f.b.BareDelete("data", p+"replica/0000/data")
43 }
44 child := "instances/" + f.w.Host + "/" + strings.Repeat("b", 64) + "/0000/data"
45 childID := f.b.Put("data", child, []byte("other incarnation"))
46 staging, err := f.b.ListVersions(t.Context(), "data", "moves/")
47 if err != nil {
48 t.Fatal(err)
49 }
50 f.b.FailOn = func(action, key string) error {
51 if action == "list" && !strings.HasPrefix(key, "parked/") && key != f.ob.Park.Location+"/" {
52 t.Errorf("instance park listed %q", key)
53 return ErrUnsafe
54 }
55 return nil
56 }
57 if err := f.e.Run(t.Context(), f.w); err != nil {
58 t.Fatal(err)
59 }
60 f.done(t)
61 m, err := f.e.manifest(t.Context(), f.w, f.ob)
62 if err != nil || m == nil || !reflect.DeepEqual(m.Delete, source) {
63 t.Fatalf("manifest = %+v, error = %v", m, err)
64 }
65 f.b.FailOn = nil
66 after, err := f.b.ListVersions(t.Context(), "data", "moves/")
67 if err != nil || !reflect.DeepEqual(after, staging) {
68 t.Fatalf("staging changed: %+v, error = %v", after, err)
69 }
70 if body, err := f.b.GetVersion(t.Context(), "data", child, childID); err != nil || string(body) != "other incarnation" {
71 t.Fatalf("child incarnation changed: %q, error = %v", body, err)
72 }
73 })
74 }
75}
76
77func TestInstanceScopeExcludesMovesKeys(t *testing.T) {
78 f := newFixture(t)
79 for _, location := range []string{"instances/" + f.w.Host, f.ob.Park.Location} {
80 for _, op := range []string{"move-1", f.ob.Park.Incarnation} {
81 key := "moves/" + f.w.Host + "/" + op + "/replica/0000/data"
82 if inScope, _ := scopeContains(f.w.Host, location, key); inScope {
83 t.Errorf("%q includes %q", location, key)
84 }
85 }
86 }
87}
88