~pedronis/ubuntu-push/automatic-land-to-vivid

« back to all changes in this revision

Viewing changes to client/client_test.go

  • Committer: CI bot
  • Author(s): Richard Huddie, CI bot, Roberto Alsina, Guillermo Gonzalez, John R. Lenton, Samuele Pedroni (Canonical Services Ltd.)
  • Date: 2014-07-21 14:17:24 UTC
  • mfrom: (91.1.177 trunk)
  • Revision ID: ps-jenkins@lists.canonical.com-20140721141724-zf0n470ryo5k4dmd
  [Samuele Pedroni]
  * Check in the api whether an app has pushed too many notifications.
  * Return payload of most recent notification in too many pending
    notifications API error.
  * Introduce clear_pending flag to clean everything pending for an app.
  * Refactor and cleanup.
  * Introduce replace_tag support in store and api, with acceptance test.
  * Teach a couple of trick to cmd/acceptanceclient: exit on run timeout,
    wait for event matching given regexp pattern.
  * Limit unicast data payload to 2K.
  * Payload should be json (fixes message needing to be base64-encoded in
    helper reply)
  * Implement limited mboxes
  * Refactor and cleanup of things done in haste by Chipaca.

  [Richard Huddie]
  * autopilot test framework and basic coverage of broadcast notifications.

  [Guillermo Gonzalez]
  * Add scripts to simplify setup/run of the autopilot tests in the
    device/emulator and include basic unicast tests.
  * Add autopilot test for notification using the emblem counter.
  * Adds scenarios to the autopilot tests for legacy and click (without
    version) applications.
  * Broadcast via the helpers route.
  * Basic support for actions (only default action) in the persistent
    notifications.
  * Change PostBroadcast to send the broadcast message to the software
    updates helper.

  [John R. Lenton]
  * Detangle client and postal.
  * Introduce PostalService interface, and change the client tests to use
    that as much as reasonable.
  * Async invocation of helpers.
  * Give click.Click knowledge of helpers.
  * Write ual-based helper launcher.
  * Switch to the ual-based helper launcher unless the environment
    variable UBUNTU_PUSH_USE_TRIVIAL_HELPER is set.
  * Threw together an implementation of helpers for legacy applications.
  * Hacked up an initial software updates helper, to be handed off to the
    appropriate team shortly.

  [Roberto Alsina]
  * Wrap the (dbus) WindowStack API and add endpoint to the Postal service
    to support inhibition of notifications for focused apps.
  * Inhibit notifications for focused apps
 

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
        "launchpad.net/ubuntu-push/bus"
36
36
        "launchpad.net/ubuntu-push/bus/networkmanager"
37
 
        "launchpad.net/ubuntu-push/bus/notifications"
38
37
        "launchpad.net/ubuntu-push/bus/systemimage"
39
38
        testibus "launchpad.net/ubuntu-push/bus/testing"
 
39
        "launchpad.net/ubuntu-push/click"
 
40
        clickhelp "launchpad.net/ubuntu-push/click/testing"
40
41
        "launchpad.net/ubuntu-push/client/service"
41
42
        "launchpad.net/ubuntu-push/client/session"
42
43
        "launchpad.net/ubuntu-push/client/session/seenstate"
61
62
        }
62
63
}
63
64
 
 
65
type dumbCommon struct {
 
66
        startCount   int
 
67
        stopCount    int
 
68
        runningCount int
 
69
        running      bool
 
70
        err          error
 
71
}
 
72
 
 
73
func (d *dumbCommon) Start() error {
 
74
        d.startCount++
 
75
        return d.err
 
76
}
 
77
func (d *dumbCommon) Stop() {
 
78
        d.stopCount++
 
79
}
 
80
func (d *dumbCommon) IsRunning() bool {
 
81
        d.runningCount++
 
82
        return d.running
 
83
}
 
84
 
 
85
type dumbPush struct {
 
86
        dumbCommon
 
87
        unregCount int
 
88
        unregArgs  []string
 
89
}
 
90
 
 
91
func (d *dumbPush) Unregister(appId string) error {
 
92
        d.unregCount++
 
93
        d.unregArgs = append(d.unregArgs, appId)
 
94
        return d.err
 
95
}
 
96
 
 
97
type postArgs struct {
 
98
        app     *click.AppId
 
99
        nid     string
 
100
        payload json.RawMessage
 
101
}
 
102
 
 
103
type dumbPostal struct {
 
104
        dumbCommon
 
105
        bcastCount int
 
106
        postCount  int
 
107
        postArgs   []postArgs
 
108
}
 
109
 
 
110
func (d *dumbPostal) Post(app *click.AppId, nid string, payload json.RawMessage) error {
 
111
        d.postCount++
 
112
        if app.Application == "ubuntu-system-settings" {
 
113
                d.bcastCount++
 
114
        }
 
115
        d.postArgs = append(d.postArgs, postArgs{app, nid, payload})
 
116
        return d.err
 
117
}
 
118
 
 
119
var _ PostalService = (*dumbPostal)(nil)
 
120
var _ PushService = (*dumbPush)(nil)
 
121
 
64
122
type clientSuite struct {
65
123
        timeouts    []time.Duration
66
124
        configPath  string
188
246
func (cs *clientSuite) TestConfigureSetsUpEndpoints(c *C) {
189
247
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
190
248
 
191
 
        // keep these in the same order as in the client struct, for sanity
192
 
        c.Check(cli.notificationsEndp, IsNil)
193
 
        c.Check(cli.urlDispatcherEndp, IsNil)
194
249
        c.Check(cli.connectivityEndp, IsNil)
195
 
        c.Check(cli.emblemcounterEndp, IsNil)
196
 
        c.Check(cli.hapticEndp, IsNil)
197
250
        c.Check(cli.systemImageEndp, IsNil)
198
 
        c.Check(cli.pushServiceEndpoint, IsNil)
199
 
        c.Check(cli.postalServiceEndpoint, IsNil)
200
251
        err := cli.configure()
201
252
        c.Assert(err, IsNil)
202
 
        c.Check(cli.notificationsEndp, NotNil)
203
 
        c.Check(cli.urlDispatcherEndp, NotNil)
204
253
        c.Check(cli.connectivityEndp, NotNil)
205
 
        c.Check(cli.emblemcounterEndp, NotNil)
206
 
        c.Check(cli.hapticEndp, NotNil)
207
254
        c.Check(cli.systemImageEndp, NotNil)
208
 
        c.Check(cli.pushServiceEndpoint, NotNil)
209
 
        c.Check(cli.postalServiceEndpoint, NotNil)
210
255
}
211
256
 
212
257
func (cs *clientSuite) TestConfigureSetsUpConnCh(c *C) {
223
268
        err := cli.configure()
224
269
        c.Assert(err, IsNil)
225
270
        c.Assert(cli.unregisterCh, NotNil)
226
 
        c.Assert(cli.hasPackage("com.bar.baz_foo"), Equals, false)
 
271
        app, err := click.ParseAppId("com.bar.baz_foo")
 
272
        c.Assert(err, IsNil)
 
273
        c.Assert(cli.installedChecker.Installed(app, false), Equals, false)
227
274
}
228
275
 
229
276
func (cs *clientSuite) TestConfigureBailsOnBadFilename(c *C) {
279
326
    addresses checking tests
280
327
******************************************************************/
281
328
 
 
329
type testInstalledChecker func(*click.AppId, bool) bool
 
330
 
 
331
func (tic testInstalledChecker) Installed(app *click.AppId, setVersion bool) bool {
 
332
        return tic(app, setVersion)
 
333
}
 
334
 
 
335
var (
 
336
        appId1     = "com.example.app1_app1"
 
337
        appId2     = "com.example.app2_app2"
 
338
        appIdHello = "com.example.test_hello"
 
339
        app1       = clickhelp.MustParseAppId(appId1)
 
340
        app2       = clickhelp.MustParseAppId(appId2)
 
341
        appHello   = clickhelp.MustParseAppId(appIdHello)
 
342
)
 
343
 
282
344
func (cs *clientSuite) TestCheckForAddressee(c *C) {
283
345
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
284
 
        cli.unregisterCh = make(chan string, 5)
 
346
        cli.log = cs.log
 
347
        cli.unregisterCh = make(chan *click.AppId, 5)
285
348
        cli.StartAddresseeBatch()
286
349
        calls := 0
287
 
        cli.hasPackage = func(appId string) bool {
 
350
        cli.installedChecker = testInstalledChecker(func(app *click.AppId, setVersion bool) bool {
288
351
                calls++
289
 
                if appId == "app1" {
 
352
                c.Assert(setVersion, Equals, true)
 
353
                if app.Original() == appId1 {
290
354
                        return false
291
355
                }
292
356
                return true
293
 
        }
294
 
        c.Check(cli.CheckForAddressee(&protocol.Notification{AppId: "app1"}), Equals, false)
 
357
        })
 
358
 
 
359
        c.Check(cli.CheckForAddressee(&protocol.Notification{AppId: "bad-id"}), IsNil)
 
360
        c.Check(calls, Equals, 0)
 
361
        c.Assert(cli.unregisterCh, HasLen, 0)
 
362
        c.Check(cs.log.Captured(), Matches, `DEBUG notification "" for invalid app id "bad-id".\n`)
 
363
        cs.log.ResetCapture()
 
364
 
 
365
        c.Check(cli.CheckForAddressee(&protocol.Notification{AppId: appId1}), IsNil)
295
366
        c.Check(calls, Equals, 1)
296
367
        c.Assert(cli.unregisterCh, HasLen, 1)
297
 
        c.Check(<-cli.unregisterCh, Equals, "app1")
298
 
        c.Check(cli.CheckForAddressee(&protocol.Notification{AppId: "app2"}), Equals, true)
299
 
        c.Check(calls, Equals, 2)
300
 
        c.Check(cli.CheckForAddressee(&protocol.Notification{AppId: "app1"}), Equals, false)
301
 
        c.Check(calls, Equals, 2)
302
 
        c.Check(cli.CheckForAddressee(&protocol.Notification{AppId: "app2"}), Equals, true)
 
368
        c.Check(<-cli.unregisterCh, DeepEquals, app1)
 
369
        c.Check(cs.log.Captured(), Matches, `DEBUG notification "" for missing app id "com.example.app1_app1".\n`)
 
370
        cs.log.ResetCapture()
 
371
 
 
372
        c.Check(cli.CheckForAddressee(&protocol.Notification{AppId: appId2}), DeepEquals, app2)
 
373
        c.Check(calls, Equals, 2)
 
374
        c.Check(cs.log.Captured(), Matches, "")
 
375
        cs.log.ResetCapture()
 
376
 
 
377
        c.Check(cli.CheckForAddressee(&protocol.Notification{AppId: appId1}), IsNil)
 
378
        c.Check(calls, Equals, 2)
 
379
        c.Check(cli.CheckForAddressee(&protocol.Notification{AppId: appId2}), DeepEquals, app2)
303
380
        c.Check(calls, Equals, 2)
304
381
        c.Check(cli.unregisterCh, HasLen, 0)
 
382
        c.Check(cs.log.Captured(), Matches, "")
305
383
}
306
384
 
307
385
/*****************************************************************
358
436
        c.Assert(err, IsNil)
359
437
        cli.deviceId = "zoo"
360
438
        expected := &service.PushServiceSetup{
361
 
                DeviceId:   "zoo",
362
 
                AuthGetter: func(string) string { return "" },
363
 
                RegURL:     helpers.ParseURL("reg://"),
 
439
                DeviceId:         "zoo",
 
440
                AuthGetter:       func(string) string { return "" },
 
441
                RegURL:           helpers.ParseURL("reg://"),
 
442
                InstalledChecker: cli.installedChecker,
364
443
        }
365
444
        // sanity check that we are looking at all fields
366
445
        vExpected := reflect.ValueOf(expected).Elem()
396
475
    startService tests
397
476
******************************************************************/
398
477
 
399
 
func (cs *clientSuite) TestStartServiceWorks(c *C) {
400
 
        cs.writeTestConfig(map[string]interface{}{
401
 
                "auth_helper": helpers.ScriptAbsPath("dummyauth.sh"),
402
 
        })
403
 
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
404
 
        err := cli.configure()
405
 
        c.Assert(err, IsNil)
406
 
        cli.log = cs.log
407
 
        cli.deviceId = "fake-id"
408
 
        cli.pushServiceEndpoint = testibus.NewTestingEndpoint(condition.Work(true), nil)
409
 
        cli.postalServiceEndpoint = testibus.NewTestingEndpoint(condition.Work(true), nil)
410
 
        c.Check(cli.pushService, IsNil)
411
 
        c.Check(cli.startService(), IsNil)
412
 
        c.Assert(cli.pushService, NotNil)
413
 
        pushService := cli.pushService.(*service.PushService)
414
 
        c.Check(pushService.IsRunning(), Equals, true)
415
 
        c.Assert(cli.setupPostalService(), IsNil)
416
 
        c.Assert(cli.startPostalService(), IsNil)
417
 
        c.Check(cli.postalService.IsRunning(), Equals, true)
418
 
        pushService.Stop()
419
 
        cli.postalService.Stop()
420
 
}
421
 
 
422
 
func (cs *clientSuite) TestStartServiceSetupError(c *C) {
 
478
func (cs *clientSuite) TestStartPushServiceCallsStart(c *C) {
 
479
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
 
480
        d := new(dumbPush)
 
481
        cli.pushService = d
 
482
        c.Check(cli.startPushService(), IsNil)
 
483
        c.Check(d.startCount, Equals, 1)
 
484
}
 
485
 
 
486
func (cs *clientSuite) TestStartPostServiceCallsStart(c *C) {
 
487
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
 
488
        d := new(dumbPostal)
 
489
        cli.postalService = d
 
490
        c.Check(cli.startPostalService(), IsNil)
 
491
        c.Check(d.startCount, Equals, 1)
 
492
}
 
493
 
 
494
func (cs *clientSuite) TestSetupPushServiceSetupError(c *C) {
423
495
        cs.writeTestConfig(map[string]interface{}{
424
496
                "registration_url": "%gh",
425
497
        })
426
498
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
427
499
        err := cli.configure()
428
500
        c.Assert(err, IsNil)
429
 
        err = cli.startService()
 
501
        err = cli.setupPushService()
430
502
        c.Check(err, ErrorMatches, "cannot parse registration url:.*")
431
503
}
432
504
 
433
 
func (cs *clientSuite) TestStartServiceErrorsOnNilLog(c *C) {
434
 
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
435
 
        c.Check(cli.log, IsNil)
436
 
        c.Check(cli.startService(), NotNil)
437
 
        c.Assert(cli.setupPostalService(), IsNil)
438
 
        c.Assert(cli.startPostalService(), NotNil)
439
 
}
440
 
 
441
 
func (cs *clientSuite) TestStartServiceErrorsOnBusDialPushFail(c *C) {
442
 
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
443
 
        cli.log = cs.log
444
 
        cli.pushServiceEndpoint = testibus.NewTestingEndpoint(condition.Work(false), nil)
445
 
        cli.postalServiceEndpoint = testibus.NewTestingEndpoint(condition.Work(false), nil)
446
 
        c.Check(cli.startService(), NotNil)
447
 
        c.Assert(cli.setupPostalService(), IsNil)
448
 
        c.Assert(cli.startPostalService(), NotNil)
449
 
}
450
 
 
451
 
func (cs *clientSuite) TestStartServiceErrorsOnBusDialPostalFail(c *C) {
452
 
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
453
 
        cli.log = cs.log
454
 
        cli.pushServiceEndpoint = testibus.NewTestingEndpoint(condition.Work(true), nil)
455
 
        cli.postalServiceEndpoint = testibus.NewTestingEndpoint(condition.Work(false), nil)
456
 
        c.Check(cli.startService(), IsNil)
457
 
        c.Assert(cli.setupPostalService(), IsNil)
458
 
        c.Assert(cli.startPostalService(), NotNil)
 
505
func (cs *clientSuite) TestSetupPushService(c *C) {
 
506
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
 
507
        c.Assert(cli.configure(), IsNil)
 
508
        c.Check(cli.pushService, IsNil)
 
509
        c.Check(cli.setupPushService(), IsNil)
 
510
        c.Check(cli.pushService, NotNil)
 
511
}
 
512
 
 
513
func (cs *clientSuite) TestStartPushErrorsOnPushStartError(c *C) {
 
514
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
 
515
        d := new(dumbPush)
 
516
        err := errors.New("potato")
 
517
        d.err = err
 
518
        cli.pushService = d
 
519
        c.Check(cli.startPushService(), Equals, err)
 
520
        c.Check(d.startCount, Equals, 1)
 
521
}
 
522
 
 
523
func (cs *clientSuite) TestStartPostalErrorsOnPostalStartError(c *C) {
 
524
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
 
525
        d := new(dumbPostal)
 
526
        err := errors.New("potato")
 
527
        d.err = err
 
528
        cli.postalService = d
 
529
        c.Check(cli.startPostalService(), Equals, err)
 
530
        c.Check(d.startCount, Equals, 1)
459
531
}
460
532
 
461
533
/*****************************************************************
499
571
        defer ts.Close()
500
572
 
501
573
        // testing endpoints
502
 
        nCond := condition.Fail2Work(3)
503
 
        nEndp := testibus.NewMultiValuedTestingEndpoint(nCond, condition.Work(true),
504
 
                []interface{}{uint32(1), "hello"})
505
 
        uCond := condition.Fail2Work(5)
506
 
        uEndp := testibus.NewTestingEndpoint(uCond, condition.Work(false))
507
574
        cCond := condition.Fail2Work(7)
508
575
        cEndp := testibus.NewTestingEndpoint(cCond, condition.Work(true),
509
576
                uint32(networkmanager.ConnectedGlobal),
511
578
        siCond := condition.Fail2Work(2)
512
579
        siEndp := testibus.NewMultiValuedTestingEndpoint(siCond, condition.Work(true), []interface{}{int32(101), "mako", "daily", "Unknown", map[string]string{}})
513
580
        testibus.SetWatchTicker(cEndp, make(chan bool))
514
 
        ecCond := condition.Fail2Work(13)
515
 
        ecEndp := testibus.NewTestingEndpoint(ecCond, condition.Work(true))
516
 
        haCond := condition.Fail2Work(2)
517
 
        haEndp := testibus.NewTestingEndpoint(haCond, condition.Work(true))
518
581
        // ok, create the thing
519
582
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
520
583
        cli.log = cs.log
521
584
        err := cli.configure()
522
585
        c.Assert(err, IsNil)
523
 
        // the user actions channel has not been set up
524
 
        c.Check(cli.actionsCh, IsNil)
525
586
 
526
587
        // and stomp on things for testing
527
588
        cli.config.ConnectivityConfig.ConnectivityCheckURL = ts.URL
528
589
        cli.config.ConnectivityConfig.ConnectivityCheckMD5 = staticHash
529
 
        cli.notificationsEndp = nEndp
530
 
        cli.urlDispatcherEndp = uEndp
531
590
        cli.connectivityEndp = cEndp
532
 
        cli.emblemcounterEndp = ecEndp
533
 
        cli.hapticEndp = haEndp
534
591
        cli.systemImageEndp = siEndp
535
592
 
536
593
        c.Assert(cli.takeTheBus(), IsNil)
537
 
        c.Assert(cli.setupPostalService(), IsNil)
538
 
        c.Assert(cli.takePostalServiceBus(), IsNil)
539
 
        // the notifications and urldispatcher endpoints retried until connected
540
 
        c.Check(nCond.OK(), Equals, true)
541
 
        c.Check(uCond.OK(), Equals, true)
542
 
        // the user actions channel has now been set up
543
 
        c.Check(cli.actionsCh, NotNil)
 
594
 
544
595
        c.Check(takeNextBool(cli.connCh), Equals, false)
545
596
        c.Check(takeNextBool(cli.connCh), Equals, true)
546
597
        // the connectivity endpoint retried until connected
547
598
        c.Check(cCond.OK(), Equals, true)
548
599
        // the systemimage endpoint retried until connected
549
600
        c.Check(siCond.OK(), Equals, true)
550
 
        // the emblemcounter endpoint retried until connected
551
 
        c.Check(ecCond.OK(), Equals, true)
552
 
        // the haptic endpoint retried until connected
553
 
        c.Check(haCond.OK(), Equals, true)
554
601
}
555
602
 
556
603
// takeTheBus can, in fact, fail
559
606
        err := cli.configure()
560
607
        cli.log = cs.log
561
608
        c.Assert(err, IsNil)
562
 
        // the user actions channel has not been set up
563
 
        c.Check(cli.actionsCh, IsNil)
564
609
 
565
610
        // and stomp on things for testing
566
 
        cli.notificationsEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false))
567
 
        cli.urlDispatcherEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false))
568
611
        cli.connectivityEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false))
569
 
        cli.emblemcounterEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false))
570
 
        cli.hapticEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false))
571
612
        cli.systemImageEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false))
572
613
 
573
614
        c.Check(cli.takeTheBus(), NotNil)
574
615
        c.Assert(cli.setupPostalService(), IsNil)
575
 
        c.Assert(cli.takePostalServiceBus(), NotNil)
576
 
        c.Check(cli.actionsCh, IsNil)
577
616
}
578
617
 
579
618
/*****************************************************************
763
802
func (cs *clientSuite) TestHandleBroadcastNotification(c *C) {
764
803
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
765
804
        cli.systemImageInfo = siInfoRes
766
 
        endp := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))
767
 
        cli.notificationsEndp = endp
768
805
        cli.log = cs.log
769
 
        cli.postalServiceEndpoint = testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))
770
 
        cli.setupPostalService()
 
806
        d := new(dumbPostal)
 
807
        cli.postalService = d
771
808
        c.Check(cli.handleBroadcastNotification(positiveBroadcastNotification), IsNil)
772
 
        // check we sent the notification
773
 
        args := testibus.GetCallArgs(endp)
774
 
        c.Assert(args, HasLen, 1)
775
 
        c.Check(args[0].Member, Equals, "Notify")
776
 
        c.Check(cs.log.Captured(), Matches, `(?s).* got notification id \d+\s*`)
 
809
        // we dun posted
 
810
        c.Check(d.bcastCount, Equals, 1)
 
811
        c.Assert(d.postArgs, HasLen, 1)
 
812
        expectedApp, _ := click.ParseAppId("_ubuntu-system-settings")
 
813
        c.Check(d.postArgs[0].app, DeepEquals, expectedApp)
 
814
        expectedData, _ := json.Marshal(positiveBroadcastNotification.Decoded[0])
 
815
        c.Check([]byte(d.postArgs[0].payload), DeepEquals, expectedData)
777
816
}
778
817
 
779
818
func (cs *clientSuite) TestHandleBroadcastNotificationNothingToDo(c *C) {
780
819
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
781
820
        cli.systemImageInfo = siInfoRes
782
 
        endp := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))
783
 
        cli.notificationsEndp = endp
784
821
        cli.log = cs.log
 
822
        d := new(dumbPostal)
 
823
        cli.postalService = d
785
824
        c.Check(cli.handleBroadcastNotification(negativeBroadcastNotification), IsNil)
786
 
        // check we sent the notification
787
 
        args := testibus.GetCallArgs(endp)
788
 
        c.Assert(args, HasLen, 0)
789
 
        c.Check(cs.log.Captured(), Matches, "")
 
825
        // we not dun no posted
 
826
        c.Check(d.bcastCount, Equals, 0)
790
827
}
791
828
 
792
829
func (cs *clientSuite) TestHandleBroadcastNotificationFail(c *C) {
793
830
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
794
831
        cli.systemImageInfo = siInfoRes
795
832
        cli.log = cs.log
796
 
        endp := testibus.NewTestingEndpoint(nil, condition.Work(false))
797
 
        cli.notificationsEndp = endp
798
 
        cli.postalServiceEndpoint = testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))
799
 
        cli.setupPostalService()
800
 
        c.Check(cli.handleBroadcastNotification(positiveBroadcastNotification), NotNil)
 
833
        d := new(dumbPostal)
 
834
        err := errors.New("potato")
 
835
        d.err = err
 
836
        cli.postalService = d
 
837
        c.Check(cli.handleBroadcastNotification(positiveBroadcastNotification), Equals, err)
 
838
        c.Check(d.bcastCount, Equals, 1)
801
839
}
802
840
 
803
841
/*****************************************************************
805
843
******************************************************************/
806
844
 
807
845
var payload = `{"message": "aGVsbG8=", "notification": {"card": {"icon": "icon-value", "summary": "summary-value", "body": "body-value", "actions": []}}}`
808
 
var notif = &protocol.Notification{AppId: "com.example.test_hello", Payload: []byte(payload), MsgId: "42"}
 
846
var notif = &protocol.Notification{AppId: appIdHello, Payload: []byte(payload), MsgId: "42"}
809
847
 
810
848
func (cs *clientSuite) TestHandleUcastNotification(c *C) {
811
849
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
812
 
        postEndp := testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true), uint32(1))
813
 
        cli.log = cs.log
814
 
        cli.postalServiceEndpoint = postEndp
815
 
        c.Assert(cli.setupPostalService(), IsNil)
816
 
        c.Assert(cli.startPostalService(), IsNil)
817
 
        c.Check(cli.handleUnicastNotification(notif), IsNil)
818
 
        // check we sent the notification
819
 
        args := testibus.GetCallArgs(postEndp)
820
 
        c.Assert(len(args), Not(Equals), 0)
821
 
        c.Check(args[len(args)-1].Member, Equals, "::Signal")
822
 
        c.Check(cs.log.Captured(), Matches, `(?m).*sending notification "42" for "com.example.test_hello".*`)
823
 
}
824
 
 
825
 
func (cs *clientSuite) TestHandleUcastFailsOnBadAppId(c *C) {
826
 
        notif := &protocol.Notification{AppId: "bad-app-id", MsgId: "-1"}
827
 
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
828
 
        cli.log = cs.log
829
 
        c.Check(cli.handleUnicastNotification(notif), ErrorMatches, "invalid app id in notification")
830
 
}
831
 
 
832
 
/*****************************************************************
833
 
    handleClick tests
834
 
******************************************************************/
835
 
 
836
 
var ACTION_ID_BROADCAST = service.ACTION_ID_PREFIX + service.SystemUpdateUrl + service.ACTION_ID_SUFFIX
837
 
 
838
 
func (cs *clientSuite) TestHandleClick(c *C) {
839
 
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
840
 
        cli.log = cs.log
841
 
        endp := testibus.NewTestingEndpoint(nil, condition.Work(true))
842
 
        cli.urlDispatcherEndp = endp
843
 
        // check we don't fail on something random
844
 
        c.Check(cli.handleClick("something random"), IsNil)
845
 
        // ... but we don't send anything either
846
 
        args := testibus.GetCallArgs(endp)
847
 
        c.Assert(args, HasLen, 0)
848
 
        // check we worked with the right action id
849
 
        c.Check(cli.handleClick(ACTION_ID_BROADCAST), IsNil)
850
 
        // check we sent the notification
851
 
        args = testibus.GetCallArgs(endp)
852
 
        c.Assert(args, HasLen, 1)
853
 
        c.Check(args[0].Member, Equals, "DispatchURL")
854
 
        c.Check(args[0].Args, DeepEquals, []interface{}{service.SystemUpdateUrl})
855
 
        // check we worked with the right action id
856
 
        c.Check(cli.handleClick(service.ACTION_ID_PREFIX+"foo"), IsNil)
857
 
        // check we sent the notification
858
 
        args = testibus.GetCallArgs(endp)
859
 
        c.Assert(args, HasLen, 2)
860
 
        c.Check(args[1].Member, Equals, "DispatchURL")
861
 
        c.Check(args[1].Args, DeepEquals, []interface{}{"foo"})
 
850
        cli.log = cs.log
 
851
        d := new(dumbPostal)
 
852
        cli.postalService = d
 
853
 
 
854
        c.Check(cli.handleUnicastNotification(session.AddressedNotification{appHello, notif}), IsNil)
 
855
        // check we sent the notification
 
856
        c.Check(d.postCount, Equals, 1)
 
857
        c.Assert(d.postArgs, HasLen, 1)
 
858
        c.Check(d.postArgs[0].app, Equals, appHello)
 
859
        c.Check(d.postArgs[0].nid, Equals, notif.MsgId)
 
860
        c.Check(d.postArgs[0].payload, DeepEquals, notif.Payload)
 
861
}
 
862
 
 
863
func (cs *clientSuite) TestHandleUcastNotificationError(c *C) {
 
864
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
 
865
        cli.log = cs.log
 
866
        d := new(dumbPostal)
 
867
        cli.postalService = d
 
868
        fail := errors.New("fail")
 
869
        d.err = fail
 
870
 
 
871
        c.Check(cli.handleUnicastNotification(session.AddressedNotification{appHello, notif}), Equals, fail)
 
872
        // check we sent the notification
 
873
        c.Check(d.postCount, Equals, 1)
862
874
}
863
875
 
864
876
/*****************************************************************
882
894
func (cs *clientSuite) TestHandleUnregister(c *C) {
883
895
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
884
896
        cli.log = cs.log
885
 
        cli.hasPackage = func(appId string) bool {
886
 
                c.Check(appId, Equals, "app1")
 
897
        cli.installedChecker = testInstalledChecker(func(app *click.AppId, setVersion bool) bool {
 
898
                c.Check(setVersion, Equals, false)
 
899
                c.Check(app.Original(), Equals, appId1)
887
900
                return false
888
 
        }
 
901
        })
889
902
        ps := &testPushService{}
890
903
        cli.pushService = ps
891
 
        cli.handleUnregister("app1")
892
 
        c.Assert(ps.unregistered, Equals, "app1")
893
 
        c.Check(cs.log.Captured(), Equals, "")
 
904
        cli.handleUnregister(app1)
 
905
        c.Assert(ps.unregistered, Equals, appId1)
 
906
        c.Check(cs.log.Captured(), Equals, "DEBUG unregistered token for com.example.app1_app1\n")
894
907
}
895
908
 
896
909
func (cs *clientSuite) TestHandleUnregisterNop(c *C) {
897
910
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
898
911
        cli.log = cs.log
899
 
        cli.hasPackage = func(appId string) bool {
900
 
                c.Check(appId, Equals, "app1")
 
912
        cli.installedChecker = testInstalledChecker(func(app *click.AppId, setVersion bool) bool {
 
913
                c.Check(setVersion, Equals, false)
 
914
                c.Check(app.Original(), Equals, appId1)
901
915
                return true
902
 
        }
 
916
        })
903
917
        ps := &testPushService{}
904
918
        cli.pushService = ps
905
 
        cli.handleUnregister("app1")
 
919
        cli.handleUnregister(app1)
906
920
        c.Assert(ps.unregistered, Equals, "")
907
921
}
908
922
 
909
923
func (cs *clientSuite) TestHandleUnregisterError(c *C) {
910
924
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
911
925
        cli.log = cs.log
912
 
        cli.hasPackage = func(appId string) bool {
 
926
        cli.installedChecker = testInstalledChecker(func(app *click.AppId, setVersion bool) bool {
913
927
                return false
914
 
        }
 
928
        })
915
929
        fail := errors.New("BAD")
916
930
        ps := &testPushService{err: fail}
917
931
        cli.pushService = ps
918
 
        cli.handleUnregister("app1")
919
 
        c.Check(cs.log.Captured(), Matches, "ERROR unregistering app1: BAD\n")
 
932
        cli.handleUnregister(app1)
 
933
        c.Check(cs.log.Captured(), Matches, "ERROR unregistering com.example.app1_app1: BAD\n")
920
934
}
921
935
 
922
936
/*****************************************************************
924
938
******************************************************************/
925
939
 
926
940
var nopConn = func(bool) {}
927
 
var nopClick = func(string) error { return nil }
928
941
var nopBcast = func(*session.BroadcastNotification) error { return nil }
929
 
var nopUcast = func(*protocol.Notification) error { return nil }
 
942
var nopUcast = func(session.AddressedNotification) error { return nil }
930
943
var nopError = func(error) {}
931
 
var nopUnregister = func(string) {}
 
944
var nopUnregister = func(*click.AppId) {}
932
945
 
933
946
func (cs *clientSuite) TestDoLoopConn(c *C) {
934
947
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
939
952
        c.Assert(cli.initSession(), IsNil)
940
953
 
941
954
        ch := make(chan bool, 1)
942
 
        go cli.doLoop(func(bool) { ch <- true }, nopClick, nopBcast, nopUcast, nopError, nopUnregister)
943
 
        c.Check(takeNextBool(ch), Equals, true)
944
 
}
945
 
 
946
 
func (cs *clientSuite) TestDoLoopClick(c *C) {
947
 
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
948
 
        cli.log = cs.log
949
 
        cli.systemImageInfo = siInfoRes
950
 
        c.Assert(cli.initSession(), IsNil)
951
 
        aCh := make(chan notifications.RawActionReply, 1)
952
 
        aCh <- notifications.RawActionReply{}
953
 
        cli.actionsCh = aCh
954
 
 
955
 
        ch := make(chan bool, 1)
956
 
        go cli.doLoop(nopConn, func(_ string) error { ch <- true; return nil }, nopBcast, nopUcast, nopError, nopUnregister)
 
955
        go cli.doLoop(func(bool) { ch <- true }, nopBcast, nopUcast, nopError, nopUnregister)
957
956
        c.Check(takeNextBool(ch), Equals, true)
958
957
}
959
958
 
966
965
        cli.session.BroadcastCh <- &session.BroadcastNotification{}
967
966
 
968
967
        ch := make(chan bool, 1)
969
 
        go cli.doLoop(nopConn, nopClick, func(_ *session.BroadcastNotification) error { ch <- true; return nil }, nopUcast, nopError, nopUnregister)
 
968
        go cli.doLoop(nopConn, func(_ *session.BroadcastNotification) error { ch <- true; return nil }, nopUcast, nopError, nopUnregister)
970
969
        c.Check(takeNextBool(ch), Equals, true)
971
970
}
972
971
 
975
974
        cli.log = cs.log
976
975
        cli.systemImageInfo = siInfoRes
977
976
        c.Assert(cli.initSession(), IsNil)
978
 
        cli.session.NotificationsCh = make(chan *protocol.Notification, 1)
979
 
        cli.session.NotificationsCh <- &protocol.Notification{}
 
977
        cli.session.NotificationsCh = make(chan session.AddressedNotification, 1)
 
978
        cli.session.NotificationsCh <- session.AddressedNotification{}
980
979
 
981
980
        ch := make(chan bool, 1)
982
 
        go cli.doLoop(nopConn, nopClick, nopBcast, func(*protocol.Notification) error { ch <- true; return nil }, nopError, nopUnregister)
 
981
        go cli.doLoop(nopConn, nopBcast, func(session.AddressedNotification) error { ch <- true; return nil }, nopError, nopUnregister)
983
982
        c.Check(takeNextBool(ch), Equals, true)
984
983
}
985
984
 
992
991
        cli.session.ErrCh <- nil
993
992
 
994
993
        ch := make(chan bool, 1)
995
 
        go cli.doLoop(nopConn, nopClick, nopBcast, nopUcast, func(error) { ch <- true }, nopUnregister)
 
994
        go cli.doLoop(nopConn, nopBcast, nopUcast, func(error) { ch <- true }, nopUnregister)
996
995
        c.Check(takeNextBool(ch), Equals, true)
997
996
}
998
997
 
1001
1000
        cli.log = cs.log
1002
1001
        cli.systemImageInfo = siInfoRes
1003
1002
        c.Assert(cli.initSession(), IsNil)
1004
 
        cli.unregisterCh = make(chan string, 1)
1005
 
        cli.unregisterCh <- "app1"
 
1003
        cli.unregisterCh = make(chan *click.AppId, 1)
 
1004
        cli.unregisterCh <- app1
1006
1005
 
1007
1006
        ch := make(chan bool, 1)
1008
 
        go cli.doLoop(nopConn, nopClick, nopBcast, nopUcast, nopError, func(appId string) { c.Check(appId, Equals, "app1"); ch <- true })
 
1007
        go cli.doLoop(nopConn, nopBcast, nopUcast, nopError, func(app *click.AppId) { c.Check(app.Original(), Equals, appId1); ch <- true })
1009
1008
        c.Check(takeNextBool(ch), Equals, true)
1010
1009
}
1011
1010
 
1044
1043
        cli := NewPushClient(cs.configPath, cs.leveldbPath)
1045
1044
        cli.connCh = make(chan bool)
1046
1045
        cli.sessionConnectedCh = make(chan uint32)
1047
 
        aCh := make(chan notifications.RawActionReply, 1)
1048
 
        cli.actionsCh = aCh
1049
1046
        cli.log = cs.log
1050
 
        cli.notificationsEndp = testibus.NewMultiValuedTestingEndpoint(condition.Work(true),
1051
 
                condition.Work(true), []interface{}{uint32(1), "hello"})
1052
 
        cli.urlDispatcherEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false))
1053
1047
        cli.connectivityEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true),
1054
1048
                uint32(networkmanager.ConnectedGlobal))
1055
1049
        cli.systemImageInfo = siInfoRes
1056
 
        cli.postalServiceEndpoint = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true), uint32(1))
1057
 
        cli.setupPostalService()
 
1050
        d := new(dumbPostal)
 
1051
        cli.postalService = d
 
1052
        c.Assert(cli.startPostalService(), IsNil)
 
1053
 
1058
1054
        c.Assert(cli.initSession(), IsNil)
1059
1055
 
1060
1056
        cli.session.BroadcastCh = make(chan *session.BroadcastNotification)
1073
1069
        tick()
1074
1070
        c.Check(cs.log.Captured(), Matches, "(?ms).*Session connected after 42 attempts$")
1075
1071
 
1076
 
        //  * actionsCh to the click handler/url dispatcher
1077
 
        aCh <- notifications.RawActionReply{ActionId: ACTION_ID_BROADCAST}
1078
 
        tick()
1079
 
        uargs := testibus.GetCallArgs(cli.urlDispatcherEndp)
1080
 
        c.Assert(uargs, HasLen, 1)
1081
 
        c.Check(uargs[0].Member, Equals, "DispatchURL")
1082
 
 
1083
1072
        // loop() should have connected:
1084
1073
        //  * connCh to the connectivity checker
1085
1074
        c.Check(cli.hasConnectivity, Equals, false)
1091
1080
        c.Check(cli.hasConnectivity, Equals, false)
1092
1081
 
1093
1082
        //  * session.BroadcastCh to the notifications handler
 
1083
        c.Check(d.bcastCount, Equals, 0)
1094
1084
        cli.session.BroadcastCh <- positiveBroadcastNotification
1095
1085
        tick()
1096
 
        nargs := testibus.GetCallArgs(cli.notificationsEndp)
1097
 
        c.Check(nargs, HasLen, 1)
 
1086
        c.Check(d.bcastCount, Equals, 1)
1098
1087
 
1099
1088
        //  * session.ErrCh to the error handler
1100
1089
        cli.session.ErrCh <- nil
1117
1106
}
1118
1107
 
1119
1108
func (cs *clientSuite) TestStart(c *C) {
 
1109
        c.Skip("no dbus")
1120
1110
        if !cs.hasDbus() {
1121
1111
                c.Skip("no dbus")
1122
1112
        }
1132
1122
        // no session,
1133
1123
        c.Check(cli.session, IsNil)
1134
1124
        // no bus,
1135
 
        c.Check(cli.notificationsEndp, IsNil)
 
1125
        c.Check(cli.systemImageEndp, IsNil)
1136
1126
        // no nuthin'.
1137
1127
 
1138
1128
        // so we start,
1147
1137
        // and a session,
1148
1138
        c.Check(cli.session, NotNil)
1149
1139
        // and a bus,
1150
 
        c.Check(cli.notificationsEndp, NotNil)
 
1140
        c.Check(cli.systemImageEndp, NotNil)
1151
1141
        // and a service,
1152
1142
        c.Check(cli.pushService, NotNil)
1153
1143
        // and everthying us just peachy!