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