Merge lp:~chipaca/ubuntu-push/url-dispatcher into lp:ubuntu-push

Proposed by John Lenton
Status: Merged
Approved by: John Lenton
Approved revision: 21
Merged at revision: 23
Proposed branch: lp:~chipaca/ubuntu-push/url-dispatcher
Merge into: lp:ubuntu-push
Prerequisite: lp:~chipaca/ubuntu-push/notifications
Diff against target: 334 lines (+165/-41)
8 files modified
bus/endpoint.go (+4/-11)
bus/testing/testing_endpoint.go (+12/-7)
bus/testing/testing_endpoint_test.go (+6/-19)
networkmanager/networkmanager_test.go (+9/-2)
notifications/raw.go (+7/-2)
notifications/raw_test.go (+9/-0)
urldispatcher/urldispatcher.go (+61/-0)
urldispatcher/urldispatcher_test.go (+57/-0)
To merge this branch: bzr merge lp:~chipaca/ubuntu-push/url-dispatcher
Reviewer Review Type Date Requested Status
Samuele Pedroni Approve
Review via email: mp+202774@code.launchpad.net

Commit message

URLDispatcher (and extended endpoint.Call to return []interface{})

Description of the change

URLDispatcher (and extended endpoint.Call to return []interface{})

To post a comment you must log in.
Revision history for this message
Samuele Pedroni (pedronis) wrote :

:)

70 + return nil, errors.New("Wrong number of arguments in reply to GetProperty")

this looks like the old confusing error message

this guy is less covered than it was:

launchpad.net/ubuntu-push/bus/testing/testing_endpoint.go: GetProperty 66.7%

20. By John Lenton

improved testingEndpoint's GetProperty error message

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

Improved the error message (to “Wrong number of values given to testingEndpoint -- GetProperty only returns a single value for now!”).
The coverage is taken to 100% in the “redialer” branch.

21. By John Lenton

improved error message for when Notify gets the wrong message back from the bus

Revision history for this message
Samuele Pedroni (pedronis) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bus/endpoint.go'
2--- bus/endpoint.go 2014-01-22 10:48:52 +0000
3+++ bus/endpoint.go 2014-01-27 10:47:45 +0000
4@@ -31,7 +31,7 @@
5 // bus.Endpoint represents the DBus connection itself.
6 type Endpoint interface {
7 WatchSignal(member string, f func(...interface{}), d func()) error
8- Call(member string, args ...interface{}) (interface{}, error)
9+ Call(member string, args ...interface{}) ([]interface{}, error)
10 GetProperty(property string) (interface{}, error)
11 Close()
12 }
13@@ -81,20 +81,13 @@
14 // Call() invokes the provided member method (on the name, path and interface
15 // provided when creating the endpoint). The return value is unpacked before
16 // being returned.
17-func (endp *endpoint) Call(member string, args ...interface{}) (interface{}, error) {
18+func (endp *endpoint) Call(member string, args ...interface{}) ([]interface{}, error) {
19 msg, err := endp.proxy.Call(endp.iface, member, args...)
20 if err != nil {
21- return 0, err
22+ return nil, err
23 }
24 rvs := endp.unpackOneMsg(msg, member)
25- switch len(rvs) {
26- default:
27- return 0, fmt.Errorf("Too many values in %s response: %d", member, len(rvs))
28- case 0:
29- return 0, fmt.Errorf("Not enough values in %s response: %d", member, len(rvs))
30- case 1:
31- return rvs[0], nil
32- }
33+ return rvs, nil
34 }
35
36 // GetProperty uses the org.freedesktop.DBus.Properties interface's Get method
37
38=== modified file 'bus/testing/testing_endpoint.go'
39--- bus/testing/testing_endpoint.go 2014-01-22 10:48:52 +0000
40+++ bus/testing/testing_endpoint.go 2014-01-27 10:47:45 +0000
41@@ -66,23 +66,28 @@
42
43 // See Endpoint's Call. This Call will check its condition to decide whether
44 // to return an error, or the first of its return values
45-func (tc *testingEndpoint) Call(member string, args ...interface{}) (interface{}, error) {
46+func (tc *testingEndpoint) Call(member string, args ...interface{}) ([]interface{}, error) {
47 if tc.cond.OK() {
48 if len(tc.retvals) == 0 {
49 panic("No return values provided!")
50 }
51- if len(tc.retvals[0]) != 1 {
52- panic("Wrong number of values provided -- Call only returns a single value for now!")
53- }
54- return tc.retvals[0][0], nil
55+ return tc.retvals[0], nil
56 } else {
57- return 0, errors.New("no way")
58+ return nil, errors.New("no way")
59 }
60 }
61
62 // See Endpoint's GetProperty. This one is just another name for Call.
63 func (tc *testingEndpoint) GetProperty(property string) (interface{}, error) {
64- return tc.Call(property)
65+ rvs, err := tc.Call(property)
66+ if err != nil {
67+ return nil, err
68+ }
69+ if len(rvs) != 1 {
70+ return nil, errors.New("Wrong number of values given to testingEndpoint" +
71+ " -- GetProperty only returns a single value for now!")
72+ }
73+ return rvs[0], err
74 }
75
76 // see Endpoint's Close. This one does nothing.
77
78=== modified file 'bus/testing/testing_endpoint_test.go'
79--- bus/testing/testing_endpoint_test.go 2014-01-21 13:38:03 +0000
80+++ bus/testing/testing_endpoint_test.go 2014-01-27 10:47:45 +0000
81@@ -34,18 +34,20 @@
82 func (s *TestingEndpointSuite) TestCallReturnsFirstRetval(c *C) {
83 var m, n uint32 = 42, 17
84 endp := NewTestingEndpoint(condition.Work(true), m, n)
85- v, e := endp.Call("what")
86+ vs, e := endp.Call("what")
87 c.Check(e, IsNil)
88- c.Check(v, Equals, m)
89+ c.Check(vs, HasLen, 1)
90+ c.Check(vs[0], Equals, m)
91 }
92
93 // Test the same Call() but with multi-valued endpoint
94 func (s *TestingEndpointSuite) TestMultiValuedCall(c *C) {
95 var m, n uint32 = 42, 17
96 endp := NewMultiValuedTestingEndpoint(condition.Work(true), []interface{}{m}, []interface{}{n})
97- v, e := endp.Call("what")
98+ vs, e := endp.Call("what")
99 c.Check(e, IsNil)
100- c.Check(v, Equals, m)
101+ c.Check(vs, HasLen, 1)
102+ c.Check(vs[0], Equals, m)
103 }
104
105 // Test that Call() with a negative condition returns an error.
106@@ -62,21 +64,6 @@
107 c.Check(func() { endp.Call("") }, PanicMatches, "No return values provided.*")
108 }
109
110-// Test that Call() with a positive condition and an empty return value panics
111-// with a helpful message.
112-func (s *TestingEndpointSuite) TestCallPanicsWithNiceMessage2(c *C) {
113- endp := NewMultiValuedTestingEndpoint(condition.Work(true), []interface{}{})
114- c.Check(func() { endp.Call("") }, PanicMatches, "Wrong number of values provided.*")
115-}
116-
117-// Test Call() with positive condition and the wrong number of arguments also
118-// fails with a helpful message
119-func (s *TestingEndpointSuite) TestMultiValuedCallPanicsWhenWrongNumberOfValues(c *C) {
120- var m, n uint32 = 42, 17
121- endp := NewMultiValuedTestingEndpoint(condition.Work(true), []interface{}{m, n})
122- c.Check(func() { endp.Call("") }, PanicMatches, "Wrong number of values provided.*")
123-}
124-
125 // Test that WatchSignal() with a positive condition sends the provided return
126 // values over the channel.
127 func (s *TestingEndpointSuite) TestWatch(c *C) {
128
129=== modified file 'networkmanager/networkmanager_test.go'
130--- networkmanager/networkmanager_test.go 2014-01-20 13:44:58 +0000
131+++ networkmanager/networkmanager_test.go 2014-01-27 10:47:45 +0000
132@@ -65,13 +65,20 @@
133 c.Check(state, Equals, Unknown)
134 }
135
136-// GetState returns the right state when dbus works but delivers rubbish
137-func (s *NMSuite) TestGetStateRubbish(c *C) {
138+// GetState returns the right state when dbus works but delivers rubbish values
139+func (s *NMSuite) TestGetStateRubbishValues(c *C) {
140 nm := New(testingbus.NewTestingEndpoint(condition.Work(false), 42), nullog)
141 state := nm.GetState()
142 c.Check(state, Equals, Unknown)
143 }
144
145+// GetState returns the right state when dbus works but delivers a rubbish structure
146+func (s *NMSuite) TestGetStateRubbishStructure(c *C) {
147+ nm := New(testingbus.NewMultiValuedTestingEndpoint(condition.Work(true), []interface{}{}), nullog)
148+ state := nm.GetState()
149+ c.Check(state, Equals, Unknown)
150+}
151+
152 // WatchState sends a stream of States over the channel
153 func (s *NMSuite) TestWatchState(c *C) {
154 tc := testingbus.NewTestingEndpoint(condition.Work(true), uint32(Unknown), uint32(Asleep), uint32(ConnectedGlobal))
155
156=== modified file 'notifications/raw.go'
157--- notifications/raw.go 2014-01-22 12:15:12 +0000
158+++ notifications/raw.go 2014-01-27 10:47:45 +0000
159@@ -22,6 +22,7 @@
160 // this is the lower-level api
161
162 import (
163+ "fmt"
164 "launchpad.net/go-dbus/v1"
165 "launchpad.net/ubuntu-push/bus"
166 "launchpad.net/ubuntu-push/logger"
167@@ -73,12 +74,16 @@
168 timeout int32) (uint32, error) {
169 // that's a long argument list! Take a breather.
170 //
171- rv, err := raw.bus.Call("Notify", app_name, reuse_id, icon,
172+ rvs, err := raw.bus.Call("Notify", app_name, reuse_id, icon,
173 summary, body, actions, hints, timeout)
174 if err != nil {
175 return 0, err
176 }
177- return rv.(uint32), nil
178+ if len(rvs) != 1 {
179+ return 0, fmt.Errorf("Wrong number of values in Notify response: %d",
180+ len(rvs))
181+ }
182+ return rvs[0].(uint32), nil
183 }
184
185 // WatchActions listens for ActionInvoked signals from the notification daemon
186
187=== modified file 'notifications/raw_test.go'
188--- notifications/raw_test.go 2014-01-21 14:58:28 +0000
189+++ notifications/raw_test.go 2014-01-27 10:47:45 +0000
190@@ -65,6 +65,15 @@
191 c.Check(err, NotNil)
192 }
193
194+func (s *RawSuite) TestNotifiesFailsWeirdly(c *C) {
195+ bus := testibus.NewMultiValuedTestingBus(condition.Work(true), condition.Work(true),
196+ []interface{}{1, 2})
197+ raw, err := Raw(bus, nullog)
198+ c.Assert(err, IsNil)
199+ _, err = raw.Notify("", 0, "", "", "", nil, nil, 0)
200+ c.Check(err, NotNil)
201+}
202+
203 func (s *RawSuite) TestWatchActions(c *C) {
204 bus := testibus.NewMultiValuedTestingBus(condition.Work(true), condition.Work(true),
205 []interface{}{uint32(1), "hello"})
206
207=== added directory 'urldispatcher'
208=== added file 'urldispatcher/urldispatcher.go'
209--- urldispatcher/urldispatcher.go 1970-01-01 00:00:00 +0000
210+++ urldispatcher/urldispatcher.go 2014-01-27 10:47:45 +0000
211@@ -0,0 +1,61 @@
212+/*
213+ Copyright 2013-2014 Canonical Ltd.
214+
215+ This program is free software: you can redistribute it and/or modify it
216+ under the terms of the GNU General Public License version 3, as published
217+ by the Free Software Foundation.
218+
219+ This program is distributed in the hope that it will be useful, but
220+ WITHOUT ANY WARRANTY; without even the implied warranties of
221+ MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
222+ PURPOSE. See the GNU General Public License for more details.
223+
224+ You should have received a copy of the GNU General Public License along
225+ with this program. If not, see <http://www.gnu.org/licenses/>.
226+*/
227+
228+// Package urldispatcher wraps the url dispatcher's dbus api point
229+package urldispatcher
230+
231+import (
232+ "launchpad.net/ubuntu-push/bus"
233+ "launchpad.net/ubuntu-push/logger"
234+)
235+
236+// UrlDispatcher lives on a well-known bus.Address
237+var BusAddress bus.Address = bus.Address{
238+ Interface: "com.canonical.URLDispatcher",
239+ Path: "/com/canonical/URLDispatcher",
240+ Name: "com.canonical.URLDispatcher",
241+}
242+
243+// A URLDispatcher is a simple beast, with a single method that does what it
244+// says on the box.
245+type URLDispatcher interface {
246+ DispatchURL(string) error
247+}
248+
249+type urlDispatcher struct {
250+ endp bus.Endpoint
251+ log logger.Logger
252+}
253+
254+// New builds a new URL dispatcher by connecting to the provided bus.
255+func New(bus bus.Bus, log logger.Logger) (URLDispatcher, error) {
256+ endp, err := bus.Connect(BusAddress, log)
257+ if err != nil {
258+ return nil, err
259+ }
260+ return &urlDispatcher{endp, log}, nil
261+}
262+
263+var _ URLDispatcher = &urlDispatcher{} // ensures it conforms
264+
265+func (ud *urlDispatcher) DispatchURL(url string) error {
266+ ud.log.Debugf("Dispatching %s", url)
267+ _, err := ud.endp.Call("DispatchURL", url)
268+ if err != nil {
269+ ud.log.Errorf("Dispatch to %s failed with %s", url, err)
270+ }
271+ return err
272+}
273
274=== added file 'urldispatcher/urldispatcher_test.go'
275--- urldispatcher/urldispatcher_test.go 1970-01-01 00:00:00 +0000
276+++ urldispatcher/urldispatcher_test.go 2014-01-27 10:47:45 +0000
277@@ -0,0 +1,57 @@
278+/*
279+ Copyright 2013-2014 Canonical Ltd.
280+
281+ This program is free software: you can redistribute it and/or modify it
282+ under the terms of the GNU General Public License version 3, as published
283+ by the Free Software Foundation.
284+
285+ This program is distributed in the hope that it will be useful, but
286+ WITHOUT ANY WARRANTY; without even the implied warranties of
287+ MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
288+ PURPOSE. See the GNU General Public License for more details.
289+
290+ You should have received a copy of the GNU General Public License along
291+ with this program. If not, see <http://www.gnu.org/licenses/>.
292+*/
293+
294+package urldispatcher
295+
296+import (
297+ "io/ioutil"
298+ . "launchpad.net/gocheck"
299+ testibus "launchpad.net/ubuntu-push/bus/testing"
300+ "launchpad.net/ubuntu-push/logger"
301+ "launchpad.net/ubuntu-push/testing/condition"
302+ "testing"
303+)
304+
305+// hook up gocheck
306+func TestUrldispatcher(t *testing.T) { TestingT(t) }
307+
308+type UDSuite struct{}
309+
310+var _ = Suite(&UDSuite{})
311+
312+var nullog = logger.NewSimpleLogger(ioutil.Discard, "error")
313+
314+func (s *UDSuite) TestWorks(c *C) {
315+ tb := testibus.NewMultiValuedTestingBus(condition.Work(true), condition.Work(true), []interface{}{})
316+ ud, err := New(tb, nullog)
317+ c.Assert(err, IsNil)
318+ err = ud.DispatchURL("this")
319+ c.Check(err, IsNil)
320+}
321+
322+func (s *UDSuite) TestFailsIfConnectFails(c *C) {
323+ tb := testibus.NewTestingBus(condition.Work(false), condition.Work(true))
324+ _, err := New(tb, nullog)
325+ c.Check(err, NotNil)
326+}
327+
328+func (s *UDSuite) TestFailsIfCallFails(c *C) {
329+ tb := testibus.NewTestingBus(condition.Work(true), condition.Work(false))
330+ ud, err := New(tb, nullog)
331+ c.Assert(err, IsNil)
332+ err = ud.DispatchURL("this")
333+ c.Check(err, NotNil)
334+}

Subscribers

People subscribed via source and target branches