carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package certwarm
2
3import (
4 "strings"
5 "testing"
6 "time"
7)
8
9func TestKeyAndHostFromKeyRoundTrip(t *testing.T) {
10 for _, host := range []string{"www.customer.com", "xn--bcher-kva.example", "a.b.c.example.org"} {
11 if got := HostFromKey(Key(host)); got != host {
12 t.Errorf("HostFromKey(Key(%q)) = %q", host, got)
13 }
14 }
15}
16
17// A listing under the prefix can contain anything an operator or a future
18// build put there. Everything that is not exactly one host record must come
19// back as "" so the caller skips it rather than treating it as a hostname —
20// a nested key decoded as a host would be pruned as "not in the warm set",
21// which is a delete of somebody else's object.
22func TestHostFromKeyRefusesEverythingElse(t *testing.T) {
23 for _, key := range []string{
24 "control/certs/example.com",
25 "control/cert-warm/",
26 "control/cert-warm/.json",
27 "control/cert-warm/nested/host.json",
28 "control/cert-warm/host.txt",
29 "cert-warm/host.json",
30 "",
31 } {
32 if got := HostFromKey(key); got != "" {
33 t.Errorf("HostFromKey(%q) = %q, want \"\"", key, got)
34 }
35 }
36}
37
38func TestEncodeStampsVersionAndTime(t *testing.T) {
39 now := time.Unix(1_700_000_000, 0)
40 body, err := Record{Host: "a.example"}.Encode(now)
41 if err != nil {
42 t.Fatal(err)
43 }
44 got, err := Parse(body)
45 if err != nil {
46 t.Fatal(err)
47 }
48 if got.V != V || got.WrittenAt != now.Unix() {
49 t.Errorf("Encode = %+v; want v%d written_at %d", got, V, now.Unix())
50 }
51 // An unset class must never reach the wire: a reader branching on it
52 // would see "" and fall through every case.
53 if got.Class != ClassOther {
54 t.Errorf("Class = %q, want %q", got.Class, ClassOther)
55 }
56}
57
58func TestEncodeTrimsRemoteErrorText(t *testing.T) {
59 body, err := Record{Host: "a.example", Error: strings.Repeat("x", ErrorMax*3)}.Encode(time.Unix(1, 0))
60 if err != nil {
61 t.Fatal(err)
62 }
63 got, err := Parse(body)
64 if err != nil {
65 t.Fatal(err)
66 }
67 if len(got.Error) != ErrorMax {
68 t.Errorf("Error length = %d, want %d — an unbounded CA string reached the bucket", len(got.Error), ErrorMax)
69 }
70}
71
72// V<1 is refused (a record with no version is not one of ours); a HIGHER
73// version parses, because the wire is additive and an older console must
74// degrade to the fields it knows rather than fail the whole fold.
75func TestParseVersionBounds(t *testing.T) {
76 if _, err := Parse([]byte(`{"host":"a.example"}`)); err == nil {
77 t.Error("a record with no version parsed")
78 }
79 got, err := Parse([]byte(`{"v":99,"host":"a.example","attempts":4}`))
80 if err != nil {
81 t.Fatalf("a newer version failed to parse: %v", err)
82 }
83 if got.Attempts != 4 {
84 t.Errorf("Attempts = %d, want 4", got.Attempts)
85 }
86}
87
88// Fresh is judged against the LATER of written-at and next-attempt, which is
89// what lets a deliberate twelve-hour rate-limit wait stay authoritative
90// while a wedged issuer's record eventually stops being believed.
91func TestFreshUsesTheNextAttemptDeadline(t *testing.T) {
92 base := time.Unix(1_700_000_000, 0)
93 rateLimited := Record{WrittenAt: base.Unix(), NextAttemptAt: base.Add(12 * time.Hour).Unix()}
94 if !rateLimited.Fresh(base.Add(6 * time.Hour)) {
95 t.Error("a record mid-way through its own backoff read as stale")
96 }
97 if rateLimited.Fresh(base.Add(12*time.Hour + Grace + time.Second)) {
98 t.Error("a record past its next attempt plus grace still read as fresh — a wedged issuer would report as trying")
99 }
100 // No stamps at all is not evidence of anything.
101 if (Record{}).Fresh(base) {
102 t.Error("an unstamped record read as fresh")
103 }
104}
105