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 linux
2
3package host
4
5import (
6 "bytes"
7 "context"
8 "errors"
9 "net"
10 "os"
11 "path/filepath"
12 "runtime"
13 "testing"
14
15 "github.com/carlosframework/platform/internal/hostclaim"
16
17 "github.com/carlosframework/platform/internal/release"
18)
19
20func TestPlan14GenerationRelocationDefaultMaterializer(t *testing.T) {
21 for _, mode := range []string{"fresh", "staged", "damaged", "already-live", "claims-off"} {
22 t.Run(mode, func(t *testing.T) {
23 f := newInstallFixture(t, nil)
24 f.cfg.materialize = nil
25 f.cfg.verifyLive = nil
26 f.cfg.ReleasePub = hsPub
27 f.cfg.Ratchet = hsRatchet(t)
28 platform := runtime.GOOS + "-" + runtime.GOARCH
29 artifact := []byte("signed relocation artifact")
30 if err := release.Ship(t.Context(), f.claims, "acct", release.Manifest{App: "app", Version: "v1", Kind: "binary", Artifacts: map[string]release.Artifact{platform: {}}}, map[string][]byte{platform: artifact}); err != nil {
31 t.Fatal(err)
32 }
33 if err := release.Promote(t.Context(), f.claims, hsPriv, "acct", "app", "canary/x", "v1"); err != nil {
34 t.Fatal(err)
35 }
36 path := release.VersionPath(f.r.OptDir, "acct", "v1", "app")
37 if err := os.Remove(path); err != nil {
38 t.Fatal(err)
39 }
40 if mode == "staged" || mode == "damaged" || mode == "already-live" {
41 // This positive control verifies the exact signed fixture independently
42 // of the relocation install, whose default materializer is under test.
43 rt, err := relocationRecord(t.Context(), f.r.DataDir, f.claims, f.read())
44 if err != nil {
45 t.Fatal(err)
46 }
47 held := rt.Route
48 held.HoldOp = f.read().Claim.Op.ID
49 if _, err := release.StageHeldVerified(t.Context(), f.claims, hsPub, f.cfg.Ratchet, f.r.OptDir, held, "v1", offProofGate(t)); err != nil {
50 t.Fatal(err)
51 }
52 }
53 if mode == "already-live" {
54 f.cfg.materialize = f.materialize
55 if _, err := f.install(); err != nil {
56 t.Fatal(err)
57 }
58 f.cfg.materialize = nil
59 }
60 if mode == "damaged" {
61 if err := os.WriteFile(path, []byte("retained inode"), 0755); err != nil {
62 t.Fatal(err)
63 }
64 }
65 if mode == "claims-off" {
66 t.Setenv("CARLOS_HOST_CLAIM", "")
67 }
68 var before []byte
69 var identity os.FileInfo
70 if mode != "fresh" && mode != "claims-off" {
71 var err error
72 before, err = os.ReadFile(path)
73 if err != nil {
74 t.Fatal(err)
75 }
76 identity, err = os.Stat(path)
77 if err != nil {
78 t.Fatal(err)
79 }
80 }
81 receipt, err := f.install()
82 if mode == "already-live" || mode == "claims-off" {
83 if err != nil || receipt.JournalSHA256 == "" {
84 t.Fatalf("verified legacy/live install: %+v %v", receipt, err)
85 }
86 got, err := os.ReadFile(path)
87 if err != nil || !bytes.Equal(got, artifact) {
88 t.Fatalf("installed artifact: %q %v", got, err)
89 }
90 return
91 }
92 if !errors.Is(err, errHeldReleaseUnavailable) {
93 t.Errorf("unsupported root relocation must refuse before materializing: %+v %v", receipt, err)
94 }
95 if receipt.JournalSHA256 != "" {
96 t.Error("unsupported relocation returned completion")
97 }
98 if _, err := os.Lstat(release.LiveLink(f.r.OptDir, buildHost)); !errors.Is(err, os.ErrNotExist) {
99 t.Errorf("relocation published live: %v", err)
100 }
101 if mode == "fresh" {
102 if _, err := os.Stat(path); !errors.Is(err, os.ErrNotExist) {
103 t.Errorf("relocation staged without root pins: %v", err)
104 }
105 } else {
106 got, err := os.ReadFile(path)
107 after, statErr := os.Stat(path)
108 if err != nil || statErr != nil || !bytes.Equal(before, got) || !os.SameFile(identity, after) {
109 t.Errorf("retained artifact changed: %q %v %v", got, err, statErr)
110 }
111 }
112 journal, pathErr := relocationInstallPath(f.r.DataDir, f.read().Claim.Op.ID)
113 if pathErr != nil {
114 t.Fatal(pathErr)
115 }
116 if _, err := os.Stat(journal); !errors.Is(err, os.ErrNotExist) {
117 t.Errorf("refusal wrote completion journal: %v", err)
118 }
119 requests, err := filepath.Glob(filepath.Join(release.HeldStageDir(f.r.DataDir), "*"))
120 if err != nil || len(requests) != 0 {
121 t.Fatalf("unsupported operation queued legacy relay: %v %v", requests, err)
122 }
123 })
124 }
125}
126
127func TestPlan14GenerationRelocationRelayRefusal(t *testing.T) {
128 for _, action := range []string{heldReleaseStage, heldReleasePublish} {
129 for _, kind := range []string{hostclaim.KindRelocating, hostclaim.KindMoving, hostclaim.KindLanding, hostclaim.KindRestoring} {
130 t.Run(action+"/"+kind, func(t *testing.T) {
131 f := newHRFixture(t)
132 f.set(func(f *hrFixture) {
133 f.claim.Op.Kind = hostclaim.KindRelocating
134 f.claim.Op.Phase = hostclaim.PhaseInstalled
135 f.claim.Op.Journal = map[string]string{"install_stamp": "7", "install_release": "v7"}
136 f.rec.Move = nil
137 f.row.Status = "relocating"
138 })
139 f.root.Authenticate = func(context.Context, net.Conn) (StopPeer, error) { return hrPeer, nil }
140 client := newHeldReleaseRootClient(serveClaimRoot(t, f.root))
141 q := f.request(action)
142 q.Kind = kind
143 if _, err := client.HeldRelease(t.Context(), q); err == nil {
144 t.Fatal("unsupported relocation granted through root relay")
145 }
146 if _, err := os.Stat(release.VersionPath(f.opt, "bab", "v7", "app")); !errors.Is(err, os.ErrNotExist) {
147 t.Fatalf("root staged unsupported relocation: %v", err)
148 }
149 if _, err := os.Lstat(release.LiveLink(f.opt, p1Host)); !errors.Is(err, os.ErrNotExist) {
150 t.Fatalf("root published unsupported relocation: %v", err)
151 }
152 entries, err := os.ReadDir(f.receipts)
153 if err != nil || len(entries) != 0 {
154 t.Fatalf("root receipted unsupported relocation: %v %v", entries, err)
155 }
156 f.sel.mu.Lock()
157 defer f.sel.mu.Unlock()
158 if len(f.sel.selected) != 0 {
159 t.Fatalf("unsupported relocation selected work: %v", f.sel.selected)
160 }
161 })
162 }
163 }
164}
165