Merge lp:~ralsina/ubuntu-push/merge-automatic into lp:ubuntu-push
- merge-automatic
- Merge into trunk
Proposed by
Roberto Alsina
Status: | Merged |
---|---|
Approved by: | Roberto Alsina |
Approved revision: | no longer in the source branch. |
Merged at revision: | 127 |
Proposed branch: | lp:~ralsina/ubuntu-push/merge-automatic |
Merge into: | lp:ubuntu-push |
Diff against target: |
1040 lines (+462/-230) 16 files modified
PACKAGE_DEPS (+1/-1) bus/urldispatcher/urldispatcher.go (+0/-76) bus/urldispatcher/urldispatcher_test.go (+0/-115) client/service/postal.go (+2/-5) client/service/postal_test.go (+58/-22) debian/changelog (+10/-0) debian/control (+1/-1) poller/poller.go (+2/-0) server/acceptance/acceptanceclient.go (+25/-0) server/acceptance/suites/suite.go (+9/-2) server/acceptance/suites/unicast.go (+7/-7) server/session/session_test.go (+1/-1) urldispatcher/curldispatcher/curldispatcher.go (+95/-0) urldispatcher/curldispatcher/curldispatcher_c.go (+39/-0) urldispatcher/urldispatcher.go (+70/-0) urldispatcher/urldispatcher_test.go (+142/-0) |
To merge this branch: | bzr merge lp:~ralsina/ubuntu-push/merge-automatic |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Push Hackers | Pending | ||
Review via email: mp+232901@code.launchpad.net |
Commit message
Latest changes from automatic
Description of the change
Latest changes from automatic:
* Use url-dispatcher C API
* Avoid busy-loop if powerd doesn't reply
To post a comment you must log in.
- 127. By Roberto Alsina
-
Latest changes from automatic
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'PACKAGE_DEPS' |
2 | --- PACKAGE_DEPS 2014-07-03 10:51:42 +0000 |
3 | +++ PACKAGE_DEPS 2014-09-02 17:24:34 +0000 |
4 | @@ -7,7 +7,7 @@ |
5 | libnih-dbus-dev |
6 | libsqlite3-dev |
7 | libubuntuoneauth-2.0-dev |
8 | -libwhoopsie-dev |
9 | libmessaging-menu-dev |
10 | libubuntu-app-launch2-dev |
11 | libclick-0.4-dev |
12 | +liburl-dispatcher1-dev |
13 | |
14 | === removed directory 'bus/urldispatcher' |
15 | === removed file 'bus/urldispatcher/urldispatcher.go' |
16 | --- bus/urldispatcher/urldispatcher.go 2014-07-25 21:50:53 +0000 |
17 | +++ bus/urldispatcher/urldispatcher.go 1970-01-01 00:00:00 +0000 |
18 | @@ -1,76 +0,0 @@ |
19 | -/* |
20 | - Copyright 2013-2014 Canonical Ltd. |
21 | - |
22 | - This program is free software: you can redistribute it and/or modify it |
23 | - under the terms of the GNU General Public License version 3, as published |
24 | - by the Free Software Foundation. |
25 | - |
26 | - This program is distributed in the hope that it will be useful, but |
27 | - WITHOUT ANY WARRANTY; without even the implied warranties of |
28 | - MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
29 | - PURPOSE. See the GNU General Public License for more details. |
30 | - |
31 | - You should have received a copy of the GNU General Public License along |
32 | - with this program. If not, see <http://www.gnu.org/licenses/>. |
33 | -*/ |
34 | - |
35 | -// Package urldispatcher wraps the url dispatcher's dbus api point |
36 | -package urldispatcher |
37 | - |
38 | -import ( |
39 | - "launchpad.net/ubuntu-push/bus" |
40 | - "launchpad.net/ubuntu-push/click" |
41 | - "launchpad.net/ubuntu-push/logger" |
42 | -) |
43 | - |
44 | -// UrlDispatcher lives on a well-known bus.Address |
45 | -var BusAddress bus.Address = bus.Address{ |
46 | - Interface: "com.canonical.URLDispatcher", |
47 | - Path: "/com/canonical/URLDispatcher", |
48 | - Name: "com.canonical.URLDispatcher", |
49 | -} |
50 | - |
51 | -// A URLDispatcher is a simple beast, with a single method that does what it |
52 | -// says on the box. |
53 | -type URLDispatcher interface { |
54 | - DispatchURL(string, *click.AppId) error |
55 | - TestURL(*click.AppId, []string) bool |
56 | -} |
57 | - |
58 | -type urlDispatcher struct { |
59 | - endp bus.Endpoint |
60 | - log logger.Logger |
61 | -} |
62 | - |
63 | -// New builds a new URL dispatcher that uses the provided bus.Endpoint |
64 | -func New(endp bus.Endpoint, log logger.Logger) URLDispatcher { |
65 | - return &urlDispatcher{endp, log} |
66 | -} |
67 | - |
68 | -var _ URLDispatcher = &urlDispatcher{} // ensures it conforms |
69 | - |
70 | -func (ud *urlDispatcher) DispatchURL(url string, app *click.AppId) error { |
71 | - ud.log.Debugf("Dispatching %s", url) |
72 | - err := ud.endp.Call("DispatchURL", bus.Args(url, app.DispatchPackage())) |
73 | - if err != nil { |
74 | - ud.log.Errorf("Dispatch to %s failed with %s", url, err) |
75 | - } |
76 | - return err |
77 | -} |
78 | - |
79 | -func (ud *urlDispatcher) TestURL(app *click.AppId, urls []string) bool { |
80 | - ud.log.Debugf("TestURL: %s", urls) |
81 | - var appIds []string |
82 | - err := ud.endp.Call("TestURL", bus.Args(urls), &appIds) |
83 | - if err != nil { |
84 | - ud.log.Errorf("TestURL for %s failed with %s", urls, err) |
85 | - return false |
86 | - } |
87 | - for _, appId := range appIds { |
88 | - if appId != app.Versioned() { |
89 | - ud.log.Debugf("Notification skipped because of different appid for actions: %v - %s != %s", urls, appId, app.Versioned()) |
90 | - return false |
91 | - } |
92 | - } |
93 | - return true |
94 | -} |
95 | |
96 | === removed file 'bus/urldispatcher/urldispatcher_test.go' |
97 | --- bus/urldispatcher/urldispatcher_test.go 2014-07-25 16:55:55 +0000 |
98 | +++ bus/urldispatcher/urldispatcher_test.go 1970-01-01 00:00:00 +0000 |
99 | @@ -1,115 +0,0 @@ |
100 | -/* |
101 | - Copyright 2013-2014 Canonical Ltd. |
102 | - |
103 | - This program is free software: you can redistribute it and/or modify it |
104 | - under the terms of the GNU General Public License version 3, as published |
105 | - by the Free Software Foundation. |
106 | - |
107 | - This program is distributed in the hope that it will be useful, but |
108 | - WITHOUT ANY WARRANTY; without even the implied warranties of |
109 | - MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
110 | - PURPOSE. See the GNU General Public License for more details. |
111 | - |
112 | - You should have received a copy of the GNU General Public License along |
113 | - with this program. If not, see <http://www.gnu.org/licenses/>. |
114 | -*/ |
115 | - |
116 | -package urldispatcher |
117 | - |
118 | -import ( |
119 | - . "launchpad.net/gocheck" |
120 | - testibus "launchpad.net/ubuntu-push/bus/testing" |
121 | - clickhelp "launchpad.net/ubuntu-push/click/testing" |
122 | - helpers "launchpad.net/ubuntu-push/testing" |
123 | - "launchpad.net/ubuntu-push/testing/condition" |
124 | - "testing" |
125 | -) |
126 | - |
127 | -// hook up gocheck |
128 | -func TestUrldispatcher(t *testing.T) { TestingT(t) } |
129 | - |
130 | -type UDSuite struct { |
131 | - log *helpers.TestLogger |
132 | -} |
133 | - |
134 | -var _ = Suite(&UDSuite{}) |
135 | - |
136 | -func (s *UDSuite) SetUpTest(c *C) { |
137 | - s.log = helpers.NewTestLogger(c, "debug") |
138 | -} |
139 | - |
140 | -func (s *UDSuite) TestDispatchURLWorks(c *C) { |
141 | - endp := testibus.NewMultiValuedTestingEndpoint(nil, condition.Work(true), []interface{}{}) |
142 | - ud := New(endp, s.log) |
143 | - appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
144 | - err := ud.DispatchURL("this", appId) |
145 | - c.Check(err, IsNil) |
146 | -} |
147 | - |
148 | -func (s *UDSuite) TestDispatchURLFailsIfCallFails(c *C) { |
149 | - endp := testibus.NewTestingEndpoint(nil, condition.Work(false)) |
150 | - ud := New(endp, s.log) |
151 | - appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
152 | - err := ud.DispatchURL("this", appId) |
153 | - c.Check(err, NotNil) |
154 | -} |
155 | - |
156 | -func (s *UDSuite) TestTestURLWorks(c *C) { |
157 | - endp := testibus.NewMultiValuedTestingEndpoint(nil, condition.Work(true), []interface{}{[]string{"com.example.test_app_0.99"}}) |
158 | - ud := New(endp, s.log) |
159 | - appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
160 | - c.Check(ud.TestURL(appId, []string{"this"}), Equals, true) |
161 | - c.Check(s.log.Captured(), Matches, `(?sm).*TestURL: \[this\].*`) |
162 | -} |
163 | - |
164 | -func (s *UDSuite) TestTestURLFailsIfCallFails(c *C) { |
165 | - endp := testibus.NewTestingEndpoint(nil, condition.Work(false)) |
166 | - ud := New(endp, s.log) |
167 | - appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
168 | - c.Check(ud.TestURL(appId, []string{"this"}), Equals, false) |
169 | -} |
170 | - |
171 | -func (s *UDSuite) TestTestURLMultipleURLs(c *C) { |
172 | - endp := testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true), []string{"com.example.test_app_0.99", "com.example.test_app_0.99"}) |
173 | - ud := New(endp, s.log) |
174 | - appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
175 | - urls := []string{"potato://test-app", "potato_a://foo"} |
176 | - c.Check(ud.TestURL(appId, urls), Equals, true) |
177 | - c.Check(s.log.Captured(), Matches, `(?sm).*TestURL: \[potato://test-app potato_a://foo\].*`) |
178 | -} |
179 | - |
180 | -func (s *UDSuite) TestTestURLWrongApp(c *C) { |
181 | - endp := testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true), []string{"com.example.test_test-app_0.1"}) |
182 | - ud := New(endp, s.log) |
183 | - appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
184 | - urls := []string{"potato://test-app"} |
185 | - c.Check(ud.TestURL(appId, urls), Equals, false) |
186 | - c.Check(s.log.Captured(), Matches, `(?sm).*Notification skipped because of different appid for actions: \[potato://test-app\] - com.example.test_test-app_0.1 != com.example.test_app_0.99`) |
187 | -} |
188 | - |
189 | -func (s *UDSuite) TestTestURLOneWrongApp(c *C) { |
190 | - endp := testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true), []string{"com.example.test_test-app_0", "com.example.test_test-app1"}) |
191 | - ud := New(endp, s.log) |
192 | - appId := clickhelp.MustParseAppId("com.example.test_test-app_0") |
193 | - urls := []string{"potato://test-app", "potato_a://foo"} |
194 | - c.Check(ud.TestURL(appId, urls), Equals, false) |
195 | - c.Check(s.log.Captured(), Matches, `(?sm).*Notification skipped because of different appid for actions: \[potato://test-app potato_a://foo\] - com.example.test_test-app1 != com.example.test_test-app.*`) |
196 | -} |
197 | - |
198 | -func (s *UDSuite) TestTestURLInvalidURL(c *C) { |
199 | - endp := testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false), []string{"com.example.test_test-app_0.1"}) |
200 | - ud := New(endp, s.log) |
201 | - appId := clickhelp.MustParseAppId("com.example.test_app_0.2") |
202 | - urls := []string{"notsupported://test-app"} |
203 | - c.Check(ud.TestURL(appId, urls), Equals, false) |
204 | - c.Check(s.log.Captured(), Matches, `(?sm).*TestURL for \[notsupported://test-app\] failed with no way.*`) |
205 | -} |
206 | - |
207 | -func (s *UDSuite) TestTestURLLegacyApp(c *C) { |
208 | - endp := testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true), []string{"ubuntu-system-settings"}) |
209 | - ud := New(endp, s.log) |
210 | - appId := clickhelp.MustParseAppId("_ubuntu-system-settings") |
211 | - urls := []string{"settings://test-app"} |
212 | - c.Check(ud.TestURL(appId, urls), Equals, true) |
213 | - c.Check(s.log.Captured(), Matches, `(?sm).*TestURL: \[settings://test-app\].*`) |
214 | -} |
215 | |
216 | === modified file 'client/service/postal.go' |
217 | --- client/service/postal.go 2014-08-08 10:15:07 +0000 |
218 | +++ client/service/postal.go 2014-09-02 17:24:34 +0000 |
219 | @@ -27,7 +27,6 @@ |
220 | "launchpad.net/ubuntu-push/bus/emblemcounter" |
221 | "launchpad.net/ubuntu-push/bus/haptic" |
222 | "launchpad.net/ubuntu-push/bus/notifications" |
223 | - "launchpad.net/ubuntu-push/bus/urldispatcher" |
224 | "launchpad.net/ubuntu-push/bus/windowstack" |
225 | "launchpad.net/ubuntu-push/click" |
226 | "launchpad.net/ubuntu-push/click/cblacklist" |
227 | @@ -37,6 +36,7 @@ |
228 | "launchpad.net/ubuntu-push/messaging/reply" |
229 | "launchpad.net/ubuntu-push/nih" |
230 | "launchpad.net/ubuntu-push/sounds" |
231 | + "launchpad.net/ubuntu-push/urldispatcher" |
232 | "launchpad.net/ubuntu-push/util" |
233 | ) |
234 | |
235 | @@ -76,7 +76,6 @@ |
236 | EmblemCounterEndp bus.Endpoint |
237 | HapticEndp bus.Endpoint |
238 | NotificationsEndp bus.Endpoint |
239 | - URLDispatcherEndp bus.Endpoint |
240 | WindowStackEndp bus.Endpoint |
241 | // presenters: |
242 | Presenters []Presenter |
243 | @@ -116,7 +115,6 @@ |
244 | svc.NotificationsEndp = bus.SessionBus.Endpoint(notifications.BusAddress, log) |
245 | svc.EmblemCounterEndp = bus.SessionBus.Endpoint(emblemcounter.BusAddress, log) |
246 | svc.HapticEndp = bus.SessionBus.Endpoint(haptic.BusAddress, log) |
247 | - svc.URLDispatcherEndp = bus.SessionBus.Endpoint(urldispatcher.BusAddress, log) |
248 | svc.WindowStackEndp = bus.SessionBus.Endpoint(windowstack.BusAddress, log) |
249 | svc.msgHandler = svc.messageHandler |
250 | svc.launchers = launch_helper.DefaultLaunchers(log) |
251 | @@ -153,7 +151,7 @@ |
252 | if err != nil { |
253 | return err |
254 | } |
255 | - svc.urlDispatcher = urldispatcher.New(svc.URLDispatcherEndp, svc.Log) |
256 | + svc.urlDispatcher = urldispatcher.New(svc.Log) |
257 | svc.notifications = notifications.Raw(svc.NotificationsEndp, svc.Log) |
258 | svc.emblemCounter = emblemcounter.New(svc.EmblemCounterEndp, svc.Log) |
259 | svc.haptic = haptic.New(svc.HapticEndp, svc.Log, svc.fallbackVibration) |
260 | @@ -226,7 +224,6 @@ |
261 | {"notifications", svc.NotificationsEndp}, |
262 | {"emblemcounter", svc.EmblemCounterEndp}, |
263 | {"haptic", svc.HapticEndp}, |
264 | - {"urldispatcher", svc.URLDispatcherEndp}, |
265 | {"windowstack", svc.WindowStackEndp}, |
266 | } |
267 | for _, endp := range endps { |
268 | |
269 | === modified file 'client/service/postal_test.go' |
270 | --- client/service/postal_test.go 2014-08-08 10:35:42 +0000 |
271 | +++ client/service/postal_test.go 2014-09-02 17:24:34 +0000 |
272 | @@ -18,11 +18,13 @@ |
273 | |
274 | import ( |
275 | "encoding/json" |
276 | + "errors" |
277 | "fmt" |
278 | "io/ioutil" |
279 | "os" |
280 | "path/filepath" |
281 | "sort" |
282 | + "sync" |
283 | "time" |
284 | |
285 | "launchpad.net/go-dbus/v1" |
286 | @@ -131,6 +133,33 @@ |
287 | return id, nil |
288 | } |
289 | |
290 | +type fakeUrlDispatcher struct { |
291 | + DispatchCalls [][]string |
292 | + TestURLCalls []map[string][]string |
293 | + NextTestURLResult bool |
294 | + DispatchShouldFail bool |
295 | + Lock sync.Mutex |
296 | +} |
297 | + |
298 | +func (fud *fakeUrlDispatcher) DispatchURL(url string, app *click.AppId) error { |
299 | + fud.Lock.Lock() |
300 | + defer fud.Lock.Unlock() |
301 | + fud.DispatchCalls = append(fud.DispatchCalls, []string{url, app.DispatchPackage()}) |
302 | + if fud.DispatchShouldFail { |
303 | + return errors.New("fail!") |
304 | + } |
305 | + return nil |
306 | +} |
307 | + |
308 | +func (fud *fakeUrlDispatcher) TestURL(app *click.AppId, urls []string) bool { |
309 | + fud.Lock.Lock() |
310 | + defer fud.Lock.Unlock() |
311 | + var args = make(map[string][]string, 1) |
312 | + args[app.DispatchPackage()] = urls |
313 | + fud.TestURLCalls = append(fud.TestURLCalls, args) |
314 | + return fud.NextTestURLResult |
315 | +} |
316 | + |
317 | type postalSuite struct { |
318 | log *helpers.TestLogger |
319 | cfg *PostalServiceSetup |
320 | @@ -138,7 +167,6 @@ |
321 | notifBus bus.Endpoint |
322 | counterBus bus.Endpoint |
323 | hapticBus bus.Endpoint |
324 | - urlDispBus bus.Endpoint |
325 | winStackBus bus.Endpoint |
326 | fakeLauncher *fakeHelperLauncher |
327 | getTempDir func(string) (string, error) |
328 | @@ -166,7 +194,6 @@ |
329 | ps.notifBus = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true)) |
330 | ps.counterBus = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true)) |
331 | ps.hapticBus = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true)) |
332 | - ps.urlDispBus = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true)) |
333 | ps.winStackBus = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true), []windowstack.WindowsInfo{}) |
334 | ps.fakeLauncher = &fakeHelperLauncher{ch: make(chan []byte)} |
335 | ps.blacklisted = false |
336 | @@ -199,7 +226,6 @@ |
337 | pst.NotificationsEndp = ps.notifBus |
338 | pst.EmblemCounterEndp = ps.counterBus |
339 | pst.HapticEndp = ps.hapticBus |
340 | - pst.URLDispatcherEndp = ps.urlDispBus |
341 | pst.WindowStackEndp = ps.winStackBus |
342 | pst.launchers = map[string]launch_helper.HelperLauncher{} |
343 | return pst |
344 | @@ -517,7 +543,6 @@ |
345 | svc.EmblemCounterEndp = endp |
346 | svc.HapticEndp = endp |
347 | svc.NotificationsEndp = endp |
348 | - svc.URLDispatcherEndp = ps.urlDispBus |
349 | svc.WindowStackEndp = ps.winStackBus |
350 | svc.launchers = map[string]launch_helper.HelperLauncher{} |
351 | svc.fallbackVibration = &launch_helper.Vibration{Pattern: []uint32{1}} |
352 | @@ -593,14 +618,20 @@ |
353 | |
354 | func (ps *postalSuite) TestMessageHandlerInvalidAction(c *C) { |
355 | svc := ps.replaceBuses(NewPostalService(ps.cfg, ps.log)) |
356 | - endp := testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false), []string{"com.example.test_test-app"}) |
357 | - svc.URLDispatcherEndp = endp |
358 | c.Assert(svc.Start(), IsNil) |
359 | + fakeDisp := new(fakeUrlDispatcher) |
360 | + svc.urlDispatcher = fakeDisp |
361 | + fakeDisp.NextTestURLResult = false |
362 | card := launch_helper.Card{Actions: []string{"notsupported://test-app"}} |
363 | output := &launch_helper.HelperOutput{Notification: &launch_helper.Notification{Card: &card}} |
364 | - b := svc.messageHandler(clickhelp.MustParseAppId("com.example.test_test-app_0"), "", output) |
365 | + appId := clickhelp.MustParseAppId("com.example.test_test-app_0") |
366 | + b := svc.messageHandler(appId, "", output) |
367 | c.Check(b, Equals, false) |
368 | - c.Check(ps.log.Captured(), Matches, `(?sm).*TestURL for \[notsupported://test-app\] failed with no way.*`) |
369 | + fakeDisp.Lock.Lock() |
370 | + defer fakeDisp.Lock.Unlock() |
371 | + c.Assert(len(fakeDisp.DispatchCalls), Equals, 0) |
372 | + c.Assert(len(fakeDisp.TestURLCalls), Equals, 1) |
373 | + c.Assert(fakeDisp.TestURLCalls[0][appId.DispatchPackage()], DeepEquals, []string{"notsupported://test-app"}) |
374 | } |
375 | |
376 | func (ps *postalSuite) TestHandleActionsDispatches(c *C) { |
377 | @@ -608,6 +639,9 @@ |
378 | fmm := new(fakeMM) |
379 | app, _ := click.ParseAppId("com.example.test_test-app") |
380 | c.Assert(svc.Start(), IsNil) |
381 | + fakeDisp := new(fakeUrlDispatcher) |
382 | + svc.urlDispatcher = fakeDisp |
383 | + fakeDisp.NextTestURLResult = true |
384 | svc.messagingMenu = fmm |
385 | aCh := make(chan *notifications.RawAction) |
386 | rCh := make(chan *reply.MMActionReply) |
387 | @@ -620,18 +654,20 @@ |
388 | }() |
389 | go svc.handleActions(aCh, rCh) |
390 | takeNextBool(bCh) |
391 | - args := testibus.GetCallArgs(ps.urlDispBus) |
392 | - c.Assert(args, HasLen, 1) |
393 | - c.Check(args[0].Member, Equals, "DispatchURL") |
394 | - c.Assert(args[0].Args, HasLen, 2) |
395 | - c.Assert(args[0].Args[0], Equals, "potato://") |
396 | - c.Assert(args[0].Args[1], Equals, app.DispatchPackage()) |
397 | + fakeDisp.Lock.Lock() |
398 | + defer fakeDisp.Lock.Unlock() |
399 | + c.Assert(len(fakeDisp.DispatchCalls), Equals, 1) |
400 | + c.Assert(fakeDisp.DispatchCalls[0][0], Equals, "potato://") |
401 | + c.Assert(fakeDisp.DispatchCalls[0][1], Equals, app.DispatchPackage()) |
402 | c.Check(fmm.calls, DeepEquals, []string{"remove:xyzzy:true"}) |
403 | } |
404 | |
405 | func (ps *postalSuite) TestHandleMMUActionsDispatches(c *C) { |
406 | svc := ps.replaceBuses(NewPostalService(ps.cfg, ps.log)) |
407 | c.Assert(svc.Start(), IsNil) |
408 | + fakeDisp := new(fakeUrlDispatcher) |
409 | + svc.urlDispatcher = fakeDisp |
410 | + fakeDisp.NextTestURLResult = true |
411 | app, _ := click.ParseAppId("com.example.test_test-app") |
412 | aCh := make(chan *notifications.RawAction) |
413 | rCh := make(chan *reply.MMActionReply) |
414 | @@ -644,21 +680,21 @@ |
415 | }() |
416 | go svc.handleActions(aCh, rCh) |
417 | takeNextBool(bCh) |
418 | - args := testibus.GetCallArgs(ps.urlDispBus) |
419 | - c.Assert(args, HasLen, 1) |
420 | - c.Check(args[0].Member, Equals, "DispatchURL") |
421 | - c.Assert(args[0].Args, HasLen, 2) |
422 | - c.Assert(args[0].Args[0], Equals, "potato://") |
423 | - c.Assert(args[0].Args[1], Equals, app.DispatchPackage()) |
424 | + fakeDisp.Lock.Lock() |
425 | + defer fakeDisp.Lock.Unlock() |
426 | + c.Assert(len(fakeDisp.DispatchCalls), Equals, 1) |
427 | + c.Assert(fakeDisp.DispatchCalls[0][0], Equals, "potato://") |
428 | + c.Assert(fakeDisp.DispatchCalls[0][1], Equals, app.DispatchPackage()) |
429 | } |
430 | |
431 | func (ps *postalSuite) TestValidateActions(c *C) { |
432 | svc := ps.replaceBuses(NewPostalService(ps.cfg, ps.log)) |
433 | - endp := testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true), []string{"com.example.test_test-app_0"}) |
434 | - svc.URLDispatcherEndp = endp |
435 | c.Assert(svc.Start(), IsNil) |
436 | card := launch_helper.Card{Actions: []string{"potato://test-app"}} |
437 | notif := &launch_helper.Notification{Card: &card} |
438 | + fakeDisp := new(fakeUrlDispatcher) |
439 | + svc.urlDispatcher = fakeDisp |
440 | + fakeDisp.NextTestURLResult = true |
441 | b := svc.validateActions(clickhelp.MustParseAppId("com.example.test_test-app_0"), notif) |
442 | c.Check(b, Equals, true) |
443 | } |
444 | |
445 | === modified file 'debian/changelog' |
446 | --- debian/changelog 2014-08-28 19:15:56 +0000 |
447 | +++ debian/changelog 2014-09-02 17:24:34 +0000 |
448 | @@ -1,3 +1,13 @@ |
449 | +ubuntu-push (0.63.2) UNRELEASED; urgency=medium |
450 | + |
451 | + [ Roberto Alsina ] |
452 | + * Avoid busy-loop wben powerd doesn't respond. |
453 | + |
454 | + [ Guillermo Gonzalez ] |
455 | + * Replace DBus url-dispatcher API with liburl-dispatcher1 C API. |
456 | + |
457 | + -- Roberto Alsina <ralsina@yoga> Mon, 01 Sep 2014 11:25:49 -0300 |
458 | + |
459 | ubuntu-push (0.63.1+14.10.20140828-0ubuntu1) utopic; urgency=medium |
460 | |
461 | [ Samuele Pedroni ] |
462 | |
463 | === modified file 'debian/control' |
464 | --- debian/control 2014-08-12 00:32:32 +0000 |
465 | +++ debian/control 2014-09-02 17:24:34 +0000 |
466 | @@ -15,12 +15,12 @@ |
467 | libgcrypt11-dev, |
468 | libglib2.0-dev (>= 2.31.6), |
469 | libmessaging-menu-dev, |
470 | - libwhoopsie-dev, |
471 | libubuntu-app-launch2-dev, |
472 | libubuntuoneauth-2.0-dev, |
473 | libdbus-1-dev, |
474 | libnih-dbus-dev, |
475 | libclick-0.4-dev, |
476 | + liburl-dispatcher1-dev, |
477 | cmake, |
478 | python3, |
479 | Standards-Version: 3.9.5 |
480 | |
481 | === modified file 'poller/poller.go' |
482 | --- poller/poller.go 2014-08-21 10:47:12 +0000 |
483 | +++ poller/poller.go 2014-09-02 17:24:34 +0000 |
484 | @@ -147,6 +147,8 @@ |
485 | _, err := p.powerd.RequestWakeup("ubuntu push client", t) |
486 | if err != nil { |
487 | p.log.Errorf("RequestWakeup got %v", err) |
488 | + // Don't do this too quickly. Pretend we are just skipping one wakeup |
489 | + time.Sleep(p.times.AlarmInterval) |
490 | return lockCookie |
491 | } |
492 | p.log.Debugf("requested wakeup at %s", t) |
493 | |
494 | === modified file 'server/acceptance/acceptanceclient.go' |
495 | --- server/acceptance/acceptanceclient.go 2014-08-20 19:48:59 +0000 |
496 | +++ server/acceptance/acceptanceclient.go 2014-09-02 17:24:34 +0000 |
497 | @@ -23,6 +23,7 @@ |
498 | "fmt" |
499 | "net" |
500 | "strings" |
501 | + "sync" |
502 | "time" |
503 | |
504 | "launchpad.net/ubuntu-push/protocol" |
505 | @@ -43,10 +44,27 @@ |
506 | TLSConfig *tls.Config |
507 | Prefix string // prefix for events |
508 | Auth string |
509 | + cookie string |
510 | + cookieLock sync.RWMutex |
511 | + ReportSetParams bool |
512 | // connection |
513 | Connection net.Conn |
514 | } |
515 | |
516 | +// GetCookie gets the current cookie. |
517 | +func (sess *ClientSession) GetCookie() string { |
518 | + sess.cookieLock.RLock() |
519 | + defer sess.cookieLock.RUnlock() |
520 | + return sess.cookie |
521 | +} |
522 | + |
523 | +// SetCookie sets the current cookie. |
524 | +func (sess *ClientSession) SetCookie(cookie string) { |
525 | + sess.cookieLock.Lock() |
526 | + defer sess.cookieLock.Unlock() |
527 | + sess.cookie = cookie |
528 | +} |
529 | + |
530 | // Dial connects to a server using the configuration in the |
531 | // ClientSession and sets up the connection. |
532 | func (sess *ClientSession) Dial() error { |
533 | @@ -75,6 +93,7 @@ |
534 | protocol.BroadcastMsg |
535 | protocol.NotificationsMsg |
536 | protocol.ConnWarnMsg |
537 | + protocol.SetParamsMsg |
538 | } |
539 | |
540 | // Run the session with the server, emits a stream of events. |
541 | @@ -96,6 +115,7 @@ |
542 | "channel": sess.ImageChannel, |
543 | }, |
544 | Authorization: sess.Auth, |
545 | + Cookie: sess.GetCookie(), |
546 | }) |
547 | if err != nil { |
548 | return err |
549 | @@ -156,6 +176,11 @@ |
550 | events <- fmt.Sprintf("%sbroadcast chan:%v app:%v topLevel:%d payloads:%s", sess.Prefix, recv.ChanId, recv.AppId, recv.TopLevel, pack) |
551 | case "warn", "connwarn": |
552 | events <- fmt.Sprintf("%sconnwarn %s", sess.Prefix, recv.Reason) |
553 | + case "setparams": |
554 | + sess.SetCookie(recv.SetCookie) |
555 | + if sess.ReportSetParams { |
556 | + events <- sess.Prefix + "setparams" |
557 | + } |
558 | } |
559 | } |
560 | return nil |
561 | |
562 | === modified file 'server/acceptance/suites/suite.go' |
563 | --- server/acceptance/suites/suite.go 2014-08-20 19:48:59 +0000 |
564 | +++ server/acceptance/suites/suite.go 2014-09-02 17:24:34 +0000 |
565 | @@ -37,15 +37,17 @@ |
566 | ServerAddr string |
567 | ServerHTTPAddr string |
568 | ServerEvents <-chan string |
569 | + // last started session |
570 | + LastSession *acceptance.ClientSession |
571 | } |
572 | |
573 | // Start a client. |
574 | func (h *ServerHandle) StartClient(c *C, devId string, levels map[string]int64) (events <-chan string, errorCh <-chan error, stop func()) { |
575 | - return h.StartClientAuth(c, devId, levels, "") |
576 | + return h.StartClientAuth(c, devId, levels, "", "") |
577 | } |
578 | |
579 | // Start a client with auth. |
580 | -func (h *ServerHandle) StartClientAuth(c *C, devId string, levels map[string]int64, auth string) (events <-chan string, errorCh <-chan error, stop func()) { |
581 | +func (h *ServerHandle) StartClientAuth(c *C, devId string, levels map[string]int64, auth string, cookie string) (events <-chan string, errorCh <-chan error, stop func()) { |
582 | errCh := make(chan error, 1) |
583 | cliEvents := make(chan string, 10) |
584 | sess := testClientSession(h.ServerAddr, devId, "m1", "img1", false) |
585 | @@ -54,8 +56,13 @@ |
586 | if auth != "" { |
587 | sess.ExchangeTimeout = 5 * time.Second |
588 | } |
589 | + if cookie != "" { |
590 | + sess.SetCookie(cookie) |
591 | + sess.ReportSetParams = true |
592 | + } |
593 | err := sess.Dial() |
594 | c.Assert(err, IsNil) |
595 | + h.LastSession = sess |
596 | clientShutdown := make(chan bool, 1) // abused as an atomic flag |
597 | intercept := func(ic *interceptingConn, op string, b []byte) (bool, int, error) { |
598 | // read after ack |
599 | |
600 | === modified file 'server/acceptance/suites/unicast.go' |
601 | --- server/acceptance/suites/unicast.go 2014-08-15 09:33:48 +0000 |
602 | +++ server/acceptance/suites/unicast.go 2014-09-02 17:24:34 +0000 |
603 | @@ -47,7 +47,7 @@ |
604 | AppId: "app1", |
605 | }) |
606 | c.Assert(err, IsNil, Commentf("%v", res)) |
607 | - events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth) |
608 | + events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth, "") |
609 | got, err := s.PostRequest("/notify", &api.Unicast{ |
610 | Token: res["token"].(string), |
611 | AppId: "app1", |
612 | @@ -65,9 +65,9 @@ |
613 | userId1, auth1 := s.associatedAuth("DEV1") |
614 | userId2, auth2 := s.associatedAuth("DEV2") |
615 | // start 1st client |
616 | - events1, errCh1, stop1 := s.StartClientAuth(c, "DEV1", nil, auth1) |
617 | + events1, errCh1, stop1 := s.StartClientAuth(c, "DEV1", nil, auth1, "") |
618 | // start 2nd client |
619 | - events2, errCh2, stop2 := s.StartClientAuth(c, "DEV2", nil, auth2) |
620 | + events2, errCh2, stop2 := s.StartClientAuth(c, "DEV2", nil, auth2, "") |
621 | // unicast to one and the other |
622 | got, err := s.PostRequest("/notify", &api.Unicast{ |
623 | UserId: userId1, |
624 | @@ -108,7 +108,7 @@ |
625 | c.Assert(err, IsNil, Commentf("%v", got)) |
626 | |
627 | // get pending on connect |
628 | - events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth) |
629 | + events, errCh, stop := s.StartClientAuth(c, "DEV1", nil, auth, "") |
630 | c.Check(NextEvent(events, errCh), Equals, `unicast app:app1 payload:{"a":42};`) |
631 | stop() |
632 | c.Assert(NextEvent(s.ServerEvents, nil), Matches, `.* ended with:.*EOF`) |
633 | @@ -130,7 +130,7 @@ |
634 | c.Assert(err, IsNil, Commentf("%v", got)) |
635 | } |
636 | |
637 | - events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth) |
638 | + events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth, "") |
639 | // getting pending on connect |
640 | n := 0 |
641 | for { |
642 | @@ -185,7 +185,7 @@ |
643 | }) |
644 | c.Assert(err, IsNil, Commentf("%v", got)) |
645 | |
646 | - events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth) |
647 | + events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth, "") |
648 | // getting the 1 pending on connect |
649 | c.Check(NextEvent(events, errCh), Equals, `unicast app:app1 payload:{"serial":1000};`) |
650 | stop() |
651 | @@ -218,7 +218,7 @@ |
652 | }) |
653 | c.Assert(err, IsNil, Commentf("%v", got)) |
654 | |
655 | - events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth) |
656 | + events, errCh, stop := s.StartClientAuth(c, "DEV2", nil, auth, "") |
657 | // getting the 1 pending on connect |
658 | c.Check(NextEvent(events, errCh), Equals, `unicast app:app1 payload:{"m":2};`) |
659 | stop() |
660 | |
661 | === modified file 'server/session/session_test.go' |
662 | --- server/session/session_test.go 2014-07-03 14:25:45 +0000 |
663 | +++ server/session/session_test.go 2014-09-02 17:24:34 +0000 |
664 | @@ -647,7 +647,7 @@ |
665 | effectiveOfPing := float64(interval) / float64(50*time.Millisecond) |
666 | comment := Commentf("effectiveOfPing=%f", effectiveOfPing) |
667 | c.Check(effectiveOfPing > 0.95, Equals, true, comment) |
668 | - c.Check(effectiveOfPing < 1.15, Equals, true, comment) |
669 | + c.Check(effectiveOfPing < 1.19, Equals, true, comment) |
670 | up <- nil // no write error |
671 | up <- io.EOF |
672 | err := <-errCh |
673 | |
674 | === added directory 'urldispatcher' |
675 | === added directory 'urldispatcher/curldispatcher' |
676 | === added file 'urldispatcher/curldispatcher/curldispatcher.go' |
677 | --- urldispatcher/curldispatcher/curldispatcher.go 1970-01-01 00:00:00 +0000 |
678 | +++ urldispatcher/curldispatcher/curldispatcher.go 2014-09-02 17:24:34 +0000 |
679 | @@ -0,0 +1,95 @@ |
680 | +/* |
681 | + Copyright 2014 Canonical Ltd. |
682 | + |
683 | + This program is free software: you can redistribute it and/or modify it |
684 | + under the terms of the GNU General Public License version 3, as published |
685 | + by the Free Software Foundation. |
686 | + |
687 | + This program is distributed in the hope that it will be useful, but |
688 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
689 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
690 | + PURPOSE. See the GNU General Public License for more details. |
691 | + |
692 | + You should have received a copy of the GNU General Public License along |
693 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
694 | +*/ |
695 | + |
696 | +// package cmessaging wraps libmessaging-menu |
697 | +package curldispatcher |
698 | + |
699 | +/* |
700 | +#cgo pkg-config: url-dispatcher-1 |
701 | + |
702 | +#include <liburl-dispatcher-1/url-dispatcher.h> |
703 | +#include <glib.h> |
704 | + |
705 | +void dispatch_url(const gchar* url, gpointer user_data); |
706 | + |
707 | +gchar** test_url(const gchar** urls); |
708 | +*/ |
709 | +import "C" |
710 | +import "unsafe" |
711 | +import "fmt" |
712 | + |
713 | +func gchar(s string) *C.gchar { |
714 | + return (*C.gchar)(C.CString(s)) |
715 | +} |
716 | + |
717 | +func gfree(s *C.gchar) { |
718 | + C.g_free((C.gpointer)(s)) |
719 | +} |
720 | + |
721 | +func getCharPtr(p uintptr) *C.char { |
722 | + return *((**C.char)(unsafe.Pointer(p))) |
723 | +} |
724 | + |
725 | +func TestURL(urls []string) []string { |
726 | + c_urls := make([]*C.gchar, len(urls)+1) |
727 | + for i, url := range urls { |
728 | + c_urls[i] = gchar(url) |
729 | + defer gfree(c_urls[i]) |
730 | + } |
731 | + results := C.test_url((**C.gchar)(unsafe.Pointer(&c_urls[0]))) |
732 | + // if there result is nil, just return empty []string |
733 | + if results == nil { |
734 | + return nil |
735 | + } |
736 | + packages := make([]string, len(urls)) |
737 | + ptrSz := unsafe.Sizeof(unsafe.Pointer(nil)) |
738 | + i := 0 |
739 | + for p := uintptr(unsafe.Pointer(results)); getCharPtr(p) != nil; p += ptrSz { |
740 | + pkg := C.GoString(getCharPtr(p)) |
741 | + packages[i] = pkg |
742 | + i += 1 |
743 | + } |
744 | + return packages |
745 | +} |
746 | + |
747 | +type DispatchPayload struct { |
748 | + doneCh chan bool |
749 | +} |
750 | + |
751 | +func DispatchURL(url string, appPackage string) error { |
752 | + c_url := gchar(url) |
753 | + defer gfree(c_url) |
754 | + c_app_package := gchar(appPackage) |
755 | + defer gfree(c_app_package) |
756 | + doneCh := make(chan bool) |
757 | + payload := DispatchPayload{doneCh: doneCh} |
758 | + C.dispatch_url(c_url, (C.gpointer)(&payload)) |
759 | + success := <-doneCh |
760 | + if !success { |
761 | + return fmt.Errorf("Failed to DispatchURL: %s for %s", url, appPackage) |
762 | + } |
763 | + return nil |
764 | +} |
765 | + |
766 | +//export handleDispatchURLResult |
767 | +func handleDispatchURLResult(c_action *C.char, c_success C.gboolean, obj unsafe.Pointer) { |
768 | + payload := (*DispatchPayload)(obj) |
769 | + success := false |
770 | + if c_success == C.TRUE { |
771 | + success = true |
772 | + } |
773 | + payload.doneCh <- success |
774 | +} |
775 | |
776 | === added file 'urldispatcher/curldispatcher/curldispatcher_c.go' |
777 | --- urldispatcher/curldispatcher/curldispatcher_c.go 1970-01-01 00:00:00 +0000 |
778 | +++ urldispatcher/curldispatcher/curldispatcher_c.go 2014-09-02 17:24:34 +0000 |
779 | @@ -0,0 +1,39 @@ |
780 | +/* |
781 | + Copyright 2014 Canonical Ltd. |
782 | + |
783 | + This program is free software: you can redistribute it and/or modify it |
784 | + under the terms of the GNU General Public License version 3, as published |
785 | + by the Free Software Foundation. |
786 | + |
787 | + This program is distributed in the hope that it will be useful, but |
788 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
789 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
790 | + PURPOSE. See the GNU General Public License for more details. |
791 | + |
792 | + You should have received a copy of the GNU General Public License along |
793 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
794 | +*/ |
795 | + |
796 | +// package curldispatcher wraps liburl-dispatch1 |
797 | +package curldispatcher |
798 | + |
799 | +/* |
800 | +#cgo pkg-config: url-dispatcher-1 |
801 | + |
802 | +#include <liburl-dispatcher-1/url-dispatcher.h> |
803 | +#include <glib.h> |
804 | + |
805 | +static void url_dispatch_callback(const gchar * url, gboolean success, gpointer user_data) { |
806 | + handleDispatchURLResult(url, success, user_data); |
807 | +} |
808 | + |
809 | +void dispatch_url(const gchar* url, gpointer user_data) { |
810 | + url_dispatch_send(url, (URLDispatchCallback)url_dispatch_callback, user_data); |
811 | +} |
812 | + |
813 | +gchar** test_url(const gchar** urls) { |
814 | + char** result = url_dispatch_url_appid(urls); |
815 | + return result; |
816 | +} |
817 | +*/ |
818 | +import "C" |
819 | |
820 | === added file 'urldispatcher/urldispatcher.go' |
821 | --- urldispatcher/urldispatcher.go 1970-01-01 00:00:00 +0000 |
822 | +++ urldispatcher/urldispatcher.go 2014-09-02 17:24:34 +0000 |
823 | @@ -0,0 +1,70 @@ |
824 | +/* |
825 | + Copyright 2013-2014 Canonical Ltd. |
826 | + |
827 | + This program is free software: you can redistribute it and/or modify it |
828 | + under the terms of the GNU General Public License version 3, as published |
829 | + by the Free Software Foundation. |
830 | + |
831 | + This program is distributed in the hope that it will be useful, but |
832 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
833 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
834 | + PURPOSE. See the GNU General Public License for more details. |
835 | + |
836 | + You should have received a copy of the GNU General Public License along |
837 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
838 | +*/ |
839 | + |
840 | +// Package urldispatcher wraps the url dispatcher's C API |
841 | +package urldispatcher |
842 | + |
843 | +import ( |
844 | + "launchpad.net/ubuntu-push/click" |
845 | + "launchpad.net/ubuntu-push/logger" |
846 | + "launchpad.net/ubuntu-push/urldispatcher/curldispatcher" |
847 | +) |
848 | + |
849 | +// A URLDispatcher wrapper. |
850 | +type URLDispatcher interface { |
851 | + DispatchURL(string, *click.AppId) error |
852 | + TestURL(*click.AppId, []string) bool |
853 | +} |
854 | + |
855 | +type urlDispatcher struct { |
856 | + log logger.Logger |
857 | +} |
858 | + |
859 | +// New builds a new URL dispatcher that uses the provided bus.Endpoint |
860 | +func New(log logger.Logger) URLDispatcher { |
861 | + return &urlDispatcher{log} |
862 | +} |
863 | + |
864 | +var _ URLDispatcher = &urlDispatcher{} // ensures it conforms |
865 | + |
866 | +var cDispatchURL = curldispatcher.DispatchURL |
867 | +var cTestURL = curldispatcher.TestURL |
868 | + |
869 | +func (ud *urlDispatcher) DispatchURL(url string, app *click.AppId) error { |
870 | + ud.log.Debugf("Dispatching %s", url) |
871 | + err := cDispatchURL(url, app.DispatchPackage()) |
872 | + if err != nil { |
873 | + ud.log.Errorf("DispatchURL failed: %s", err) |
874 | + } |
875 | + return err |
876 | +} |
877 | + |
878 | +func (ud *urlDispatcher) TestURL(app *click.AppId, urls []string) bool { |
879 | + ud.log.Debugf("TestURL: %s", urls) |
880 | + var appIds []string |
881 | + appIds = cTestURL(urls) |
882 | + if len(appIds) == 0 { |
883 | + ud.log.Debugf("TestURL: invalid urls: %s - %s", urls, app.Versioned()) |
884 | + return false |
885 | + } |
886 | + for _, appId := range appIds { |
887 | + if appId != app.Versioned() { |
888 | + ud.log.Debugf("Notification skipped because of different appid for actions: %v - %s != %s", urls, appId, app.Versioned()) |
889 | + return false |
890 | + } |
891 | + } |
892 | + return true |
893 | +} |
894 | |
895 | === added file 'urldispatcher/urldispatcher_test.go' |
896 | --- urldispatcher/urldispatcher_test.go 1970-01-01 00:00:00 +0000 |
897 | +++ urldispatcher/urldispatcher_test.go 2014-09-02 17:24:34 +0000 |
898 | @@ -0,0 +1,142 @@ |
899 | +/* |
900 | + Copyright 2013-2014 Canonical Ltd. |
901 | + |
902 | + This program is free software: you can redistribute it and/or modify it |
903 | + under the terms of the GNU General Public License version 3, as published |
904 | + by the Free Software Foundation. |
905 | + |
906 | + This program is distributed in the hope that it will be useful, but |
907 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
908 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
909 | + PURPOSE. See the GNU General Public License for more details. |
910 | + |
911 | + You should have received a copy of the GNU General Public License along |
912 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
913 | +*/ |
914 | + |
915 | +package urldispatcher |
916 | + |
917 | +import ( |
918 | + "errors" |
919 | + |
920 | + . "launchpad.net/gocheck" |
921 | + clickhelp "launchpad.net/ubuntu-push/click/testing" |
922 | + helpers "launchpad.net/ubuntu-push/testing" |
923 | + "testing" |
924 | +) |
925 | + |
926 | +// hook up gocheck |
927 | +func TestUrldispatcher(t *testing.T) { TestingT(t) } |
928 | + |
929 | +type UDSuite struct { |
930 | + log *helpers.TestLogger |
931 | + cDispatchURL func(string, string) error |
932 | + cTestURL func([]string) []string |
933 | +} |
934 | + |
935 | +var _ = Suite(&UDSuite{}) |
936 | + |
937 | +func (s *UDSuite) SetUpTest(c *C) { |
938 | + s.log = helpers.NewTestLogger(c, "debug") |
939 | + s.cDispatchURL = cDispatchURL |
940 | + s.cTestURL = cTestURL |
941 | + // replace it with a always succeed version |
942 | + cDispatchURL = func(url string, appId string) error { |
943 | + return nil |
944 | + } |
945 | +} |
946 | + |
947 | +func (s *UDSuite) TearDownTest(c *C) { |
948 | + cDispatchURL = s.cDispatchURL |
949 | + cTestURL = s.cTestURL |
950 | +} |
951 | + |
952 | +func (s *UDSuite) TestDispatchURLWorks(c *C) { |
953 | + ud := New(s.log) |
954 | + appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
955 | + err := ud.DispatchURL("this", appId) |
956 | + c.Check(err, IsNil) |
957 | +} |
958 | + |
959 | +func (s *UDSuite) TestDispatchURLFailsIfCallFails(c *C) { |
960 | + cDispatchURL = func(url string, appId string) error { |
961 | + return errors.New("fail!") |
962 | + } |
963 | + ud := New(s.log) |
964 | + appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
965 | + err := ud.DispatchURL("this", appId) |
966 | + c.Check(err, NotNil) |
967 | +} |
968 | + |
969 | +func (s *UDSuite) TestTestURLWorks(c *C) { |
970 | + cTestURL = func(url []string) []string { |
971 | + return []string{"com.example.test_app_0.99"} |
972 | + } |
973 | + ud := New(s.log) |
974 | + appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
975 | + c.Check(ud.TestURL(appId, []string{"this"}), Equals, true) |
976 | + c.Check(s.log.Captured(), Matches, `(?sm).*TestURL: \[this\].*`) |
977 | +} |
978 | + |
979 | +func (s *UDSuite) TestTestURLFailsIfCallFails(c *C) { |
980 | + cTestURL = func(url []string) []string { |
981 | + return []string{} |
982 | + } |
983 | + ud := New(s.log) |
984 | + appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
985 | + c.Check(ud.TestURL(appId, []string{"this"}), Equals, false) |
986 | +} |
987 | + |
988 | +func (s *UDSuite) TestTestURLMultipleURLs(c *C) { |
989 | + cTestURL = func(url []string) []string { |
990 | + return []string{"com.example.test_app_0.99", "com.example.test_app_0.99"} |
991 | + } |
992 | + ud := New(s.log) |
993 | + appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
994 | + urls := []string{"potato://test-app", "potato_a://foo"} |
995 | + c.Check(ud.TestURL(appId, urls), Equals, true) |
996 | + c.Check(s.log.Captured(), Matches, `(?sm).*TestURL: \[potato://test-app potato_a://foo\].*`) |
997 | +} |
998 | + |
999 | +func (s *UDSuite) TestTestURLWrongApp(c *C) { |
1000 | + cTestURL = func(url []string) []string { |
1001 | + return []string{"com.example.test_test-app_0.1"} |
1002 | + } |
1003 | + ud := New(s.log) |
1004 | + appId := clickhelp.MustParseAppId("com.example.test_app_0.99") |
1005 | + urls := []string{"potato://test-app"} |
1006 | + c.Check(ud.TestURL(appId, urls), Equals, false) |
1007 | + c.Check(s.log.Captured(), Matches, `(?sm).*Notification skipped because of different appid for actions: \[potato://test-app\] - com.example.test_test-app_0.1 != com.example.test_app_0.99`) |
1008 | +} |
1009 | + |
1010 | +func (s *UDSuite) TestTestURLOneWrongApp(c *C) { |
1011 | + cTestURL = func(url []string) []string { |
1012 | + return []string{"com.example.test_test-app_0", "com.example.test_test-app1"} |
1013 | + } |
1014 | + ud := New(s.log) |
1015 | + appId := clickhelp.MustParseAppId("com.example.test_test-app_0") |
1016 | + urls := []string{"potato://test-app", "potato_a://foo"} |
1017 | + c.Check(ud.TestURL(appId, urls), Equals, false) |
1018 | + c.Check(s.log.Captured(), Matches, `(?sm).*Notification skipped because of different appid for actions: \[potato://test-app potato_a://foo\] - com.example.test_test-app1 != com.example.test_test-app.*`) |
1019 | +} |
1020 | + |
1021 | +func (s *UDSuite) TestTestURLInvalidURL(c *C) { |
1022 | + cTestURL = func(url []string) []string { |
1023 | + return []string{} |
1024 | + } |
1025 | + ud := New(s.log) |
1026 | + appId := clickhelp.MustParseAppId("com.example.test_app_0.2") |
1027 | + urls := []string{"notsupported://test-app"} |
1028 | + c.Check(ud.TestURL(appId, urls), Equals, false) |
1029 | +} |
1030 | + |
1031 | +func (s *UDSuite) TestTestURLLegacyApp(c *C) { |
1032 | + cTestURL = func(url []string) []string { |
1033 | + return []string{"ubuntu-system-settings"} |
1034 | + } |
1035 | + ud := New(s.log) |
1036 | + appId := clickhelp.MustParseAppId("_ubuntu-system-settings") |
1037 | + urls := []string{"settings://test-app"} |
1038 | + c.Check(ud.TestURL(appId, urls), Equals, true) |
1039 | + c.Check(s.log.Captured(), Matches, `(?sm).*TestURL: \[settings://test-app\].*`) |
1040 | +} |