Merge lp:~ralsina/ubuntu-push/merge-automatic into lp:ubuntu-push

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
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+}

Subscribers

People subscribed via source and target branches