carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package hostquarantine
2
3import (
4 "context"
5 "errors"
6 "os"
7 "testing"
8 "time"
9)
10
11type fakeDirectory struct {
12 actor Actor
13 err error
14 calls int
15}
16
17func (f *fakeDirectory) Lookup(_ context.Context, _ string) (Actor, error) {
18 f.calls++
19 return f.actor, f.err
20}
21
22func TestCheckRequiresFreshExactActiveEnrollment(t *testing.T) {
23 d := &fakeDirectory{actor: Actor{Enrollment: "enroll-1", State: StateActive, QuarantineRevision: 3}}
24 if err := Check(t.Context(), d, "box-1", "enroll-1"); err != nil {
25 t.Fatal(err)
26 }
27 d.actor.State = StateQuarantined
28 if err := Check(t.Context(), d, "box-1", "enroll-1"); !errors.Is(err, ErrAdmission) {
29 t.Fatalf("quarantine error = %v", err)
30 }
31 if d.calls != 2 {
32 t.Fatalf("directory calls = %d, want a fresh lookup per check", d.calls)
33 }
34}
35
36func TestCheckFailsClosed(t *testing.T) {
37 cases := map[string]*fakeDirectory{
38 "missing": {err: os.ErrNotExist},
39 "unreadable": {err: errors.New("signature refused")},
40 "mismatch": {actor: Actor{Enrollment: "other", State: StateActive}},
41 "retired": {actor: Actor{Enrollment: "enroll-1", State: StateRetired}},
42 "unknown": {actor: Actor{Enrollment: "enroll-1", State: "paused"}},
43 }
44 for name, d := range cases {
45 t.Run(name, func(t *testing.T) {
46 if err := Check(t.Context(), d, "box-1", "enroll-1"); !errors.Is(err, ErrAdmission) {
47 t.Fatalf("error = %v", err)
48 }
49 })
50 }
51}
52
53func TestRetirementCompletionKeyAndValidation(t *testing.T) {
54 key, err := RetirementKey("box-1", "enroll-1", 7)
55 if err != nil || key != "control/host-retirement/box-1/enroll-1/7.json" {
56 t.Fatalf("key = %q, %v", key, err)
57 }
58 hash := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
59 r := RetirementCompletion{
60 V: 1, Box: "box-1", Enrollment: "enroll-1", InstanceID: "i-123", QuarantineRevision: 7,
61 BootID: "boot-1", CompletedAt: time.Date(2026, 10, 5, 12, 0, 0, 0, time.UTC), Complete: true,
62 InventorySHA256: hash,
63 Entries: []RetirementEntry{{Host: "app.example.com", Incarnation: "inc-1", Stamp: 8, RetirementID: "retire-1", JournalSHA256: hash}},
64 }
65 if err := r.Validate(); err != nil {
66 t.Fatal(err)
67 }
68 r.Entries = nil
69 if err := r.Validate(); !errors.Is(err, ErrRecord) {
70 t.Fatalf("nil entries error = %v", err)
71 }
72 r.Entries = []RetirementEntry{{Host: "app.example.com", Incarnation: "inc-1", Stamp: 8, RetirementID: "retire-1", JournalSHA256: hash}}
73 r.Entries[0].JournalSHA256 = ""
74 if err := r.Validate(); !errors.Is(err, ErrRecord) {
75 t.Fatalf("error = %v", err)
76 }
77}
78