Merge lp:~pedronis/ubuntu-push/kindpool-test-derace into lp:ubuntu-push
- kindpool-test-derace
- Merge into trunk
Proposed by
Samuele Pedroni
Status: | Superseded |
---|---|
Proposed branch: | lp:~pedronis/ubuntu-push/kindpool-test-derace |
Merge into: | lp:ubuntu-push |
Diff against target: |
1106 lines (+405/-177) 18 files modified
bus/notifications/raw.go (+1/-1) bus/notifications/raw_test.go (+13/-0) click/click.go (+13/-0) click/click_test.go (+18/-0) client/client_test.go (+6/-2) dependencies.tsv (+1/-1) launch_helper/kindpool.go (+1/-1) launch_helper/kindpool_test.go (+10/-3) launch_helper/legacy/legacy.go (+20/-6) launch_helper/legacy/legacy_test.go (+16/-2) server/acceptance/acceptanceclient.go (+15/-16) server/acceptance/cmd/acceptanceclient.go (+54/-0) server/acceptance/kit/api.go (+82/-0) server/acceptance/kit/cliloop.go (+75/-52) server/acceptance/kit/helpers.go (+46/-0) server/acceptance/suites/broadcast.go (+14/-27) server/acceptance/suites/suite.go (+5/-40) server/acceptance/suites/unicast.go (+15/-26) |
To merge this branch: | bzr merge lp:~pedronis/ubuntu-push/kindpool-test-derace |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Push Hackers | Pending | ||
Review via email: mp+231905@code.launchpad.net |
Commit message
avoid rare race in kindpool_test.go
Description of the change
avoid rare race in test,
better to change globals once in SetUpSuite than again and again in SetUpTest
To post a comment you must log in.
- 314. By Samuele Pedroni
-
avoid rare race in test
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bus/notifications/raw.go' |
2 | --- bus/notifications/raw.go 2014-07-27 00:58:08 +0000 |
3 | +++ bus/notifications/raw.go 2014-08-22 14:47:03 +0000 |
4 | @@ -144,7 +144,7 @@ |
5 | } |
6 | |
7 | hints := make(map[string]*dbus.Variant) |
8 | - hints["x-canonical-secondary-icon"] = &dbus.Variant{app.Icon()} |
9 | + hints["x-canonical-secondary-icon"] = &dbus.Variant{app.SymbolicIcon()} |
10 | |
11 | appId := app.Original() |
12 | actions := make([]string, 2*len(card.Actions)) |
13 | |
14 | === modified file 'bus/notifications/raw_test.go' |
15 | --- bus/notifications/raw_test.go 2014-07-27 00:58:08 +0000 |
16 | +++ bus/notifications/raw_test.go 2014-08-22 14:47:03 +0000 |
17 | @@ -210,6 +210,19 @@ |
18 | c.Check(hints["x-canonical-secondary-icon"], NotNil) |
19 | } |
20 | |
21 | +func (s *RawSuite) TestPresentUsesSymbolic(c *C) { |
22 | + endp := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1)) |
23 | + raw := Raw(endp, s.log) |
24 | + worked := raw.Present(s.app, "notifId", &launch_helper.Notification{Card: &launch_helper.Card{Summary: "summary", Popup: true}}) |
25 | + c.Assert(worked, Equals, true) |
26 | + callArgs := testibus.GetCallArgs(endp) |
27 | + c.Assert(callArgs, HasLen, 1) |
28 | + c.Assert(callArgs[0].Args, HasLen, 8) |
29 | + hints, ok := callArgs[0].Args[6].(map[string]*dbus.Variant) |
30 | + c.Assert(ok, Equals, true) |
31 | + c.Check(hints["x-canonical-secondary-icon"].Value.(string), Equals, "-symbolic") |
32 | +} |
33 | + |
34 | func (s *RawSuite) TestPresentNoNotificationPanics(c *C) { |
35 | endp := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1)) |
36 | raw := Raw(endp, s.log) |
37 | |
38 | === modified file 'click/click.go' |
39 | --- click/click.go 2014-08-06 02:44:06 +0000 |
40 | +++ click/click.go 2014-08-22 14:47:03 +0000 |
41 | @@ -136,6 +136,19 @@ |
42 | return cappinfo.AppIconFromDesktopId(app.DesktopId()) |
43 | } |
44 | |
45 | +func _symbolic(icon string) string { |
46 | + if strings.ContainsRune(icon, '/') { |
47 | + return icon |
48 | + } |
49 | + return icon + "-symbolic" |
50 | +} |
51 | + |
52 | +var symbolic = _symbolic |
53 | + |
54 | +func (app *AppId) SymbolicIcon() string { |
55 | + return symbolic(app.Icon()) |
56 | +} |
57 | + |
58 | func (app *AppId) MarshalJSON() ([]byte, error) { |
59 | return json.Marshal(app.Original()) |
60 | } |
61 | |
62 | === modified file 'click/click_test.go' |
63 | --- click/click_test.go 2014-08-06 03:50:14 +0000 |
64 | +++ click/click_test.go 2014-08-22 14:47:03 +0000 |
65 | @@ -182,3 +182,21 @@ |
66 | c.Check(app, NotNil) |
67 | c.Check(app.Original(), Equals, "_non-existent-app") |
68 | } |
69 | + |
70 | +func (s *clickSuite) TestSymbolicAppendsSymbolicIfIconIsName(c *C) { |
71 | + symb := symbolic("foo") |
72 | + c.Check(symb, Equals, "foo-symbolic") |
73 | +} |
74 | + |
75 | +func (s *clickSuite) TestSymbolicLeavesAloneIfIconIsPath(c *C) { |
76 | + symb := symbolic("foo/bar") |
77 | + c.Check(symb, Equals, "foo/bar") |
78 | +} |
79 | + |
80 | +func (s *clickSuite) TestSymbolicIconCallsSymbolic(c *C) { |
81 | + symbolic = func(string) string { return "xyzzy" } |
82 | + defer func() { symbolic = _symbolic }() |
83 | + app, err := ParseAppId("_python3.4") |
84 | + c.Assert(err, IsNil) |
85 | + c.Check(app.SymbolicIcon(), Equals, "xyzzy") |
86 | +} |
87 | |
88 | === modified file 'client/client_test.go' |
89 | --- client/client_test.go 2014-08-12 00:32:32 +0000 |
90 | +++ client/client_test.go 2014-08-22 14:47:03 +0000 |
91 | @@ -143,7 +143,11 @@ |
92 | |
93 | func (cs *clientSuite) SetUpSuite(c *C) { |
94 | config.IgnoreParsedFlags = true // because configure() uses <flags> |
95 | - newIdentifier = func() (identifier.Id, error) { return idtesting.Settable(), nil } |
96 | + newIdentifier = func() (identifier.Id, error) { |
97 | + id := idtesting.Settable() |
98 | + id.Set("42") // must be hex of len 32 |
99 | + return id, nil |
100 | + } |
101 | cs.timeouts = util.SwapTimeouts([]time.Duration{0}) |
102 | cs.leveldbPath = "" |
103 | } |
104 | @@ -1141,7 +1145,7 @@ |
105 | // and now everthing is better! We have a config, |
106 | c.Check(string(cli.config.Addr), Equals, ":0") |
107 | // and a device id, |
108 | - c.Check(cli.deviceId, HasLen, 32) |
109 | + c.Check(cli.deviceId, HasLen, 40) |
110 | // and a session, |
111 | c.Check(cli.session, NotNil) |
112 | // and a bus, |
113 | |
114 | === modified file 'dependencies.tsv' |
115 | --- dependencies.tsv 2014-07-26 07:28:59 +0000 |
116 | +++ dependencies.tsv 2014-08-22 14:47:03 +0000 |
117 | @@ -1,5 +1,5 @@ |
118 | code.google.com/p/go-uuid hg 7dda39b2e7d5e265014674c5af696ba4186679e9 11 |
119 | code.google.com/p/gosqlite hg 74691fb6f83716190870cde1b658538dd4b18eb0 15 |
120 | -launchpad.net/go-dbus/v1 bzr james@jamesh.id.au-20140530132806-hpqbkxczif6o1dpz 127 |
121 | +launchpad.net/go-dbus/v1 bzr james@jamesh.id.au-20140801110939-lzfql7fk76dt6ckd 128 |
122 | launchpad.net/go-xdg/v0 bzr john.lenton@canonical.com-20140208094800-gubd5md7cro3mtxa 10 |
123 | launchpad.net/gocheck bzr gustavo@niemeyer.net-20140225173054-xu9zlkf9kxhvow02 87 |
124 | |
125 | === modified file 'launch_helper/kindpool.go' |
126 | --- launch_helper/kindpool.go 2014-07-29 15:24:01 +0000 |
127 | +++ launch_helper/kindpool.go 2014-08-22 14:47:03 +0000 |
128 | @@ -72,7 +72,7 @@ |
129 | func DefaultLaunchers(log logger.Logger) map[string]HelperLauncher { |
130 | return map[string]HelperLauncher{ |
131 | "click": cual.New(log), |
132 | - "legacy": legacy.New(), |
133 | + "legacy": legacy.New(log), |
134 | } |
135 | } |
136 | |
137 | |
138 | === modified file 'launch_helper/kindpool_test.go' |
139 | --- launch_helper/kindpool_test.go 2014-08-08 09:03:42 +0000 |
140 | +++ launch_helper/kindpool_test.go 2014-08-22 14:47:03 +0000 |
141 | @@ -102,16 +102,22 @@ |
142 | return args |
143 | } |
144 | |
145 | +func (s *poolSuite) SetUpSuite(c *C) { |
146 | + xdgCacheHome = c.MkDir |
147 | +} |
148 | + |
149 | +func (s *poolSuite) TearDownSuite(c *C) { |
150 | + xdgCacheHome = xdg.Cache.Home |
151 | +} |
152 | + |
153 | func (s *poolSuite) SetUpTest(c *C) { |
154 | s.log = helpers.NewTestLogger(c, "debug") |
155 | s.fakeLauncher = &fakeHelperLauncher{argCh: make(chan [5]string, 10)} |
156 | s.pool = NewHelperPool(map[string]HelperLauncher{"fake": s.fakeLauncher}, s.log) |
157 | - xdgCacheHome = c.MkDir |
158 | } |
159 | |
160 | func (s *poolSuite) TearDownTest(c *C) { |
161 | s.pool = nil |
162 | - xdgCacheHome = xdg.Cache.Home |
163 | } |
164 | |
165 | func (s *poolSuite) TestDefaultLaunchers(c *C) { |
166 | @@ -379,8 +385,9 @@ |
167 | } |
168 | |
169 | func (s *poolSuite) TestGetTempFilename(c *C) { |
170 | + tmpDir := c.MkDir() |
171 | GetTempDir = func(pkgName string) (string, error) { |
172 | - return c.MkDir(), nil |
173 | + return tmpDir, nil |
174 | } |
175 | // restore it when we are done |
176 | defer func() { |
177 | |
178 | === modified file 'launch_helper/legacy/legacy.go' |
179 | --- launch_helper/legacy/legacy.go 2014-07-18 20:45:21 +0000 |
180 | +++ launch_helper/legacy/legacy.go 2014-08-22 14:47:03 +0000 |
181 | @@ -18,20 +18,23 @@ |
182 | package legacy |
183 | |
184 | import ( |
185 | + "io" |
186 | "os" |
187 | "os/exec" |
188 | "path/filepath" |
189 | "strconv" |
190 | |
191 | "launchpad.net/ubuntu-push/click" |
192 | + "launchpad.net/ubuntu-push/logger" |
193 | ) |
194 | |
195 | type legacyHelperLauncher struct { |
196 | + log logger.Logger |
197 | done func(string) |
198 | } |
199 | |
200 | -func New() *legacyHelperLauncher { |
201 | - return new(legacyHelperLauncher) |
202 | +func New(log logger.Logger) *legacyHelperLauncher { |
203 | + return &legacyHelperLauncher{log: log} |
204 | } |
205 | |
206 | func (lhl *legacyHelperLauncher) InstallObserver(done func(string)) error { |
207 | @@ -50,9 +53,10 @@ |
208 | func (lhl *legacyHelperLauncher) Launch(_, progname, f1, f2 string) (string, error) { |
209 | cmd := exec.Command(progname, f1, f2) |
210 | cmd.Stdin = nil |
211 | - cmd.Stdout = nil |
212 | - cmd.Stderr = nil |
213 | - |
214 | + var stdout_r, stdout_w = io.Pipe() |
215 | + var stderr_r, stderr_w = io.Pipe() |
216 | + cmd.Stdout = stdout_w |
217 | + cmd.Stderr = stderr_w |
218 | err := cmd.Start() |
219 | if err != nil { |
220 | return "", err |
221 | @@ -63,7 +67,17 @@ |
222 | } |
223 | id := strconv.FormatInt((int64)(proc.Pid), 36) |
224 | go func() { |
225 | - proc.Wait() |
226 | + state, p_err := proc.Wait() |
227 | + if p_err != nil || !state.Success() { |
228 | + // Helper failed, log output |
229 | + var data []byte |
230 | + stdout_w.Close() |
231 | + stdout_r.Read(data) |
232 | + lhl.log.Errorf("Legacy helper failed. Stdout: %s", data) |
233 | + stderr_w.Close() |
234 | + stderr_r.Read(data) |
235 | + lhl.log.Errorf("Legacy helper failed. Stderr: %s", data) |
236 | + } |
237 | lhl.done(id) |
238 | }() |
239 | |
240 | |
241 | === modified file 'launch_helper/legacy/legacy_test.go' |
242 | --- launch_helper/legacy/legacy_test.go 2014-07-18 20:45:21 +0000 |
243 | +++ launch_helper/legacy/legacy_test.go 2014-08-22 14:47:03 +0000 |
244 | @@ -32,7 +32,7 @@ |
245 | select { |
246 | case s := <-ch: |
247 | return s |
248 | - case <-time.After(time.Second): |
249 | + case <-time.After(5 * time.Second): |
250 | c.Fatal("timed out waiting for value") |
251 | return "" |
252 | } |
253 | @@ -42,12 +42,14 @@ |
254 | |
255 | type legacySuite struct { |
256 | lhl *legacyHelperLauncher |
257 | + log *helpers.TestLogger |
258 | } |
259 | |
260 | var _ = Suite(&legacySuite{}) |
261 | |
262 | func (ls *legacySuite) SetUpTest(c *C) { |
263 | - ls.lhl = New() |
264 | + ls.log = helpers.NewTestLogger(c, "info") |
265 | + ls.lhl = New(ls.log) |
266 | } |
267 | |
268 | func (ls *legacySuite) TestInstallObserver(c *C) { |
269 | @@ -94,12 +96,24 @@ |
270 | c.Assert(err, NotNil) |
271 | } |
272 | |
273 | +func (ls *legacySuite) TestHelperFails(c *C) { |
274 | + ch := make(chan string, 1) |
275 | + c.Assert(ls.lhl.InstallObserver(func(id string) { ch <- id }), IsNil) |
276 | + |
277 | + _, err := ls.lhl.Launch("", "/bin/false", "", "") |
278 | + c.Assert(err, IsNil) |
279 | + |
280 | + takeNext(ch, c) |
281 | + c.Check(ls.log.Captured(), Matches, "(?s).*Legacy helper failed.*") |
282 | +} |
283 | + |
284 | func (ls *legacySuite) TestStop(c *C) { |
285 | ch := make(chan string, 1) |
286 | c.Assert(ls.lhl.InstallObserver(func(id string) { ch <- id }), IsNil) |
287 | |
288 | exe := helpers.ScriptAbsPath("slow-helper.sh") |
289 | id, err := ls.lhl.Launch("", exe, "", "") |
290 | + c.Assert(err, IsNil) |
291 | |
292 | err = ls.lhl.Stop("", "===") |
293 | c.Check(err, NotNil) // not a valid id |
294 | |
295 | === modified file 'server/acceptance/acceptanceclient.go' |
296 | --- server/acceptance/acceptanceclient.go 2014-06-05 09:32:43 +0000 |
297 | +++ server/acceptance/acceptanceclient.go 2014-08-22 14:47:03 +0000 |
298 | @@ -19,9 +19,7 @@ |
299 | |
300 | import ( |
301 | "crypto/tls" |
302 | - "crypto/x509" |
303 | "encoding/json" |
304 | - "errors" |
305 | "fmt" |
306 | "net" |
307 | "strings" |
308 | @@ -40,35 +38,36 @@ |
309 | ImageChannel string |
310 | ServerAddr string |
311 | ExchangeTimeout time.Duration |
312 | - CertPEMBlock []byte |
313 | ReportPings bool |
314 | Levels map[string]int64 |
315 | - Insecure bool // don't verify certs |
316 | + TLSConfig *tls.Config |
317 | Prefix string // prefix for events |
318 | Auth string |
319 | // connection |
320 | Connection net.Conn |
321 | } |
322 | |
323 | -// Dial connects to a server using the configuration in the ClientSession |
324 | -// and sets up the connection. |
325 | +// Dial connects to a server using the configuration in the |
326 | +// ClientSession and sets up the connection. |
327 | func (sess *ClientSession) Dial() error { |
328 | conn, err := net.DialTimeout("tcp", sess.ServerAddr, sess.ExchangeTimeout) |
329 | if err != nil { |
330 | return err |
331 | } |
332 | - tlsConfig := &tls.Config{} |
333 | - if sess.CertPEMBlock != nil { |
334 | - cp := x509.NewCertPool() |
335 | - ok := cp.AppendCertsFromPEM(sess.CertPEMBlock) |
336 | - if !ok { |
337 | - return errors.New("dial: could not parse certificate") |
338 | - } |
339 | - tlsConfig.RootCAs = cp |
340 | + sess.TLSWrapAndSet(conn) |
341 | + return nil |
342 | +} |
343 | + |
344 | +// TLSWrapAndSet wraps a socket connection in tls and sets it as |
345 | +// session.Connection. For use instead of Dial(). |
346 | +func (sess *ClientSession) TLSWrapAndSet(conn net.Conn) { |
347 | + var tlsConfig *tls.Config |
348 | + if sess.TLSConfig != nil { |
349 | + tlsConfig = sess.TLSConfig |
350 | + } else { |
351 | + tlsConfig = &tls.Config{} |
352 | } |
353 | - tlsConfig.InsecureSkipVerify = sess.Insecure |
354 | sess.Connection = tls.Client(conn, tlsConfig) |
355 | - return nil |
356 | } |
357 | |
358 | type serverMsg struct { |
359 | |
360 | === added file 'server/acceptance/cmd/acceptanceclient.go' |
361 | --- server/acceptance/cmd/acceptanceclient.go 1970-01-01 00:00:00 +0000 |
362 | +++ server/acceptance/cmd/acceptanceclient.go 2014-08-22 14:47:03 +0000 |
363 | @@ -0,0 +1,54 @@ |
364 | +/* |
365 | + Copyright 2013-2014 Canonical Ltd. |
366 | + |
367 | + This program is free software: you can redistribute it and/or modify it |
368 | + under the terms of the GNU General Public License version 3, as published |
369 | + by the Free Software Foundation. |
370 | + |
371 | + This program is distributed in the hope that it will be useful, but |
372 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
373 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
374 | + PURPOSE. See the GNU General Public License for more details. |
375 | + |
376 | + You should have received a copy of the GNU General Public License along |
377 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
378 | +*/ |
379 | + |
380 | +// acceptanceclient command for playing. |
381 | +package main |
382 | + |
383 | +import ( |
384 | + "log" |
385 | + "os/exec" |
386 | + "strings" |
387 | + |
388 | + "launchpad.net/ubuntu-push/server/acceptance" |
389 | + "launchpad.net/ubuntu-push/server/acceptance/kit" |
390 | +) |
391 | + |
392 | +type configuration struct { |
393 | + kit.Configuration |
394 | + AuthHelper string `json:"auth_helper"` |
395 | + WaitFor string `json:"wait_for"` |
396 | +} |
397 | + |
398 | +func main() { |
399 | + kit.Defaults["auth_helper"] = "" |
400 | + kit.Defaults["wait_for"] = "" |
401 | + cfg := &configuration{} |
402 | + kit.CliLoop(cfg, &cfg.Configuration, func(session *acceptance.ClientSession, cfgDir string) { |
403 | + log.Printf("with: %#v", session) |
404 | + }, func(url string) string { |
405 | + if cfg.AuthHelper == "" { |
406 | + return "" |
407 | + } |
408 | + auth, err := exec.Command(cfg.AuthHelper, url).Output() |
409 | + if err != nil { |
410 | + log.Fatalf("auth helper: %v", err) |
411 | + } |
412 | + return strings.TrimSpace(string(auth)) |
413 | + }, func() string { |
414 | + return cfg.WaitFor |
415 | + }, func() { |
416 | + }) |
417 | +} |
418 | |
419 | === added directory 'server/acceptance/kit' |
420 | === added file 'server/acceptance/kit/api.go' |
421 | --- server/acceptance/kit/api.go 1970-01-01 00:00:00 +0000 |
422 | +++ server/acceptance/kit/api.go 2014-08-22 14:47:03 +0000 |
423 | @@ -0,0 +1,82 @@ |
424 | +/* |
425 | + Copyright 2013-2014 Canonical Ltd. |
426 | + |
427 | + This program is free software: you can redistribute it and/or modify it |
428 | + under the terms of the GNU General Public License version 3, as published |
429 | + by the Free Software Foundation. |
430 | + |
431 | + This program is distributed in the hope that it will be useful, but |
432 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
433 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
434 | + PURPOSE. See the GNU General Public License for more details. |
435 | + |
436 | + You should have received a copy of the GNU General Public License along |
437 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
438 | +*/ |
439 | + |
440 | +// Package kit contains reusable building blocks for acceptance. |
441 | +package kit |
442 | + |
443 | +import ( |
444 | + "bytes" |
445 | + "crypto/tls" |
446 | + "encoding/json" |
447 | + "errors" |
448 | + "io/ioutil" |
449 | + "net/http" |
450 | +) |
451 | + |
452 | +// APIClient helps making api requests. |
453 | +type APIClient struct { |
454 | + ServerAPIURL string |
455 | + // hook to adjust requests |
456 | + MassageRequest func(req *http.Request, message interface{}) *http.Request |
457 | + // other state |
458 | + httpClient *http.Client |
459 | +} |
460 | + |
461 | +// SetupClient sets up the http client to make requests. |
462 | +func (api *APIClient) SetupClient(tlsConfig *tls.Config) { |
463 | + api.httpClient = &http.Client{ |
464 | + Transport: &http.Transport{TLSClientConfig: tlsConfig}, |
465 | + } |
466 | +} |
467 | + |
468 | +var ErrNOk = errors.New("not ok") |
469 | + |
470 | +// Post a API request. |
471 | +func (api *APIClient) PostRequest(path string, message interface{}) (map[string]interface{}, error) { |
472 | + packedMessage, err := json.Marshal(message) |
473 | + if err != nil { |
474 | + panic(err) |
475 | + } |
476 | + reader := bytes.NewReader(packedMessage) |
477 | + |
478 | + url := api.ServerAPIURL + path |
479 | + request, _ := http.NewRequest("POST", url, reader) |
480 | + request.ContentLength = int64(reader.Len()) |
481 | + request.Header.Set("Content-Type", "application/json") |
482 | + |
483 | + if api.MassageRequest != nil { |
484 | + request = api.MassageRequest(request, message) |
485 | + } |
486 | + |
487 | + resp, err := api.httpClient.Do(request) |
488 | + if err != nil { |
489 | + return nil, err |
490 | + } |
491 | + defer resp.Body.Close() |
492 | + body, err := ioutil.ReadAll(resp.Body) |
493 | + if err != nil { |
494 | + return nil, err |
495 | + } |
496 | + var res map[string]interface{} |
497 | + err = json.Unmarshal(body, &res) |
498 | + if err != nil { |
499 | + return nil, err |
500 | + } |
501 | + if ok, _ := res["ok"].(bool); !ok { |
502 | + return res, ErrNOk |
503 | + } |
504 | + return res, nil |
505 | +} |
506 | |
507 | === renamed file 'server/acceptance/cmd/acceptanceclient.go' => 'server/acceptance/kit/cliloop.go' |
508 | --- server/acceptance/cmd/acceptanceclient.go 2014-07-11 21:24:21 +0000 |
509 | +++ server/acceptance/kit/cliloop.go 2014-08-22 14:47:03 +0000 |
510 | @@ -14,15 +14,13 @@ |
511 | with this program. If not, see <http://www.gnu.org/licenses/>. |
512 | */ |
513 | |
514 | -// acceptanceclient command for playing. |
515 | -package main |
516 | +package kit |
517 | |
518 | import ( |
519 | "flag" |
520 | "fmt" |
521 | "log" |
522 | "os" |
523 | - "os/exec" |
524 | "path/filepath" |
525 | "regexp" |
526 | "strings" |
527 | @@ -32,27 +30,58 @@ |
528 | "launchpad.net/ubuntu-push/server/acceptance" |
529 | ) |
530 | |
531 | -var ( |
532 | - insecureFlag = flag.Bool("insecure", false, "disable checking of server certificate and hostname") |
533 | - reportPingsFlag = flag.Bool("reportPings", true, "report each Ping from the server") |
534 | - deviceModel = flag.String("model", "?", "device image model") |
535 | - imageChannel = flag.String("imageChannel", "?", "image channel") |
536 | -) |
537 | - |
538 | -type configuration struct { |
539 | +type Configuration struct { |
540 | // session configuration |
541 | ExchangeTimeout config.ConfigTimeDuration `json:"exchange_timeout"` |
542 | // server connection config |
543 | - Addr config.ConfigHostPort |
544 | - CertPEMFile string `json:"cert_pem_file"` |
545 | - AuthHelper string `json:"auth_helper"` |
546 | - RunTimeout config.ConfigTimeDuration `json:"run_timeout"` |
547 | - WaitFor string `json:"wait_for"` |
548 | -} |
549 | - |
550 | -func main() { |
551 | + Target string `json:"target"` |
552 | + Addr config.ConfigHostPort `json:"addr"` |
553 | + CertPEMFile string `json:"cert_pem_file"` |
554 | + Insecure bool `json:"insecure" help:"disable checking of server certificate and hostname"` |
555 | + Domain string `json:"domain" help:"domain for tls connect"` |
556 | + // run timeout |
557 | + RunTimeout config.ConfigTimeDuration `json:"run_timeout"` |
558 | + // flags |
559 | + ReportPings bool `json:"reportPings" help:"report each Ping from the server"` |
560 | + DeviceModel string `json:"model" help:"device image model"` |
561 | + ImageChannel string `json:"imageChannel" help:"image channel"` |
562 | +} |
563 | + |
564 | +func (cfg *Configuration) PickByTarget(what, productionValue, stagingValue string) (value string) { |
565 | + switch cfg.Target { |
566 | + case "production": |
567 | + value = productionValue |
568 | + case "staging": |
569 | + value = stagingValue |
570 | + case "": |
571 | + log.Fatalf("either %s or target must be given", what) |
572 | + default: |
573 | + log.Fatalf("if specified target should be production|staging") |
574 | + } |
575 | + return |
576 | +} |
577 | + |
578 | +// Control. |
579 | +var ( |
580 | + Name = "acceptanceclient" |
581 | + Defaults = map[string]interface{}{ |
582 | + "target": "", |
583 | + "addr": ":0", |
584 | + "exchange_timeout": "5s", |
585 | + "cert_pem_file": "", |
586 | + "insecure": false, |
587 | + "domain": "", |
588 | + "run_timeout": "0s", |
589 | + "reportPings": true, |
590 | + "model": "?", |
591 | + "imageChannel": "?", |
592 | + } |
593 | +) |
594 | + |
595 | +// CliLoop parses command line arguments and runs a client loop. |
596 | +func CliLoop(totalCfg interface{}, cfg *Configuration, onSetup func(sess *acceptance.ClientSession, cfgDir string), auth func(string) string, waitFor func() string, onConnect func()) { |
597 | flag.Usage = func() { |
598 | - fmt.Fprintf(os.Stderr, "Usage: acceptancclient [options] <device id>\n") |
599 | + fmt.Fprintf(os.Stderr, "Usage: %s [options] <device id>\n", Name) |
600 | flag.PrintDefaults() |
601 | } |
602 | missingArg := func(what string) { |
603 | @@ -60,14 +89,7 @@ |
604 | flag.Usage() |
605 | os.Exit(2) |
606 | } |
607 | - cfg := &configuration{} |
608 | - err := config.ReadFilesDefaults(cfg, map[string]interface{}{ |
609 | - "exchange_timeout": "5s", |
610 | - "cert_pem_file": "", |
611 | - "auth_helper": "", |
612 | - "run_timeout": "0s", |
613 | - "wait_for": "", |
614 | - }, "<flags>") |
615 | + err := config.ReadFilesDefaults(totalCfg, Defaults, "<flags>") |
616 | if err != nil { |
617 | log.Fatalf("reading config: %v", err) |
618 | } |
619 | @@ -76,36 +98,34 @@ |
620 | case narg < 1: |
621 | missingArg("device-id") |
622 | } |
623 | + addr := "" |
624 | + if cfg.Addr == ":0" { |
625 | + addr = cfg.PickByTarget("addr", "push-delivery.ubuntu.com:443", |
626 | + "push-delivery.staging.ubuntu.com:443") |
627 | + } else { |
628 | + addr = cfg.Addr.HostPort() |
629 | + } |
630 | session := &acceptance.ClientSession{ |
631 | ExchangeTimeout: cfg.ExchangeTimeout.TimeDuration(), |
632 | - ServerAddr: cfg.Addr.HostPort(), |
633 | + ServerAddr: addr, |
634 | DeviceId: flag.Arg(0), |
635 | // flags |
636 | - Model: *deviceModel, |
637 | - ImageChannel: *imageChannel, |
638 | - ReportPings: *reportPingsFlag, |
639 | - Insecure: *insecureFlag, |
640 | - } |
641 | - log.Printf("with: %#v", session) |
642 | - if !*insecureFlag && cfg.CertPEMFile != "" { |
643 | - cfgDir := filepath.Dir(flag.Lookup("cfg@").Value.String()) |
644 | - log.Printf("cert: %v relToDir: %v", cfg.CertPEMFile, cfgDir) |
645 | - session.CertPEMBlock, err = config.LoadFile(cfg.CertPEMFile, cfgDir) |
646 | - if err != nil { |
647 | - log.Fatalf("reading CertPEMFile: %v", err) |
648 | - } |
649 | - } |
650 | - if len(cfg.AuthHelper) != 0 { |
651 | - auth, err := exec.Command(cfg.AuthHelper, "https://push.ubuntu.com/").Output() |
652 | - if err != nil { |
653 | - log.Fatalf("auth helper: %v", err) |
654 | - } |
655 | - session.Auth = strings.TrimSpace(string(auth)) |
656 | - } |
657 | + Model: cfg.DeviceModel, |
658 | + ImageChannel: cfg.ImageChannel, |
659 | + ReportPings: cfg.ReportPings, |
660 | + } |
661 | + cfgDir := filepath.Dir(flag.Lookup("cfg@").Value.String()) |
662 | + onSetup(session, cfgDir) |
663 | + session.TLSConfig, err = MakeTLSConfig(cfg.Domain, cfg.Insecure, cfg.CertPEMFile, cfgDir) |
664 | + if err != nil { |
665 | + log.Fatalf("tls config: %v", err) |
666 | + } |
667 | + session.Auth = auth("https://push.ubuntu.com/") |
668 | var waitForRegexp *regexp.Regexp |
669 | - if cfg.WaitFor != "" { |
670 | + waitForStr := waitFor() |
671 | + if waitForStr != "" { |
672 | var err error |
673 | - waitForRegexp, err = regexp.Compile(cfg.WaitFor) |
674 | + waitForRegexp, err = regexp.Compile(waitForStr) |
675 | if err != nil { |
676 | log.Fatalf("wait_for regexp: %v", err) |
677 | } |
678 | @@ -118,6 +138,9 @@ |
679 | go func() { |
680 | for { |
681 | ev := <-events |
682 | + if strings.HasPrefix(ev, "connected") { |
683 | + onConnect() |
684 | + } |
685 | if waitForRegexp != nil && waitForRegexp.MatchString(ev) { |
686 | log.Println("<matching-event>:", ev) |
687 | os.Exit(0) |
688 | |
689 | === added file 'server/acceptance/kit/helpers.go' |
690 | --- server/acceptance/kit/helpers.go 1970-01-01 00:00:00 +0000 |
691 | +++ server/acceptance/kit/helpers.go 2014-08-22 14:47:03 +0000 |
692 | @@ -0,0 +1,46 @@ |
693 | +/* |
694 | + Copyright 2013-2014 Canonical Ltd. |
695 | + |
696 | + This program is free software: you can redistribute it and/or modify it |
697 | + under the terms of the GNU General Public License version 3, as published |
698 | + by the Free Software Foundation. |
699 | + |
700 | + This program is distributed in the hope that it will be useful, but |
701 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
702 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
703 | + PURPOSE. See the GNU General Public License for more details. |
704 | + |
705 | + You should have received a copy of the GNU General Public License along |
706 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
707 | +*/ |
708 | + |
709 | +package kit |
710 | + |
711 | +import ( |
712 | + "crypto/tls" |
713 | + "crypto/x509" |
714 | + "fmt" |
715 | + |
716 | + "launchpad.net/ubuntu-push/config" |
717 | +) |
718 | + |
719 | +// MakeTLSConfig makes a tls.Config, optionally reading a cert from |
720 | +// disk, possibly relative to relDir. |
721 | +func MakeTLSConfig(domain string, insecure bool, certPEMFile string, relDir string) (*tls.Config, error) { |
722 | + tlsConfig := &tls.Config{} |
723 | + tlsConfig.ServerName = domain |
724 | + tlsConfig.InsecureSkipVerify = insecure |
725 | + if !insecure && certPEMFile != "" { |
726 | + certPEMBlock, err := config.LoadFile(certPEMFile, relDir) |
727 | + if err != nil { |
728 | + return nil, fmt.Errorf("reading cert: %v", err) |
729 | + } |
730 | + cp := x509.NewCertPool() |
731 | + ok := cp.AppendCertsFromPEM(certPEMBlock) |
732 | + if !ok { |
733 | + return nil, fmt.Errorf("could not parse certificate") |
734 | + } |
735 | + tlsConfig.RootCAs = cp |
736 | + } |
737 | + return tlsConfig, nil |
738 | +} |
739 | |
740 | === modified file 'server/acceptance/suites/broadcast.go' |
741 | --- server/acceptance/suites/broadcast.go 2014-06-25 11:00:15 +0000 |
742 | +++ server/acceptance/suites/broadcast.go 2014-08-22 14:47:03 +0000 |
743 | @@ -41,8 +41,7 @@ |
744 | ExpireOn: future, |
745 | Data: json.RawMessage(`{"img1/m1": 42}`), |
746 | }) |
747 | - c.Assert(err, IsNil) |
748 | - c.Assert(got, Matches, OK) |
749 | + c.Assert(err, IsNil, Commentf("%v", got)) |
750 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":42}]`) |
751 | stop() |
752 | c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
753 | @@ -56,14 +55,13 @@ |
754 | ExpireOn: future, |
755 | Data: json.RawMessage(`{"img1/m2": 10}`), |
756 | }) |
757 | - c.Assert(err, IsNil) |
758 | + c.Assert(err, IsNil, Commentf("%v", got)) |
759 | got, err = s.PostRequest("/broadcast", &api.Broadcast{ |
760 | Channel: "system", |
761 | ExpireOn: future, |
762 | Data: json.RawMessage(`{"img1/m1": 20}`), |
763 | }) |
764 | - c.Assert(err, IsNil) |
765 | - c.Assert(got, Matches, OK) |
766 | + c.Assert(err, IsNil, Commentf("%v", got)) |
767 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:2 payloads:[{"img1/m1":20}]`) |
768 | stop() |
769 | c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
770 | @@ -77,8 +75,7 @@ |
771 | ExpireOn: future, |
772 | Data: json.RawMessage(`{"img1/m1": 1}`), |
773 | }) |
774 | - c.Assert(err, IsNil) |
775 | - c.Assert(got, Matches, OK) |
776 | + c.Assert(err, IsNil, Commentf("%v", got)) |
777 | |
778 | events, errCh, stop := s.StartClient(c, "DEVB", nil) |
779 | // gettting pending on connect |
780 | @@ -97,8 +94,7 @@ |
781 | ExpireOn: future, |
782 | Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)), |
783 | }) |
784 | - c.Assert(err, IsNil) |
785 | - c.Assert(got, Matches, OK) |
786 | + c.Assert(err, IsNil, Commentf("%v", got)) |
787 | } |
788 | |
789 | events, errCh, stop := s.StartClient(c, "DEVC", nil) |
790 | @@ -130,8 +126,7 @@ |
791 | ExpireOn: future, |
792 | Data: json.RawMessage(`{"img1/m1": 42}`), |
793 | }) |
794 | - c.Assert(err, IsNil) |
795 | - c.Assert(got, Matches, OK) |
796 | + c.Assert(err, IsNil, Commentf("%v", got)) |
797 | c.Check(NextEvent(events1, errCh1), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":42}]`) |
798 | c.Check(NextEvent(events2, errCh2), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":42}]`) |
799 | stop1() |
800 | @@ -149,8 +144,7 @@ |
801 | ExpireOn: future, |
802 | Data: json.RawMessage(`{"img1/m1": 1}`), |
803 | }) |
804 | - c.Assert(err, IsNil) |
805 | - c.Assert(got, Matches, OK) |
806 | + c.Assert(err, IsNil, Commentf("%v", got)) |
807 | c.Check(NextEvent(events, errCh), Equals, `broadcast chan:0 app: topLevel:1 payloads:[{"img1/m1":1}]`) |
808 | stop() |
809 | c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
810 | @@ -161,8 +155,7 @@ |
811 | ExpireOn: future, |
812 | Data: json.RawMessage(`{"img1/m1": 2}`), |
813 | }) |
814 | - c.Assert(err, IsNil) |
815 | - c.Assert(got, Matches, OK) |
816 | + c.Assert(err, IsNil, Commentf("%v", got)) |
817 | // reconnect, provide levels, get only later notification |
818 | events, errCh, stop = s.StartClient(c, "DEVD", map[string]int64{ |
819 | protocol.SystemChannelId: 1, |
820 | @@ -180,15 +173,13 @@ |
821 | ExpireOn: future, |
822 | Data: json.RawMessage(`{"img1/m1": 1}`), |
823 | }) |
824 | - c.Assert(err, IsNil) |
825 | - c.Assert(got, Matches, OK) |
826 | + c.Assert(err, IsNil, Commentf("%v", got)) |
827 | got, err = s.PostRequest("/broadcast", &api.Broadcast{ |
828 | Channel: "system", |
829 | ExpireOn: future, |
830 | Data: json.RawMessage(`{"img1/m1": 2}`), |
831 | }) |
832 | - c.Assert(err, IsNil) |
833 | - c.Assert(got, Matches, OK) |
834 | + c.Assert(err, IsNil, Commentf("%v", got)) |
835 | |
836 | events, errCh, stop := s.StartClient(c, "DEVB", map[string]int64{ |
837 | protocol.SystemChannelId: 10, |
838 | @@ -219,15 +210,13 @@ |
839 | ExpireOn: future, |
840 | Data: json.RawMessage(`{"img1/m1": 1}`), |
841 | }) |
842 | - c.Assert(err, IsNil) |
843 | - c.Assert(got, Matches, OK) |
844 | + c.Assert(err, IsNil, Commentf("%v", got)) |
845 | got, err = s.PostRequest("/broadcast", &api.Broadcast{ |
846 | Channel: "system", |
847 | ExpireOn: future, |
848 | Data: json.RawMessage(`{"img1/m1": 2}`), |
849 | }) |
850 | - c.Assert(err, IsNil) |
851 | - c.Assert(got, Matches, OK) |
852 | + c.Assert(err, IsNil, Commentf("%v", got)) |
853 | |
854 | events, errCh, stop := s.StartClient(c, "DEVB", map[string]int64{ |
855 | protocol.SystemChannelId: -10, |
856 | @@ -246,15 +235,13 @@ |
857 | ExpireOn: future, |
858 | Data: json.RawMessage(`{"img1/m1": 1}`), |
859 | }) |
860 | - c.Assert(err, IsNil) |
861 | - c.Assert(got, Matches, OK) |
862 | + c.Assert(err, IsNil, Commentf("%v", got)) |
863 | got, err = s.PostRequest("/broadcast", &api.Broadcast{ |
864 | Channel: "system", |
865 | ExpireOn: time.Now().Add(1 * time.Second).Format(time.RFC3339), |
866 | Data: json.RawMessage(`{"img1/m1": 2}`), |
867 | }) |
868 | - c.Assert(err, IsNil) |
869 | - c.Assert(got, Matches, OK) |
870 | + c.Assert(err, IsNil, Commentf("%v", got)) |
871 | |
872 | time.Sleep(2 * time.Second) |
873 | // second broadcast is expired |
874 | |
875 | === modified file 'server/acceptance/suites/suite.go' |
876 | --- server/acceptance/suites/suite.go 2014-06-25 11:00:15 +0000 |
877 | +++ server/acceptance/suites/suite.go 2014-08-22 14:47:03 +0000 |
878 | @@ -18,13 +18,9 @@ |
879 | package suites |
880 | |
881 | import ( |
882 | - "bytes" |
883 | - "encoding/json" |
884 | "flag" |
885 | "fmt" |
886 | - "io/ioutil" |
887 | "net" |
888 | - "net/http" |
889 | "os" |
890 | "runtime" |
891 | "time" |
892 | @@ -32,6 +28,7 @@ |
893 | . "launchpad.net/gocheck" |
894 | |
895 | "launchpad.net/ubuntu-push/server/acceptance" |
896 | + "launchpad.net/ubuntu-push/server/acceptance/kit" |
897 | helpers "launchpad.net/ubuntu-push/testing" |
898 | ) |
899 | |
900 | @@ -84,14 +81,10 @@ |
901 | StartServer func(c *C, s *AcceptanceSuite, handle *ServerHandle) |
902 | // populated by StartServer |
903 | ServerHandle |
904 | - ServerAPIURL string |
905 | + kit.APIClient // has ServerAPIURL |
906 | // KillGroup should be populated by StartServer with functions |
907 | // to kill the server process |
908 | KillGroup map[string]func(os.Signal) |
909 | - // hook to adjust requests |
910 | - MassageRequest func(req *http.Request, message interface{}) *http.Request |
911 | - // other state |
912 | - httpClient *http.Client |
913 | } |
914 | |
915 | // Start a new server for each test. |
916 | @@ -101,7 +94,7 @@ |
917 | c.Assert(s.ServerHandle.ServerEvents, NotNil) |
918 | c.Assert(s.ServerHandle.ServerAddr, Not(Equals), "") |
919 | c.Assert(s.ServerAPIURL, Not(Equals), "") |
920 | - s.httpClient = &http.Client{} |
921 | + s.SetupClient(nil) |
922 | } |
923 | |
924 | func (s *AcceptanceSuite) TearDownTest(c *C) { |
925 | @@ -110,45 +103,19 @@ |
926 | } |
927 | } |
928 | |
929 | -// Post a API request. |
930 | -func (s *AcceptanceSuite) PostRequest(path string, message interface{}) (string, error) { |
931 | - packedMessage, err := json.Marshal(message) |
932 | - if err != nil { |
933 | - panic(err) |
934 | - } |
935 | - reader := bytes.NewReader(packedMessage) |
936 | - |
937 | - url := s.ServerAPIURL + path |
938 | - request, _ := http.NewRequest("POST", url, reader) |
939 | - request.ContentLength = int64(reader.Len()) |
940 | - request.Header.Set("Content-Type", "application/json") |
941 | - |
942 | - if s.MassageRequest != nil { |
943 | - request = s.MassageRequest(request, message) |
944 | - } |
945 | - |
946 | - resp, err := s.httpClient.Do(request) |
947 | - if err != nil { |
948 | - panic(err) |
949 | - } |
950 | - defer resp.Body.Close() |
951 | - body, err := ioutil.ReadAll(resp.Body) |
952 | - return string(body), err |
953 | -} |
954 | - |
955 | func testClientSession(addr string, deviceId, model, imageChannel string, reportPings bool) *acceptance.ClientSession { |
956 | - certPEMBlock, err := ioutil.ReadFile(helpers.SourceRelative("../ssl/testing.cert")) |
957 | + tlsConfig, err := kit.MakeTLSConfig("", false, helpers.SourceRelative("../ssl/testing.cert"), "") |
958 | if err != nil { |
959 | panic(fmt.Sprintf("could not read ssl/testing.cert: %v", err)) |
960 | } |
961 | return &acceptance.ClientSession{ |
962 | ExchangeTimeout: 100 * time.Millisecond, |
963 | ServerAddr: addr, |
964 | - CertPEMBlock: certPEMBlock, |
965 | DeviceId: deviceId, |
966 | Model: model, |
967 | ImageChannel: imageChannel, |
968 | ReportPings: reportPings, |
969 | + TLSConfig: tlsConfig, |
970 | } |
971 | } |
972 | |
973 | @@ -198,5 +165,3 @@ |
974 | |
975 | // Long after the end of the tests. |
976 | var future = time.Now().Add(9 * time.Hour).Format(time.RFC3339) |
977 | - |
978 | -const OK = `.*"ok":true.*` |
979 | |
980 | === modified file 'server/acceptance/suites/unicast.go' |
981 | --- server/acceptance/suites/unicast.go 2014-07-14 15:23:17 +0000 |
982 | +++ server/acceptance/suites/unicast.go 2014-08-22 14:47:03 +0000 |
983 | @@ -23,6 +23,7 @@ |
984 | |
985 | . "launchpad.net/gocheck" |
986 | |
987 | + "launchpad.net/ubuntu-push/server/acceptance/kit" |
988 | "launchpad.net/ubuntu-push/server/api" |
989 | ) |
990 | |
991 | @@ -45,20 +46,15 @@ |
992 | DeviceId: "DEV1", |
993 | AppId: "app1", |
994 | }) |
995 | - c.Assert(err, IsNil) |
996 | - c.Assert(res, Matches, OK) |
997 | - var reg map[string]interface{} |
998 | - err = json.Unmarshal([]byte(res), ®) |
999 | - c.Assert(err, IsNil) |
1000 | + c.Assert(err, IsNil, Commentf("%v", res)) |
1001 | events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth) |
1002 | got, err := s.PostRequest("/notify", &api.Unicast{ |
1003 | - Token: reg["token"].(string), |
1004 | + Token: res["token"].(string), |
1005 | AppId: "app1", |
1006 | ExpireOn: future, |
1007 | Data: json.RawMessage(`{"a": 42}`), |
1008 | }) |
1009 | - c.Assert(err, IsNil) |
1010 | - c.Assert(got, Matches, OK) |
1011 | + c.Assert(err, IsNil, Commentf("%v", got)) |
1012 | c.Check(NextEvent(events, errCh), Equals, `unicast app:app1 payload:{"a":42};`) |
1013 | stop() |
1014 | c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
1015 | @@ -80,8 +76,7 @@ |
1016 | ExpireOn: future, |
1017 | Data: json.RawMessage(`{"to": 1}`), |
1018 | }) |
1019 | - c.Assert(err, IsNil) |
1020 | - c.Assert(got, Matches, OK) |
1021 | + c.Assert(err, IsNil, Commentf("%v", got)) |
1022 | got, err = s.PostRequest("/notify", &api.Unicast{ |
1023 | UserId: userId2, |
1024 | DeviceId: "DEV2", |
1025 | @@ -89,8 +84,7 @@ |
1026 | ExpireOn: future, |
1027 | Data: json.RawMessage(`{"to": 2}`), |
1028 | }) |
1029 | - c.Assert(err, IsNil) |
1030 | - c.Assert(got, Matches, OK) |
1031 | + c.Assert(err, IsNil, Commentf("%v", got)) |
1032 | c.Check(NextEvent(events1, errCh1), Equals, `unicast app:app1 payload:{"to":1};`) |
1033 | c.Check(NextEvent(events2, errCh2), Equals, `unicast app:app1 payload:{"to":2};`) |
1034 | stop1() |
1035 | @@ -111,8 +105,7 @@ |
1036 | ExpireOn: future, |
1037 | Data: json.RawMessage(`{"a": 42}`), |
1038 | }) |
1039 | - c.Assert(err, IsNil) |
1040 | - c.Assert(got, Matches, OK) |
1041 | + c.Assert(err, IsNil, Commentf("%v", got)) |
1042 | |
1043 | // get pending on connect |
1044 | events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth) |
1045 | @@ -134,8 +127,7 @@ |
1046 | ExpireOn: future, |
1047 | Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)), |
1048 | }) |
1049 | - c.Assert(err, IsNil) |
1050 | - c.Assert(got, Matches, OK) |
1051 | + c.Assert(err, IsNil, Commentf("%v", got)) |
1052 | } |
1053 | |
1054 | events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth) |
1055 | @@ -168,8 +160,7 @@ |
1056 | ExpireOn: future, |
1057 | Data: json.RawMessage(fmt.Sprintf(payloadFmt, i)), |
1058 | }) |
1059 | - c.Assert(err, IsNil) |
1060 | - c.Assert(got, Matches, OK) |
1061 | + c.Assert(err, IsNil, Commentf("%v", got)) |
1062 | } |
1063 | |
1064 | got, err := s.PostRequest("/notify", &api.Unicast{ |
1065 | @@ -179,8 +170,9 @@ |
1066 | ExpireOn: future, |
1067 | Data: json.RawMessage(fmt.Sprintf(payloadFmt, MaxNotificationsPerApplication)), |
1068 | }) |
1069 | - c.Assert(err, IsNil) |
1070 | - c.Assert(got, Matches, `.*"error":"too-many-pending".*`) |
1071 | + c.Assert(err, Equals, kit.ErrNOk, Commentf("%v", got)) |
1072 | + errorStr, _ := got["error"].(string) |
1073 | + c.Assert(errorStr, Equals, "too-many-pending") |
1074 | |
1075 | // clear all pending |
1076 | got, err = s.PostRequest("/notify", &api.Unicast{ |
1077 | @@ -191,8 +183,7 @@ |
1078 | Data: json.RawMessage(fmt.Sprintf(payloadFmt, 1000)), |
1079 | ClearPending: true, |
1080 | }) |
1081 | - c.Assert(err, IsNil) |
1082 | - c.Assert(got, Matches, OK) |
1083 | + c.Assert(err, IsNil, Commentf("%v", got)) |
1084 | |
1085 | events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth) |
1086 | // getting the 1 pending on connect |
1087 | @@ -214,8 +205,7 @@ |
1088 | Data: json.RawMessage(`{"m": 1}`), |
1089 | ReplaceTag: "tagFoo", |
1090 | }) |
1091 | - c.Assert(err, IsNil) |
1092 | - c.Assert(got, Matches, OK) |
1093 | + c.Assert(err, IsNil, Commentf("%v", got)) |
1094 | |
1095 | // replace |
1096 | got, err = s.PostRequest("/notify", &api.Unicast{ |
1097 | @@ -226,8 +216,7 @@ |
1098 | Data: json.RawMessage(`{"m": 2}`), |
1099 | ReplaceTag: "tagFoo", |
1100 | }) |
1101 | - c.Assert(err, IsNil) |
1102 | - c.Assert(got, Matches, OK) |
1103 | + c.Assert(err, IsNil, Commentf("%v", got)) |
1104 | |
1105 | events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth) |
1106 | // getting the 1 pending on connect |