carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package release
2
3import (
4 "context"
5 "encoding/json"
6 "errors"
7 "os"
8 "strings"
9 "testing"
10 "time"
11)
12
13func testSystemRelease(v string) SystemRelease {
14 return SystemRelease{
15 Version: v,
16 Artifacts: map[string]SystemArtifact{
17 "linux-arm64": {Key: SystemArtifactKey(v, "linux-arm64"), SHA256: strings.Repeat("ab", 32)},
18 },
19 Source: "release:" + v,
20 ReleasedAt: time.Date(2026, 9, 6, 8, 0, 0, 0, time.UTC),
21 }
22}
23
24func TestSystemPointerRoundTrip(t *testing.T) {
25 priv, pub := testKeys(t)
26 s := NewDirStore(t.TempDir())
27 ctx := context.Background()
28 if _, _, err := GetSystemPointer(ctx, s, pub, SystemComponentRouter, "stable"); !errors.Is(err, os.ErrNotExist) {
29 t.Fatalf("missing pointer: err = %v, want ErrNotExist", err)
30 }
31 p, err := PromoteSystem(ctx, s, RootSigner(priv), SystemComponentRouter, "stable", testSystemRelease("v0.18.0"),
32 SystemPromoteOptions{Actor: "paul", Spread: 5 * time.Minute})
33 if err != nil {
34 t.Fatal(err)
35 }
36 if p.Current.Version != "v0.18.0" || p.Spread != "5m0s" || p.Schema != 1 || p.PromotedAt.IsZero() {
37 t.Fatalf("promoted pointer = %+v", p)
38 }
39 got, etag, err := GetSystemPointer(ctx, s, pub, SystemComponentRouter, "stable")
40 if err != nil || etag == "" {
41 t.Fatalf("get: %v etag=%q", err, etag)
42 }
43 if got.Current.Artifacts["linux-arm64"].SHA256 != strings.Repeat("ab", 32) {
44 t.Fatalf("artifact lost: %+v", got.Current)
45 }
46 if got.SpreadDuration() != 5*time.Minute {
47 t.Fatalf("spread = %v", got.SpreadDuration())
48 }
49 if len(got.Audit) != 1 || got.Audit[0].Actor != "paul" || got.Audit[0].Version != "v0.18.0" {
50 t.Fatalf("audit = %+v", got.Audit)
51 }
52}
53
54func TestSystemPromoteKeepsWholeReleaseInHistoryAndRollbackRestoresIt(t *testing.T) {
55 priv, pub := testKeys(t)
56 s := NewDirStore(t.TempDir())
57 ctx := context.Background()
58 sg := RootSigner(priv)
59 if _, err := PromoteSystem(ctx, s, sg, "router", "canary", testSystemRelease("v0.18.0"), SystemPromoteOptions{}); err != nil {
60 t.Fatal(err)
61 }
62 first, _, _ := GetSystemPointer(ctx, s, pub, "router", "canary")
63 time.Sleep(1100 * time.Millisecond) // PromotedAt is second-truncated; the rollback must be NEWER
64 if _, err := PromoteSystem(ctx, s, sg, "router", "canary", testSystemRelease("v0.19.0"), SystemPromoteOptions{}); err != nil {
65 t.Fatal(err)
66 }
67 p, _, _ := GetSystemPointer(ctx, s, pub, "router", "canary")
68 if len(p.History) != 1 || p.History[0].Version != "v0.18.0" || p.History[0].Artifacts["linux-arm64"].Key == "" {
69 t.Fatalf("history must carry the whole release: %+v", p.History)
70 }
71 time.Sleep(1100 * time.Millisecond)
72 rb, err := RollbackSystem(ctx, s, sg, "router", "canary", "paul")
73 if err != nil {
74 t.Fatal(err)
75 }
76 if rb.Current.Version != "v0.18.0" || rb.Current.Artifacts["linux-arm64"].Key != SystemArtifactKey("v0.18.0", "linux-arm64") {
77 t.Fatalf("rollback current = %+v", rb.Current)
78 }
79 if !rb.PromotedAt.After(first.PromotedAt) || !rb.PromotedAt.After(p.PromotedAt) {
80 t.Fatalf("a rollback is a NEW promote: promoted_at %v must be newer than %v and %v", rb.PromotedAt, first.PromotedAt, p.PromotedAt)
81 }
82 if len(rb.History) != 0 {
83 t.Fatalf("history after rollback = %+v", rb.History)
84 }
85 if _, err := RollbackSystem(ctx, s, sg, "router", "canary", "paul"); !errors.Is(err, ErrNoSystemHistory) {
86 t.Fatalf("second rollback err = %v", err)
87 }
88}
89
90func TestSystemPromoteSameVersionDoesNotGrowHistory(t *testing.T) {
91 priv, pub := testKeys(t)
92 s := NewDirStore(t.TempDir())
93 ctx := context.Background()
94 sg := RootSigner(priv)
95 for i := 0; i < 2; i++ {
96 if _, err := PromoteSystem(ctx, s, sg, "router", "stable", testSystemRelease("v1.0.0"), SystemPromoteOptions{}); err != nil {
97 t.Fatal(err)
98 }
99 }
100 p, _, _ := GetSystemPointer(ctx, s, pub, "router", "stable")
101 if len(p.History) != 0 {
102 t.Fatalf("re-promoting the running version must not push it into history: %+v", p.History)
103 }
104}
105
106func TestSystemPointerRefusesScopedSigner(t *testing.T) {
107 _, _, sg := scopedFixture(t, []string{RungCanary, RungEdge}, 30*24*time.Hour)
108 s := NewDirStore(t.TempDir())
109 _, err := PromoteSystem(context.Background(), s, sg, "router", "canary", testSystemRelease("v1.0.0"), SystemPromoteOptions{})
110 if err == nil || !strings.Contains(err.Error(), "root key") {
111 t.Fatalf("scoped signer signed a system pointer: err = %v", err)
112 }
113}
114
115func TestSystemPointerRefusesAGrantOnTheWire(t *testing.T) {
116 // A wrapper carrying a grant is refused BEFORE the signature is checked,
117 // like the production flag (production.go) and the pipeline.
118 priv, pub := testKeys(t)
119 s := NewDirStore(t.TempDir())
120 ctx := context.Background()
121 if _, err := PromoteSystem(ctx, s, RootSigner(priv), "router", "stable", testSystemRelease("v1.0.0"), SystemPromoteOptions{}); err != nil {
122 t.Fatal(err)
123 }
124 body, etag, _ := s.Get(ctx, SystemPointerKey("router", "stable"))
125 var sw signedWrapper
126 if err := json.Unmarshal(body, &sw); err != nil {
127 t.Fatal(err)
128 }
129 sw.Grant = &signedGrant{Payload: "x", Sig: "y"}
130 tampered, _ := json.Marshal(sw)
131 if _, err := s.Put(ctx, SystemPointerKey("router", "stable"), tampered, etag); err != nil {
132 t.Fatal(err)
133 }
134 if _, _, err := GetSystemPointer(ctx, s, pub, "router", "stable"); err == nil || !strings.Contains(err.Error(), "root key") {
135 t.Fatalf("grant-bearing wrapper accepted: err = %v", err)
136 }
137}
138
139func TestSystemPointerTamperAndCrossChannelRefused(t *testing.T) {
140 priv, pub := testKeys(t)
141 s := NewDirStore(t.TempDir())
142 ctx := context.Background()
143 if _, err := PromoteSystem(ctx, s, RootSigner(priv), "router", "canary", testSystemRelease("v1.0.0"), SystemPromoteOptions{}); err != nil {
144 t.Fatal(err)
145 }
146 body, _, _ := s.Get(ctx, SystemPointerKey("router", "canary"))
147 // Cross-channel replay: the canary wrapper planted at the stable key.
148 if _, err := s.Put(ctx, SystemPointerKey("router", "stable"), body, ""); err != nil {
149 t.Fatal(err)
150 }
151 // Refusals are typed, not stringly: a box tells "not authority" (refuse)
152 // from "the bucket is unreachable" (defer) with errors.Is.
153 if _, _, err := GetSystemPointer(ctx, s, pub, "router", "stable"); err == nil || !errors.Is(err, ErrBadSystemPointer) {
154 t.Fatalf("a canary pointer verified as stable: err = %v", err)
155 }
156 // Tampered signature.
157 var sw signedWrapper
158 _ = json.Unmarshal(body, &sw)
159 sw.Sig = "AA" + sw.Sig[2:]
160 bad, _ := json.Marshal(sw)
161 _, etag, _ := s.Get(ctx, SystemPointerKey("router", "canary"))
162 if _, err := s.Put(ctx, SystemPointerKey("router", "canary"), bad, etag); err != nil {
163 t.Fatal(err)
164 }
165 if _, _, err := GetSystemPointer(ctx, s, pub, "router", "canary"); err == nil || !errors.Is(err, ErrBadSystemPointer) {
166 t.Fatalf("tampered signature verified: err = %v", err)
167 }
168}
169
170func TestSystemPointerValidation(t *testing.T) {
171 priv, _ := testKeys(t)
172 sg := RootSigner(priv)
173 ctx := context.Background()
174 cases := map[string]SystemRelease{
175 "dev version": {Version: "dev", Artifacts: testSystemRelease("x").Artifacts},
176 "no artifacts": {Version: "v1.0.0"},
177 "bad platform": {Version: "v1.0.0", Artifacts: map[string]SystemArtifact{"linux_arm64": {Key: "bootstrap/router/v1.0.0/carlos-linux_arm64", SHA256: strings.Repeat("a", 64)}}},
178 "key not derived": {Version: "v1.0.0", Artifacts: map[string]SystemArtifact{"linux-arm64": {Key: "bootstrap/carlos", SHA256: strings.Repeat("a", 64)}}},
179 "short sha": {Version: "v1.0.0", Artifacts: map[string]SystemArtifact{"linux-arm64": {Key: SystemArtifactKey("v1.0.0", "linux-arm64"), SHA256: "abc"}}},
180 "version traversal": {Version: "../x", Artifacts: testSystemRelease("../x").Artifacts},
181 }
182 for name, rel := range cases {
183 s := NewDirStore(t.TempDir())
184 if _, err := PromoteSystem(ctx, s, sg, "router", "stable", rel, SystemPromoteOptions{}); err == nil {
185 t.Errorf("%s: accepted", name)
186 }
187 }
188 s := NewDirStore(t.TempDir())
189 if _, err := PromoteSystem(ctx, s, sg, "Router", "stable", testSystemRelease("v1.0.0"), SystemPromoteOptions{}); err == nil {
190 t.Error("bad component accepted")
191 }
192 if _, err := PromoteSystem(ctx, s, sg, "router", "stable", testSystemRelease("v1.0.0"), SystemPromoteOptions{Spread: 48 * time.Hour}); err == nil {
193 t.Error("48h spread accepted")
194 }
195}
196
197func TestSystemPromoteCASConflict(t *testing.T) {
198 priv, _ := testKeys(t)
199 ctx := context.Background()
200 inner := NewDirStore(t.TempDir())
201 // A store whose Put always says "someone else moved it".
202 s := conflictingStore{Store: inner}
203 if _, err := PromoteSystem(ctx, s, RootSigner(priv), "router", "stable", testSystemRelease("v1.0.0"), SystemPromoteOptions{}); !errors.Is(err, ErrCASConflict) {
204 t.Fatalf("err = %v, want ErrCASConflict", err)
205 }
206}
207
208type conflictingStore struct{ Store }
209
210func (c conflictingStore) Put(ctx context.Context, key string, body []byte, ifMatch string) (string, error) {
211 return "", ErrCASConflict
212}
213