oficina / sheets Public

Clone
git clone https://amadan.net/oficina/sheets

Plain git — no account needed to clone.

Download

Download this file

1package sealtest
2
3import (
4 "os"
5 "path/filepath"
6 "testing"
7
8 "amadan.net/oficina/sheets/internal/sheets/seal"
9)
10
11func testDEK() []byte {
12 d := make([]byte, 32)
13 for i := range d {
14 d[i] = byte(i)
15 }
16 return d
17}
18
19// leaked is the detection core AssertNoPlaintext relies on. Exercising it
20// directly is the permanent proof that the gate CAN fail: these two tests
21// show it correctly flags a canary and correctly ignores clean bytes,
22// without needing to crash the test process to observe a failure.
23func TestLeakedDetectsCanary(t *testing.T) {
24 for _, c := range Canaries {
25 if got := leaked(c); got == nil {
26 t.Fatalf("leaked(%q) = nil, want a match", c)
27 }
28 }
29}
30
31func TestLeakedIgnoresCleanBytes(t *testing.T) {
32 if got := leaked([]byte("nothing to see here, just cell math and formulas")); got != nil {
33 t.Fatalf("leaked(clean) = %q, want nil", got)
34 }
35}
36
37// TestAssertNoPlaintextPassesOnSealedData is the gate's normal-operation
38// path: a canary sealed through the real Sealer must not be readable in
39// the raw bytes the gate scans.
40func TestAssertNoPlaintextPassesOnSealedData(t *testing.T) {
41 s, err := seal.New(testDEK())
42 if err != nil {
43 t.Fatal(err)
44 }
45 ct, err := s.Seal("cell.input", Canaries[0])
46 if err != nil {
47 t.Fatal(err)
48 }
49 dbPath := filepath.Join(t.TempDir(), "sealed.db")
50 if err := os.WriteFile(dbPath, ct, 0o600); err != nil {
51 t.Fatal(err)
52 }
53 AssertNoPlaintext(t, dbPath)
54}
55
56// TestAssertNoPlaintextToleratesMissingSidecars proves the gate does not
57// require a WAL or SHM file to exist (most callers won't have one), while
58// still being willing to read them when they do — see
59// TestAssertNoPlaintextChecksWAL below and the manual failure exercise
60// recorded in the task report.
61func TestAssertNoPlaintextToleratesMissingSidecars(t *testing.T) {
62 dbPath := filepath.Join(t.TempDir(), "clean.db")
63 if err := os.WriteFile(dbPath, []byte("not a leak"), 0o600); err != nil {
64 t.Fatal(err)
65 }
66 AssertNoPlaintext(t, dbPath)
67}
68
69// TestFindLeakChecksWAL proves the gate's detection core reads the WAL
70// sidecar, not just the main file. Litestream ships WAL frames
71// continuously, so a value written plainly reaches the bucket before any
72// delete would remove it from the main file — a leak that only ever
73// touched the WAL must still be caught. This test seeds the canary into
74// the WAL only; a scan that checked just the main file would wrongly miss
75// it. (This is tested against findLeak rather than AssertNoPlaintext
76// itself: a failing subtest always fails its parent in Go's testing
77// package, so routing a deliberately-positive leak case through a live
78// *testing.T would leave this package permanently red.)
79func TestFindLeakChecksWAL(t *testing.T) {
80 dir := t.TempDir()
81 dbPath := filepath.Join(dir, "leaky.db")
82 if err := os.WriteFile(dbPath, []byte("clean main file"), 0o600); err != nil {
83 t.Fatal(err)
84 }
85 if err := os.WriteFile(dbPath+"-wal", Canaries[1], 0o600); err != nil {
86 t.Fatal(err)
87 }
88
89 c, f, err := findLeak(dbPath)
90 if err != nil {
91 t.Fatal(err)
92 }
93 if c == nil {
94 t.Fatal("did not detect a canary present only in the WAL")
95 }
96 if f != "leaky.db-wal" {
97 t.Fatalf("found in %q, want leaky.db-wal", f)
98 }
99}
100