Merge lp:~chipaca/ubuntu-push/fix-1390663-for-rtm into lp:ubuntu-push/krillin-rtm

Proposed by John Lenton
Status: Merged
Approved by: John Lenton
Approved revision: 139
Merged at revision: 139
Proposed branch: lp:~chipaca/ubuntu-push/fix-1390663-for-rtm
Merge into: lp:ubuntu-push/krillin-rtm
Diff against target: 937 lines (+185/-104)
31 files modified
bus/connectivity/connectivity.go (+23/-12)
bus/connectivity/connectivity_test.go (+10/-11)
bus/connectivity/webchecker.go (+4/-4)
bus/endpoint.go (+7/-7)
bus/networkmanager/networkmanager.go (+6/-6)
bus/notifications/raw.go (+1/-1)
bus/systemimage/systemimage.go (+1/-1)
client/client.go (+3/-3)
client/client_test.go (+1/-1)
client/service/postal.go (+0/-1)
client/service/service.go (+3/-3)
client/session/session.go (+38/-2)
dependencies.tsv (+1/-1)
identifier/identifier.go (+1/-1)
identifier/identifier_test.go (+1/-1)
launch_helper/helper_finder/helper_finder.go (+1/-1)
launch_helper/helper_finder/helper_finder_test.go (+1/-1)
launch_helper/kindpool.go (+1/-1)
launch_helper/legacy/legacy.go (+1/-1)
launch_helper/legacy/legacy_test.go (+1/-1)
messaging/messaging.go (+1/-1)
poller/poller.go (+1/-1)
server/acceptance/acceptanceclient.go (+2/-0)
server/acceptance/suites/suite.go (+9/-2)
testing/helpers.go (+1/-1)
ubuntu-push-client.go (+18/-0)
urldispatcher/curldispatcher/curldispatcher.go (+1/-1)
urldispatcher/urldispatcher.go (+2/-2)
urldispatcher/urldispatcher_test.go (+2/-2)
util/redialer.go (+36/-27)
util/redialer_test.go (+7/-7)
To merge this branch: bzr merge lp:~chipaca/ubuntu-push/fix-1390663-for-rtm
Reviewer Review Type Date Requested Status
Bret Barker (community) Approve
Review via email: mp+247328@code.launchpad.net

Commit message

Chery pick r140 from trunk to fix lp:1390663 for RTM.

To post a comment you must log in.
Revision history for this message
Bret Barker (noise) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bus/connectivity/connectivity.go'
2--- bus/connectivity/connectivity.go 2014-07-04 19:12:38 +0000
3+++ bus/connectivity/connectivity.go 2015-01-22 17:41:21 +0000
4@@ -82,7 +82,7 @@
5 // Get the current state.
6 initial = nm.GetState()
7 if initial == networkmanager.Unknown {
8- cs.log.Debugf("Failed to get state.")
9+ cs.log.Debugf("failed to get state.")
10 goto Continue
11 }
12 cs.log.Debugf("got initial state of %s", initial)
13@@ -120,40 +120,51 @@
14 case <-cs.networkConCh:
15 cs.webgetCh = nil
16 cs.timer.Reset(stabilizingTimeout)
17- log.Debugf("PrimaryConnection changed. Assuming disconnect.")
18 if cs.lastSent == true {
19+ log.Debugf("connectivity: PrimaryConnection changed. lastSent: %v, sending 'disconnected'.", cs.lastSent)
20 cs.lastSent = false
21 break Loop
22+ } else {
23+ log.Debugf("connectivity: PrimaryConnection changed. lastSent: %v, Ignoring.", cs.lastSent)
24 }
25
26 case v, ok := <-cs.networkStateCh:
27+ // Handle only disconnecting here, connecting handled under the timer below
28 if !ok {
29 // tear it all down and start over
30 return false, errors.New("got not-OK from StateChanged watch")
31 }
32 cs.webgetCh = nil
33+ lastState := cs.currentState
34 cs.currentState = v
35- cs.timer.Reset(stabilizingTimeout)
36- log.Debugf("State changed to %s. Assuming disconnect.", v)
37- if cs.lastSent == true {
38- log.Infof("Sending 'disconnected'.")
39- cs.lastSent = false
40- break Loop
41+ // ignore Connecting (followed immediately by "Connected Global") and repeats
42+ if v != networkmanager.Connecting && lastState != v {
43+ cs.timer.Reset(stabilizingTimeout)
44+ log.Debugf("state changed to %s. Assuming disconnect.", v)
45+ if cs.lastSent == true {
46+ log.Debugf("connectivity: %s -> %s. lastSent: %v, sending 'disconnected'", lastState, v, cs.lastSent)
47+ cs.lastSent = false
48+ break Loop
49+ } else {
50+ log.Debugf("connectivity: %s -> %s. lastSent: %v, Ignoring.", lastState, v, cs.lastSent)
51+ }
52+ } else {
53+ log.Debugf("connectivity: %s -> %s. lastSent: %v, Ignoring.", lastState, v, cs.lastSent)
54 }
55
56 case <-cs.timer.C:
57 if cs.currentState == networkmanager.ConnectedGlobal {
58- log.Debugf("May be connected; checking...")
59+ log.Debugf("connectivity: timer signal, state: ConnectedGlobal, checking...")
60 cs.webgetCh = make(chan bool)
61 go cs.webget(cs.webgetCh)
62 }
63
64 case connected := <-cs.webgetCh:
65 cs.timer.Reset(recheckTimeout)
66- log.Debugf("Connection check says: %t", connected)
67+ log.Debugf("connectivity: connection check says: %t", connected)
68 cs.webgetCh = nil
69 if connected && cs.lastSent == false {
70- log.Infof("Sending 'connected'.")
71+ log.Debugf("connectivity: connection check ok, lastSent: %v, sending 'connected'.", cs.lastSent)
72 cs.lastSent = true
73 break Loop
74 }
75@@ -178,7 +189,7 @@
76 }
77
78 Start:
79- log.Infof("Sending initial 'disconnected'.")
80+ log.Debugf("sending initial 'disconnected'.")
81 out <- false
82 cs.lastSent = false
83 cs.currentState = cs.start()
84
85=== modified file 'bus/connectivity/connectivity_test.go'
86--- bus/connectivity/connectivity_test.go 2014-07-04 23:00:42 +0000
87+++ bus/connectivity/connectivity_test.go 2015-01-22 17:41:21 +0000
88@@ -217,20 +217,22 @@
89 f, e := cs.connectedStateStep()
90 c.Check(e, IsNil)
91 c.Check(f, Equals, true)
92- ch <- networkmanager.ConnectedGlobal // a ConnectedGlobal when connected signals trouble
93- f, e = cs.connectedStateStep()
94- c.Check(e, IsNil)
95- c.Check(f, Equals, false) // so we assume a disconnect happened
96- f, e = cs.connectedStateStep()
97- c.Check(e, IsNil)
98- c.Check(f, Equals, true) // and if the web check works, go back to connected
99+ ch <- networkmanager.Disconnected
100+ ch <- networkmanager.ConnectedGlobal
101+ f, e = cs.connectedStateStep()
102+ c.Check(e, IsNil)
103+ c.Check(f, Equals, false)
104+ f, e = cs.connectedStateStep()
105+ c.Check(e, IsNil)
106+ c.Check(f, Equals, true)
107
108 // same scenario, but with failing web check
109 webget_p = condition.Fail2Work(1)
110+ ch <- networkmanager.Disconnected
111 ch <- networkmanager.ConnectedGlobal
112 f, e = cs.connectedStateStep()
113 c.Check(e, IsNil)
114- c.Check(f, Equals, false) // first false is from assuming a Connected signals trouble
115+ c.Check(f, Equals, false) // first false is from the Disconnected
116
117 // the next call to Step will time out
118 _ch := make(chan bool, 1)
119@@ -284,7 +286,6 @@
120
121 endp := testingbus.NewTestingEndpoint(condition.Work(true), condition.Work(true),
122 uint32(networkmanager.ConnectedGlobal),
123- uint32(networkmanager.ConnectedGlobal),
124 uint32(networkmanager.Disconnected),
125 )
126
127@@ -303,8 +304,6 @@
128 }{
129 {false, "first state is always false", 0},
130 {true, "then it should be true as per ConnectedGlobal above", 0},
131- {false, "then, false (upon receiving the next ConnectedGlobal)", 2},
132- {true, "then it should be true (webcheck passed)", 0},
133 {false, "then it should be false (Disconnected)", 2},
134 {false, "then it should be false again because it's restarted", 2},
135 }
136
137=== modified file 'bus/connectivity/webchecker.go'
138--- bus/connectivity/webchecker.go 2014-03-20 12:24:33 +0000
139+++ bus/connectivity/webchecker.go 2015-01-22 17:41:21 +0000
140@@ -64,7 +64,7 @@
141 func (wb *webchecker) Webcheck(ch chan<- bool) {
142 response, err := wb.cli.Get(wb.url)
143 if err != nil {
144- wb.log.Errorf("While GETting %s: %v", wb.url, err)
145+ wb.log.Errorf("while GETting %s: %v", wb.url, err)
146 ch <- false
147 return
148 }
149@@ -72,17 +72,17 @@
150 hash := md5.New()
151 _, err = io.CopyN(hash, response.Body, 1024)
152 if err != io.EOF {
153- wb.log.Errorf("Reading %s, expecting EOF, got: %v",
154+ wb.log.Errorf("reading %s, expecting EOF, got: %v",
155 wb.url, err)
156 ch <- false
157 return
158 }
159 sum := fmt.Sprintf("%x", hash.Sum(nil))
160 if sum == wb.target {
161- wb.log.Infof("Connectivity check passed.")
162+ wb.log.Infof("connectivity check passed.")
163 ch <- true
164 } else {
165- wb.log.Infof("Connectivity check failed: content mismatch.")
166+ wb.log.Infof("connectivity check failed: content mismatch.")
167 ch <- false
168 }
169 }
170
171=== modified file 'bus/endpoint.go'
172--- bus/endpoint.go 2014-09-08 15:48:00 +0000
173+++ bus/endpoint.go 2015-01-22 17:41:21 +0000
174@@ -84,7 +84,7 @@
175 name := endp.addr.Name
176 hasOwner, err := d.NameHasOwner(name)
177 if err != nil {
178- endp.log.Debugf("Unable to determine ownership of %#v: %v", name, err)
179+ endp.log.Debugf("unable to determine ownership of %#v: %v", name, err)
180 bus.Close()
181 return err
182 }
183@@ -110,7 +110,7 @@
184 return errors.New(msg)
185 }
186 }
187- endp.log.Infof("%#v dialed in.", name)
188+ endp.log.Debugf("%#v dialed in.", name)
189 endp.bus = bus
190 endp.proxy = bus.Object(name, dbus.ObjectPath(endp.addr.Path))
191 return nil
192@@ -126,7 +126,7 @@
193 func (endp *endpoint) WatchSignal(member string, f func(...interface{}), d func()) error {
194 watch, err := endp.proxy.WatchSignal(endp.addr.Interface, member)
195 if err != nil {
196- endp.log.Debugf("Failed to set up the watch: %s", err)
197+ endp.log.Debugf("failed to set up the watch: %s", err)
198 return err
199 }
200
201@@ -167,15 +167,15 @@
202 variantvs := endp.unpackOneMsg(msg, property)
203 switch len(variantvs) {
204 default:
205- return nil, fmt.Errorf("Too many values in Properties.Get response: %d", len(variantvs))
206+ return nil, fmt.Errorf("too many values in Properties.Get response: %d", len(variantvs))
207 case 0:
208- return nil, fmt.Errorf("Not enough values in Properties.Get response: %d", len(variantvs))
209+ return nil, fmt.Errorf("not enough values in Properties.Get response: %d", len(variantvs))
210 case 1:
211 // carry on
212 }
213 variant, ok := variantvs[0].(*dbus.Variant)
214 if !ok {
215- return nil, fmt.Errorf("Response from Properties.Get wasn't a *dbus.Variant")
216+ return nil, fmt.Errorf("response from Properties.Get wasn't a *dbus.Variant")
217 }
218 return variant.Value, nil
219 }
220@@ -324,6 +324,6 @@
221 }
222 f(endp.unpackOneMsg(msg, member)...)
223 }
224- endp.log.Errorf("Got not-OK from %s watch", member)
225+ endp.log.Errorf("got not-OK from %s watch", member)
226 d()
227 }
228
229=== modified file 'bus/networkmanager/networkmanager.go'
230--- bus/networkmanager/networkmanager.go 2014-04-04 12:01:42 +0000
231+++ bus/networkmanager/networkmanager.go 2015-01-22 17:41:21 +0000
232@@ -71,14 +71,14 @@
233 func (nm *networkManager) GetState() State {
234 s, err := nm.bus.GetProperty("state")
235 if err != nil {
236- nm.log.Errorf("Failed gettting current state: %s", err)
237- nm.log.Debugf("Defaulting state to Unknown")
238+ nm.log.Errorf("failed gettting current state: %s", err)
239+ nm.log.Debugf("defaulting state to Unknown")
240 return Unknown
241 }
242
243 v, ok := s.(uint32)
244 if !ok {
245- nm.log.Errorf("Got weird state: %#v", s)
246+ nm.log.Errorf("got weird state: %#v", s)
247 return Unknown
248 }
249
250@@ -110,8 +110,8 @@
251 func (nm *networkManager) GetPrimaryConnection() string {
252 s, err := nm.bus.GetProperty("PrimaryConnection")
253 if err != nil {
254- nm.log.Errorf("Failed gettting current primary connection: %s", err)
255- nm.log.Debugf("Defaulting primary connection to empty")
256+ nm.log.Errorf("failed gettting current primary connection: %s", err)
257+ nm.log.Debugf("defaulting primary connection to empty")
258 return ""
259 }
260
261@@ -146,7 +146,7 @@
262 ch <- string(con)
263 }, func() { close(ch) })
264 if err != nil {
265- nm.log.Debugf("Failed to set up the watch: %s", err)
266+ nm.log.Debugf("failed to set up the watch: %s", err)
267 return nil, err
268 }
269
270
271=== modified file 'bus/notifications/raw.go'
272--- bus/notifications/raw.go 2014-08-15 10:33:04 +0000
273+++ bus/notifications/raw.go 2015-01-22 17:41:21 +0000
274@@ -119,7 +119,7 @@
275 ch <- action
276 }, func() { close(ch) })
277 if err != nil {
278- raw.log.Debugf("Failed to set up the watch: %s", err)
279+ raw.log.Debugf("failed to set up the watch: %s", err)
280 return nil, err
281 }
282 return ch, nil
283
284=== modified file 'bus/systemimage/systemimage.go'
285--- bus/systemimage/systemimage.go 2014-04-02 08:46:48 +0000
286+++ bus/systemimage/systemimage.go 2015-01-22 17:41:21 +0000
287@@ -57,7 +57,7 @@
288 var _ SystemImage = &systemImage{} // ensures it conforms
289
290 func (si *systemImage) Info() (*InfoResult, error) {
291- si.log.Debugf("Invoking Info")
292+ si.log.Debugf("invoking Info")
293 res := &InfoResult{}
294 err := si.endp.Call("Info", bus.Args(), &res.BuildNumber, &res.Device, &res.Channel, &res.LastUpdate, &res.VersionDetail)
295 if err != nil {
296
297=== modified file 'client/client.go'
298--- client/client.go 2014-10-23 19:30:24 +0000
299+++ client/client.go 2015-01-22 17:41:21 +0000
300@@ -376,15 +376,15 @@
301
302 // handleConnState deals with connectivity events
303 func (client *PushClient) handleConnState(hasConnectivity bool) {
304+ client.log.Debugf("handleConnState: %v", hasConnectivity)
305 if client.hasConnectivity == hasConnectivity {
306 // nothing to do!
307 return
308 }
309 client.hasConnectivity = hasConnectivity
310+ client.session.Close()
311 if hasConnectivity {
312 client.session.AutoRedial(client.sessionConnectedCh)
313- } else {
314- client.session.Close()
315 }
316 }
317
318@@ -490,7 +490,7 @@
319 case err := <-client.session.ErrCh:
320 errhandler(err)
321 case count := <-client.sessionConnectedCh:
322- client.log.Debugf("Session connected after %d attempts", count)
323+ client.log.Debugf("session connected after %d attempts", count)
324 case app := <-client.unregisterCh:
325 unregisterhandler(app)
326 }
327
328=== modified file 'client/client_test.go'
329--- client/client_test.go 2014-09-05 10:47:29 +0000
330+++ client/client_test.go 2015-01-22 17:41:21 +0000
331@@ -1135,7 +1135,7 @@
332 // sessionConnectedCh to nothing in particular, but it'll help sync this test
333 cli.sessionConnectedCh <- 42
334 tick()
335- c.Check(cs.log.Captured(), Matches, "(?ms).*Session connected after 42 attempts$")
336+ c.Check(cs.log.Captured(), Matches, "(?msi).*Session connected after 42 attempts$")
337
338 // loop() should have connected:
339 // * connCh to the connectivity checker
340
341=== modified file 'client/service/postal.go'
342--- client/service/postal.go 2014-10-23 14:39:53 +0000
343+++ client/service/postal.go 2015-01-22 17:41:21 +0000
344@@ -244,7 +244,6 @@
345 for _, endp := range endps {
346 go func(name string, endp bus.Endpoint) {
347 util.NewAutoRedialer(endp).Redial()
348- svc.Log.Debugf("%s dialed in", name)
349 wg.Done()
350 }(endp.name, endp.endp)
351 }
352
353=== modified file 'client/service/service.go'
354--- client/service/service.go 2014-10-23 14:39:53 +0000
355+++ client/service/service.go 2015-01-22 17:41:21 +0000
356@@ -147,14 +147,14 @@
357 // errors below here Can't Happen (tm).
358 body, err := ioutil.ReadAll(resp.Body)
359 if err != nil {
360- svc.Log.Errorf("Reading response body: %v", err)
361+ svc.Log.Errorf("during ReadAll() of response body: %v", err)
362 return nil, err
363 }
364
365 var reply registrationReply
366 err = json.Unmarshal(body, &reply)
367 if err != nil {
368- svc.Log.Errorf("Unmarshalling response body: %v", err)
369+ svc.Log.Errorf("during Unmarshal of response body: %v", err)
370 return nil, fmt.Errorf("unable to unmarshal register response: %v", err)
371 }
372
373@@ -179,7 +179,7 @@
374 }
375
376 if !reply.Ok || reply.Token == "" {
377- svc.Log.Errorf("Unexpected response: %#v", reply)
378+ svc.Log.Errorf("unexpected response: %#v", reply)
379 return nil, ErrBadToken
380 }
381
382
383=== modified file 'client/session/session.go'
384--- client/session/session.go 2015-01-16 16:40:55 +0000
385+++ client/session/session.go 2015-01-22 17:41:21 +0000
386@@ -74,8 +74,22 @@
387 Connected
388 Started
389 Running
390+ Unknown
391 )
392
393+func (s ClientSessionState) String() string {
394+ if s >= Unknown {
395+ return fmt.Sprintf("??? (%d)", s)
396+ }
397+ return [Unknown]string{
398+ "Error",
399+ "Disconnected",
400+ "Connected",
401+ "Started",
402+ "Running",
403+ }[s]
404+}
405+
406 type hostGetter interface {
407 Get() (*gethosts.Host, error)
408 }
409@@ -131,6 +145,7 @@
410 proto protocol.Protocol
411 pingInterval time.Duration
412 retrier util.AutoRedialer
413+ retrierLock sync.Mutex
414 cookie string
415 // status
416 stateP *uint32
417@@ -220,6 +235,7 @@
418 }
419
420 func (sess *ClientSession) setState(state ClientSessionState) {
421+ sess.Log.Debugf("session.setState: %s -> %s", ClientSessionState(atomic.LoadUint32(sess.stateP)), state)
422 atomic.StoreUint32(sess.stateP, uint32(state))
423 }
424
425@@ -348,6 +364,8 @@
426 }
427
428 func (sess *ClientSession) stopRedial() {
429+ sess.retrierLock.Lock()
430+ defer sess.retrierLock.Unlock()
431 if sess.retrier != nil {
432 sess.retrier.Stop()
433 sess.retrier = nil
434@@ -360,15 +378,31 @@
435 sess.setShouldDelay()
436 }
437 time.Sleep(sess.redialDelay(sess))
438+ sess.retrierLock.Lock()
439+ defer sess.retrierLock.Unlock()
440+ if sess.retrier != nil {
441+ panic("session AutoRedial: unexpected non-nil retrier.")
442+ }
443 sess.retrier = util.NewAutoRedialer(sess)
444 sess.lastAutoRedial = time.Now()
445- go func() { doneCh <- sess.retrier.Redial() }()
446+ go func() {
447+ sess.retrierLock.Lock()
448+ retrier := sess.retrier
449+ sess.retrierLock.Unlock()
450+ if retrier == nil {
451+ sess.Log.Debugf("session autoredialer skipping retry: retrier has been set to nil.")
452+ return
453+ }
454+ sess.Log.Debugf("session autoredialier launching Redial goroutine")
455+ doneCh <- retrier.Redial()
456+ }()
457 }
458
459 func (sess *ClientSession) Close() {
460 sess.stopRedial()
461 sess.doClose()
462 }
463+
464 func (sess *ClientSession) doClose() {
465 sess.connLock.Lock()
466 defer sess.connLock.Unlock()
467@@ -508,6 +542,7 @@
468 sess.proto.SetDeadline(time.Now().Add(deadAfter))
469 err = sess.proto.ReadMessage(&recv)
470 if err != nil {
471+ sess.Log.Debugf("session aborting with error on read.")
472 sess.setState(Error)
473 return err
474 }
475@@ -529,6 +564,7 @@
476 sess.Log.Errorf("server sent warning: %s", recv.Reason)
477 }
478 if err != nil {
479+ sess.Log.Debugf("session aborting with error from handler.")
480 return err
481 }
482 }
483@@ -591,7 +627,7 @@
484 }
485 sess.proto = proto
486 sess.pingInterval = pingInterval
487- sess.Log.Debugf("Connected %v.", conn.RemoteAddr())
488+ sess.Log.Debugf("connected %v.", conn.RemoteAddr())
489 sess.started() // deals with choosing which host to retry with as well
490 return nil
491 }
492
493=== modified file 'dependencies.tsv'
494--- dependencies.tsv 2014-08-20 12:42:51 +0000
495+++ dependencies.tsv 2015-01-22 17:41:21 +0000
496@@ -1,5 +1,5 @@
497 code.google.com/p/go-uuid hg 7dda39b2e7d5e265014674c5af696ba4186679e9 11
498 code.google.com/p/gosqlite hg 74691fb6f83716190870cde1b658538dd4b18eb0 15
499-launchpad.net/go-dbus/v1 bzr james@jamesh.id.au-20140801110939-lzfql7fk76dt6ckd 128
500+launchpad.net/go-dbus/v1 bzr jlenton@gmail.com-20141023032446-s5icvsucwlv5o38a 129
501 launchpad.net/go-xdg/v0 bzr john.lenton@canonical.com-20140208094800-gubd5md7cro3mtxa 10
502 launchpad.net/gocheck bzr gustavo@niemeyer.net-20140225173054-xu9zlkf9kxhvow02 87
503
504=== modified file 'identifier/identifier.go'
505--- identifier/identifier.go 2014-08-04 20:40:50 +0000
506+++ identifier/identifier.go 2015-01-22 17:41:21 +0000
507@@ -48,7 +48,7 @@
508 func New() (Id, error) {
509 value, err := readMachineId()
510 if err != nil {
511- return &Identifier{value: ""}, fmt.Errorf("Failed to read the machine id: %s", err)
512+ return &Identifier{value: ""}, fmt.Errorf("failed to read the machine id: %s", err)
513 }
514 return &Identifier{value: value}, nil
515 }
516
517=== modified file 'identifier/identifier_test.go'
518--- identifier/identifier_test.go 2014-08-12 00:32:32 +0000
519+++ identifier/identifier_test.go 2015-01-22 17:41:21 +0000
520@@ -48,7 +48,7 @@
521 machineIdPath = "/var/lib/dbus/no-such-file"
522 id, err := New()
523 c.Check(err, NotNil)
524- c.Check(err.Error(), Equals, "Failed to read the machine id: open /var/lib/dbus/no-such-file: no such file or directory")
525+ c.Check(err.Error(), Equals, "failed to read the machine id: open /var/lib/dbus/no-such-file: no such file or directory")
526 c.Check(id.String(), HasLen, 0)
527 }
528
529
530=== modified file 'launch_helper/helper_finder/helper_finder.go'
531--- launch_helper/helper_finder/helper_finder.go 2014-07-29 15:36:00 +0000
532+++ launch_helper/helper_finder/helper_finder.go 2015-01-22 17:41:21 +0000
533@@ -72,7 +72,7 @@
534 fInfo, err := os.Stat(helpersDataPath)
535 if err != nil {
536 // cache file is missing, go via the slow route
537- log.Infof("Cache file not found, falling back to .json file lookup")
538+ log.Infof("cache file not found, falling back to .json file lookup")
539 return helperFromHookFile(app)
540 }
541 // get the lock as the map can be changed while we read
542
543=== modified file 'launch_helper/helper_finder/helper_finder_test.go'
544--- launch_helper/helper_finder/helper_finder_test.go 2014-07-29 15:36:00 +0000
545+++ launch_helper/helper_finder/helper_finder_test.go 2015-01-22 17:41:21 +0000
546@@ -139,7 +139,7 @@
547 hid, hex := Helper(app, s.log)
548 c.Check(hid, Equals, "com.example.test_test-helper_1")
549 c.Check(hex, Equals, filepath.Join(s.symlinkPath, "tsthlpr"))
550- c.Check(s.log.Captured(), Matches, ".*Cache file not found, falling back to .json file lookup\n")
551+ c.Check(s.log.Captured(), Matches, ".*(?i)Cache file not found, falling back to .json file lookup\n")
552 }
553
554 func (s *helperSuite) TestHelperFromHookBasic(c *C) {
555
556=== modified file 'launch_helper/kindpool.go'
557--- launch_helper/kindpool.go 2015-01-16 16:40:55 +0000
558+++ launch_helper/kindpool.go 2015-01-22 17:41:21 +0000
559@@ -296,7 +296,7 @@
560 if err != nil {
561 pool.log.Errorf("unable to read output from %v helper: %v", args.AppId, err)
562 } else {
563- pool.log.Infof("%v helper output: %#v", args.AppId, payload)
564+ pool.log.Infof("%v helper output: %s", args.AppId, payload)
565 res := &HelperResult{Input: args.Input}
566 err = json.Unmarshal(payload, &res.HelperOutput)
567 if err != nil {
568
569=== modified file 'launch_helper/legacy/legacy.go'
570--- launch_helper/legacy/legacy.go 2015-01-16 16:40:55 +0000
571+++ launch_helper/legacy/legacy.go 2015-01-22 17:41:21 +0000
572@@ -78,7 +78,7 @@
573 p_err := cmd.Wait()
574 if p_err != nil {
575 // Helper failed or got killed, log output/errors
576- lhl.log.Errorf("Legacy helper failed: appId: %v, helper: %v, pid: %v, error: %v, stdout: %#v, stderr: %#v.",
577+ lhl.log.Errorf("legacy helper failed: appId: %v, helper: %v, pid: %v, error: %v, stdout: %#v, stderr: %#v.",
578 appId, progname, id, p_err, stdout.String(), stderr.String())
579 }
580 lhl.done(id)
581
582=== modified file 'launch_helper/legacy/legacy_test.go'
583--- launch_helper/legacy/legacy_test.go 2014-08-21 18:03:49 +0000
584+++ launch_helper/legacy/legacy_test.go 2015-01-22 17:41:21 +0000
585@@ -104,7 +104,7 @@
586 c.Assert(err, IsNil)
587
588 takeNext(ch, c)
589- c.Check(ls.log.Captured(), Matches, "(?s).*Legacy helper failed.*")
590+ c.Check(ls.log.Captured(), Matches, "(?si).*Legacy helper failed.*")
591 }
592
593 func (ls *legacySuite) TestHelperFailsLog(c *C) {
594
595=== modified file 'messaging/messaging.go'
596--- messaging/messaging.go 2014-07-27 02:54:40 +0000
597+++ messaging/messaging.go 2015-01-22 17:41:21 +0000
598@@ -181,7 +181,7 @@
599 Action: action,
600 })
601 if err != nil {
602- mmu.Log.Errorf("Failed to build action: %s", action)
603+ mmu.Log.Errorf("failed to build action: %s", action)
604 return false
605 }
606 actions[2*i] = string(act)
607
608=== modified file 'poller/poller.go'
609--- poller/poller.go 2014-08-29 13:50:16 +0000
610+++ poller/poller.go 2015-01-22 17:41:21 +0000
611@@ -167,7 +167,7 @@
612 // the channel will produce a true for every
613 // wakeup, not only the one we asked for
614 now := time.Now()
615- p.log.Debugf("got woken up; time is %s", now)
616+ p.log.Debugf("got woken up; time is %s (𝛥: %s)", now, now.Sub(t))
617 if !now.Before(t) {
618 break
619 }
620
621=== modified file 'server/acceptance/acceptanceclient.go'
622--- server/acceptance/acceptanceclient.go 2014-08-27 21:19:51 +0000
623+++ server/acceptance/acceptanceclient.go 2015-01-22 17:41:21 +0000
624@@ -176,6 +176,8 @@
625 events <- fmt.Sprintf("%sbroadcast chan:%v app:%v topLevel:%d payloads:%s", sess.Prefix, recv.ChanId, recv.AppId, recv.TopLevel, pack)
626 case "warn", "connwarn":
627 events <- fmt.Sprintf("%sconnwarn %s", sess.Prefix, recv.Reason)
628+ case "connbroken":
629+ events <- fmt.Sprintf("%sconnbroken %s", sess.Prefix, recv.Reason)
630 case "setparams":
631 sess.SetCookie(recv.SetCookie)
632 if sess.ReportSetParams {
633
634=== modified file 'server/acceptance/suites/suite.go'
635--- server/acceptance/suites/suite.go 2014-09-01 14:48:03 +0000
636+++ server/acceptance/suites/suite.go 2015-01-22 17:41:21 +0000
637@@ -22,6 +22,7 @@
638 "fmt"
639 "net"
640 "os"
641+ "regexp"
642 "runtime"
643 "time"
644
645@@ -48,6 +49,13 @@
646
647 // Start a client with auth.
648 func (h *ServerHandle) StartClientAuth(c *C, devId string, levels map[string]int64, auth string, cookie string) (events <-chan string, errorCh <-chan error, stop func()) {
649+ cliEvents, errCh, stop := h.StartClientAuthFlex(c, devId, levels, auth, cookie, regexp.QuoteMeta(devId))
650+ c.Assert(NextEvent(cliEvents, errCh), Matches, "connected .*")
651+ return cliEvents, errCh, stop
652+}
653+
654+// Start a client with auth, take a devId regexp, don't check any client event.
655+func (h *ServerHandle) StartClientAuthFlex(c *C, devId string, levels map[string]int64, auth, cookie, devIdRegexp string) (events <-chan string, errorCh <-chan error, stop func()) {
656 errCh := make(chan error, 1)
657 cliEvents := make(chan string, 10)
658 sess := testClientSession(h.ServerAddr, devId, "m1", "img1", false)
659@@ -76,9 +84,8 @@
660 go func() {
661 errCh <- sess.Run(cliEvents)
662 }()
663- c.Assert(NextEvent(cliEvents, errCh), Matches, "connected .*")
664 c.Assert(NextEvent(h.ServerEvents, nil), Matches, ".*session.* connected .*")
665- c.Assert(NextEvent(h.ServerEvents, nil), Matches, ".*session.* registered "+devId)
666+ c.Assert(NextEvent(h.ServerEvents, nil), Matches, ".*session.* registered "+devIdRegexp)
667 return cliEvents, errCh, func() { clientShutdown <- true }
668 }
669
670
671=== modified file 'testing/helpers.go'
672--- testing/helpers.go 2014-07-11 19:42:57 +0000
673+++ testing/helpers.go 2015-01-22 17:41:21 +0000
674@@ -118,7 +118,7 @@
675
676 idx := strings.LastIndex(dir, sep)
677 if idx == -1 {
678- panic(fmt.Errorf("Unable to find %s in %#v", sep, dir))
679+ panic(fmt.Errorf("unable to find %s in %#v", sep, dir))
680 }
681 idx += len(sep)
682
683
684=== modified file 'ubuntu-push-client.go'
685--- ubuntu-push-client.go 2014-05-08 22:29:26 +0000
686+++ ubuntu-push-client.go 2015-01-22 17:41:21 +0000
687@@ -18,13 +18,31 @@
688
689 import (
690 "log"
691+ "os"
692+ "os/signal"
693+ "runtime"
694+ "syscall"
695
696 "launchpad.net/go-xdg/v0"
697
698 "launchpad.net/ubuntu-push/client"
699 )
700
701+func installSigQuitHandler() {
702+ go func() {
703+ sigs := make(chan os.Signal, 1)
704+ signal.Notify(sigs, syscall.SIGQUIT)
705+ buf := make([]byte, 1<<20)
706+ for {
707+ <-sigs
708+ runtime.Stack(buf, true)
709+ log.Printf("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end\n", buf)
710+ }
711+ }()
712+}
713+
714 func main() {
715+ installSigQuitHandler()
716 cfgFname, err := xdg.Config.Find("ubuntu-push-client/config.json")
717 if err != nil {
718 log.Fatalf("unable to find a configuration file: %v", err)
719
720=== modified file 'urldispatcher/curldispatcher/curldispatcher.go'
721--- urldispatcher/curldispatcher/curldispatcher.go 2014-09-01 13:27:17 +0000
722+++ urldispatcher/curldispatcher/curldispatcher.go 2015-01-22 17:41:21 +0000
723@@ -79,7 +79,7 @@
724 C.dispatch_url(c_url, (C.gpointer)(&payload))
725 success := <-doneCh
726 if !success {
727- return fmt.Errorf("Failed to DispatchURL: %s for %s", url, appPackage)
728+ return fmt.Errorf("failed to DispatchURL: %s for %s", url, appPackage)
729 }
730 return nil
731 }
732
733=== modified file 'urldispatcher/urldispatcher.go'
734--- urldispatcher/urldispatcher.go 2014-09-01 13:27:17 +0000
735+++ urldispatcher/urldispatcher.go 2015-01-22 17:41:21 +0000
736@@ -44,7 +44,7 @@
737 var cTestURL = curldispatcher.TestURL
738
739 func (ud *urlDispatcher) DispatchURL(url string, app *click.AppId) error {
740- ud.log.Debugf("Dispatching %s", url)
741+ ud.log.Debugf("dispatching %s", url)
742 err := cDispatchURL(url, app.DispatchPackage())
743 if err != nil {
744 ud.log.Errorf("DispatchURL failed: %s", err)
745@@ -62,7 +62,7 @@
746 }
747 for _, appId := range appIds {
748 if appId != app.Versioned() {
749- ud.log.Debugf("Notification skipped because of different appid for actions: %v - %s != %s", urls, appId, app.Versioned())
750+ ud.log.Debugf("notification skipped because of different appid for actions: %v - %s != %s", urls, appId, app.Versioned())
751 return false
752 }
753 }
754
755=== modified file 'urldispatcher/urldispatcher_test.go'
756--- urldispatcher/urldispatcher_test.go 2014-08-21 17:45:01 +0000
757+++ urldispatcher/urldispatcher_test.go 2015-01-22 17:41:21 +0000
758@@ -106,7 +106,7 @@
759 appId := clickhelp.MustParseAppId("com.example.test_app_0.99")
760 urls := []string{"potato://test-app"}
761 c.Check(ud.TestURL(appId, urls), Equals, false)
762- c.Check(s.log.Captured(), Matches, `(?sm).*Notification skipped because of different appid for actions: \[potato://test-app\] - com.example.test_test-app_0.1 != com.example.test_app_0.99`)
763+ c.Check(s.log.Captured(), Matches, `(?smi).*notification skipped because of different appid for actions: \[potato://test-app\] - com.example.test_test-app_0.1 != com.example.test_app_0.99`)
764 }
765
766 func (s *UDSuite) TestTestURLOneWrongApp(c *C) {
767@@ -117,7 +117,7 @@
768 appId := clickhelp.MustParseAppId("com.example.test_test-app_0")
769 urls := []string{"potato://test-app", "potato_a://foo"}
770 c.Check(ud.TestURL(appId, urls), Equals, false)
771- c.Check(s.log.Captured(), Matches, `(?sm).*Notification skipped because of different appid for actions: \[potato://test-app potato_a://foo\] - com.example.test_test-app1 != com.example.test_test-app.*`)
772+ c.Check(s.log.Captured(), Matches, `(?smi).*notification skipped because of different appid for actions: \[potato://test-app potato_a://foo\] - com.example.test_test-app1 != com.example.test_test-app.*`)
773 }
774
775 func (s *UDSuite) TestTestURLInvalidURL(c *C) {
776
777=== modified file 'util/redialer.go'
778--- util/redialer.go 2014-03-20 12:15:47 +0000
779+++ util/redialer.go 2015-01-22 17:41:21 +0000
780@@ -19,6 +19,7 @@
781
782 import (
783 "sync"
784+ "sync/atomic"
785 "time"
786 )
787
788@@ -65,30 +66,42 @@
789 Stop() // Stop shuts down the given AutoRedialer, if it is still retrying.
790 }
791
792+type redialerState uint32
793+
794+const (
795+ Unconfigured redialerState = iota
796+ Redialing
797+ Stopped
798+)
799+
800+func (s *redialerState) String() string {
801+ return [3]string{"Unconfigured", "Redialing", "Stopped"}[uint32(*s)]
802+}
803+
804 type autoRedialer struct {
805- stop chan bool
806- lock sync.RWMutex
807+ stateP *redialerState
808 dial func() error
809 jitter func(time.Duration) time.Duration
810 }
811
812+func (ar *autoRedialer) state() redialerState {
813+ return redialerState(atomic.LoadUint32((*uint32)(ar.stateP)))
814+}
815+
816+func (ar *autoRedialer) setState(s redialerState) {
817+ atomic.StoreUint32((*uint32)(ar.stateP), uint32(s))
818+}
819+
820+func (ar *autoRedialer) setStateIfEqual(oldState, newState redialerState) bool {
821+ return atomic.CompareAndSwapUint32((*uint32)(ar.stateP), uint32(oldState), uint32(newState))
822+}
823+
824 func (ar *autoRedialer) Stop() {
825 if ar != nil {
826- ar.lock.RLock()
827- defer ar.lock.RUnlock()
828- if ar.stop != nil {
829- ar.stop <- true
830- }
831+ ar.setState(Stopped)
832 }
833 }
834
835-func (ar *autoRedialer) shutdown() {
836- ar.lock.Lock()
837- defer ar.lock.Unlock()
838- close(ar.stop)
839- ar.stop = nil
840-}
841-
842 // Redial keeps on calling Dial until it stops returning an error. It does
843 // exponential backoff, adding back the output of Jitter at each step.
844 func (ar *autoRedialer) Redial() uint32 {
845@@ -96,20 +109,19 @@
846 // at least it's better than a segfault...
847 panic("you can't Redial a nil AutoRedialer")
848 }
849- if ar.stop == nil {
850- panic("this AutoRedialer has already been shut down")
851+ if !ar.setStateIfEqual(Unconfigured, Redialing) {
852+ // XXX log this
853+ return 0
854 }
855- defer ar.shutdown()
856-
857- ar.lock.RLock()
858- stop := ar.stop
859- ar.lock.RUnlock()
860
861 var timeout time.Duration
862 var dialAttempts uint32 = 0 // unsigned so it can wrap safely ...
863 timeouts := Timeouts()
864 var numTimeouts uint32 = uint32(len(timeouts))
865 for {
866+ if ar.state() != Redialing {
867+ return dialAttempts
868+ }
869 if ar.dial() == nil {
870 return dialAttempts + 1
871 }
872@@ -122,18 +134,15 @@
873 timeout += ar.jitter(timeout)
874 }
875 dialAttempts++
876- select {
877- case <-stop:
878- return dialAttempts
879- case <-time.After(timeout):
880- }
881+ time.Sleep(timeout)
882 }
883 }
884
885 // Returns a stoppable AutoRedialer using the provided Dialer. If the Dialer
886 // is also a Jitterer, the backoff will be jittered.
887 func NewAutoRedialer(dialer Dialer) AutoRedialer {
888- ar := &autoRedialer{stop: make(chan bool), dial: dialer.Dial}
889+ state := Unconfigured
890+ ar := &autoRedialer{stateP: &state, dial: dialer.Dial}
891 jitterer, ok := dialer.(Jitterer)
892 if ok {
893 ar.jitter = jitterer.Jitter
894
895=== modified file 'util/redialer_test.go'
896--- util/redialer_test.go 2014-02-05 13:02:47 +0000
897+++ util/redialer_test.go 2015-01-22 17:41:21 +0000
898@@ -48,10 +48,10 @@
899 func (s *RedialerSuite) TestWorks(c *C) {
900 endp := testibus.NewTestingEndpoint(condition.Fail2Work(3), nil)
901 ar := NewAutoRedialer(endp)
902- c.Check(ar.(*autoRedialer).stop, NotNil)
903+ // c.Check(ar.(*autoRedialer).stop, NotNil)
904 c.Check(ar.Redial(), Equals, uint32(4))
905 // and on success, the stopper goes away
906- c.Check(ar.(*autoRedialer).stop, IsNil)
907+ // c.Check(ar.(*autoRedialer).stop, IsNil)
908 }
909
910 func (s *RedialerSuite) TestRetryNil(c *C) {
911@@ -63,7 +63,7 @@
912 endp := testibus.NewTestingEndpoint(condition.Work(true), nil)
913 ar := NewAutoRedialer(endp)
914 c.Check(ar.Redial(), Equals, uint32(1))
915- c.Check(ar.Redial, PanicMatches, ".*shut.?down.*")
916+ c.Check(ar.Redial(), Equals, uint32(0))
917 }
918
919 type JitteringEndpoint struct {
920@@ -103,13 +103,13 @@
921 go func() { countCh <- ar.Redial() }()
922 ar.Stop()
923 select {
924- case n := <-countCh:
925- c.Check(n, Equals, uint32(1))
926+ case <-countCh:
927+ // pass
928 case <-time.After(20 * time.Millisecond):
929 c.Fatal("timed out waiting for redial")
930 }
931- // on Stop(), the stopper goes away too
932- c.Check(ar.(*autoRedialer).stop, IsNil)
933+ // on Stop(), the redialer is Stopped
934+ c.Check(ar.(*autoRedialer).state(), Equals, Stopped)
935 // and the next Stop() doesn't panic nor block
936 ar.Stop()
937 }

Subscribers

People subscribed via source and target branches