Merge lp:~chipaca/ubuntu-push/chamera-orchestra into lp:ubuntu-push

Proposed by John Lenton
Status: Merged
Approved by: John Lenton
Approved revision: no longer in the source branch.
Merged at revision: 57
Proposed branch: lp:~chipaca/ubuntu-push/chamera-orchestra
Merge into: lp:ubuntu-push
Prerequisite: lp:~chipaca/ubuntu-push/test-logger-client-bits
Diff against target: 602 lines (+264/-38)
7 files modified
bus/bus.go (+6/-0)
bus/connectivity/connectivity.go (+9/-5)
bus/endpoint.go (+33/-1)
bus/endpoint_test.go (+7/-0)
bus/testing/testing_endpoint.go (+9/-2)
client/client.go (+29/-2)
client/client_test.go (+171/-28)
To merge this branch: bzr merge lp:~chipaca/ubuntu-push/chamera-orchestra
Reviewer Review Type Date Requested Status
Samuele Pedroni Approve
Review via email: mp+204962@code.launchpad.net

Commit message

and this completes the client library (for now)

To post a comment you must log in.
54. By John Lenton

[r=pedronis] Reworked or refactored util/redialer, and a bit of client/session, and client.

Revision history for this message
Samuele Pedroni (pedronis) wrote :

203 + aCh <- notifications.RawActionReply{}

couldn't this be closed to the actual check? like the rest?

219 + // sessionConnectedCh to nothing in particular, but it'll help sync this test
220 + cli.sessionConnectedCh <- 42
221 + cli.sessionConnectedCh <- 42 // we check things one loop later (loopy, i know)

these comments didn't help me understand that cli.sessionConnectedCh sending is used to assure that we went through the full preceding loop

Revision history for this message
Samuele Pedroni (pedronis) wrote :

I'm getting this sort of error in a lxc, running tests in go client

2014/02/05 18:58:51.638238 ERROR Failed gettting current state: org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.NetworkManager was not provided by any .service files

I don't know if it applies to tarmac or not,

also the tests never finish

review: Needs Fixing
Revision history for this message
Samuele Pedroni (pedronis) wrote :

s/go client/client/

Revision history for this message
Samuele Pedroni (pedronis) wrote :

I'm surprised there's no race in TestLoop, I had to invent SyncedLogBuffer for that situation

in case it's solvable using a TestLogger

Revision history for this message
Samuele Pedroni (pedronis) wrote :

the need fixing is because in that faling scenario the test doesn't stop, there's a missing timeout when waiting for some channel?

55. By John Lenton

[r=pedronis] TestLogger

Revision history for this message
John Lenton (chipaca) wrote :

Ah, yes, stuffing things into aCh should be further down.
Was thinking about the race myself too, not sure why I'm getting away with it.

Revision history for this message
John Lenton (chipaca) wrote :

P.s. that's not the only potential race in tests i'm getting away with, i think.

56. By Samuele Pedroni

[r=chipaca] be explicit with the MinLogger interface, stops 1.1 compiler from exploding

Revision history for this message
Samuele Pedroni (pedronis) wrote :

looks good! there's a race in the test though

review: Approve
57. By John Lenton

[r=pedronis] and this completes the client library (for now)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bus/bus.go'
2--- bus/bus.go 2014-01-23 14:33:08 +0000
3+++ bus/bus.go 2014-02-06 13:26:26 +0000
4@@ -80,3 +80,9 @@
5 Path string
6 Interface string
7 }
8+
9+var BusDaemonAddress = Address{
10+ dbus.BUS_DAEMON_NAME,
11+ string(dbus.BUS_DAEMON_PATH),
12+ dbus.BUS_DAEMON_IFACE,
13+}
14
15=== modified file 'bus/connectivity/connectivity.go'
16--- bus/connectivity/connectivity.go 2014-02-05 02:13:35 +0000
17+++ bus/connectivity/connectivity.go 2014-02-06 13:26:26 +0000
18@@ -63,6 +63,8 @@
19 // up the watch.
20 func (cs *connectedState) start() networkmanager.State {
21 var initial networkmanager.State
22+ var ch <-chan networkmanager.State
23+ var err error
24 for {
25 ar := util.NewAutoRedialer(cs.endp)
26 cs.connAttempts += ar.Redial()
27@@ -72,20 +74,22 @@
28 initial = nm.GetState()
29 if initial == networkmanager.Unknown {
30 cs.log.Debugf("Failed to get state.")
31- cs.endp.Close()
32- continue
33+ goto Continue
34 }
35
36 // set up the watch
37- ch, err := nm.WatchState()
38+ ch, err = nm.WatchState()
39 if err != nil {
40 cs.log.Debugf("Failed to set up the watch: %s", err)
41- cs.endp.Close()
42- continue
43+ goto Continue
44 }
45
46 cs.networkStateCh = ch
47 return initial
48+
49+ Continue:
50+ cs.endp.Close()
51+ time.Sleep(10 * time.Millisecond) // that should cool things
52 }
53 }
54
55
56=== modified file 'bus/endpoint.go'
57--- bus/endpoint.go 2014-02-05 02:15:55 +0000
58+++ bus/endpoint.go 2014-02-06 13:26:26 +0000
59@@ -19,6 +19,7 @@
60 // Here we define the Endpoint, which represents the DBus connection itself.
61
62 import (
63+ "errors"
64 "fmt"
65 "launchpad.net/go-dbus/v1"
66 "launchpad.net/ubuntu-push/logger"
67@@ -64,8 +65,39 @@
68 if err != nil {
69 return err
70 }
71+ d := dbus.BusDaemon{bus.Object(dbus.BUS_DAEMON_NAME, dbus.BUS_DAEMON_PATH)}
72+ name := endp.addr.Name
73+ hasOwner, err := d.NameHasOwner(name)
74+ if err != nil {
75+ endp.log.Debugf("Unable to determine ownership of %#v: %v", name, err)
76+ bus.Close()
77+ return err
78+ }
79+ if !hasOwner {
80+ // maybe it's waiting to be activated?
81+ names, err := d.ListActivatableNames()
82+ if err != nil {
83+ endp.log.Debugf("%#v has no owner, and when listing activatable: %v", name, err)
84+ bus.Close()
85+ return err
86+ }
87+ found := false
88+ for _, name := range names {
89+ if name == name {
90+ found = true
91+ break
92+ }
93+ }
94+ if !found {
95+ msg := fmt.Sprintf("%#v has no owner, and not in activatables", name)
96+ endp.log.Debugf(msg)
97+ bus.Close()
98+ return errors.New(msg)
99+ }
100+ }
101+ endp.log.Infof("%#v dialed in.", name)
102 endp.bus = bus
103- endp.proxy = bus.Object(endp.addr.Name, dbus.ObjectPath(endp.addr.Path))
104+ endp.proxy = bus.Object(name, dbus.ObjectPath(endp.addr.Path))
105 return nil
106 }
107
108
109=== modified file 'bus/endpoint_test.go'
110--- bus/endpoint_test.go 2014-02-05 18:17:26 +0000
111+++ bus/endpoint_test.go 2014-02-06 13:26:26 +0000
112@@ -39,6 +39,13 @@
113 // Tests that we can connect to the *actual* system bus.
114 // XXX maybe connect to a mock/fake/etc bus?
115 func (s *EndpointSuite) TestDial(c *C) {
116+ // if somebody's set up the env var, assume it's "live"
117+ if os.Getenv("DBUS_SYSTEM_BUS_ADDRESS") == "" {
118+ // otherwise, check
119+ if _, err := os.Stat("/var/run/dbus/system_bus_socket"); os.IsNotExist(err) {
120+ c.Skip("system bus not present")
121+ }
122+ }
123 endp := newEndpoint(SystemBus, Address{"", "", ""}, s.log)
124 c.Assert(endp.bus, IsNil)
125 err := endp.Dial()
126
127=== modified file 'bus/testing/testing_endpoint.go'
128--- bus/testing/testing_endpoint.go 2014-02-05 02:13:35 +0000
129+++ bus/testing/testing_endpoint.go 2014-02-06 13:26:26 +0000
130@@ -23,6 +23,7 @@
131 "fmt"
132 "launchpad.net/ubuntu-push/bus"
133 "launchpad.net/ubuntu-push/testing/condition"
134+ "sync"
135 "time"
136 )
137
138@@ -37,6 +38,7 @@
139 retvals [][]interface{}
140 watchTicker chan bool
141 callArgs []callArgs
142+ callArgsLck sync.RWMutex
143 }
144
145 // Build a bus.Endpoint that calls OK() on its condition before returning
146@@ -45,7 +47,7 @@
147 // NOTE: Call() always returns the first return value; Watch() will provide
148 // each of them in turn, irrespective of whether Call has been called.
149 func NewMultiValuedTestingEndpoint(dialCond condition.Interface, callCond condition.Interface, retvalses ...[]interface{}) bus.Endpoint {
150- return &testingEndpoint{dialCond, callCond, retvalses, nil, nil}
151+ return &testingEndpoint{dialCond: dialCond, callCond: callCond, retvals: retvalses}
152 }
153
154 func NewTestingEndpoint(dialCond condition.Interface, callCond condition.Interface, retvals ...interface{}) bus.Endpoint {
155@@ -53,7 +55,7 @@
156 for i, x := range retvals {
157 retvalses[i] = []interface{}{x}
158 }
159- return &testingEndpoint{dialCond, callCond, retvalses, nil, nil}
160+ return &testingEndpoint{dialCond: dialCond, callCond: callCond, retvals: retvalses}
161 }
162
163 // If SetWatchTicker is called with a non-nil watchTicker, it is used
164@@ -65,6 +67,8 @@
165
166 // GetCallArgs returns a list of the arguments for each Call() invocation.
167 func GetCallArgs(tc bus.Endpoint) []callArgs {
168+ tc.(*testingEndpoint).callArgsLck.RLock()
169+ defer tc.(*testingEndpoint).callArgsLck.RUnlock()
170 return tc.(*testingEndpoint).callArgs
171 }
172
173@@ -92,6 +96,9 @@
174 // See Endpoint's Call. This Call will check its condition to decide whether
175 // to return an error, or the first of its return values
176 func (tc *testingEndpoint) Call(member string, args ...interface{}) ([]interface{}, error) {
177+ tc.callArgsLck.Lock()
178+ defer tc.callArgsLck.Unlock()
179+
180 tc.callArgs = append(tc.callArgs, callArgs{member, args})
181 if tc.callCond.OK() {
182 if len(tc.retvals) == 0 {
183
184=== modified file 'client/client.go'
185--- client/client.go 2014-02-05 02:13:35 +0000
186+++ client/client.go 2014-02-06 13:26:26 +0000
187@@ -66,8 +66,8 @@
188 sessionConnectedCh chan uint32
189 }
190
191-// Configure loads the configuration specified in configPath, and sets it up.
192-func (client *Client) Configure(configPath string) error {
193+// configure loads the configuration specified in configPath, and sets it up.
194+func (client *Client) configure(configPath string) error {
195 f, err := os.Open(configPath)
196 if err != nil {
197 return fmt.Errorf("opening config: %v", err)
198@@ -210,3 +210,30 @@
199 }
200 }
201 }
202+
203+// doStart calls each of its arguments in order, returning the first non-nil
204+// error (or nil at the end)
205+func (client *Client) doStart(fs ...func() error) error {
206+ for _, f := range fs {
207+ if err := f(); err != nil {
208+ return err
209+ }
210+ }
211+ return nil
212+}
213+
214+// Loop calls doLoop with the "real" handlers
215+func (client *Client) Loop() {
216+ client.doLoop(client.handleConnState, client.handleClick,
217+ client.handleNotification, client.handleErr)
218+}
219+
220+// Start calls doStart with the "real" starters
221+func (client *Client) Start(configPath string) error {
222+ return client.doStart(
223+ func() error { return client.configure(configPath) },
224+ client.getDeviceId,
225+ client.initSession,
226+ client.takeTheBus,
227+ )
228+}
229
230=== modified file 'client/client_test.go'
231--- client/client_test.go 2014-02-05 18:17:26 +0000
232+++ client/client_test.go 2014-02-06 13:26:26 +0000
233@@ -17,16 +17,15 @@
234 package client
235
236 import (
237- "bytes"
238 "errors"
239 "fmt"
240 "io/ioutil"
241 . "launchpad.net/gocheck"
242+ "launchpad.net/ubuntu-push/bus"
243 "launchpad.net/ubuntu-push/bus/networkmanager"
244 "launchpad.net/ubuntu-push/bus/notifications"
245 testibus "launchpad.net/ubuntu-push/bus/testing"
246 "launchpad.net/ubuntu-push/client/session"
247- "launchpad.net/ubuntu-push/logger"
248 helpers "launchpad.net/ubuntu-push/testing"
249 "launchpad.net/ubuntu-push/testing/condition"
250 "launchpad.net/ubuntu-push/util"
251@@ -54,7 +53,7 @@
252 type clientSuite struct {
253 timeouts []time.Duration
254 configPath string
255- log logger.Logger
256+ log *helpers.TestLogger
257 }
258
259 var _ = Suite(&clientSuite{})
260@@ -100,12 +99,12 @@
261 }
262
263 /*****************************************************************
264- Configure tests
265+ configure tests
266 ******************************************************************/
267
268 func (cs *clientSuite) TestConfigureWorks(c *C) {
269 cli := new(Client)
270- err := cli.Configure(cs.configPath)
271+ err := cli.configure(cs.configPath)
272 c.Assert(err, IsNil)
273 c.Assert(cli.config, NotNil)
274 c.Check(cli.config.ExchangeTimeout.Duration, Equals, time.Duration(10*time.Millisecond))
275@@ -114,7 +113,7 @@
276 func (cs *clientSuite) TestConfigureSetsUpLog(c *C) {
277 cli := new(Client)
278 c.Check(cli.log, IsNil)
279- err := cli.Configure(cs.configPath)
280+ err := cli.configure(cs.configPath)
281 c.Assert(err, IsNil)
282 c.Assert(cli.log, NotNil)
283 }
284@@ -122,7 +121,7 @@
285 func (cs *clientSuite) TestConfigureSetsUpPEM(c *C) {
286 cli := new(Client)
287 c.Check(cli.pem, IsNil)
288- err := cli.Configure(cs.configPath)
289+ err := cli.configure(cs.configPath)
290 c.Assert(err, IsNil)
291 c.Assert(cli.pem, NotNil)
292 }
293@@ -130,7 +129,7 @@
294 func (cs *clientSuite) TestConfigureSetsUpIdder(c *C) {
295 cli := new(Client)
296 c.Check(cli.idder, IsNil)
297- err := cli.Configure(cs.configPath)
298+ err := cli.configure(cs.configPath)
299 c.Assert(err, IsNil)
300 c.Assert(cli.idder, DeepEquals, identifier.New())
301 }
302@@ -140,7 +139,7 @@
303 c.Check(cli.notificationsEndp, IsNil)
304 c.Check(cli.urlDispatcherEndp, IsNil)
305 c.Check(cli.connectivityEndp, IsNil)
306- err := cli.Configure(cs.configPath)
307+ err := cli.configure(cs.configPath)
308 c.Assert(err, IsNil)
309 c.Assert(cli.notificationsEndp, NotNil)
310 c.Assert(cli.urlDispatcherEndp, NotNil)
311@@ -150,20 +149,20 @@
312 func (cs *clientSuite) TestConfigureSetsUpConnCh(c *C) {
313 cli := new(Client)
314 c.Check(cli.connCh, IsNil)
315- err := cli.Configure(cs.configPath)
316+ err := cli.configure(cs.configPath)
317 c.Assert(err, IsNil)
318 c.Assert(cli.connCh, NotNil)
319 }
320
321 func (cs *clientSuite) TestConfigureBailsOnBadFilename(c *C) {
322 cli := new(Client)
323- err := cli.Configure("/does/not/exist")
324+ err := cli.configure("/does/not/exist")
325 c.Assert(err, NotNil)
326 }
327
328 func (cs *clientSuite) TestConfigureBailsOnBadConfig(c *C) {
329 cli := new(Client)
330- err := cli.Configure("/etc/passwd")
331+ err := cli.configure("/etc/passwd")
332 c.Assert(err, NotNil)
333 }
334
335@@ -180,7 +179,7 @@
336 }`), 0600)
337
338 cli := new(Client)
339- err := cli.Configure(cs.configPath)
340+ err := cli.configure(cs.configPath)
341 c.Assert(err, NotNil)
342 }
343
344@@ -197,7 +196,7 @@
345 }`), 0600)
346
347 cli := new(Client)
348- err := cli.Configure(cs.configPath)
349+ err := cli.configure(cs.configPath)
350 c.Assert(err, NotNil)
351 }
352
353@@ -245,7 +244,7 @@
354 // ok, create the thing
355 cli := new(Client)
356 cli.log = cs.log
357- err := cli.Configure(cs.configPath)
358+ err := cli.configure(cs.configPath)
359 c.Assert(err, IsNil)
360 // the user actions channel has not been set up
361 c.Check(cli.actionsCh, IsNil)
362@@ -272,7 +271,7 @@
363 // takeTheBus can, in fact, fail
364 func (cs *clientSuite) TestTakeTheBusCanFail(c *C) {
365 cli := new(Client)
366- err := cli.Configure(cs.configPath)
367+ err := cli.configure(cs.configPath)
368 cli.log = cs.log
369 c.Assert(err, IsNil)
370 // the user actions channel has not been set up
371@@ -292,13 +291,12 @@
372 ******************************************************************/
373
374 func (cs *clientSuite) TestHandleErr(c *C) {
375- buf := &bytes.Buffer{}
376 cli := new(Client)
377- cli.log = logger.NewSimpleLogger(buf, "debug")
378- cli.initSession()
379+ cli.log = cs.log
380+ c.Assert(cli.initSession(), IsNil)
381 cli.hasConnectivity = true
382 cli.handleErr(errors.New("bananas"))
383- c.Check(buf.String(), Matches, ".*session exited.*bananas\n")
384+ c.Check(cs.log.Captured(), Matches, ".*session exited.*bananas\n")
385 }
386
387 /*****************************************************************
388@@ -308,7 +306,7 @@
389 func (cs *clientSuite) TestHandleConnStateD2C(c *C) {
390 cli := new(Client)
391 cli.log = cs.log
392- cli.initSession()
393+ c.Assert(cli.initSession(), IsNil)
394
395 c.Assert(cli.hasConnectivity, Equals, false)
396 cli.handleConnState(true)
397@@ -358,17 +356,16 @@
398 ******************************************************************/
399
400 func (cs *clientSuite) TestHandleNotification(c *C) {
401- buf := &bytes.Buffer{}
402 cli := new(Client)
403 endp := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))
404 cli.notificationsEndp = endp
405- cli.log = logger.NewSimpleLogger(buf, "debug")
406+ cli.log = cs.log
407 c.Check(cli.handleNotification(), IsNil)
408 // check we sent the notification
409 args := testibus.GetCallArgs(endp)
410 c.Assert(args, HasLen, 1)
411 c.Check(args[0].Member, Equals, "Notify")
412- c.Check(buf.String(), Matches, `.* got notification id \d+\s*`)
413+ c.Check(cs.log.Captured(), Matches, `.* got notification id \d+\s*`)
414 }
415
416 func (cs *clientSuite) TestHandleNotificationFail(c *C) {
417@@ -405,7 +402,7 @@
418 cli.log = cs.log
419 cli.connCh = make(chan bool, 1)
420 cli.connCh <- true
421- cli.initSession()
422+ c.Assert(cli.initSession(), IsNil)
423
424 ch := make(chan bool, 1)
425 go cli.doLoop(func(bool) { ch <- true }, func() error { return nil }, func() error { return nil }, func(error) {})
426@@ -415,7 +412,7 @@
427 func (cs *clientSuite) TestDoLoopClick(c *C) {
428 cli := new(Client)
429 cli.log = cs.log
430- cli.initSession()
431+ c.Assert(cli.initSession(), IsNil)
432 aCh := make(chan notifications.RawActionReply, 1)
433 aCh <- notifications.RawActionReply{}
434 cli.actionsCh = aCh
435@@ -428,7 +425,7 @@
436 func (cs *clientSuite) TestDoLoopNotif(c *C) {
437 cli := new(Client)
438 cli.log = cs.log
439- cli.initSession()
440+ c.Assert(cli.initSession(), IsNil)
441 cli.session.MsgCh = make(chan *session.Notification, 1)
442 cli.session.MsgCh <- &session.Notification{}
443
444@@ -440,7 +437,7 @@
445 func (cs *clientSuite) TestDoLoopErr(c *C) {
446 cli := new(Client)
447 cli.log = cs.log
448- cli.initSession()
449+ c.Assert(cli.initSession(), IsNil)
450 cli.session.ErrCh = make(chan error, 1)
451 cli.session.ErrCh <- nil
452
453@@ -448,3 +445,149 @@
454 go cli.doLoop(func(bool) {}, func() error { return nil }, func() error { return nil }, func(error) { ch <- true })
455 c.Check(takeNextBool(ch), Equals, true)
456 }
457+
458+/*****************************************************************
459+ doStart tests
460+******************************************************************/
461+
462+func (cs *clientSuite) TestDoStartWorks(c *C) {
463+ cli := new(Client)
464+ one_called := false
465+ two_called := false
466+ one := func() error { one_called = true; return nil }
467+ two := func() error { two_called = true; return nil }
468+ c.Check(cli.doStart(one, two), IsNil)
469+ c.Check(one_called, Equals, true)
470+ c.Check(two_called, Equals, true)
471+}
472+
473+func (cs *clientSuite) TestDoStartFailsAsExpected(c *C) {
474+ cli := new(Client)
475+ one_called := false
476+ two_called := false
477+ failure := errors.New("Failure")
478+ one := func() error { one_called = true; return failure }
479+ two := func() error { two_called = true; return nil }
480+ c.Check(cli.doStart(one, two), Equals, failure)
481+ c.Check(one_called, Equals, true)
482+ c.Check(two_called, Equals, false)
483+}
484+
485+/*****************************************************************
486+ Loop() tests
487+******************************************************************/
488+
489+func (cs *clientSuite) TestLoop(c *C) {
490+ cli := new(Client)
491+ cli.connCh = make(chan bool)
492+ cli.sessionConnectedCh = make(chan uint32)
493+ aCh := make(chan notifications.RawActionReply, 1)
494+ cli.actionsCh = aCh
495+ cli.log = cs.log
496+ cli.notificationsEndp = testibus.NewMultiValuedTestingEndpoint(condition.Work(true),
497+ condition.Work(true), []interface{}{uint32(1), "hello"})
498+ cli.urlDispatcherEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(false))
499+ cli.connectivityEndp = testibus.NewTestingEndpoint(condition.Work(true), condition.Work(true),
500+ uint32(networkmanager.ConnectedGlobal))
501+
502+ c.Assert(cli.initSession(), IsNil)
503+
504+ cli.session.MsgCh = make(chan *session.Notification)
505+ cli.session.ErrCh = make(chan error)
506+
507+ // we use tick() to make sure things have been through the
508+ // event loop at least once before looking at things;
509+ // otherwise there's a race between what we're trying to look
510+ // at and the loop itself.
511+ tick := func() { cli.sessionConnectedCh <- 42 }
512+
513+ go cli.Loop()
514+
515+ // sessionConnectedCh to nothing in particular, but it'll help sync this test
516+ cli.sessionConnectedCh <- 42
517+ tick()
518+ c.Check(cs.log.Captured(), Matches, "(?ms).*Session connected after 42 attempts$")
519+
520+ // * actionsCh to the click handler/url dispatcher
521+ aCh <- notifications.RawActionReply{}
522+ tick()
523+ uargs := testibus.GetCallArgs(cli.urlDispatcherEndp)
524+ c.Assert(uargs, HasLen, 1)
525+ c.Check(uargs[0].Member, Equals, "DispatchURL")
526+
527+ // loop() should have connected:
528+ // * connCh to the connectivity checker
529+ c.Check(cli.hasConnectivity, Equals, false)
530+ cli.connCh <- true
531+ tick()
532+ c.Check(cli.hasConnectivity, Equals, true)
533+ cli.connCh <- false
534+ tick()
535+ c.Check(cli.hasConnectivity, Equals, false)
536+
537+ // * session.MsgCh to the notifications handler
538+ cli.session.MsgCh <- &session.Notification{}
539+ tick()
540+ nargs := testibus.GetCallArgs(cli.notificationsEndp)
541+ c.Check(nargs, HasLen, 1)
542+
543+ // * session.ErrCh to the error handler
544+ cli.session.ErrCh <- nil
545+ tick()
546+ c.Check(cs.log.Captured(), Matches, "(?ms).*session exited.*")
547+}
548+
549+/*****************************************************************
550+ Start() tests
551+******************************************************************/
552+
553+// XXX this is a hack.
554+func (cs *clientSuite) hasDbus() bool {
555+ for _, b := range []bus.Bus{bus.SystemBus, bus.SessionBus} {
556+ if b.Endpoint(bus.BusDaemonAddress, cs.log).Dial() != nil {
557+ return false
558+ }
559+ }
560+ return true
561+}
562+
563+func (cs *clientSuite) TestStart(c *C) {
564+ if !cs.hasDbus() {
565+ c.Skip("no dbus")
566+ }
567+
568+ cli := new(Client)
569+ // before start, everything sucks:
570+ // no config,
571+ c.Check(string(cli.config.Addr), Equals, "")
572+ // no device id,
573+ c.Check(cli.deviceId, HasLen, 0)
574+ // no session,
575+ c.Check(cli.session, IsNil)
576+ // no bus,
577+ c.Check(cli.notificationsEndp, IsNil)
578+ // no nuthin'.
579+
580+ // so we start,
581+ err := cli.Start(cs.configPath)
582+ // and it works
583+ c.Check(err, IsNil)
584+
585+ // and now everthing is better! We have a config,
586+ c.Check(string(cli.config.Addr), Equals, ":0")
587+ // and a device id,
588+ c.Check(cli.deviceId, HasLen, 128)
589+ // and a session,
590+ c.Check(cli.session, NotNil)
591+ // and a bus,
592+ c.Check(cli.notificationsEndp, NotNil)
593+ // and everthying us just peachy!
594+}
595+
596+func (cs *clientSuite) TestStartCanFail(c *C) {
597+ cli := new(Client)
598+ // easiest way for it to fail is to feed it a bad config
599+ err := cli.Start("/does/not/exist")
600+ // and it works. Err. Doesn't.
601+ c.Check(err, NotNil)
602+}

Subscribers

People subscribed via source and target branches