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 "context"
7 "os"
8 "path/filepath"
9 "slices"
10 "strings"
11 "testing"
12)
13
14var plan9Fix2RuntimeMaskDefault = claimEdgeRuntimeMask
15
16// plan9Fix2Systemctl fakes systemctl for a stopped edge whose unit file state
17// is enabled. It records every call.
18func plan9Fix2Systemctl(t *testing.T, enabled string, calls *[]string) {
19 t.Helper()
20 if claimEdgeRuntimeMask == plan9Fix2RuntimeMaskDefault {
21 restoreMask := claimEdgeRuntimeMask
22 t.Cleanup(func() { claimEdgeRuntimeMask = restoreMask })
23 claimEdgeRuntimeMask = filepath.Join(t.TempDir(), "carlos-edge.service")
24 }
25 if enabled == "masked-runtime" {
26 if _, err := os.Lstat(claimEdgeRuntimeMask); os.IsNotExist(err) {
27 if err = os.Symlink("/dev/null", claimEdgeRuntimeMask); err != nil {
28 t.Fatal(err)
29 }
30 } else if err != nil {
31 t.Fatal(err)
32 }
33 }
34 restore := claimSystemctl
35 t.Cleanup(func() { claimSystemctl = restore })
36 restoreOwner := claimQuiesceOwner
37 t.Cleanup(func() { claimQuiesceOwner = restoreOwner })
38 claimQuiesceOwner = func() (int, int, error) { return 1 << 30, 1 << 30, nil }
39 claimSystemctl = func(_ context.Context, args ...string) ([]byte, error) {
40 *calls = append(*calls, strings.Join(args, " "))
41 switch args[0] {
42 case "is-enabled":
43 return []byte(enabled + "\n"), nil
44 case "show":
45 return []byte("inactive\n"), nil
46 case "mask":
47 return nil, os.Symlink("/dev/null", claimEdgeRuntimeMask)
48 case "unmask":
49 err := os.Remove(claimEdgeRuntimeMask)
50 if os.IsNotExist(err) {
51 err = nil
52 }
53 return nil, err
54 }
55 return nil, nil
56 }
57}
58
59func plan9Fix2MaskOwner(t *testing.T) string {
60 t.Helper()
61 restore := claimEdgeMaskOwner
62 t.Cleanup(func() { claimEdgeMaskOwner = restore })
63 claimEdgeMaskOwner = filepath.Join(t.TempDir(), "edge-mask")
64 return claimEdgeMaskOwner
65}
66
67func plan9Fix2Boot(t *testing.T) string {
68 t.Helper()
69 boot, err := os.ReadFile("/proc/sys/kernel/random/boot_id")
70 if err != nil {
71 t.Fatal(err)
72 }
73 return strings.TrimSpace(string(boot))
74}
75
76func plan11Rev4WriteOwnedMask(t *testing.T, owner string) claimEdgeMaskRecord {
77 t.Helper()
78 token := strings.Repeat("a", 32)
79 anchor := claimEdgeMaskAnchor(token)
80 if err := os.Link(claimEdgeRuntimeMask, anchor); err != nil {
81 t.Fatal(err)
82 }
83 record, err := currentClaimEdgeMask(anchor, plan9Fix2Boot(t), token)
84 if err != nil {
85 t.Fatal(err)
86 }
87 if err = writeClaimEdgeMaskRecord(record); err != nil {
88 t.Fatal(err)
89 }
90 if owner != claimEdgeMaskOwner {
91 t.Fatalf("owner fixture drifted: %q != %q", owner, claimEdgeMaskOwner)
92 }
93 return record
94}
95
96// m-7: a runtime mask left by a migration that was killed while masked is
97// recognised as the migration's own and lifted by the next attempt.
98func TestPlan9Fix2QuiesceLiftsMaskLeftByCrashedAttempt(t *testing.T) {
99 var calls []string
100 plan9Fix2Systemctl(t, "masked-runtime", &calls)
101 owner := plan9Fix2MaskOwner(t)
102 plan11Rev4WriteOwnedMask(t, owner)
103 release, err := quiesceLegacyClaimJournals(t.Context())
104 if err != nil {
105 t.Fatal(err)
106 }
107 release()
108 if !slices.Contains(calls, "unmask --runtime carlos-edge.service") {
109 t.Fatalf("mask left by a crashed migration not lifted: %v", calls)
110 }
111 if _, err = os.Stat(owner); !os.IsNotExist(err) {
112 t.Fatalf("mask record kept after the mask was lifted: %v", err)
113 }
114}
115
116// The durable record identifies the exact private anchor that is linked into
117// the unit name before systemd reloads its view.
118func TestPlan9Fix2QuiesceRecordsConcreteMaskObject(t *testing.T) {
119 var calls []string
120 plan9Fix2Systemctl(t, "enabled", &calls)
121 owner := plan9Fix2MaskOwner(t)
122 restore := claimSystemctl
123 claimSystemctl = func(ctx context.Context, args ...string) ([]byte, error) {
124 if args[0] == "daemon-reload" {
125 raw, err := os.ReadFile(owner)
126 record, recorded := decodeClaimEdgeMaskRecord(raw, plan9Fix2Boot(t))
127 if err != nil || !recorded {
128 t.Errorf("mask identity not recorded before reload: %q %v", raw, err)
129 } else if ours, identityErr := claimEdgeMaskStillOwned(record); identityErr != nil || !ours {
130 t.Errorf("record does not own concrete mask: %v %v", ours, identityErr)
131 }
132 }
133 return restore(ctx, args...)
134 }
135 release, err := quiesceLegacyClaimJournals(t.Context())
136 if err != nil {
137 t.Fatal(err)
138 }
139 release()
140 if !slices.Contains(calls, "daemon-reload") || !slices.Contains(calls, "unmask --runtime carlos-edge.service") {
141 t.Fatalf("calls: %v", calls)
142 }
143 if _, err = os.Stat(owner); !os.IsNotExist(err) {
144 t.Fatalf("mask record kept: %v", err)
145 }
146}
147
148// m-7: an operator's runtime mask, or one with a record from another boot,
149// is never lifted.
150func TestPlan9Fix2QuiesceKeepsOperatorMask(t *testing.T) {
151 for _, record := range []string{"", "another-boot"} {
152 var calls []string
153 plan9Fix2Systemctl(t, "masked-runtime", &calls)
154 owner := plan9Fix2MaskOwner(t)
155 if record != "" {
156 if err := os.WriteFile(owner, []byte(record), 0600); err != nil {
157 t.Fatal(err)
158 }
159 }
160 release, err := quiesceLegacyClaimJournals(t.Context())
161 if err != nil {
162 t.Fatal(err)
163 }
164 release()
165 for _, call := range calls {
166 if strings.HasPrefix(call, "unmask") || strings.HasPrefix(call, "mask") {
167 t.Fatalf("record %q: operator mask touched: %v", record, calls)
168 }
169 }
170 if _, err = os.Stat(owner); !os.IsNotExist(err) {
171 t.Fatalf("stale record kept: %v", err)
172 }
173 }
174}
175