Merge lp:ubuntu-push/automatic into lp:ubuntu-push

Proposed by John Lenton
Status: Merged
Merged at revision: 92
Proposed branch: lp:ubuntu-push/automatic
Merge into: lp:ubuntu-push
Diff against target: 436 lines (+138/-36)
13 files modified
client/client.go (+10/-6)
client/client_test.go (+6/-6)
client/session/session.go (+2/-2)
client/session/session_test.go (+1/-1)
config/config.go (+46/-9)
config/config_test.go (+41/-0)
debian/changelog (+6/-0)
debian/ubuntu-push-client.install (+1/-1)
server/acceptance/suites/helpers.go (+2/-2)
server/acceptance/suites/suite.go (+4/-3)
server/dev/server.go (+1/-1)
server/runner_http.go (+8/-4)
server/runner_test.go (+10/-1)
To merge this branch: bzr merge lp:ubuntu-push/automatic
Reviewer Review Type Date Requested Status
Ubuntu Push Hackers Pending
Review via email: mp+213058@code.launchpad.net

Commit message

Merge automatic into trunk.

Description of the change

Merge automatic into trunk.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'client/client.go'
2--- client/client.go 2014-03-12 11:08:57 +0000
3+++ client/client.go 2014-03-27 13:38:43 +0000
4@@ -186,17 +186,21 @@
5 }
6
7 // handleNotification deals with receiving a notification
8-func (client *PushClient) handleNotification() error {
9+func (client *PushClient) handleNotification(msg *session.Notification) error {
10 action_id := "dummy_id"
11 a := []string{action_id, "Go get it!"} // action value not visible on the phone
12 h := map[string]*dbus.Variant{"x-canonical-switch-to-application": &dbus.Variant{true}}
13 nots := notifications.Raw(client.notificationsEndp, client.log)
14+ body := "Tap to open the system updater."
15+ if msg != nil {
16+ body = fmt.Sprintf("[%d] %s", msg.TopLevel, body)
17+ }
18 not_id, err := nots.Notify(
19 "ubuntu-push-client", // app name
20 uint32(0), // id
21 "update_manager_icon", // icon
22- "There's an updated system image!", // summary
23- "You've got to get it! Now! Run!", // body
24+ "There's an updated system image.", // summary
25+ body, // body
26 a, // actions
27 h, // hints
28 int32(10*1000), // timeout (ms)
29@@ -217,15 +221,15 @@
30 }
31
32 // doLoop connects events with their handlers
33-func (client *PushClient) doLoop(connhandler func(bool), clickhandler, notifhandler func() error, errhandler func(error)) {
34+func (client *PushClient) doLoop(connhandler func(bool), clickhandler func() error, notifhandler func(*session.Notification) error, errhandler func(error)) {
35 for {
36 select {
37 case state := <-client.connCh:
38 connhandler(state)
39 case <-client.actionsCh:
40 clickhandler()
41- case <-client.session.MsgCh:
42- notifhandler()
43+ case msg := <-client.session.MsgCh:
44+ notifhandler(msg)
45 case err := <-client.session.ErrCh:
46 errhandler(err)
47 case count := <-client.sessionConnectedCh:
48
49=== modified file 'client/client_test.go'
50--- client/client_test.go 2014-02-08 18:31:01 +0000
51+++ client/client_test.go 2014-03-27 13:38:43 +0000
52@@ -392,7 +392,7 @@
53 endp := testibus.NewTestingEndpoint(nil, condition.Work(true), uint32(1))
54 cli.notificationsEndp = endp
55 cli.log = cs.log
56- c.Check(cli.handleNotification(), IsNil)
57+ c.Check(cli.handleNotification(nil), IsNil)
58 // check we sent the notification
59 args := testibus.GetCallArgs(endp)
60 c.Assert(args, HasLen, 1)
61@@ -405,7 +405,7 @@
62 cli.log = cs.log
63 endp := testibus.NewTestingEndpoint(nil, condition.Work(false))
64 cli.notificationsEndp = endp
65- c.Check(cli.handleNotification(), NotNil)
66+ c.Check(cli.handleNotification(nil), NotNil)
67 }
68
69 /*****************************************************************
70@@ -437,7 +437,7 @@
71 c.Assert(cli.initSession(), IsNil)
72
73 ch := make(chan bool, 1)
74- go cli.doLoop(func(bool) { ch <- true }, func() error { return nil }, func() error { return nil }, func(error) {})
75+ go cli.doLoop(func(bool) { ch <- true }, func() error { return nil }, func(_ *session.Notification) error { return nil }, func(error) {})
76 c.Check(takeNextBool(ch), Equals, true)
77 }
78
79@@ -450,7 +450,7 @@
80 cli.actionsCh = aCh
81
82 ch := make(chan bool, 1)
83- go cli.doLoop(func(bool) {}, func() error { ch <- true; return nil }, func() error { return nil }, func(error) {})
84+ go cli.doLoop(func(bool) {}, func() error { ch <- true; return nil }, func(_ *session.Notification) error { return nil }, func(error) {})
85 c.Check(takeNextBool(ch), Equals, true)
86 }
87
88@@ -462,7 +462,7 @@
89 cli.session.MsgCh <- &session.Notification{}
90
91 ch := make(chan bool, 1)
92- go cli.doLoop(func(bool) {}, func() error { return nil }, func() error { ch <- true; return nil }, func(error) {})
93+ go cli.doLoop(func(bool) {}, func() error { return nil }, func(_ *session.Notification) error { ch <- true; return nil }, func(error) {})
94 c.Check(takeNextBool(ch), Equals, true)
95 }
96
97@@ -474,7 +474,7 @@
98 cli.session.ErrCh <- nil
99
100 ch := make(chan bool, 1)
101- go cli.doLoop(func(bool) {}, func() error { return nil }, func() error { return nil }, func(error) { ch <- true })
102+ go cli.doLoop(func(bool) {}, func() error { return nil }, func(_ *session.Notification) error { return nil }, func(error) { ch <- true })
103 c.Check(takeNextBool(ch), Equals, true)
104 }
105
106
107=== modified file 'client/session/session.go'
108--- client/session/session.go 2014-03-19 22:31:20 +0000
109+++ client/session/session.go 2014-03-27 13:38:43 +0000
110@@ -36,7 +36,7 @@
111 var wireVersionBytes = []byte{protocol.ProtocolWireVersion}
112
113 type Notification struct {
114- // something something something
115+ TopLevel int64
116 }
117
118 type serverMsg struct {
119@@ -189,7 +189,7 @@
120 if bcast.ChanId == protocol.SystemChannelId {
121 // the system channel id, the only one we care about for now
122 sess.Log.Debugf("sending it over")
123- sess.MsgCh <- &Notification{}
124+ sess.MsgCh <- &Notification{bcast.TopLevel}
125 sess.Log.Debugf("sent it over")
126 } else {
127 sess.Log.Debugf("what is this weird channel, %#v?", bcast.ChanId)
128
129=== modified file 'client/session/session_test.go'
130--- client/session/session_test.go 2014-03-19 23:46:18 +0000
131+++ client/session/session_test.go 2014-03-27 13:38:43 +0000
132@@ -390,7 +390,7 @@
133 s.upCh <- nil // ack ok
134 c.Check(<-s.errCh, Equals, nil)
135 c.Assert(len(s.sess.MsgCh), Equals, 1)
136- c.Check(<-s.sess.MsgCh, Equals, &Notification{})
137+ c.Check(<-s.sess.MsgCh, DeepEquals, &Notification{TopLevel: 2})
138 // and finally, the session keeps track of the levels
139 levels, err := s.sess.Levels.GetAll()
140 c.Check(err, IsNil)
141
142=== modified file 'config/config.go'
143--- config/config.go 2014-02-21 16:17:28 +0000
144+++ config/config.go 2014-03-27 13:38:43 +0000
145@@ -31,10 +31,10 @@
146 "time"
147 )
148
149-func checkDestConfig(destConfig interface{}) (reflect.Value, error) {
150+func checkDestConfig(name string, destConfig interface{}) (reflect.Value, error) {
151 destValue := reflect.ValueOf(destConfig)
152 if destValue.Kind() != reflect.Ptr || destValue.Elem().Kind() != reflect.Struct {
153- return reflect.Value{}, errors.New("destConfig not *struct")
154+ return reflect.Value{}, fmt.Errorf("%s not *struct", name)
155 }
156 return destValue, nil
157 }
158@@ -44,6 +44,15 @@
159 dest interface{}
160 }
161
162+func (f destField) configName() string {
163+ fld := f.fld
164+ configName := strings.Split(fld.Tag.Get("json"), ",")[0]
165+ if configName == "" {
166+ configName = strings.ToLower(fld.Name[:1]) + fld.Name[1:]
167+ }
168+ return configName
169+}
170+
171 func traverseStruct(destStruct reflect.Value) <-chan destField {
172 ch := make(chan destField)
173 var traverse func(reflect.Value, chan<- destField)
174@@ -76,11 +85,7 @@
175 func fillDestConfig(destValue reflect.Value, p map[string]json.RawMessage) error {
176 destStruct := destValue.Elem()
177 for destField := range traverseStruct(destStruct) {
178- fld := destField.fld
179- configName := strings.Split(fld.Tag.Get("json"), ",")[0]
180- if configName == "" {
181- configName = strings.ToLower(fld.Name[:1]) + fld.Name[1:]
182- }
183+ configName := destField.configName()
184 raw, found := p[configName]
185 if !found { // assume all fields are mandatory for now
186 return fmt.Errorf("missing %s", configName)
187@@ -100,7 +105,7 @@
188 // fields in errors. Configuration fields in the JSON object are
189 // expected to start with lower case.
190 func ReadConfig(r io.Reader, destConfig interface{}) error {
191- destValue, err := checkDestConfig(destConfig)
192+ destValue, err := checkDestConfig("destConfig", destConfig)
193 if err != nil {
194 return err
195 }
196@@ -195,7 +200,7 @@
197
198 // ReadFiles reads configuration from a set of files. Uses ReadConfig internally.
199 func ReadFiles(destConfig interface{}, cfgFpaths ...string) error {
200- destValue, err := checkDestConfig(destConfig)
201+ destValue, err := checkDestConfig("destConfig", destConfig)
202 if err != nil {
203 return err
204 }
205@@ -221,3 +226,35 @@
206 }
207 return fillDestConfig(destValue, p1)
208 }
209+
210+// CompareConfigs compares the two given configuration structures. It returns a list of differing fields or nil if the config contents are the same.
211+func CompareConfig(config1, config2 interface{}) ([]string, error) {
212+ v1, err := checkDestConfig("config1", config1)
213+ if err != nil {
214+ return nil, err
215+ }
216+ v2, err := checkDestConfig("config2", config2)
217+ if err != nil {
218+ return nil, err
219+ }
220+ if v1.Type() != v2.Type() {
221+ return nil, errors.New("config1 and config2 don't have the same type")
222+ }
223+ fields1 := traverseStruct(v1.Elem())
224+ fields2 := traverseStruct(v2.Elem())
225+ diff := make([]string, 0)
226+ for {
227+ d1 := <-fields1
228+ d2 := <-fields2
229+ if d1.dest == nil {
230+ break
231+ }
232+ if !reflect.DeepEqual(d1.dest, d2.dest) {
233+ diff = append(diff, d1.configName())
234+ }
235+ }
236+ if len(diff) != 0 {
237+ return diff, nil
238+ }
239+ return nil, nil
240+}
241
242=== modified file 'config/config_test.go'
243--- config/config_test.go 2014-02-10 22:50:59 +0000
244+++ config/config_test.go 2014-03-27 13:38:43 +0000
245@@ -189,3 +189,44 @@
246 }
247 c.Check(a, DeepEquals, A{1, B{2}, 0})
248 }
249+
250+type testConfig2 struct {
251+ A int
252+ B string
253+ C []string `json:"c_list"`
254+ D ConfigTimeDuration
255+}
256+
257+func (s *configSuite) TestCompareConfig(c *C) {
258+ var cfg1 = testConfig2{
259+ A: 1,
260+ B: "xyz",
261+ C: []string{"a", "b"},
262+ D: ConfigTimeDuration{200 * time.Millisecond},
263+ }
264+ var cfg2 = testConfig2{
265+ A: 1,
266+ B: "xyz",
267+ C: []string{"a", "b"},
268+ D: ConfigTimeDuration{200 * time.Millisecond},
269+ }
270+ _, err := CompareConfig(cfg1, &cfg2)
271+ c.Check(err, ErrorMatches, `config1 not \*struct`)
272+ _, err = CompareConfig(&cfg1, cfg2)
273+ c.Check(err, ErrorMatches, `config2 not \*struct`)
274+ _, err = CompareConfig(&cfg1, &testConfig1{})
275+ c.Check(err, ErrorMatches, `config1 and config2 don't have the same type`)
276+
277+ res, err := CompareConfig(&cfg1, &cfg2)
278+ c.Assert(err, IsNil)
279+ c.Check(res, IsNil)
280+
281+ cfg1.B = "zyx"
282+ cfg2.C = []string{"a", "B"}
283+ cfg2.D = ConfigTimeDuration{205 * time.Millisecond}
284+
285+ res, err = CompareConfig(&cfg1, &cfg2)
286+ c.Assert(err, IsNil)
287+ c.Check(res, DeepEquals, []string{"b", "c_list", "d"})
288+
289+}
290
291=== modified file 'debian/changelog'
292--- debian/changelog 2014-03-25 17:27:10 +0000
293+++ debian/changelog 2014-03-27 13:38:43 +0000
294@@ -1,3 +1,9 @@
295+ubuntu-push (0.1-0ubuntu2) UNRELEASED; urgency=medium
296+
297+ * got rid of multiarch bug
298+
299+ -- John Lenton <john.lenton@canonical.com> Wed, 26 Mar 2014 16:27:06 +0000
300+
301 ubuntu-push (0.1+14.04.20140325.2-0ubuntu1) trusty; urgency=low
302
303 [ Diogo Baeder de Paula Pinto ]
304
305=== modified file 'debian/ubuntu-push-client.install'
306--- debian/ubuntu-push-client.install 2014-02-07 19:36:38 +0000
307+++ debian/ubuntu-push-client.install 2014-03-27 13:38:43 +0000
308@@ -1,4 +1,4 @@
309 #!/usr/bin/dh-exec
310 debian/config.json /etc/xdg/ubuntu-push-client
311 debian/ubuntu-push-client.conf /usr/share/upstart/sessions
312-usr/bin/ubuntu-push => /usr/lib/${DEB_HOST_MULTIARCH}/ubuntu-push-client/ubuntu-push-client
313+usr/bin/ubuntu-push => /usr/lib/ubuntu-push-client/ubuntu-push-client
314
315=== modified file 'server/acceptance/suites/helpers.go'
316--- server/acceptance/suites/helpers.go 2014-03-03 16:55:55 +0000
317+++ server/acceptance/suites/helpers.go 2014-03-27 13:38:43 +0000
318@@ -81,7 +81,7 @@
319
320 // RunAndObserve runs cmdName and returns a channel that will receive
321 // cmdName stderr logging and a function to kill the process.
322-func RunAndObserve(c *C, cmdName string, arg ...string) (<-chan string, func()) {
323+func RunAndObserve(c *C, cmdName string, arg ...string) (<-chan string, func(os.Signal)) {
324 cmd := exec.Command(cmdName, arg...)
325 stderr, err := cmd.StderrPipe()
326 if err != nil {
327@@ -127,7 +127,7 @@
328 logs <- info
329 }
330 }()
331- return logs, func() { cmd.Process.Kill() }
332+ return logs, func(sig os.Signal) { cmd.Process.Signal(sig) }
333 }
334
335 const (
336
337=== modified file 'server/acceptance/suites/suite.go'
338--- server/acceptance/suites/suite.go 2014-03-05 17:37:12 +0000
339+++ server/acceptance/suites/suite.go 2014-03-27 13:38:43 +0000
340@@ -25,6 +25,7 @@
341 "io/ioutil"
342 "net"
343 "net/http"
344+ "os"
345 "runtime"
346 "time"
347
348@@ -77,7 +78,7 @@
349 ServerAPIURL string
350 // KillGroup should be populated by StartServer with functions
351 // to kill the server process
352- KillGroup map[string]func()
353+ KillGroup map[string]func(os.Signal)
354 // hook to adjust requests
355 MassageRequest func(req *http.Request) *http.Request
356 // other state
357@@ -86,7 +87,7 @@
358
359 // Start a new server for each test.
360 func (s *AcceptanceSuite) SetUpTest(c *C) {
361- s.KillGroup = make(map[string]func())
362+ s.KillGroup = make(map[string]func(os.Signal))
363 s.StartServer(c, s, &s.ServerHandle)
364 c.Assert(s.ServerHandle.ServerEvents, NotNil)
365 c.Assert(s.ServerHandle.ServerAddr, Not(Equals), "")
366@@ -96,7 +97,7 @@
367
368 func (s *AcceptanceSuite) TearDownTest(c *C) {
369 for _, f := range s.KillGroup {
370- f()
371+ f(os.Kill)
372 }
373 }
374
375
376=== modified file 'server/dev/server.go'
377--- server/dev/server.go 2014-03-06 19:21:44 +0000
378+++ server/dev/server.go 2014-03-27 13:38:43 +0000
379@@ -62,7 +62,7 @@
380 }
381 mux := api.MakeHandlersMux(storeForRequest, broker, logger)
382 handler := api.PanicTo500Handler(mux, logger)
383- go server.HTTPServeRunner(handler, &cfg.HTTPServeParsedConfig)()
384+ go server.HTTPServeRunner(nil, handler, &cfg.HTTPServeParsedConfig)()
385 // listen for device connections
386 server.DevicesRunner(nil, func(conn net.Conn) error {
387 track := session.NewTracker(logger)
388
389=== modified file 'server/runner_http.go'
390--- server/runner_http.go 2014-02-10 23:19:08 +0000
391+++ server/runner_http.go 2014-03-27 13:38:43 +0000
392@@ -31,10 +31,14 @@
393 }
394
395 // HTTPServeRunner returns a function to serve HTTP requests.
396-func HTTPServeRunner(h http.Handler, parsedCfg *HTTPServeParsedConfig) func() {
397- httpLst, err := net.Listen("tcp", parsedCfg.ParsedHTTPAddr.HostPort())
398- if err != nil {
399- BootLogFatalf("start http listening: %v", err)
400+// If httpLst is not nil it will be used as the underlying listener.
401+func HTTPServeRunner(httpLst net.Listener, h http.Handler, parsedCfg *HTTPServeParsedConfig) func() {
402+ if httpLst == nil {
403+ var err error
404+ httpLst, err = net.Listen("tcp", parsedCfg.ParsedHTTPAddr.HostPort())
405+ if err != nil {
406+ BootLogFatalf("start http listening: %v", err)
407+ }
408 }
409 BootLogListener("http", httpLst)
410 srv := &http.Server{
411
412=== modified file 'server/runner_test.go'
413--- server/runner_test.go 2014-03-06 19:21:44 +0000
414+++ server/runner_test.go 2014-03-27 13:38:43 +0000
415@@ -68,7 +68,7 @@
416 func (s *runnerSuite) TestHTTPServeRunner(c *C) {
417 errCh := make(chan interface{}, 1)
418 h := http.HandlerFunc(testHandle)
419- runner := HTTPServeRunner(h, &testHTTPServeParsedConfig)
420+ runner := HTTPServeRunner(nil, h, &testHTTPServeParsedConfig)
421 c.Assert(s.lst, Not(IsNil))
422 defer s.lst.Close()
423 c.Check(s.kind, Equals, "http")
424@@ -130,3 +130,12 @@
425 c.Check(s.lst.Addr().String(), Equals, lst0.Addr().String())
426 s.lst.Close()
427 }
428+
429+func (s *runnerSuite) TestHTTPServeRunnerAdoptListener(c *C) {
430+ lst0, err := net.Listen("tcp", "127.0.0.1:0")
431+ c.Assert(err, IsNil)
432+ defer lst0.Close()
433+ HTTPServeRunner(lst0, nil, &testHTTPServeParsedConfig)
434+ c.Assert(s.lst, Equals, lst0)
435+ c.Check(s.kind, Equals, "http")
436+}

Subscribers

People subscribed via source and target branches