1 /* reliable-chat - multipath chat
2 * Copyright (C) 2012 Scott Worley <sworley@chkno.net>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
14 * You should have received a copy of the GNU Affero General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 func expectMessage(t *testing.T, m *Message, at time.Time, id, say string) {
37 func TestMessageInsertAndRetreive(t *testing.T) {
39 say := "'Ello, Mister Polly Parrot!"
41 var zero_time time.Time
42 store := start_store()
43 store.Add <- &Message{at, id, say}
44 messages_from_store := make(chan []Message, 1)
45 store.Get <- &StoreRequest{zero_time, messages_from_store}
46 messages := <-messages_from_store
47 if len(messages) != 1 {
50 expectMessage(t, &messages[0], at, id, say)
55 func TestFetchBlocksUntilSpeak(t *testing.T) {
56 start_fetch_wait_count := fetch_wait_count.String()
58 say := "I've got a lovely fresh cuttle fish for you"
60 var zero_time time.Time
61 store := start_store()
62 messages_from_store := make(chan []Message, 1)
63 store.Get <- &StoreRequest{zero_time, messages_from_store}
64 for start_fetch_wait_count == fetch_wait_count.String() {
67 store.Add <- &Message{at, id, say}
68 messages := <-messages_from_store
69 if len(messages) != 1 {
72 expectMessage(t, &messages[0], at, id, say)
77 func TestMultipleListeners(t *testing.T) {
79 say := "This is your nine o'clock alarm call!"
81 var zero_time time.Time
82 store := start_store()
83 const num_clients = 13
84 var messages_from_store [num_clients]chan []Message
85 for i := 0; i < num_clients; i++ {
86 messages_from_store[i] = make(chan []Message, 1)
87 store.Get <- &StoreRequest{zero_time, messages_from_store[i]}
89 store.Add <- &Message{at, id, say}
90 for i := 0; i < num_clients; i++ {
91 messages := <-messages_from_store[i]
92 if len(messages) != 1 {
95 expectMessage(t, &messages[0], at, id, say)
101 func parseDuration(s string) time.Duration {
102 d, err := time.ParseDuration(s)
109 func atoi(s string) int {
110 i, err := strconv.Atoi(s)
117 func TestPartialRetreive(t *testing.T) {
118 start_speak_count := atoi(speak_count.String())
122 say1 := "No, no.....No, 'e's stunned!"
123 say2 := "You stunned him, just as he was wakin' up!"
124 say3 := "Norwegian Blues stun easily, major."
126 at1 := base.Add(parseDuration("-4m"))
127 since := base.Add(parseDuration("-3m"))
128 at2 := base.Add(parseDuration("-2m"))
129 at3 := base.Add(parseDuration("-1m"))
130 store := start_store()
131 store.Add <- &Message{at1, id1, say1}
132 store.Add <- &Message{at2, id2, say2}
133 store.Add <- &Message{at3, id3, say3}
134 for atoi(speak_count.String()) != start_speak_count+3 {
137 messages_from_store := make(chan []Message, 1)
138 store.Get <- &StoreRequest{since, messages_from_store}
139 messages := <-messages_from_store
140 if len(messages) != 2 {
143 expectMessage(t, &messages[0], at2, id2, say2)
144 expectMessage(t, &messages[1], at3, id3, say3)
149 func TestPrecisePartialRetreive(t *testing.T) {
150 start_speak_count := atoi(speak_count.String())
154 say1 := "Well, he's...he's, ah...probably pining for the fjords."
155 say2 := "PININ' for the FJORDS?!?!?!?"
156 say3 := "look, why did he fall flat on his back the moment I got 'im home?"
158 at1 := base.Add(parseDuration("-3m"))
159 at2 := base.Add(parseDuration("-2m"))
160 at3 := base.Add(parseDuration("-1m"))
162 store := start_store()
163 store.Add <- &Message{at1, id1, say1}
164 store.Add <- &Message{at2, id2, say2}
165 store.Add <- &Message{at3, id3, say3}
166 for atoi(speak_count.String()) != start_speak_count+3 {
169 messages_from_store := make(chan []Message, 1)
170 store.Get <- &StoreRequest{since, messages_from_store}
171 messages := <-messages_from_store
172 if len(messages) != 1 {
175 expectMessage(t, &messages[0], at3, id3, say3)
180 func TestTypicalFlow(t *testing.T) {
183 say1 := "The Norwegian Blue prefers kippin' on it's back!"
184 say2 := "Remarkable bird, innit, squire? Lovely plumage!"
185 store := start_store()
187 // A waiting zero-time fetch.
188 var zero_time time.Time
189 prev_fetch_wait_count := fetch_wait_count.String()
190 fetch1 := make(chan []Message, 1)
191 store.Get <- &StoreRequest{zero_time, fetch1}
192 for prev_fetch_wait_count == fetch_wait_count.String() {
196 // Someone speaks. This triggers delivery.
198 store.Add <- &Message{at1, id1, say1}
199 messages1 := <-fetch1
200 if len(messages1) != 1 {
203 expectMessage(t, &messages1[0], at1, id1, say1)
205 // Upon recipt, client blocks on fetch with since=at1
206 prev_fetch_wait_count = fetch_wait_count.String()
207 fetch2 := make(chan []Message, 1)
208 store.Get <- &StoreRequest{at1, fetch2}
209 for prev_fetch_wait_count == fetch_wait_count.String() {
213 // Someone speaks again. This triggers another delivery.
218 store.Add <- &Message{at2, id2, say2}
219 messages2 := <-fetch2
220 if len(messages2) != 1 {
223 expectMessage(t, &messages2[0], at2, id2, say2)