carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1//go:build unix
2
3package hostguard
4
5import (
6 "context"
7 "encoding/json"
8 "errors"
9
10 "github.com/carlosframework/platform/internal/hostclaim"
11 "testing"
12)
13
14// Fix round 1, finding 1 (and round 2): an obsolete pending intent is settled into a
15// quarantine the migration census may inspect, while every execution read
16// still refuses it. A landed commit is recorded as the commit would have
17// recorded it; an unlanded one leaves the record's installation.
18func TestSettleObsoleteRootInventory(t *testing.T) {
19 for _, landed := range []bool{true, false} {
20 name := "unlanded"
21 if landed {
22 name = "landed"
23 }
24 t.Run(name, func(t *testing.T) {
25 ctx := t.Context()
26 f, target, captured := fenceFixture(t)
27 f.obs.Claim.Holder.Account, f.obs.Claim.Holder.App = "bab", "console"
28 f.g.Root = NewRootAuthority(&rootTestStore{dir: t.TempDir()})
29 in := RootInstallation{Host: target.Host, Incarnation: captured.Incarnation, Stamp: captured.Stamp, Account: "bab", App: "console", Record: "record", Box: target.Box, Enrollment: target.Enrollment, Migration: 1, InventoryRevision: 1}
30 if err := f.g.EstablishRoot(ctx, in, allow); err != nil {
31 t.Fatal(err)
32 }
33 before := in
34 in.InventoryRevision++
35 fault := errors.New("interrupted")
36 if err := f.g.CommitRootInventory(ctx, in, []byte("exact"), allow, nil, func(RootInstallation) error { return fault }); !errors.Is(err, fault) {
37 t.Fatal(err)
38 }
39 if err := f.g.SettleObsoleteRootInventory(ctx, target.Host, []byte("forged"), func(context.Context, RootInstallation) (bool, error) { return landed, nil }); !errors.Is(err, ErrInvalidInput) {
40 t.Fatal("forged intent settled:", err)
41 }
42 var got RootInstallation
43 if err := f.g.SettleObsoleteRootInventory(ctx, target.Host, []byte("exact"), func(_ context.Context, p RootInstallation) (bool, error) { got = p; return landed, nil }); err != nil {
44 t.Fatal(err)
45 }
46 if got != in {
47 t.Fatalf("applied asked about %+v, want the pending %+v", got, in)
48 }
49 r, err := f.g.Root.read(target.Host)
50 if err != nil || !r.quarantined || !r.settled || r.pendingInstallation != nil {
51 t.Fatalf("after settlement: %+v %v", r, err)
52 }
53 want := before
54 if landed {
55 want = in
56 }
57 if r.installation != want {
58 t.Fatalf("installation %+v, want %+v", r.installation, want)
59 }
60 // Execution reads refuse; the census lists it, marked Settled.
61 if _, err := f.g.Root.View(ctx, target.Host, captured); !errors.Is(err, ErrFenced) {
62 t.Fatal("execution view of a settled installation:", err)
63 }
64 if err := r.admits(f.obs.Claim, captured); !errors.Is(err, ErrFenced) {
65 t.Fatal("admission of a settled installation:", err)
66 }
67 views, err := f.g.Root.MigrationInstallations(ctx)
68 if err != nil || len(views) != 1 || !views[0].Settled || views[0].Installation != want {
69 t.Fatalf("census: %+v %v", views, err)
70 }
71 // Settled without the quarantine is malformed.
72 raw, err := f.g.Root.store.Read(target.Host + ".json")
73 if err != nil {
74 t.Fatal(err)
75 }
76 var saved map[string]any
77 if err := json.Unmarshal(raw, &saved); err != nil {
78 t.Fatal(err)
79 }
80 delete(saved, "Quarantined")
81 forged, _ := json.Marshal(saved)
82 if err := f.g.Root.store.Write(target.Host+".json", forged); err != nil {
83 t.Fatal(err)
84 }
85 if _, err := f.g.Root.read(target.Host); !errors.Is(err, ErrMalformedRecord) {
86 t.Fatal("settled without quarantine:", err)
87 }
88 })
89 }
90
91 // The superseded-claim abandonment ends in the same terminal state (fix
92 // round 2): it keeps its exact-intent and fresh-claim checks, reconciles a
93 // landed commit, and leaves an installation the census can inspect and
94 // execution still refuses.
95 for _, landed := range []bool{true, false} {
96 name := "abandoned-unlanded"
97 if landed {
98 name = "abandoned-landed"
99 }
100 t.Run(name, func(t *testing.T) {
101 ctx := t.Context()
102 f, target, captured := fenceFixture(t)
103 f.obs.Claim.Holder.Account, f.obs.Claim.Holder.App = "bab", "console"
104 f.g.Root = NewRootAuthority(&rootTestStore{dir: t.TempDir()})
105 in := RootInstallation{Host: target.Host, Incarnation: captured.Incarnation, Stamp: captured.Stamp, Account: "bab", App: "console", Record: "record", Box: target.Box, Enrollment: target.Enrollment, Migration: 1, InventoryRevision: 1}
106 if err := f.g.EstablishRoot(ctx, in, allow); err != nil {
107 t.Fatal(err)
108 }
109 before := in
110 in.InventoryRevision++
111 fault := errors.New("interrupted")
112 if err := f.g.CommitRootInventory(ctx, in, []byte("exact"), allow, nil, func(RootInstallation) error { return fault }); !errors.Is(err, fault) {
113 t.Fatal(err)
114 }
115 answer := func(context.Context, RootInstallation) (bool, error) { return landed, nil }
116 if err := f.g.AbandonRootInventory(ctx, target.Host, []byte("forged"), func(*hostclaim.Claim) bool { return true }, answer); !errors.Is(err, ErrInvalidInput) {
117 t.Fatal("forged intent abandoned:", err)
118 }
119 if err := f.g.AbandonRootInventory(ctx, target.Host, []byte("exact"), func(*hostclaim.Claim) bool { return false }, answer); !errors.Is(err, ErrFenced) {
120 t.Fatal("unsuperseded intent abandoned:", err)
121 }
122 if pending, err := f.g.Root.PendingInstallations(); err != nil || len(pending) != 1 {
123 t.Fatalf("refused abandonment changed the intent: %d %v", len(pending), err)
124 }
125 if err := f.g.AbandonRootInventory(ctx, target.Host, []byte("exact"), func(*hostclaim.Claim) bool { return true }, answer); err != nil {
126 t.Fatal(err)
127 }
128 r, err := f.g.Root.read(target.Host)
129 if err != nil || !r.quarantined || !r.settled || r.pendingInstallation != nil {
130 t.Fatalf("after abandonment: %+v %v", r, err)
131 }
132 want := before
133 if landed {
134 want = in
135 }
136 if r.installation != want {
137 t.Fatalf("installation %+v, want %+v", r.installation, want)
138 }
139 if _, err := f.g.Root.View(ctx, target.Host, captured); !errors.Is(err, ErrFenced) {
140 t.Fatal("execution view of an abandoned installation:", err)
141 }
142 if err := r.admits(f.obs.Claim, captured); !errors.Is(err, ErrFenced) {
143 t.Fatal("admission of an abandoned installation:", err)
144 }
145 views, err := f.g.Root.MigrationInstallations(ctx)
146 if err != nil || len(views) != 1 || !views[0].Settled || views[0].Installation != want {
147 t.Fatalf("census of an abandoned installation: %+v %v", views, err)
148 }
149 })
150 }
151}
152
153// unlanded is an applied answer for an intent whose commit never landed.
154func unlanded(context.Context, RootInstallation) (bool, error) { return false, nil }
155