Merge lp:~pedronis/ubuntu-push/expose-more-acceptance-details into lp:ubuntu-push
- expose-more-acceptance-details
- Merge into trunk
Proposed by
Samuele Pedroni
Status: | Merged |
---|---|
Approved by: | Samuele Pedroni |
Approved revision: | 80 |
Merged at revision: | 76 |
Proposed branch: | lp:~pedronis/ubuntu-push/expose-more-acceptance-details |
Merge into: | lp:ubuntu-push |
Prerequisite: | lp:~pedronis/ubuntu-push/fix-split-reuse |
Diff against target: |
491 lines (+113/-94) 5 files modified
server/acceptance/acceptance_test.go (+6/-5) server/acceptance/suites/broadcast.go (+35/-35) server/acceptance/suites/helpers.go (+11/-2) server/acceptance/suites/pingpong.go (+8/-8) server/acceptance/suites/suite.go (+53/-44) |
To merge this branch: | bzr merge lp:~pedronis/ubuntu-push/expose-more-acceptance-details |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nicola Larosa (community) | Approve | ||
Review via email: mp+208467@code.launchpad.net |
Commit message
refactor acceptance tests to expose more hooking points/details
Description of the change
expose more bits of acceptance tests
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'server/acceptance/acceptance_test.go' |
2 | --- server/acceptance/acceptance_test.go 2014-02-13 19:33:14 +0000 |
3 | +++ server/acceptance/acceptance_test.go 2014-02-26 20:26:43 +0000 |
4 | @@ -38,7 +38,7 @@ |
5 | } |
6 | |
7 | // Start a server. |
8 | -func StartServer(c *C) (<-chan string, func(), string, string) { |
9 | +func StartServer(c *C, s *suites.AcceptanceSuite, handle *suites.ServerHandle) { |
10 | if *serverCmd == "" { |
11 | c.Skip("executable server not specified") |
12 | } |
13 | @@ -46,10 +46,11 @@ |
14 | cfg := testServerConfig("127.0.0.1:0", "127.0.0.1:0") |
15 | cfgFilename := suites.WriteConfig(c, tmpDir, "config.json", cfg) |
16 | logs, killServer := suites.RunAndObserve(c, *serverCmd, cfgFilename) |
17 | - serverHTTPAddr := suites.ExtractListeningAddr(c, logs, suites.HTTPListeningOnPat) |
18 | - serverURL := fmt.Sprintf("http://%s", serverHTTPAddr) |
19 | - serverAddr := suites.ExtractListeningAddr(c, logs, suites.DevListeningOnPat) |
20 | - return logs, killServer, serverAddr, serverURL |
21 | + s.KillGroup["server"] = killServer |
22 | + handle.ServerHTTPAddr = suites.ExtractListeningAddr(c, logs, suites.HTTPListeningOnPat) |
23 | + s.ServerAPIURL = fmt.Sprintf("http://%s", handle.ServerHTTPAddr) |
24 | + handle.ServerAddr = suites.ExtractListeningAddr(c, logs, suites.DevListeningOnPat) |
25 | + handle.ServerEvents = logs |
26 | } |
27 | |
28 | // ping pong/connectivity |
29 | |
30 | === modified file 'server/acceptance/suites/broadcast.go' |
31 | --- server/acceptance/suites/broadcast.go 2014-02-12 15:43:24 +0000 |
32 | +++ server/acceptance/suites/broadcast.go 2014-02-26 20:26:43 +0000 |
33 | @@ -37,8 +37,8 @@ |
34 | var future = time.Now().Add(9 * time.Hour).Format(time.RFC3339) |
35 | |
36 | func (s *BroadcastAcceptanceSuite) TestBroadcastToConnected(c *C) { |
37 | - events, errCh, stop := s.startClient(c, "DEVB", nil) |
38 | - got, err := s.postRequest("/broadcast", &api.Broadcast{ |
39 | + events, errCh, stop := s.StartClient(c, "DEVB", nil) |
40 | + got, err := s.PostRequest("/broadcast", &api.Broadcast{ |
41 | Channel: "system", |
42 | ExpireOn: future, |
43 | Data: json.RawMessage(`{"n": 42}`), |
44 | @@ -47,13 +47,13 @@ |
45 | c.Assert(got, Matches, ".*ok.*") |
46 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"n":42}]`) |
47 | stop() |
48 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
49 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
50 | c.Check(len(errCh), Equals, 0) |
51 | } |
52 | |
53 | func (s *BroadcastAcceptanceSuite) TestBroadcastPending(c *C) { |
54 | // send broadcast that will be pending |
55 | - got, err := s.postRequest("/broadcast", &api.Broadcast{ |
56 | + got, err := s.PostRequest("/broadcast", &api.Broadcast{ |
57 | Channel: "system", |
58 | ExpireOn: future, |
59 | Data: json.RawMessage(`{"b": 1}`), |
60 | @@ -61,11 +61,11 @@ |
61 | c.Assert(err, IsNil) |
62 | c.Assert(got, Matches, ".*ok.*") |
63 | |
64 | - events, errCh, stop := s.startClient(c, "DEVB", nil) |
65 | + events, errCh, stop := s.StartClient(c, "DEVB", nil) |
66 | // gettting pending on connect |
67 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"b":1}]`) |
68 | stop() |
69 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
70 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
71 | c.Check(len(errCh), Equals, 0) |
72 | } |
73 | |
74 | @@ -73,7 +73,7 @@ |
75 | // send bunch of broadcasts that will be pending |
76 | payloadFmt := fmt.Sprintf(`{"b":%%d,"bloat":"%s"}`, strings.Repeat("x", 1024*2)) |
77 | for i := 0; i < 32; i++ { |
78 | - got, err := s.postRequest("/broadcast", &api.Broadcast{ |
79 | + got, err := s.PostRequest("/broadcast", &api.Broadcast{ |
80 | Channel: "system", |
81 | ExpireOn: future, |
82 | Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)), |
83 | @@ -82,22 +82,22 @@ |
84 | c.Assert(got, Matches, ".*ok.*") |
85 | } |
86 | |
87 | - events, errCh, stop := s.startClient(c, "DEVC", nil) |
88 | + events, errCh, stop := s.StartClient(c, "DEVC", nil) |
89 | // gettting pending on connect |
90 | c.Check(NextEvent(events, errCh), Matches, `broadcast chan:0 app: topLevel:30 payloads:\[{"b":0,.*`) |
91 | c.Check(NextEvent(events, errCh), Matches, `broadcast chan:0 app: topLevel:32 payloads:\[.*`) |
92 | stop() |
93 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
94 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
95 | c.Check(len(errCh), Equals, 0) |
96 | } |
97 | |
98 | func (s *BroadcastAcceptanceSuite) TestBroadcastDistribution2(c *C) { |
99 | - // start 1st clinet |
100 | - events1, errCh1, stop1 := s.startClient(c, "DEV1", nil) |
101 | + // start 1st client |
102 | + events1, errCh1, stop1 := s.StartClient(c, "DEV1", nil) |
103 | // start 2nd client |
104 | - events2, errCh2, stop2 := s.startClient(c, "DEV2", nil) |
105 | + events2, errCh2, stop2 := s.StartClient(c, "DEV2", nil) |
106 | // broadcast |
107 | - got, err := s.postRequest("/broadcast", &api.Broadcast{ |
108 | + got, err := s.PostRequest("/broadcast", &api.Broadcast{ |
109 | Channel: "system", |
110 | ExpireOn: future, |
111 | Data: json.RawMessage(`{"n": 42}`), |
112 | @@ -108,15 +108,15 @@ |
113 | c.Check(NextEvent(events2, errCh2), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"n":42}]`) |
114 | stop1() |
115 | stop2() |
116 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
117 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
118 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
119 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
120 | c.Check(len(errCh1), Equals, 0) |
121 | c.Check(len(errCh2), Equals, 0) |
122 | } |
123 | |
124 | func (s *BroadcastAcceptanceSuite) TestBroadcastFilterByLevel(c *C) { |
125 | - events, errCh, stop := s.startClient(c, "DEVD", nil) |
126 | - got, err := s.postRequest("/broadcast", &api.Broadcast{ |
127 | + events, errCh, stop := s.StartClient(c, "DEVD", nil) |
128 | + got, err := s.PostRequest("/broadcast", &api.Broadcast{ |
129 | Channel: "system", |
130 | ExpireOn: future, |
131 | Data: json.RawMessage(`{"b": 1}`), |
132 | @@ -125,10 +125,10 @@ |
133 | c.Assert(got, Matches, ".*ok.*") |
134 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"b":1}]`) |
135 | stop() |
136 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
137 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
138 | c.Check(len(errCh), Equals, 0) |
139 | // another broadcast |
140 | - got, err = s.postRequest("/broadcast", &api.Broadcast{ |
141 | + got, err = s.PostRequest("/broadcast", &api.Broadcast{ |
142 | Channel: "system", |
143 | ExpireOn: future, |
144 | Data: json.RawMessage(`{"b": 2}`), |
145 | @@ -136,25 +136,25 @@ |
146 | c.Assert(err, IsNil) |
147 | c.Assert(got, Matches, ".*ok.*") |
148 | // reconnect, provide levels, get only later notification |
149 | - events, errCh, stop = s.startClient(c, "DEVD", map[string]int64{ |
150 | + events, errCh, stop = s.StartClient(c, "DEVD", map[string]int64{ |
151 | protocol.SystemChannelId: 1, |
152 | }) |
153 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:2 payloads:[{"b":2}]`) |
154 | stop() |
155 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
156 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
157 | c.Check(len(errCh), Equals, 0) |
158 | } |
159 | |
160 | func (s *BroadcastAcceptanceSuite) TestBroadcastTooAhead(c *C) { |
161 | // send broadcasts that will be pending |
162 | - got, err := s.postRequest("/broadcast", &api.Broadcast{ |
163 | + got, err := s.PostRequest("/broadcast", &api.Broadcast{ |
164 | Channel: "system", |
165 | ExpireOn: future, |
166 | Data: json.RawMessage(`{"b": 1}`), |
167 | }) |
168 | c.Assert(err, IsNil) |
169 | c.Assert(got, Matches, ".*ok.*") |
170 | - got, err = s.postRequest("/broadcast", &api.Broadcast{ |
171 | + got, err = s.PostRequest("/broadcast", &api.Broadcast{ |
172 | Channel: "system", |
173 | ExpireOn: future, |
174 | Data: json.RawMessage(`{"b": 2}`), |
175 | @@ -162,38 +162,38 @@ |
176 | c.Assert(err, IsNil) |
177 | c.Assert(got, Matches, ".*ok.*") |
178 | |
179 | - events, errCh, stop := s.startClient(c, "DEVB", map[string]int64{ |
180 | + events, errCh, stop := s.StartClient(c, "DEVB", map[string]int64{ |
181 | protocol.SystemChannelId: 10, |
182 | }) |
183 | // gettting last one pending on connect |
184 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:2 payloads:[{"b":2}]`) |
185 | stop() |
186 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
187 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
188 | c.Check(len(errCh), Equals, 0) |
189 | } |
190 | |
191 | func (s *BroadcastAcceptanceSuite) TestBroadcastTooAheadOnEmpty(c *C) { |
192 | // nothing there |
193 | - events, errCh, stop := s.startClient(c, "DEVB", map[string]int64{ |
194 | + events, errCh, stop := s.StartClient(c, "DEVB", map[string]int64{ |
195 | protocol.SystemChannelId: 10, |
196 | }) |
197 | // gettting empty pending on connect |
198 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:0 payloads:null`) |
199 | stop() |
200 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
201 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
202 | c.Check(len(errCh), Equals, 0) |
203 | } |
204 | |
205 | func (s *BroadcastAcceptanceSuite) TestBroadcastWayBehind(c *C) { |
206 | // send broadcasts that will be pending |
207 | - got, err := s.postRequest("/broadcast", &api.Broadcast{ |
208 | + got, err := s.PostRequest("/broadcast", &api.Broadcast{ |
209 | Channel: "system", |
210 | ExpireOn: future, |
211 | Data: json.RawMessage(`{"b": 1}`), |
212 | }) |
213 | c.Assert(err, IsNil) |
214 | c.Assert(got, Matches, ".*ok.*") |
215 | - got, err = s.postRequest("/broadcast", &api.Broadcast{ |
216 | + got, err = s.PostRequest("/broadcast", &api.Broadcast{ |
217 | Channel: "system", |
218 | ExpireOn: future, |
219 | Data: json.RawMessage(`{"b": 2}`), |
220 | @@ -201,26 +201,26 @@ |
221 | c.Assert(err, IsNil) |
222 | c.Assert(got, Matches, ".*ok.*") |
223 | |
224 | - events, errCh, stop := s.startClient(c, "DEVB", map[string]int64{ |
225 | + events, errCh, stop := s.StartClient(c, "DEVB", map[string]int64{ |
226 | protocol.SystemChannelId: -10, |
227 | }) |
228 | // gettting pending on connect |
229 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:2 payloads:[{"b":1},{"b":2}]`) |
230 | stop() |
231 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
232 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
233 | c.Check(len(errCh), Equals, 0) |
234 | } |
235 | |
236 | func (s *BroadcastAcceptanceSuite) TestBroadcastExpiration(c *C) { |
237 | // send broadcast that will be pending, and one that will expire |
238 | - got, err := s.postRequest("/broadcast", &api.Broadcast{ |
239 | + got, err := s.PostRequest("/broadcast", &api.Broadcast{ |
240 | Channel: "system", |
241 | ExpireOn: future, |
242 | Data: json.RawMessage(`{"b": 1}`), |
243 | }) |
244 | c.Assert(err, IsNil) |
245 | c.Assert(got, Matches, ".*ok.*") |
246 | - got, err = s.postRequest("/broadcast", &api.Broadcast{ |
247 | + got, err = s.PostRequest("/broadcast", &api.Broadcast{ |
248 | Channel: "system", |
249 | ExpireOn: time.Now().Add(1 * time.Second).Format(time.RFC3339), |
250 | Data: json.RawMessage(`{"b": 2}`), |
251 | @@ -231,10 +231,10 @@ |
252 | time.Sleep(2 * time.Second) |
253 | // second broadcast is expired |
254 | |
255 | - events, errCh, stop := s.startClient(c, "DEVB", nil) |
256 | + events, errCh, stop := s.StartClient(c, "DEVB", nil) |
257 | // gettting pending on connect |
258 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:2 payloads:[{"b":1}]`) |
259 | stop() |
260 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*EOF`) |
261 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
262 | c.Check(len(errCh), Equals, 0) |
263 | } |
264 | |
265 | === modified file 'server/acceptance/suites/helpers.go' |
266 | --- server/acceptance/suites/helpers.go 2014-02-11 20:36:32 +0000 |
267 | +++ server/acceptance/suites/helpers.go 2014-02-26 20:26:43 +0000 |
268 | @@ -92,12 +92,15 @@ |
269 | c.Fatal(err) |
270 | } |
271 | bufErr := bufio.NewReaderSize(stderr, 5000) |
272 | - getLineInfo := func() (string, error) { |
273 | + getLineInfo := func(full bool) (string, error) { |
274 | for { |
275 | line, err := bufErr.ReadString('\n') |
276 | if err != nil { |
277 | return "", err |
278 | } |
279 | + if full { |
280 | + return strings.TrimRight(line, "\n"), nil |
281 | + } |
282 | extracted := rxLineInfo.FindStringSubmatch(line) |
283 | if extracted == nil { |
284 | return "", fmt.Errorf("unexpected line: %#v", line) |
285 | @@ -108,13 +111,19 @@ |
286 | } |
287 | logs := make(chan string, 10) |
288 | go func() { |
289 | + paniced := false |
290 | for { |
291 | - info, err := getLineInfo() |
292 | + info, err := getLineInfo(paniced) |
293 | if err != nil { |
294 | logs <- fmt.Sprintf("%s capture: %v", cmdName, err) |
295 | close(logs) |
296 | return |
297 | } |
298 | + if paniced || strings.HasPrefix(info, "ERROR(PANIC") { |
299 | + paniced = true |
300 | + c.Log(info) |
301 | + continue |
302 | + } |
303 | logs <- info |
304 | } |
305 | }() |
306 | |
307 | === modified file 'server/acceptance/suites/pingpong.go' |
308 | --- server/acceptance/suites/pingpong.go 2014-02-11 20:36:32 +0000 |
309 | +++ server/acceptance/suites/pingpong.go 2014-02-26 20:26:43 +0000 |
310 | @@ -34,7 +34,7 @@ |
311 | func (s *PingPongAcceptanceSuite) TestConnectPingPing(c *C) { |
312 | errCh := make(chan error, 1) |
313 | events := make(chan string, 10) |
314 | - sess := testClientSession(s.serverAddr, "DEVA", true) |
315 | + sess := testClientSession(s.ServerAddr, "DEVA", true) |
316 | err := sess.Dial() |
317 | c.Assert(err, IsNil) |
318 | intercept := func(ic *interceptingConn, op string, b []byte) (bool, int, error) { |
319 | @@ -50,8 +50,8 @@ |
320 | errCh <- sess.Run(events) |
321 | }() |
322 | connectCli := NextEvent(events, errCh) |
323 | - connectSrv := NextEvent(s.serverEvents, nil) |
324 | - registeredSrv := NextEvent(s.serverEvents, nil) |
325 | + connectSrv := NextEvent(s.ServerEvents, nil) |
326 | + registeredSrv := NextEvent(s.ServerEvents, nil) |
327 | tconnect := time.Now() |
328 | c.Assert(connectSrv, Matches, ".*session.* connected .*") |
329 | c.Assert(registeredSrv, Matches, ".*session.* registered DEVA") |
330 | @@ -61,14 +61,14 @@ |
331 | c.Check(elapsedOfPing >= 1.0, Equals, true) |
332 | c.Check(elapsedOfPing < 1.05, Equals, true) |
333 | c.Assert(NextEvent(events, errCh), Equals, "Ping") |
334 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, ".*session.* ended with: EOF") |
335 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, ".*session.* ended with: EOF") |
336 | c.Check(len(errCh), Equals, 0) |
337 | } |
338 | |
339 | func (s *PingPongAcceptanceSuite) TestConnectPingNeverPong(c *C) { |
340 | errCh := make(chan error, 1) |
341 | events := make(chan string, 10) |
342 | - sess := testClientSession(s.serverAddr, "DEVB", true) |
343 | + sess := testClientSession(s.ServerAddr, "DEVB", true) |
344 | err := sess.Dial() |
345 | c.Assert(err, IsNil) |
346 | intercept := func(ic *interceptingConn, op string, b []byte) (bool, int, error) { |
347 | @@ -85,9 +85,9 @@ |
348 | errCh <- sess.Run(events) |
349 | }() |
350 | c.Assert(NextEvent(events, errCh), Matches, "connected .*") |
351 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, ".*session.* connected .*") |
352 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, ".*session.* registered .*") |
353 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, ".*session.* connected .*") |
354 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, ".*session.* registered .*") |
355 | c.Assert(NextEvent(events, errCh), Equals, "Ping") |
356 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, `.* ended with:.*timeout`) |
357 | + c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*timeout`) |
358 | c.Check(len(errCh), Equals, 0) |
359 | } |
360 | |
361 | === modified file 'server/acceptance/suites/suite.go' |
362 | --- server/acceptance/suites/suite.go 2014-02-11 20:36:32 +0000 |
363 | +++ server/acceptance/suites/suite.go 2014-02-26 20:26:43 +0000 |
364 | @@ -34,43 +34,79 @@ |
365 | helpers "launchpad.net/ubuntu-push/testing" |
366 | ) |
367 | |
368 | +// ServerHandle holds the information to attach a client to the test server. |
369 | +type ServerHandle struct { |
370 | + ServerAddr string |
371 | + ServerHTTPAddr string |
372 | + ServerEvents <-chan string |
373 | +} |
374 | + |
375 | +// Start a client. |
376 | +func (h *ServerHandle) StartClient(c *C, devId string, levels map[string]int64) (events <-chan string, errorCh <-chan error, stop func()) { |
377 | + errCh := make(chan error, 1) |
378 | + cliEvents := make(chan string, 10) |
379 | + sess := testClientSession(h.ServerAddr, devId, false) |
380 | + sess.Levels = levels |
381 | + err := sess.Dial() |
382 | + c.Assert(err, IsNil) |
383 | + clientShutdown := make(chan bool, 1) // abused as an atomic flag |
384 | + intercept := func(ic *interceptingConn, op string, b []byte) (bool, int, error) { |
385 | + // read after ack |
386 | + if op == "read" && len(clientShutdown) > 0 { |
387 | + // exit the sess.Run() goroutine, client will close |
388 | + runtime.Goexit() |
389 | + } |
390 | + return false, 0, nil |
391 | + } |
392 | + sess.Connection = &interceptingConn{sess.Connection, 0, 0, intercept} |
393 | + go func() { |
394 | + errCh <- sess.Run(cliEvents) |
395 | + }() |
396 | + c.Assert(NextEvent(cliEvents, errCh), Matches, "connected .*") |
397 | + c.Assert(NextEvent(h.ServerEvents, nil), Matches, ".*session.* connected .*") |
398 | + c.Assert(NextEvent(h.ServerEvents, nil), Matches, ".*session.* registered "+devId) |
399 | + return cliEvents, errCh, func() { clientShutdown <- true } |
400 | +} |
401 | + |
402 | // AcceptanceSuite has the basic functionality of the acceptance suites. |
403 | type AcceptanceSuite struct { |
404 | // hook to start the server(s) |
405 | - StartServer func(c *C) (logs <-chan string, kill func(), serverAddr, apiURL string) |
406 | - // running bits |
407 | - serverKill func() |
408 | - serverAddr string |
409 | - serverAPIURL string |
410 | - serverEvents <-chan string |
411 | - httpClient *http.Client |
412 | + StartServer func(c *C, s *AcceptanceSuite, handle *ServerHandle) |
413 | + // populated by StartServer |
414 | + ServerHandle |
415 | + ServerAPIURL string |
416 | + // KillGroup should be populated by StartServer with functions |
417 | + // to kill the server process |
418 | + KillGroup map[string]func() |
419 | + // other state |
420 | + httpClient *http.Client |
421 | } |
422 | |
423 | // Start a new server for each test. |
424 | func (s *AcceptanceSuite) SetUpTest(c *C) { |
425 | - logs, kill, addr, url := s.StartServer(c) |
426 | - s.serverEvents = logs |
427 | - s.serverKill = kill |
428 | - s.serverAddr = addr |
429 | - s.serverAPIURL = url |
430 | + s.KillGroup = make(map[string]func()) |
431 | + s.StartServer(c, s, &s.ServerHandle) |
432 | + c.Assert(s.ServerHandle.ServerEvents, NotNil) |
433 | + c.Assert(s.ServerHandle.ServerAddr, Not(Equals), "") |
434 | + c.Assert(s.ServerAPIURL, Not(Equals), "") |
435 | s.httpClient = &http.Client{} |
436 | } |
437 | |
438 | func (s *AcceptanceSuite) TearDownTest(c *C) { |
439 | - if s.serverKill != nil { |
440 | - s.serverKill() |
441 | + for _, f := range s.KillGroup { |
442 | + f() |
443 | } |
444 | } |
445 | |
446 | -// Post a request. |
447 | -func (s *AcceptanceSuite) postRequest(path string, message interface{}) (string, error) { |
448 | +// Post a API request. |
449 | +func (s *AcceptanceSuite) PostRequest(path string, message interface{}) (string, error) { |
450 | packedMessage, err := json.Marshal(message) |
451 | if err != nil { |
452 | panic(err) |
453 | } |
454 | reader := bytes.NewReader(packedMessage) |
455 | |
456 | - url := s.serverAPIURL + path |
457 | + url := s.ServerAPIURL + path |
458 | request, _ := http.NewRequest("POST", url, reader) |
459 | request.ContentLength = int64(reader.Len()) |
460 | request.Header.Set("Content-Type", "application/json") |
461 | @@ -141,30 +177,3 @@ |
462 | } |
463 | return |
464 | } |
465 | - |
466 | -// Start a client. |
467 | -func (s *AcceptanceSuite) startClient(c *C, devId string, levels map[string]int64) (events <-chan string, errorCh <-chan error, stop func()) { |
468 | - errCh := make(chan error, 1) |
469 | - cliEvents := make(chan string, 10) |
470 | - sess := testClientSession(s.serverAddr, devId, false) |
471 | - sess.Levels = levels |
472 | - err := sess.Dial() |
473 | - c.Assert(err, IsNil) |
474 | - clientShutdown := make(chan bool, 1) // abused as an atomic flag |
475 | - intercept := func(ic *interceptingConn, op string, b []byte) (bool, int, error) { |
476 | - // read after ack |
477 | - if op == "read" && len(clientShutdown) > 0 { |
478 | - // exit the sess.Run() goroutine, client will close |
479 | - runtime.Goexit() |
480 | - } |
481 | - return false, 0, nil |
482 | - } |
483 | - sess.Connection = &interceptingConn{sess.Connection, 0, 0, intercept} |
484 | - go func() { |
485 | - errCh <- sess.Run(cliEvents) |
486 | - }() |
487 | - c.Assert(NextEvent(cliEvents, errCh), Matches, "connected .*") |
488 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, ".*session.* connected .*") |
489 | - c.Assert(NextEvent(s.serverEvents, nil), Matches, ".*session.* registered "+devId) |
490 | - return cliEvents, errCh, func() { clientShutdown <- true } |
491 | -} |
LGTM, except you want "panicked" rather than "paniced".