]> git.giacomolli.uk - onechat/blob - memory_delivery_test.go
Store shared private images by content hash
[onechat] / memory_delivery_test.go
1 package main
2
3 import (
4 "errors"
5 "testing"
6
7 "github.com/stretchr/testify/require"
8 )
9
10 func TestQueuedAppendResumesWithoutADuplicate(t *testing.T) {
11 dir := t.TempDir()
12 memory, err := openMemory(t.Context(), dir, newTestClock().Now, newFakeSummarizer(), discardLog())
13 require.NoError(t, err)
14
15 var saved *int
16
17 first, err := memory.AppendOnce("user", "Record the gate size.", nil, func(id int) error {
18 saved = &id
19
20 require.Equal(t, 0, memory.log.Len())
21
22 return nil
23 })
24 require.NoError(t, err)
25 require.NoError(t, memory.Close())
26
27 memory, err = openMemory(t.Context(), dir, newTestClock().Now, newFakeSummarizer(), discardLog())
28 require.NoError(t, err)
29
30 defer func() {
31 require.NoError(t, memory.Close())
32 }()
33
34 second, err := memory.AppendOnce("user", first.Text, saved, func(int) error {
35 require.FailNow(t, "a recorded message must not be prepared again")
36
37 return nil
38 })
39 require.NoError(t, err)
40 require.Equal(t, first, second)
41 require.Equal(t, 1, memory.Len())
42 }
43
44 func TestQueuedAppendRetriesAnUnwrittenPreparedMessage(t *testing.T) {
45 memory, err := openMemory(t.Context(), t.TempDir(), newTestClock().Now, newFakeSummarizer(), discardLog())
46 require.NoError(t, err)
47
48 defer func() {
49 require.NoError(t, memory.Close())
50 }()
51
52 failure := errors.New("fake queue write failure")
53
54 var saved *int
55
56 _, err = memory.AppendOnce("work", "[Garden] Check the gate.", nil, func(id int) error {
57 saved = &id
58
59 return failure
60 })
61 require.ErrorIs(t, err, failure)
62 require.Equal(t, 0, memory.Len())
63
64 message, err := memory.AppendOnce("work", "[Garden] Check the gate.", saved, func(id int) error {
65 require.Equal(t, *saved, id)
66
67 return nil
68 })
69 require.NoError(t, err)
70 require.Equal(t, 0, message.ID)
71 require.Equal(t, 1, memory.Len())
72 }
73
74 func TestQueuedAppendRefusesAnInvalidReceipt(t *testing.T) {
75 memory, err := openMemory(t.Context(), t.TempDir(), newTestClock().Now, newFakeSummarizer(), discardLog())
76 require.NoError(t, err)
77
78 defer func() {
79 require.NoError(t, memory.Close())
80 }()
81
82 _, err = memory.Append("user", "Keep the original.")
83 require.NoError(t, err)
84
85 testCases := []struct {
86 name string
87 id int
88 cause string
89 }{
90 {
91 name: "receipt points to different text",
92 id: 0,
93 cause: "does not match",
94 },
95 {
96 name: "receipt skips a log position",
97 id: 2,
98 cause: "beyond the log",
99 },
100 {
101 name: "receipt has a negative position",
102 id: -1,
103 cause: "read queued message",
104 },
105 }
106 for _, tc := range testCases {
107 t.Run(tc.name, func(t *testing.T) {
108 _, err := memory.AppendOnce("user", "Other text.", &tc.id, func(int) error {
109 require.FailNow(t, "an invalid receipt must not be prepared")
110
111 return nil
112 })
113 require.ErrorContains(t, err, tc.cause)
114 require.Equal(t, 1, memory.Len())
115 })
116 }
117 }