Merge lp:~pedronis/ubuntu-push/refactor-service-setup into lp:ubuntu-push

Proposed by Samuele Pedroni
Status: Superseded
Proposed branch: lp:~pedronis/ubuntu-push/refactor-service-setup
Merge into: lp:ubuntu-push
Diff against target: 823 lines (+285/-178)
8 files modified
client/client.go (+28/-10)
client/client_test.go (+64/-7)
client/service/postal.go (+14/-21)
client/service/postal_test.go (+32/-0)
client/service/service.go (+54/-68)
client/service/service_test.go (+82/-71)
debian/config.json (+1/-1)
testing/helpers.go (+10/-0)
To merge this branch: bzr merge lp:~pedronis/ubuntu-push/refactor-service-setup
Reviewer Review Type Date Requested Status
Ubuntu Push Hackers Pending
Review via email: mp+225477@code.launchpad.net

This proposal has been superseded by a proposal from 2014-07-03.

Description of the change

* let take NewPushService a setup obj, have a generic manageReg
* update config.json now that registration is a base url

To post a comment you must log in.
217. By Samuele Pedroni

wait for inc elapsed time

218. By Samuele Pedroni

Unregister method

219. By Samuele Pedroni

Merged ubuntu-push into unregister.

220. By Samuele Pedroni

tweak test

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'client/client.go'
2--- client/client.go 2014-07-01 11:55:30 +0000
3+++ client/client.go 2014-07-03 14:00:43 +0000
4@@ -26,6 +26,7 @@
5 "errors"
6 "fmt"
7 "io/ioutil"
8+ "net/url"
9 "os"
10 "os/exec"
11 "strings"
12@@ -163,6 +164,19 @@
13 }
14 }
15
16+// derivePushServiceSetup derives the service setup from the client configuration bits.
17+func (client *PushClient) derivePushServiceSetup() (*service.PushServiceSetup, error) {
18+ setup := new(service.PushServiceSetup)
19+ purl, err := url.Parse(client.config.RegistrationURL)
20+ if err != nil {
21+ return nil, fmt.Errorf("cannot parse registration url: %v", err)
22+ }
23+ setup.RegURL = purl
24+ setup.DeviceId = client.deviceId
25+ setup.AuthGetter = client.getAuthorization
26+ return setup, nil
27+}
28+
29 // getAuthorization gets the authorization blob to send to the server
30 func (client *PushClient) getAuthorization(url string) string {
31 client.log.Debugf("getting authorization for %s", url)
32@@ -320,9 +334,7 @@
33 if !client.filterBroadcastNotification(msg) {
34 return nil
35 }
36- not_id, err := client.postalService.SendNotification(service.ACTION_ID_BROADCAST,
37- "update_manager_icon", "There's an updated system image.",
38- "Tap to open the system updater.")
39+ not_id, err := client.postalService.InjectBroadcast()
40 if err != nil {
41 client.log.Errorf("showing notification: %s", err)
42 return err
43@@ -338,15 +350,20 @@
44 }
45
46 // handleClick deals with the user clicking a notification
47-func (client *PushClient) handleClick(action_id string) error {
48+func (client *PushClient) handleClick(actionId string) error {
49 // “The string is a stark data structure and everywhere it is passed
50 // there is much duplication of process. It is a perfect vehicle for
51 // hiding information.”
52 //
53 // From ACM's SIGPLAN publication, (September, 1982), Article
54 // "Epigrams in Programming", by Alan J. Perlis of Yale University.
55- url := strings.TrimPrefix(action_id, service.ACTION_ID_SNOWFLAKE)
56- if len(url) == len(action_id) || len(url) == 0 {
57+ url := actionId
58+ // XXX: branch for the broadcast notifications
59+ if strings.HasPrefix(actionId, service.ACTION_ID_PREFIX) {
60+ parts := strings.Split(actionId, "::")
61+ url = parts[1]
62+ }
63+ if len(url) == len(actionId) || len(url) == 0 {
64 // it didn't start with the prefix
65 return nil
66 }
67@@ -396,6 +413,10 @@
68 }
69
70 func (client *PushClient) startService() error {
71+ setup, err := client.derivePushServiceSetup()
72+ if err != nil {
73+ return err
74+ }
75 if client.pushServiceEndpoint == nil {
76 client.pushServiceEndpoint = bus.SessionBus.Endpoint(service.PushServiceBusAddress, client.log)
77 }
78@@ -403,10 +424,7 @@
79 client.postalServiceEndpoint = bus.SessionBus.Endpoint(service.PostalServiceBusAddress, client.log)
80 }
81
82- client.pushService = service.NewPushService(client.pushServiceEndpoint, client.log)
83- client.pushService.SetRegistrationURL(client.config.RegistrationURL)
84- client.pushService.SetAuthGetter(client.getAuthorization)
85- client.pushService.SetDeviceId(client.deviceId)
86+ client.pushService = service.NewPushService(client.pushServiceEndpoint, setup, client.log)
87 if err := client.pushService.Start(); err != nil {
88 return err
89 }
90
91=== modified file 'client/client_test.go'
92--- client/client_test.go 2014-07-01 11:55:30 +0000
93+++ client/client_test.go 2014-07-03 14:00:43 +0000
94@@ -289,7 +289,7 @@
95 // finally compare
96 conf := cli.deriveSessionConfig(info)
97 // compare authGetter by string
98- c.Check(fmt.Sprintf("%v", conf.AuthGetter), Equals, fmt.Sprintf("%v", cli.getAuthorization))
99+ c.Check(fmt.Sprintf("%#v", conf.AuthGetter), Equals, fmt.Sprintf("%#v", cli.getAuthorization))
100 // and set it to nil
101 conf.AuthGetter = nil
102 expected.AuthGetter = nil
103@@ -297,6 +297,51 @@
104 }
105
106 /*****************************************************************
107+ derivePushServiceSetup tests
108+******************************************************************/
109+
110+func (cs *clientSuite) TestDerivePushServiceSetup(c *C) {
111+ cs.writeTestConfig(map[string]interface{}{})
112+ cli := NewPushClient(cs.configPath, cs.leveldbPath)
113+ err := cli.configure()
114+ c.Assert(err, IsNil)
115+ cli.deviceId = "zoo"
116+ expected := &service.PushServiceSetup{
117+ DeviceId: "zoo",
118+ AuthGetter: func(string) string { return "" },
119+ RegURL: helpers.ParseURL("reg://"),
120+ }
121+ // sanity check that we are looking at all fields
122+ vExpected := reflect.ValueOf(expected).Elem()
123+ nf := vExpected.NumField()
124+ for i := 0; i < nf; i++ {
125+ fv := vExpected.Field(i)
126+ // field isn't empty/zero
127+ c.Assert(fv.Interface(), Not(DeepEquals), reflect.Zero(fv.Type()).Interface(), Commentf("forgot about: %s", vExpected.Type().Field(i).Name))
128+ }
129+ // finally compare
130+ setup, err := cli.derivePushServiceSetup()
131+ c.Assert(err, IsNil)
132+ // compare authGetter by string
133+ c.Check(fmt.Sprintf("%#v", setup.AuthGetter), Equals, fmt.Sprintf("%#v", cli.getAuthorization))
134+ // and set it to nil
135+ setup.AuthGetter = nil
136+ expected.AuthGetter = nil
137+ c.Check(setup, DeepEquals, expected)
138+}
139+
140+func (cs *clientSuite) TestDerivePushServiceSetupError(c *C) {
141+ cs.writeTestConfig(map[string]interface{}{
142+ "registration_url": "%gh",
143+ })
144+ cli := NewPushClient(cs.configPath, cs.leveldbPath)
145+ err := cli.configure()
146+ c.Assert(err, IsNil)
147+ _, err = cli.derivePushServiceSetup()
148+ c.Check(err, ErrorMatches, "cannot parse registration url:.*")
149+}
150+
151+/*****************************************************************
152 startService tests
153 ******************************************************************/
154
155@@ -305,7 +350,8 @@
156 "auth_helper": helpers.ScriptAbsPath("dummyauth.sh"),
157 })
158 cli := NewPushClient(cs.configPath, cs.leveldbPath)
159- cli.configure()
160+ err := cli.configure()
161+ c.Assert(err, IsNil)
162 cli.log = cs.log
163 cli.deviceId = "fake-id"
164 cli.pushServiceEndpoint = testibus.NewTestingEndpoint(condition.Work(true), nil)
165@@ -314,8 +360,6 @@
166 c.Check(cli.startService(), IsNil)
167 c.Assert(cli.pushService, NotNil)
168 c.Check(cli.pushService.IsRunning(), Equals, true)
169- c.Check(cli.pushService.GetDeviceId(), Equals, "fake-id")
170- c.Check(cli.pushService.GetRegistrationAuthorization(), Equals, "hello reg://")
171 c.Assert(cli.setupPostalService(), IsNil)
172 c.Assert(cli.startPostalService(), IsNil)
173 c.Check(cli.postalService.IsRunning(), Equals, true)
174@@ -323,6 +367,17 @@
175 cli.postalService.Stop()
176 }
177
178+func (cs *clientSuite) TestStartServiceSetupError(c *C) {
179+ cs.writeTestConfig(map[string]interface{}{
180+ "registration_url": "%gh",
181+ })
182+ cli := NewPushClient(cs.configPath, cs.leveldbPath)
183+ err := cli.configure()
184+ c.Assert(err, IsNil)
185+ err = cli.startService()
186+ c.Check(err, ErrorMatches, "cannot parse registration url:.*")
187+}
188+
189 func (cs *clientSuite) TestStartServiceErrorsOnNilLog(c *C) {
190 cli := NewPushClient(cs.configPath, cs.leveldbPath)
191 c.Check(cli.log, IsNil)
192@@ -712,6 +767,8 @@
193 handleClick tests
194 ******************************************************************/
195
196+var ACTION_ID_BROADCAST = service.ACTION_ID_PREFIX + service.SystemUpdateUrl + service.ACTION_ID_SUFFIX
197+
198 func (cs *clientSuite) TestHandleClick(c *C) {
199 cli := NewPushClient(cs.configPath, cs.leveldbPath)
200 cli.log = cs.log
201@@ -723,14 +780,14 @@
202 args := testibus.GetCallArgs(endp)
203 c.Assert(args, HasLen, 0)
204 // check we worked with the right action id
205- c.Check(cli.handleClick(service.ACTION_ID_BROADCAST), IsNil)
206+ c.Check(cli.handleClick(ACTION_ID_BROADCAST), IsNil)
207 // check we sent the notification
208 args = testibus.GetCallArgs(endp)
209 c.Assert(args, HasLen, 1)
210 c.Check(args[0].Member, Equals, "DispatchURL")
211 c.Check(args[0].Args, DeepEquals, []interface{}{service.SystemUpdateUrl})
212 // check we worked with the right action id
213- c.Check(cli.handleClick(service.ACTION_ID_SNOWFLAKE+"foo"), IsNil)
214+ c.Check(cli.handleClick(service.ACTION_ID_PREFIX+"foo"), IsNil)
215 // check we sent the notification
216 args = testibus.GetCallArgs(endp)
217 c.Assert(args, HasLen, 2)
218@@ -879,7 +936,7 @@
219 c.Check(cs.log.Captured(), Matches, "(?ms).*Session connected after 42 attempts$")
220
221 // * actionsCh to the click handler/url dispatcher
222- aCh <- notifications.RawActionReply{ActionId: service.ACTION_ID_BROADCAST}
223+ aCh <- notifications.RawActionReply{ActionId: ACTION_ID_BROADCAST}
224 tick()
225 uargs := testibus.GetCallArgs(cli.urlDispatcherEndp)
226 c.Assert(uargs, HasLen, 1)
227
228=== modified file 'client/service/postal.go'
229--- client/service/postal.go 2014-07-01 11:55:30 +0000
230+++ client/service/postal.go 2014-07-03 14:00:43 +0000
231@@ -20,7 +20,6 @@
232 "strings"
233
234 "code.google.com/p/go-uuid/uuid"
235- "launchpad.net/go-dbus/v1"
236
237 "launchpad.net/ubuntu-push/bus"
238 "launchpad.net/ubuntu-push/bus/notifications"
239@@ -50,9 +49,9 @@
240 )
241
242 var (
243- SystemUpdateUrl = "settings:///system/system-update"
244- ACTION_ID_SNOWFLAKE = "::ubuntu-push-client::"
245- ACTION_ID_BROADCAST = ACTION_ID_SNOWFLAKE + SystemUpdateUrl
246+ SystemUpdateUrl = "settings:///system/system-update"
247+ ACTION_ID_PREFIX = "ubuntu-push-client::"
248+ ACTION_ID_SUFFIX = "::0"
249 )
250
251 // NewPostalService() builds a new service and returns it.
252@@ -90,9 +89,7 @@
253 }
254
255 func (svc *PostalService) TakeTheBus() (<-chan notifications.RawActionReply, error) {
256- iniCh := make(chan uint32)
257- go func() { iniCh <- util.NewAutoRedialer(svc.notificationsEndp).Redial() }()
258- <-iniCh
259+ util.NewAutoRedialer(svc.notificationsEndp).Redial()
260 actionsCh, err := notifications.Raw(svc.notificationsEndp, svc.Log).WatchActions()
261 return actionsCh, err
262 }
263@@ -164,18 +161,14 @@
264 return err
265 }
266
267-func (svc *PostalService) SendNotification(action_id, icon, summary, body string) (uint32, error) {
268- a := []string{action_id, "Switch to app"} // action value not visible on the phone
269- h := map[string]*dbus.Variant{"x-canonical-switch-to-application": &dbus.Variant{true}}
270- nots := notifications.Raw(svc.notificationsEndp, svc.Log)
271- return nots.Notify(
272- "ubuntu-push-client", // app name
273- uint32(0), // id
274- icon, // icon
275- summary, // summary
276- body, // body
277- a, // actions
278- h, // hints
279- int32(10*1000), // timeout (ms)
280- )
281+func (svc *PostalService) InjectBroadcast() (uint32, error) {
282+ // XXX: call a helper?
283+ // XXX: Present force us to send the url as the notificationId
284+ icon := "update_manager_icon"
285+ summary := "There's an updated system image."
286+ body := "Tap to open the system updater."
287+ actions := []string{"Switch to app"} // action value not visible on the phone
288+ card := &launch_helper.Card{Icon: icon, Summary: summary, Body: body, Actions: actions, Popup: true}
289+ output := &launch_helper.HelperOutput{[]byte(""), &launch_helper.Notification{Card: card}}
290+ return 0, svc.msgHandler("ubuntu-push-client", SystemUpdateUrl, output)
291 }
292
293=== modified file 'client/service/postal_test.go'
294--- client/service/postal_test.go 2014-07-01 11:55:30 +0000
295+++ client/service/postal_test.go 2014-07-03 14:00:43 +0000
296@@ -157,6 +157,38 @@
297 }
298
299 //
300+// Injection (Broadcast) tests
301+
302+func (ss *postalSuite) TestInjectBroadcast(c *C) {
303+ bus := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))
304+ svc := NewPostalService(ss.bus, bus, ss.log)
305+ //svc.msgHandler = nil
306+ rvs, err := svc.InjectBroadcast()
307+ c.Assert(err, IsNil)
308+ c.Check(rvs, Equals, uint32(0))
309+ c.Assert(err, IsNil)
310+ // and check it fired the right signal (twice)
311+ callArgs := testibus.GetCallArgs(bus)
312+ c.Assert(callArgs, HasLen, 1)
313+ c.Check(callArgs[0].Member, Equals, "Notify")
314+ c.Check(callArgs[0].Args[0:6], DeepEquals, []interface{}{"ubuntu-push-client", uint32(0), "update_manager_icon",
315+ "There's an updated system image.", "Tap to open the system updater.",
316+ []string{"ubuntu-push-client::settings:///system/system-update::0", "Switch to app"}})
317+ // TODO: check the map in callArgs?
318+ // c.Check(callArgs[0].Args[7]["x-canonical-secondary-icon"], NotNil)
319+ // c.Check(callArgs[0].Args[7]["x-canonical-snap-decisions"], NotNil)
320+}
321+
322+func (ss *postalSuite) TestInjectBroadcastFails(c *C) {
323+ bus := testibus.NewTestingEndpoint(condition.Work(true),
324+ condition.Work(false))
325+ svc := NewPostalService(ss.bus, bus, ss.log)
326+ svc.SetMessageHandler(func(string, string, *launch_helper.HelperOutput) error { return errors.New("fail") })
327+ _, err := svc.InjectBroadcast()
328+ c.Check(err, NotNil)
329+}
330+
331+//
332 // Notifications tests
333 func (ss *postalSuite) TestNotificationsWorks(c *C) {
334 svc := NewPostalService(ss.bus, ss.notifBus, ss.log)
335
336=== modified file 'client/service/service.go'
337--- client/service/service.go 2014-07-01 11:55:30 +0000
338+++ client/service/service.go 2014-07-03 14:00:43 +0000
339@@ -23,6 +23,7 @@
340 "fmt"
341 "io/ioutil"
342 "net/http"
343+ "net/url"
344 "os"
345 "strings"
346
347@@ -32,10 +33,17 @@
348 "launchpad.net/ubuntu-push/nih"
349 )
350
351+// PushServiceSetup encapsulates the params for setting up a PushService.
352+type PushServiceSetup struct {
353+ RegURL *url.URL
354+ DeviceId string
355+ AuthGetter func(string) string
356+}
357+
358 // PushService is the dbus api
359 type PushService struct {
360 DBusService
361- regURL string
362+ regURL *url.URL
363 deviceId string
364 authGetter func(string) string
365 httpCli http13.Client
366@@ -50,59 +58,28 @@
367 )
368
369 // NewPushService() builds a new service and returns it.
370-func NewPushService(bus bus.Endpoint, log logger.Logger) *PushService {
371+func NewPushService(bus bus.Endpoint, setup *PushServiceSetup, log logger.Logger) *PushService {
372 var svc = &PushService{}
373 svc.Log = log
374 svc.Bus = bus
375+ svc.regURL = setup.RegURL
376+ svc.deviceId = setup.DeviceId
377+ svc.authGetter = setup.AuthGetter
378 return svc
379 }
380
381-// SetRegistrationURL() sets the registration url for the service
382-func (svc *PushService) SetRegistrationURL(url string) {
383- svc.lock.Lock()
384- defer svc.lock.Unlock()
385- svc.regURL = url
386-}
387-
388-// SetAuthGetter() sets the authorization getter for the service
389-func (svc *PushService) SetAuthGetter(authGetter func(string) string) {
390- svc.lock.Lock()
391- defer svc.lock.Unlock()
392- svc.authGetter = authGetter
393-}
394-
395-// getRegistrationAuthorization() returns the authorization header for
396-// POSTing to the registration HTTP endpoint
397-//
398-// (this is for calling with the lock held)
399-func (svc *PushService) getRegistrationAuthorization() string {
400- if svc.authGetter != nil && svc.regURL != "" {
401- return svc.authGetter(svc.regURL)
402- } else {
403- return ""
404- }
405-}
406-
407-// GetRegistrationAuthorization() returns the authorization header for
408-// POSTing to the registration HTTP endpoint
409-func (svc *PushService) GetRegistrationAuthorization() string {
410- svc.lock.RLock()
411- defer svc.lock.RUnlock()
412- return svc.getRegistrationAuthorization()
413-}
414-
415-// SetDeviceId() sets the device id
416-func (svc *PushService) SetDeviceId(deviceId string) {
417- svc.lock.Lock()
418- defer svc.lock.Unlock()
419- svc.deviceId = deviceId
420-}
421-
422-// GetDeviceId() returns the device id
423-func (svc *PushService) GetDeviceId() string {
424- svc.lock.RLock()
425- defer svc.lock.RUnlock()
426- return svc.deviceId
427+// getAuthorization() returns the URL and the authorization header for
428+// POSTing to the registration HTTP endpoint for op
429+func (svc *PushService) getAuthorization(op string) (string, string) {
430+ if svc.authGetter == nil || svc.regURL == nil {
431+ return "", ""
432+ }
433+ purl, err := svc.regURL.Parse(op)
434+ if err != nil {
435+ panic("op to getAuthorization was invalid")
436+ }
437+ url := purl.String()
438+ return url, svc.authGetter(url)
439 }
440
441 func (svc *PushService) Start() error {
442@@ -130,32 +107,21 @@
443 Message string `json:"message"` //
444 }
445
446-func (svc *PushService) register(path string, args, _ []interface{}) ([]interface{}, error) {
447- svc.lock.RLock()
448- defer svc.lock.RUnlock()
449- if len(args) != 0 {
450- return nil, BadArgCount
451- }
452- raw_appname := path[strings.LastIndex(path, "/")+1:]
453- appname := string(nih.Unquote([]byte(raw_appname)))
454-
455- rv := os.Getenv("PUSH_REG_" + raw_appname)
456- if rv != "" {
457- return []interface{}{rv}, nil
458- }
459-
460- req_body, err := json.Marshal(registrationRequest{svc.deviceId, appname})
461+func (svc *PushService) manageReg(op, appId string) (*registrationReply, error) {
462+ req_body, err := json.Marshal(registrationRequest{svc.deviceId, appId})
463 if err != nil {
464 return nil, fmt.Errorf("unable to marshal register request body: %v", err)
465 }
466- req, err := http13.NewRequest("POST", svc.regURL, bytes.NewReader(req_body))
467- if err != nil {
468- return nil, fmt.Errorf("unable to build register request: %v", err)
469- }
470- auth := svc.getRegistrationAuthorization()
471+
472+ url, auth := svc.getAuthorization(op)
473 if auth == "" {
474 return nil, BadAuth
475 }
476+
477+ req, err := http13.NewRequest("POST", url, bytes.NewReader(req_body))
478+ if err != nil {
479+ panic(fmt.Errorf("unable to build register request: %v", err))
480+ }
481 req.Header.Add("Authorization", auth)
482 req.Header.Add("Content-Type", "application/json")
483
484@@ -188,6 +154,26 @@
485 return nil, fmt.Errorf("unable to unmarshal register response: %v", err)
486 }
487
488+ return &reply, nil
489+}
490+
491+func (svc *PushService) register(path string, args, _ []interface{}) ([]interface{}, error) {
492+ if len(args) != 0 {
493+ return nil, BadArgCount
494+ }
495+ raw_appname := path[strings.LastIndex(path, "/")+1:]
496+ appname := string(nih.Unquote([]byte(raw_appname)))
497+
498+ rv := os.Getenv("PUSH_REG_" + raw_appname)
499+ if rv != "" {
500+ return []interface{}{rv}, nil
501+ }
502+
503+ reply, err := svc.manageReg("/register", appname)
504+ if err != nil {
505+ return nil, err
506+ }
507+
508 if !reply.Ok || reply.Token == "" {
509 svc.Log.Errorf("Unexpected response: %#v", reply)
510 return nil, BadToken
511
512=== modified file 'client/service/service_test.go'
513--- client/service/service_test.go 2014-06-20 12:33:03 +0000
514+++ client/service/service_test.go 2014-07-03 14:00:43 +0000
515@@ -47,8 +47,25 @@
516 ss.bus = testibus.NewTestingEndpoint(condition.Work(true), nil)
517 }
518
519+var testSetup = &PushServiceSetup{}
520+
521+func (ss *serviceSuite) TestBuild(c *C) {
522+ setup := &PushServiceSetup{
523+ RegURL: helpers.ParseURL("http://reg"),
524+ DeviceId: "FOO",
525+ AuthGetter: func(s string) string {
526+ return ""
527+ },
528+ }
529+ svc := NewPushService(ss.bus, setup, ss.log)
530+ c.Check(svc.Bus, Equals, ss.bus)
531+ c.Check(svc.regURL, DeepEquals, helpers.ParseURL("http://reg"))
532+ c.Check(fmt.Sprintf("%#v", svc.authGetter), Equals, fmt.Sprintf("%#v", setup.AuthGetter))
533+ // ...
534+}
535+
536 func (ss *serviceSuite) TestStart(c *C) {
537- svc := NewPushService(ss.bus, ss.log)
538+ svc := NewPushService(ss.bus, testSetup, ss.log)
539 c.Check(svc.IsRunning(), Equals, false)
540 c.Check(svc.Start(), IsNil)
541 c.Check(svc.IsRunning(), Equals, true)
542@@ -56,31 +73,31 @@
543 }
544
545 func (ss *serviceSuite) TestStartTwice(c *C) {
546- svc := NewPushService(ss.bus, ss.log)
547+ svc := NewPushService(ss.bus, testSetup, ss.log)
548 c.Check(svc.Start(), IsNil)
549 c.Check(svc.Start(), Equals, AlreadyStarted)
550 svc.Stop()
551 }
552
553 func (ss *serviceSuite) TestStartNoLog(c *C) {
554- svc := NewPushService(ss.bus, nil)
555+ svc := NewPushService(ss.bus, testSetup, nil)
556 c.Check(svc.Start(), Equals, NotConfigured)
557 }
558
559 func (ss *serviceSuite) TestStartNoBus(c *C) {
560- svc := NewPushService(nil, ss.log)
561+ svc := NewPushService(nil, testSetup, ss.log)
562 c.Check(svc.Start(), Equals, NotConfigured)
563 }
564
565 func (ss *serviceSuite) TestStartFailsOnBusDialFailure(c *C) {
566 bus := testibus.NewTestingEndpoint(condition.Work(false), nil)
567- svc := NewPushService(bus, ss.log)
568+ svc := NewPushService(bus, testSetup, ss.log)
569 c.Check(svc.Start(), ErrorMatches, `.*(?i)cond said no.*`)
570 svc.Stop()
571 }
572
573 func (ss *serviceSuite) TestStartGrabsName(c *C) {
574- svc := NewPushService(ss.bus, ss.log)
575+ svc := NewPushService(ss.bus, testSetup, ss.log)
576 c.Assert(svc.Start(), IsNil)
577 callArgs := testibus.GetCallArgs(ss.bus)
578 defer svc.Stop()
579@@ -89,7 +106,7 @@
580 }
581
582 func (ss *serviceSuite) TestStopClosesBus(c *C) {
583- svc := NewPushService(ss.bus, ss.log)
584+ svc := NewPushService(ss.bus, testSetup, ss.log)
585 c.Assert(svc.Start(), IsNil)
586 svc.Stop()
587 callArgs := testibus.GetCallArgs(ss.bus)
588@@ -99,35 +116,27 @@
589
590 // registration tests
591
592-func (ss *serviceSuite) TestSetRegURLWorks(c *C) {
593- svc := NewPushService(ss.bus, ss.log)
594- c.Check(svc.regURL, Equals, "")
595- svc.SetRegistrationURL("xyzzy://")
596- c.Check(svc.regURL, Equals, "xyzzy://")
597-}
598-
599-func (ss *serviceSuite) TestSetAuthGetterWorks(c *C) {
600- svc := NewPushService(ss.bus, ss.log)
601- c.Check(svc.authGetter, IsNil)
602- f := func(string) string { return "" }
603- svc.SetAuthGetter(f)
604- c.Check(fmt.Sprintf("%#v", svc.authGetter), Equals, fmt.Sprintf("%#v", f))
605-}
606-
607 func (ss *serviceSuite) TestGetRegAuthWorks(c *C) {
608- svc := NewPushService(ss.bus, ss.log)
609- svc.SetRegistrationURL("xyzzy://")
610 ch := make(chan string, 1)
611- f := func(s string) string { ch <- s; return "Auth " + s }
612- svc.SetAuthGetter(f)
613- c.Check(svc.getRegistrationAuthorization(), Equals, "Auth xyzzy://")
614+ setup := &PushServiceSetup{
615+ RegURL: helpers.ParseURL("http://foo"),
616+ AuthGetter: func(s string) string {
617+ ch <- s
618+ return "Auth " + s
619+ },
620+ }
621+ svc := NewPushService(ss.bus, setup, ss.log)
622+ url, auth := svc.getAuthorization("/op")
623+ c.Check(auth, Equals, "Auth http://foo/op")
624 c.Assert(len(ch), Equals, 1)
625- c.Check(<-ch, Equals, "xyzzy://")
626+ c.Check(<-ch, Equals, "http://foo/op")
627+ c.Check(url, Equals, "http://foo/op")
628 }
629
630 func (ss *serviceSuite) TestGetRegAuthDoesNotPanic(c *C) {
631- svc := NewPushService(ss.bus, ss.log)
632- c.Check(svc.getRegistrationAuthorization(), Equals, "")
633+ svc := NewPushService(ss.bus, testSetup, ss.log)
634+ _, auth := svc.getAuthorization("/op")
635+ c.Check(auth, Equals, "")
636 }
637
638 func (ss *serviceSuite) TestRegistrationFailsIfBadArgs(c *C) {
639@@ -149,11 +158,12 @@
640 fmt.Fprintln(w, `{"ok":true,"token":"blob-of-bytes"}`)
641 }))
642 defer ts.Close()
643-
644- svc := NewPushService(ss.bus, ss.log)
645- svc.SetAuthGetter(func(string) string { return "tok" })
646- svc.SetRegistrationURL(ts.URL)
647- svc.SetDeviceId("fake-device-id")
648+ setup := &PushServiceSetup{
649+ DeviceId: "fake-device-id",
650+ RegURL: helpers.ParseURL(ts.URL),
651+ AuthGetter: func(string) string { return "tok" },
652+ }
653+ svc := NewPushService(ss.bus, setup, ss.log)
654 // this'll check (un)quoting, too
655 reg, err := svc.register("/an_2dapp_2did", nil, nil)
656 c.Assert(err, IsNil)
657@@ -175,60 +185,59 @@
658 c.Check(err, IsNil)
659 }
660
661-func (ss *serviceSuite) TestRegistrationFailsOnBadReqURL(c *C) {
662- svc := NewPushService(ss.bus, ss.log)
663- svc.SetRegistrationURL("%gh")
664- reg, err := svc.register("thing", nil, nil)
665- c.Check(reg, IsNil)
666- c.Check(err, ErrorMatches, "unable to build register request: .*")
667-}
668-
669-func (ss *serviceSuite) TestRegistrationFailsOnBadAuth(c *C) {
670- svc := NewPushService(ss.bus, ss.log)
671+func (ss *serviceSuite) TestManageRegFailsOnBadAuth(c *C) {
672 // ... no auth added
673+ svc := NewPushService(ss.bus, testSetup, ss.log)
674 reg, err := svc.register("thing", nil, nil)
675 c.Check(reg, IsNil)
676 c.Check(err, Equals, BadAuth)
677 }
678
679-func (ss *serviceSuite) TestRegistrationFailsOnNoServer(c *C) {
680- svc := NewPushService(ss.bus, ss.log)
681- svc.SetRegistrationURL("xyzzy://")
682- svc.SetAuthGetter(func(string) string { return "tok" })
683+func (ss *serviceSuite) TestManageRegFailsOnNoServer(c *C) {
684+ setup := &PushServiceSetup{
685+ DeviceId: "fake-device-id",
686+ RegURL: helpers.ParseURL("xyzzy://"),
687+ AuthGetter: func(string) string { return "tok" },
688+ }
689+ svc := NewPushService(ss.bus, setup, ss.log)
690 reg, err := svc.register("thing", nil, nil)
691 c.Check(reg, IsNil)
692 c.Check(err, ErrorMatches, "unable to request registration: .*")
693 }
694
695-func (ss *serviceSuite) TestRegistrationFailsOn40x(c *C) {
696+func (ss *serviceSuite) TestManageRegFailsOn40x(c *C) {
697 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
698 http.Error(w, "I'm a teapot", 418)
699 }))
700 defer ts.Close()
701-
702- svc := NewPushService(ss.bus, ss.log)
703- svc.SetAuthGetter(func(string) string { return "tok" })
704- svc.SetRegistrationURL(ts.URL)
705+ setup := &PushServiceSetup{
706+ DeviceId: "fake-device-id",
707+ RegURL: helpers.ParseURL(ts.URL),
708+ AuthGetter: func(string) string { return "tok" },
709+ }
710+ svc := NewPushService(ss.bus, setup, ss.log)
711 reg, err := svc.register("/thing", nil, nil)
712 c.Check(err, Equals, BadRequest)
713 c.Check(reg, IsNil)
714 }
715
716-func (ss *serviceSuite) TestRegistrationFailsOn50x(c *C) {
717+func (ss *serviceSuite) TestManageRegFailsOn50x(c *C) {
718 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
719 http.Error(w, "Not implemented", 501)
720 }))
721 defer ts.Close()
722-
723- svc := NewPushService(ss.bus, ss.log)
724- svc.SetAuthGetter(func(string) string { return "tok" })
725- svc.SetRegistrationURL(ts.URL)
726+ setup := &PushServiceSetup{
727+ DeviceId: "fake-device-id",
728+ RegURL: helpers.ParseURL(ts.URL),
729+ AuthGetter: func(string) string { return "tok" },
730+ }
731+ svc := NewPushService(ss.bus, setup, ss.log)
732 reg, err := svc.register("/thing", nil, nil)
733 c.Check(err, Equals, BadServer)
734 c.Check(reg, IsNil)
735 }
736
737-func (ss *serviceSuite) TestRegistrationFailsOnBadJSON(c *C) {
738+func (ss *serviceSuite) TestManageRegFailsOnBadJSON(c *C) {
739 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
740 buf := make([]byte, 256)
741 n, e := r.Body.Read(buf)
742@@ -241,18 +250,19 @@
743 fmt.Fprintln(w, `{`)
744 }))
745 defer ts.Close()
746-
747- svc := NewPushService(ss.bus, ss.log)
748- svc.SetAuthGetter(func(string) string { return "tok" })
749- svc.SetRegistrationURL(ts.URL)
750- svc.SetDeviceId("fake-device-id")
751+ setup := &PushServiceSetup{
752+ DeviceId: "fake-device-id",
753+ RegURL: helpers.ParseURL(ts.URL),
754+ AuthGetter: func(string) string { return "tok" },
755+ }
756+ svc := NewPushService(ss.bus, setup, ss.log)
757 // this'll check (un)quoting, too
758 reg, err := svc.register("/an_2dapp_2did", nil, nil)
759 c.Check(reg, IsNil)
760 c.Check(err, ErrorMatches, "unable to unmarshal register response: .*")
761 }
762
763-func (ss *serviceSuite) TestRegistrationFailsOnBadJSONDocument(c *C) {
764+func (ss *serviceSuite) TestManageRegFailsOnBadJSONDocument(c *C) {
765 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
766 buf := make([]byte, 256)
767 n, e := r.Body.Read(buf)
768@@ -265,11 +275,12 @@
769 fmt.Fprintln(w, `{"bananas": "very yes"}`)
770 }))
771 defer ts.Close()
772-
773- svc := NewPushService(ss.bus, ss.log)
774- svc.SetAuthGetter(func(string) string { return "tok" })
775- svc.SetRegistrationURL(ts.URL)
776- svc.SetDeviceId("fake-device-id")
777+ setup := &PushServiceSetup{
778+ DeviceId: "fake-device-id",
779+ RegURL: helpers.ParseURL(ts.URL),
780+ AuthGetter: func(string) string { return "tok" },
781+ }
782+ svc := NewPushService(ss.bus, setup, ss.log)
783 // this'll check (un)quoting, too
784 reg, err := svc.register("/an_2dapp_2did", nil, nil)
785 c.Check(reg, IsNil)
786
787=== modified file 'debian/config.json'
788--- debian/config.json 2014-06-19 21:12:04 +0000
789+++ debian/config.json 2014-07-03 14:00:43 +0000
790@@ -1,7 +1,7 @@
791 {
792 "auth_helper": "/usr/lib/ubuntu-push-client/signing-helper",
793 "session_url": "https://push.ubuntu.com/",
794- "registration_url": "https://push.ubuntu.com/register",
795+ "registration_url": "https://push.ubuntu.com",
796 "connect_timeout": "20s",
797 "exchange_timeout": "30s",
798 "hosts_cache_expiry": "12h",
799
800=== modified file 'testing/helpers.go'
801--- testing/helpers.go 2014-06-23 12:46:28 +0000
802+++ testing/helpers.go 2014-07-03 14:00:43 +0000
803@@ -20,6 +20,7 @@
804 import (
805 "encoding/json"
806 "fmt"
807+ "net/url"
808 "os"
809 "path"
810 "path/filepath"
811@@ -160,3 +161,12 @@
812 }
813 return res
814 }
815+
816+// ParseURL parses a URL conveniently.
817+func ParseURL(s string) *url.URL {
818+ purl, err := url.Parse(s)
819+ if err != nil {
820+ panic(err)
821+ }
822+ return purl
823+}

Subscribers

People subscribed via source and target branches