]> git.scottworley.com Git - reliable-chat/blame - server/server_test.go
Add an id to messages
[reliable-chat] / server / server_test.go
CommitLineData
cc9bd370
SW
1package main
2
3import "testing"
ca612dcb 4import "runtime"
d69a32e6 5import "strconv"
cc9bd370
SW
6import "time"
7
8func TestMessageInsertAndRetreive(t *testing.T) {
b199796a 9 id := "1"
ca612dcb 10 say := "'Ello, Mister Polly Parrot!"
cc9bd370
SW
11 at := time.Now()
12 var zero_time time.Time
13 store := start_store()
b199796a 14 store.Add <- &Message{at, id, say}
cc9bd370 15 messages_from_store := make(chan []Message, 1)
fa5e7c1b 16 store.Get <- &StoreRequest{zero_time, messages_from_store}
cc9bd370
SW
17 messages := <-messages_from_store
18 if len(messages) != 1 {
d69a32e6 19 t.FailNow()
cc9bd370
SW
20 }
21 if messages[0].Time != at {
22 t.Fail()
23 }
b199796a
SW
24 if messages[0].ID != id {
25 t.Fail()
26 }
cc9bd370
SW
27 if messages[0].Text != say {
28 t.Fail()
29 }
c282d878
SW
30 close(store.Get)
31 close(store.Add)
cc9bd370 32}
ca612dcb
SW
33
34func TestFetchBlocksUntilSpeak(t *testing.T) {
35 start_fetch_wait_count := fetch_wait_count.String()
b199796a 36 id := "2"
ca612dcb
SW
37 say := "I've got a lovely fresh cuttle fish for you"
38 at := time.Now()
39 var zero_time time.Time
40 store := start_store()
41 messages_from_store := make(chan []Message, 1)
42 store.Get <- &StoreRequest{zero_time, messages_from_store}
43 for start_fetch_wait_count == fetch_wait_count.String() {
44 runtime.Gosched()
45 }
b199796a 46 store.Add <- &Message{at, id, say}
ca612dcb
SW
47 messages := <-messages_from_store
48 if len(messages) != 1 {
d69a32e6 49 t.FailNow()
ca612dcb
SW
50 }
51 if messages[0].Time != at {
52 t.Fail()
53 }
b199796a
SW
54 if messages[0].ID != id {
55 t.Fail()
56 }
ca612dcb
SW
57 if messages[0].Text != say {
58 t.Fail()
59 }
60 close(store.Get)
61 close(store.Add)
62}
d4039f63
SW
63
64func TestMultipleListeners(t *testing.T) {
b199796a 65 id := "3"
d4039f63
SW
66 say := "This is your nine o'clock alarm call!"
67 at := time.Now()
68 var zero_time time.Time
69 store := start_store()
70 const num_clients = 13
71 var messages_from_store [num_clients]chan []Message
72 for i := 0; i < num_clients; i++ {
73 messages_from_store[i] = make(chan []Message, 1)
74 store.Get <- &StoreRequest{zero_time, messages_from_store[i]}
75 }
b199796a 76 store.Add <- &Message{at, id, say}
d4039f63
SW
77 for i := 0; i < num_clients; i++ {
78 messages := <-messages_from_store[i]
79 if len(messages) != 1 {
d69a32e6 80 t.FailNow()
d4039f63
SW
81 }
82 if messages[0].Time != at {
83 t.Fail()
84 }
b199796a
SW
85 if messages[0].ID != id {
86 t.Fail()
87 }
d4039f63
SW
88 if messages[0].Text != say {
89 t.Fail()
90 }
91 }
92 close(store.Get)
93 close(store.Add)
94}
d69a32e6
SW
95
96func parseDuration(s string) time.Duration {
97 d, err := time.ParseDuration(s)
98 if err != nil {
99 panic(err)
100 }
101 return d
102}
103
104func atoi(s string) int {
105 i, err := strconv.Atoi(s)
106 if err != nil {
107 panic(err)
108 }
109 return i
110}
111
112func TestPartialRetreive(t *testing.T) {
113 start_speak_count := atoi(speak_count.String())
b199796a
SW
114 id1 := "4"
115 id2 := "5"
116 id3 := "6"
d69a32e6
SW
117 say1 := "No, no.....No, 'e's stunned!"
118 say2 := "You stunned him, just as he was wakin' up!"
119 say3 := "Norwegian Blues stun easily, major."
120 base := time.Now()
121 at1 := base.Add(parseDuration("-4m"))
122 since := base.Add(parseDuration("-3m"))
123 at2 := base.Add(parseDuration("-2m"))
124 at3 := base.Add(parseDuration("-1m"))
125 store := start_store()
b199796a
SW
126 store.Add <- &Message{at1, id1, say1}
127 store.Add <- &Message{at2, id2, say2}
128 store.Add <- &Message{at3, id3, say3}
d69a32e6
SW
129 for atoi(speak_count.String()) != start_speak_count+3 {
130 runtime.Gosched()
131 }
132 messages_from_store := make(chan []Message, 1)
133 store.Get <- &StoreRequest{since, messages_from_store}
134 messages := <-messages_from_store
135 if len(messages) != 2 {
136 t.FailNow()
137 }
138 if messages[0].Time != at2 {
139 t.Fail()
140 }
b199796a
SW
141 if messages[0].ID != id2 {
142 t.Fail()
143 }
d69a32e6
SW
144 if messages[0].Text != say2 {
145 t.Fail()
146 }
147 if messages[1].Time != at3 {
148 t.Fail()
149 }
b199796a
SW
150 if messages[1].ID != id3 {
151 t.Fail()
152 }
d69a32e6
SW
153 if messages[1].Text != say3 {
154 t.Fail()
155 }
156 close(store.Get)
157 close(store.Add)
158}
6e7f760f
SW
159
160func TestPrecisePartialRetreive(t *testing.T) {
161 start_speak_count := atoi(speak_count.String())
b199796a
SW
162 id1 := "7"
163 id2 := "8"
164 id3 := "9"
6e7f760f
SW
165 say1 := "Well, he's...he's, ah...probably pining for the fjords."
166 say2 := "PININ' for the FJORDS?!?!?!?"
167 say3 := "look, why did he fall flat on his back the moment I got 'im home?"
168 base := time.Now()
169 at1 := base.Add(parseDuration("-3m"))
170 at2 := base.Add(parseDuration("-2m"))
171 at3 := base.Add(parseDuration("-1m"))
172 since := at2
173 store := start_store()
b199796a
SW
174 store.Add <- &Message{at1, id1, say1}
175 store.Add <- &Message{at2, id2, say2}
176 store.Add <- &Message{at3, id3, say3}
6e7f760f
SW
177 for atoi(speak_count.String()) != start_speak_count+3 {
178 runtime.Gosched()
179 }
180 messages_from_store := make(chan []Message, 1)
181 store.Get <- &StoreRequest{since, messages_from_store}
182 messages := <-messages_from_store
183 if len(messages) != 1 {
184 t.FailNow()
185 }
186 if messages[0].Time != at3 {
187 t.Fail()
188 }
b199796a
SW
189 if messages[0].ID != id3 {
190 t.Fail()
191 }
6e7f760f
SW
192 if messages[0].Text != say3 {
193 t.Fail()
194 }
195 close(store.Get)
196 close(store.Add)
197}
198
199func TestTypicalFlow(t *testing.T) {
b199796a
SW
200 id1 := "10"
201 id2 := "11"
6e7f760f
SW
202 say1 := "The Norwegian Blue prefers kippin' on it's back!"
203 say2 := "Remarkable bird, innit, squire? Lovely plumage!"
204 store := start_store()
205
206 // A waiting zero-time fetch.
207 var zero_time time.Time
208 prev_fetch_wait_count := fetch_wait_count.String()
209 fetch1 := make(chan []Message, 1)
210 store.Get <- &StoreRequest{zero_time, fetch1}
211 for prev_fetch_wait_count == fetch_wait_count.String() {
212 runtime.Gosched()
213 }
214
215 // Someone speaks. This triggers delivery.
216 at1 := time.Now()
b199796a 217 store.Add <- &Message{at1, id1, say1}
6e7f760f
SW
218 messages1 := <-fetch1
219 if len(messages1) != 1 {
220 t.FailNow()
221 }
222 if messages1[0].Time != at1 {
223 t.Fail()
224 }
b199796a
SW
225 if messages1[0].ID != id1 {
226 t.Fail()
227 }
6e7f760f
SW
228 if messages1[0].Text != say1 {
229 t.Fail()
230 }
231
232 // Upon recipt, client blocks on fetch with since=at1
233 prev_fetch_wait_count = fetch_wait_count.String()
234 fetch2 := make(chan []Message, 1)
235 store.Get <- &StoreRequest{at1, fetch2}
236 for prev_fetch_wait_count == fetch_wait_count.String() {
237 runtime.Gosched()
238 }
239
240 // Someone speaks again. This triggers another delivery.
241 at2 := time.Now()
242 if !at2.After(at1) {
243 t.Fail()
244 }
b199796a 245 store.Add <- &Message{at2, id2, say2}
6e7f760f
SW
246 messages2 := <-fetch2
247 if len(messages2) != 1 {
248 t.FailNow()
249 }
250 if messages2[0].Time != at2 {
251 t.Fail()
252 }
b199796a
SW
253 if messages2[0].ID != id2 {
254 t.Fail()
255 }
6e7f760f
SW
256 if messages2[0].Text != say2 {
257 t.Fail()
258 }
259
260 close(store.Get)
261 close(store.Add)
262}