carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package provision
2
3import (
4 "context"
5 "errors"
6 "os"
7 "strings"
8 "testing"
9 "time"
10
11 "github.com/carlosframework/platform/internal/release"
12)
13
14func TestSidecarHostAndValidation(t *testing.T) {
15 got := SidecarHost("bot-acme", "eleven", "bdm")
16 if want := "bot-acme.eleven.bdm.sidecar.internal"; got != want {
17 t.Fatalf("SidecarHost = %q, want %q", got, want)
18 }
19 if !ValidSidecarHost(got, "eleven", "bdm") {
20 t.Fatal("its own SidecarHost output must validate")
21 }
22 for _, bad := range []string{
23 "bot-acme.other.bdm.sidecar.internal", // wrong app
24 "bot-acme.eleven.bad.sidecar.internal", // wrong sqid
25 "bot-acme.eleven.bdm.example.com", // wrong suffix
26 "a.b.bot.eleven.bdm.sidecar.internal", // more than one label
27 } {
28 if ValidSidecarHost(bad, "eleven", "bdm") {
29 t.Fatalf("ValidSidecarHost(%q) = true, want false", bad)
30 }
31 }
32 for _, bad := range []string{"", "-lead", "trail-", "UPPER", "has.dot", "has/slash", "..", strings.Repeat("a", 64)} {
33 if ValidSidecarName(bad) {
34 t.Fatalf("ValidSidecarName(%q) = true — the name becomes a bucket key AND a filesystem path segment", bad)
35 }
36 }
37}
38
39func TestParseSidecarKey(t *testing.T) {
40 known := map[string]bool{"bdm": true}
41 acct, app, name, ok := ParseSidecarKey("apps/bdm/eleven/sidecars/bot-acme.json", known)
42 if !ok || acct != "bdm" || app != "eleven" || name != "bot-acme" {
43 t.Fatalf("ParseSidecarKey = %q/%q/%q ok=%v", acct, app, name, ok)
44 }
45 for _, bad := range []string{
46 "apps/bdm/eleven/sidecars.json", // the manifest, not a record
47 "apps/bdm/eleven/sidecars/nested/x.json", // nested
48 "apps/bdm/eleven/sidecars/.json", // empty name
49 "apps/unknown/eleven/sidecars/bot.json", // account not materialized
50 "apps/bdm/channels/sidecars/bot.json", // release-plane collision
51 "apps/bdm/eleven/instances/bot.json", // the other family
52 } {
53 if _, _, _, ok := ParseSidecarKey(bad, known); ok {
54 t.Fatalf("ParseSidecarKey(%q) parsed, want refusal", bad)
55 }
56 }
57}
58
59func TestCreateSidecarRecordIsCreateOnly(t *testing.T) {
60 ctx := context.Background()
61 s := dirStore(t) // the helper reconcile_test.go already uses
62 rec := SidecarRecord{
63 Schema: 1, Name: "bot-acme", Host: SidecarHost("bot-acme", "eleven", "bdm"),
64 App: "eleven", Account: "bdm", Channel: "stable",
65 }
66 if err := CreateSidecarRecord(ctx, s, rec); err != nil {
67 t.Fatalf("first create: %v", err)
68 }
69 err := CreateSidecarRecord(ctx, s, rec)
70 if !errors.Is(err, release.ErrCASConflict) {
71 t.Fatalf("second create err = %v, want ErrCASConflict — a lost race must never silently overwrite", err)
72 }
73}
74
75func TestCreateSidecarRecordRoundTripsCreatedAt(t *testing.T) {
76 ctx := context.Background()
77 s := dirStore(t)
78 want := time.Date(2026, 8, 17, 23, 0, 0, 0, time.UTC)
79 rec := SidecarRecord{
80 Schema: 1, Name: "bot-acme", Host: SidecarHost("bot-acme", "eleven", "bdm"),
81 App: "eleven", Account: "bdm", Channel: "stable", CreatedAt: want,
82 }
83 if err := CreateSidecarRecord(ctx, s, rec); err != nil {
84 t.Fatalf("create: %v", err)
85 }
86 got, err := GetSidecarRecord(ctx, s, "bdm", "eleven", "bot-acme")
87 if err != nil {
88 t.Fatalf("get: %v", err)
89 }
90 // .Equal, not ==: a struct comparison would fail on the monotonic-clock
91 // reading time.Now() carries and json round-trips never preserve, and
92 // .UTC() side-steps any location difference too — the store only owes
93 // us the same instant back, not the same in-memory representation of it.
94 if !got.CreatedAt.Equal(want) {
95 t.Fatalf("CreatedAt round-trip = %v, want %v", got.CreatedAt, want)
96 }
97 if got.CreatedAt.UTC().Format(time.RFC3339) != "2026-08-17T23:00:00Z" {
98 t.Fatalf("CreatedAt wire format = %v, want RFC3339 like the spec's example", got.CreatedAt.UTC().Format(time.RFC3339))
99 }
100}
101
102func TestGetSidecarRecordRefusesRecordThatLiesAboutItsPath(t *testing.T) {
103 ctx := context.Background()
104 s := dirStore(t)
105 body := []byte(`{"schema":1,"name":"bot-acme","app":"OTHER","account":"bdm"}`)
106 if _, err := s.Put(ctx, SidecarRecordKey("bdm", "eleven", "bot-acme"), body, ""); err != nil {
107 t.Fatalf("seed: %v", err)
108 }
109 if _, err := GetSidecarRecord(ctx, s, "bdm", "eleven", "bot-acme"); err == nil {
110 t.Fatal("a record disagreeing with its own key path must be refused, never guessed at")
111 }
112}
113
114func TestSidecarManifestDefaults(t *testing.T) {
115 var m SidecarManifest
116 if m.IdleOrDefault() != 5*time.Minute {
117 t.Fatalf("idle default = %v, want 5m", m.IdleOrDefault())
118 }
119 if m.MaxRunOrDefault() != time.Hour {
120 t.Fatalf("max_run default = %v, want 1h", m.MaxRunOrDefault())
121 }
122 if !m.HibernateOrDefault() {
123 t.Fatal("hibernate must default true")
124 }
125 if m.PlacementOrDefault() != "any" {
126 t.Fatalf("placement default = %q, want any", m.PlacementOrDefault())
127 }
128 no := false
129 m2 := SidecarManifest{Hibernate: &no}
130 if m2.HibernateOrDefault() {
131 t.Fatal("an explicit false must win — tri-state, like instances' Hibernate")
132 }
133}
134
135func TestSidecarManifestSchemaNewerIsRefused(t *testing.T) {
136 ctx := context.Background()
137 s := dirStore(t)
138 if _, err := s.Put(ctx, SidecarManifestKey("bdm", "eleven"), []byte(`{"schema":2}`), ""); err != nil {
139 t.Fatalf("seed: %v", err)
140 }
141 if _, err := GetSidecarManifest(ctx, s, "bdm", "eleven"); err == nil {
142 t.Fatal("a schema newer than this binary understands must be refused, not silently truncated")
143 }
144}
145
146func TestSidecarManifestAbsenceIsNotExist(t *testing.T) {
147 _, err := GetSidecarManifest(context.Background(), dirStore(t), "bdm", "eleven")
148 if !errors.Is(err, os.ErrNotExist) {
149 t.Fatalf("absence err = %v, want os.ErrNotExist — absence means the feature does not exist for that app", err)
150 }
151}
152
153func TestValidateSidecarShape(t *testing.T) {
154 ok := SidecarRecord{Schema: 1, Name: "bot", Host: SidecarHost("bot", "eleven", "bdm"),
155 App: "eleven", Account: "bdm", Channel: "stable", Placement: "no-inbound"}
156 if err := ValidateSidecarShape(ok); err != nil {
157 t.Fatalf("valid record refused: %v", err)
158 }
159 bad := ok
160 bad.Placement = "sideways"
161 if err := ValidateSidecarShape(bad); err == nil {
162 t.Fatal("placement vocabulary must be closed")
163 }
164}
165