eleven / messenger Public

Clone
git clone https://amadan.net/eleven/messenger

Plain git — no account needed to clone.

Download

Download this file

1package main
2
3import (
4 "bytes"
5 "errors"
6 "io"
7 "io/fs"
8 "path/filepath"
9 "testing"
10)
11
12// blobPath points tests at the default disk store's file for a blob id —
13// test-only sugar (asserting bytes really live on disk / were unlinked).
14// Production code goes through db.blobs and must not assume bytes are files.
15func (db *DB) blobPath(id string) string { return db.blobs.(*diskBlobStore).path(id) }
16
17// The blobStore contract, exercised against implementation #1 (disk): a staged
18// write committed under an id round-trips byte-for-byte, and remove makes it
19// unopenable. Any future implementation (an object store, per issue #550) must
20// pass this same sequence.
21func TestDiskBlobStoreRoundTrip(t *testing.T) {
22 store, err := newDiskBlobStore(filepath.Join(t.TempDir(), "blobs"))
23 if err != nil {
24 t.Fatalf("newDiskBlobStore: %v", err)
25 }
26 payload := []byte("pretend-this-is-encrypted-bytes\x00\x01\x02")
27
28 // put: stream in two writes to prove staging accumulates, then publish.
29 w, err := store.create()
30 if err != nil {
31 t.Fatalf("create: %v", err)
32 }
33 if _, err := w.Write(payload[:10]); err != nil {
34 t.Fatalf("write: %v", err)
35 }
36 if _, err := w.Write(payload[10:]); err != nil {
37 t.Fatalf("write: %v", err)
38 }
39 if err := w.commit("blobid_123-abc"); err != nil {
40 t.Fatalf("commit: %v", err)
41 }
42
43 // open: bytes, size, and a usable modtime all come back.
44 r, size, modTime, err := store.open("blobid_123-abc")
45 if err != nil {
46 t.Fatalf("open: %v", err)
47 }
48 got, err := io.ReadAll(r)
49 r.Close()
50 if err != nil || !bytes.Equal(got, payload) {
51 t.Fatalf("round-trip mismatch: err=%v got=%q", err, got)
52 }
53 if size != int64(len(payload)) {
54 t.Fatalf("size = %d, want %d", size, len(payload))
55 }
56 if modTime.IsZero() {
57 t.Fatal("zero modtime")
58 }
59
60 // delete → open fails with the contractual not-exist error.
61 if err := store.remove("blobid_123-abc"); err != nil {
62 t.Fatalf("remove: %v", err)
63 }
64 if _, _, _, err := store.open("blobid_123-abc"); !errors.Is(err, fs.ErrNotExist) {
65 t.Fatalf("open after remove: want fs.ErrNotExist, got %v", err)
66 }
67 // GC unlinks best-effort, so removing an id that's already gone is not an
68 // error.
69 if err := store.remove("blobid_123-abc"); err != nil {
70 t.Fatalf("remove of missing id: %v", err)
71 }
72}
73
74// An aborted staged write leaves nothing fetchable — the id is never published.
75func TestDiskBlobStoreAbortDiscards(t *testing.T) {
76 store, err := newDiskBlobStore(filepath.Join(t.TempDir(), "blobs"))
77 if err != nil {
78 t.Fatalf("newDiskBlobStore: %v", err)
79 }
80 w, err := store.create()
81 if err != nil {
82 t.Fatalf("create: %v", err)
83 }
84 if _, err := w.Write([]byte("half an upload")); err != nil {
85 t.Fatalf("write: %v", err)
86 }
87 w.abort()
88 if _, _, _, err := store.open("neverpublished"); !errors.Is(err, fs.ErrNotExist) {
89 t.Fatalf("open of aborted write: want fs.ErrNotExist, got %v", err)
90 }
91}
92