440
442
conf := cli.deriveSessionConfig(info)
441
443
// compare authGetter by string
442
444
c.Check(fmt.Sprintf("%#v", conf.AuthGetter), Equals, fmt.Sprintf("%#v", cli.getAuthorization))
445
// channels are ok as long as non-nil
446
conf.BroadcastCh = nil
447
conf.NotificationsCh = nil
448
expected.BroadcastCh = nil
449
expected.NotificationsCh = nil
443
450
// and set it to nil
444
451
conf.AuthGetter = nil
445
452
expected.AuthGetter = nil
521
528
/*****************************************************************
522
529
derivePollerSetup tests
523
530
******************************************************************/
531
type derivePollerSession struct{}
533
func (s *derivePollerSession) ResetCookie() {}
534
func (s *derivePollerSession) State() session.ClientSessionState { return session.Unknown }
535
func (s *derivePollerSession) HasConnectivity(bool) {}
536
func (s *derivePollerSession) KeepConnection() error { return nil }
537
func (s *derivePollerSession) StopKeepConnection() {}
524
539
func (cs *clientSuite) TestDerivePollerSetup(c *C) {
525
540
cs.writeTestConfig(map[string]interface{}{})
526
541
cli := NewPushClient(cs.configPath, cs.leveldbPath)
527
cli.session = new(session.ClientSession)
542
cli.session = new(derivePollerSession)
528
543
err := cli.configure()
529
544
c.Assert(err, IsNil)
530
545
expected := &poller.PollerSetup{
707
722
/*****************************************************************
709
******************************************************************/
711
func (cs *clientSuite) TestHandleErr(c *C) {
712
cli := NewPushClient(cs.configPath, cs.leveldbPath)
714
cli.systemImageInfo = siInfoRes
715
c.Assert(cli.initSessionAndPoller(), IsNil)
716
cs.log.ResetCapture()
717
cli.hasConnectivity = true
718
defer cli.session.Close()
719
cli.handleErr(errors.New("bananas"))
720
c.Check(cs.log.Captured(), Matches, ".*session exited.*bananas\n")
723
/*****************************************************************
724
723
seenStateFactory tests
725
724
******************************************************************/
743
742
/*****************************************************************
744
handleConnState tests
745
******************************************************************/
747
func (cs *clientSuite) TestHandleConnStateD2C(c *C) {
748
cli := NewPushClient(cs.configPath, cs.leveldbPath)
750
cli.systemImageInfo = siInfoRes
751
c.Assert(cli.initSessionAndPoller(), IsNil)
753
c.Assert(cli.hasConnectivity, Equals, false)
754
defer cli.session.Close()
755
cli.handleConnState(true)
756
c.Check(cli.hasConnectivity, Equals, true)
757
c.Assert(cli.session, NotNil)
760
func (cs *clientSuite) TestHandleConnStateSame(c *C) {
761
cli := NewPushClient(cs.configPath, cs.leveldbPath)
763
// here we want to check that we don't do anything
764
c.Assert(cli.session, IsNil)
765
c.Assert(cli.hasConnectivity, Equals, false)
766
cli.handleConnState(false)
767
c.Check(cli.session, IsNil)
769
cli.hasConnectivity = true
770
cli.handleConnState(true)
771
c.Check(cli.session, IsNil)
774
func (cs *clientSuite) TestHandleConnStateC2D(c *C) {
775
cli := NewPushClient(cs.configPath, cs.leveldbPath)
777
cli.session, _ = session.NewSession(cli.config.Addr, cli.deriveSessionConfig(nil), cli.deviceId, seenstate.NewSeenState, cs.log)
779
cli.hasConnectivity = true
781
// cli.session.State() will be "Error" here, for now at least
782
c.Check(cli.session.State(), Not(Equals), session.Disconnected)
783
cli.handleConnState(false)
784
c.Check(cli.session.State(), Equals, session.Disconnected)
787
func (cs *clientSuite) TestHandleConnStateC2DPending(c *C) {
788
cli := NewPushClient(cs.configPath, cs.leveldbPath)
790
cli.session, _ = session.NewSession(cli.config.Addr, cli.deriveSessionConfig(nil), cli.deviceId, seenstate.NewSeenState, cs.log)
791
cli.hasConnectivity = true
793
cli.handleConnState(false)
794
c.Check(cli.session.State(), Equals, session.Disconnected)
797
/*****************************************************************
798
743
filterBroadcastNotification tests
799
744
******************************************************************/
812
757
msg := &session.BroadcastNotification{}
813
758
c.Check(cli.filterBroadcastNotification(msg), Equals, false)
815
msg = &session.BroadcastNotification{
816
Decoded: []map[string]interface{}{
817
map[string]interface{}{
818
"daily/mako": []interface{}{float64(102), "tubular"},
822
c.Check(cli.filterBroadcastNotification(msg), Equals, false)
823
// higher build number and pick last
824
msg = &session.BroadcastNotification{
825
Decoded: []map[string]interface{}{
826
map[string]interface{}{
827
"daily/mako": []interface{}{float64(102), "tubular"},
829
map[string]interface{}{
830
"daily/mako": []interface{}{float64(103), "tubular"},
834
c.Check(cli.filterBroadcastNotification(msg), Equals, true)
835
// going backward by a margin, assume switch of alias
836
msg = &session.BroadcastNotification{
837
Decoded: []map[string]interface{}{
838
map[string]interface{}{
839
"daily/mako": []interface{}{float64(102), "tubular"},
841
map[string]interface{}{
842
"daily/mako": []interface{}{float64(2), "urban"},
759
// same build number, we let the helper deal
760
msg = &session.BroadcastNotification{
761
Decoded: []map[string]interface{}{
762
map[string]interface{}{
763
"daily/mako": []interface{}{float64(102), "tubular"},
1025
943
c.Assert(cli.initSessionAndPoller(), IsNil)
1027
945
ch := make(chan bool, 1)
1028
go cli.doLoop(func(bool) { ch <- true }, nopBcast, nopUcast, nopError, nopUnregister, nopAcct)
946
go cli.doLoop(func(bool) { ch <- true }, nopBcast, nopUcast, nopUnregister, nopAcct)
1029
947
c.Check(takeNextBool(ch), Equals, true)
1034
952
cli.log = cs.log
1035
953
cli.systemImageInfo = siInfoRes
1036
954
c.Assert(cli.initSessionAndPoller(), IsNil)
1037
cli.session.BroadcastCh = make(chan *session.BroadcastNotification, 1)
1038
cli.session.BroadcastCh <- &session.BroadcastNotification{}
955
cli.broadcastCh = make(chan *session.BroadcastNotification, 1)
956
cli.broadcastCh <- &session.BroadcastNotification{}
1040
958
ch := make(chan bool, 1)
1041
go cli.doLoop(nopConn, func(_ *session.BroadcastNotification) error { ch <- true; return nil }, nopUcast, nopError, nopUnregister, nopAcct)
959
go cli.doLoop(nopConn, func(_ *session.BroadcastNotification) error { ch <- true; return nil }, nopUcast, nopUnregister, nopAcct)
1042
960
c.Check(takeNextBool(ch), Equals, true)
1047
965
cli.log = cs.log
1048
966
cli.systemImageInfo = siInfoRes
1049
967
c.Assert(cli.initSessionAndPoller(), IsNil)
1050
cli.session.NotificationsCh = make(chan session.AddressedNotification, 1)
1051
cli.session.NotificationsCh <- session.AddressedNotification{}
1053
ch := make(chan bool, 1)
1054
go cli.doLoop(nopConn, nopBcast, func(session.AddressedNotification) error { ch <- true; return nil }, nopError, nopUnregister, nopAcct)
1055
c.Check(takeNextBool(ch), Equals, true)
1058
func (cs *clientSuite) TestDoLoopErr(c *C) {
1059
cli := NewPushClient(cs.configPath, cs.leveldbPath)
1061
cli.systemImageInfo = siInfoRes
1062
c.Assert(cli.initSessionAndPoller(), IsNil)
1063
cli.session.ErrCh = make(chan error, 1)
1064
cli.session.ErrCh <- nil
1066
ch := make(chan bool, 1)
1067
go cli.doLoop(nopConn, nopBcast, nopUcast, func(error) { ch <- true }, nopUnregister, nopAcct)
968
cli.notificationsCh = make(chan session.AddressedNotification, 1)
969
cli.notificationsCh <- session.AddressedNotification{}
971
ch := make(chan bool, 1)
972
go cli.doLoop(nopConn, nopBcast, func(session.AddressedNotification) error { ch <- true; return nil }, nopUnregister, nopAcct)
1068
973
c.Check(takeNextBool(ch), Equals, true)
1077
982
cli.unregisterCh <- app1
1079
984
ch := make(chan bool, 1)
1080
go cli.doLoop(nopConn, nopBcast, nopUcast, nopError, func(app *click.AppId) { c.Check(app.Original(), Equals, appId1); ch <- true }, nopAcct)
985
go cli.doLoop(nopConn, nopBcast, nopUcast, func(app *click.AppId) { c.Check(app.Original(), Equals, appId1); ch <- true }, nopAcct)
1081
986
c.Check(takeNextBool(ch), Equals, true)
1091
996
cli.accountsCh = acctCh
1093
998
ch := make(chan bool, 1)
1094
go cli.doLoop(nopConn, nopBcast, nopUcast, nopError, nopUnregister, func() { ch <- true })
999
go cli.doLoop(nopConn, nopBcast, nopUcast, nopUnregister, func() { ch <- true })
1095
1000
c.Check(takeNextBool(ch), Equals, true)
1127
1032
******************************************************************/
1034
type loopSession struct{ hasConn bool }
1036
func (s *loopSession) ResetCookie() {}
1037
func (s *loopSession) State() session.ClientSessionState {
1039
return session.Connected
1041
return session.Disconnected
1044
func (s *loopSession) HasConnectivity(hasConn bool) { s.hasConn = hasConn }
1045
func (s *loopSession) KeepConnection() error { return nil }
1046
func (s *loopSession) StopKeepConnection() {}
1129
1048
func (cs *clientSuite) TestLoop(c *C) {
1130
1049
cli := NewPushClient(cs.configPath, cs.leveldbPath)
1131
1050
cli.connCh = make(chan bool)
1159
1081
// loop() should have connected:
1160
1082
// * connCh to the connectivity checker
1161
c.Check(cli.hasConnectivity, Equals, false)
1083
c.Check(cli.session.State(), Equals, session.Disconnected)
1162
1084
cli.connCh <- true
1164
c.Check(cli.hasConnectivity, Equals, true)
1086
c.Check(cli.session.State(), Equals, session.Connected)
1165
1087
cli.connCh <- false
1167
c.Check(cli.hasConnectivity, Equals, false)
1089
c.Check(cli.session.State(), Equals, session.Disconnected)
1169
1091
// * session.BroadcastCh to the notifications handler
1170
1092
c.Check(d.bcastCount, Equals, 0)
1171
cli.session.BroadcastCh <- positiveBroadcastNotification
1093
cli.broadcastCh <- positiveBroadcastNotification
1173
1095
c.Check(d.bcastCount, Equals, 1)
1175
// * session.ErrCh to the error handler
1176
cli.session.ErrCh <- nil
1178
c.Check(cs.log.Captured(), Matches, "(?ms).*session exited.*")
1181
1098
/*****************************************************************