Merge lp:~chipaca/ubuntu-push/networkmanager into lp:ubuntu-push

Proposed by John Lenton
Status: Merged
Approved by: John Lenton
Approved revision: 15
Merged at revision: 11
Proposed branch: lp:~chipaca/ubuntu-push/networkmanager
Merge into: lp:ubuntu-push
Prerequisite: lp:~chipaca/ubuntu-push/simple-bus-interface
Diff against target: 285 lines (+240/-3)
5 files modified
bus/testing/testing_bus.go (+2/-2)
bus/testing/testing_endpoint.go (+1/-1)
networkmanager/networkmanager.go (+85/-0)
networkmanager/networkmanager_test.go (+100/-0)
networkmanager/state.go (+52/-0)
To merge this branch: bzr merge lp:~chipaca/ubuntu-push/networkmanager
Reviewer Review Type Date Requested Status
Samuele Pedroni Approve
Review via email: mp+202242@code.launchpad.net

Commit message

A simplified, testable, Network Manager wrapper

Description of the change

A very small, partial, wrapper around network manager.

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

Merged simple-bus-interface into networkmanager.

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

+ return NetworkManager{conn, log}

the struct is big enough that that should return a pointer and the methods be on pointers

218 +func (nm State) String() string {

nm should be state there

the const group ins state, NetworkManager and New need docs

according to coverage this is not hit by tests:

67 + func() { close(ch) })

13. By John Lenton

Merged simple-bus-interface into networkmanager.

14. By John Lenton

addressed issues raised by pedronis during peer review

15. By John Lenton

Merged simple-bus-interface into networkmanager.

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/testing/testing_bus.go'
2--- bus/testing/testing_bus.go 2014-01-20 13:45:52 +0000
3+++ bus/testing/testing_bus.go 2014-01-20 13:45:52 +0000
4@@ -33,13 +33,13 @@
5
6 type testingBus struct {
7 TestCond condition.Interface
8- TestEndp *testingEndpoint
9+ TestEndp bus.Endpoint
10 }
11
12 // Build a bus.Bus that takes a condition to determine whether it should work,
13 // as well as a condition and series of return values for the testing
14 // bus.Endpoint it builds.
15-func NewTestingBus(clientTC condition.Interface, busTC condition.Interface, retvals ...interface{}) *testingBus {
16+func NewTestingBus(clientTC condition.Interface, busTC condition.Interface, retvals ...interface{}) bus.Bus {
17 return &testingBus{clientTC, NewTestingEndpoint(busTC, retvals...)}
18 }
19
20
21=== modified file 'bus/testing/testing_endpoint.go'
22--- bus/testing/testing_endpoint.go 2014-01-20 13:45:52 +0000
23+++ bus/testing/testing_endpoint.go 2014-01-20 13:45:52 +0000
24@@ -35,7 +35,7 @@
25 //
26 // NOTE: Call() always returns the first return value; Watch() will provide
27 // each of them intern, irrespective of whether Call has been called.
28-func NewTestingEndpoint(cond condition.Interface, retvals ...interface{}) *testingEndpoint {
29+func NewTestingEndpoint(cond condition.Interface, retvals ...interface{}) bus.Endpoint {
30 return &testingEndpoint{cond, retvals}
31 }
32
33
34=== added directory 'networkmanager'
35=== added file 'networkmanager/networkmanager.go'
36--- networkmanager/networkmanager.go 1970-01-01 00:00:00 +0000
37+++ networkmanager/networkmanager.go 2014-01-20 13:45:52 +0000
38@@ -0,0 +1,85 @@
39+/*
40+ Copyright 2013-2014 Canonical Ltd.
41+
42+ This program is free software: you can redistribute it and/or modify it
43+ under the terms of the GNU General Public License version 3, as published
44+ by the Free Software Foundation.
45+
46+ This program is distributed in the hope that it will be useful, but
47+ WITHOUT ANY WARRANTY; without even the implied warranties of
48+ MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
49+ PURPOSE. See the GNU General Public License for more details.
50+
51+ You should have received a copy of the GNU General Public License along
52+ with this program. If not, see <http://www.gnu.org/licenses/>.
53+*/
54+
55+// Package networkmanager wraps a couple of NetworkManager's DBus API points:
56+// the org.freedesktop.NetworkManager.state call, and listening for the
57+// StateChange signal.
58+package networkmanager
59+
60+import (
61+ "launchpad.net/ubuntu-push/bus"
62+ "launchpad.net/ubuntu-push/logger"
63+)
64+
65+// NetworkManager lives on a well-knwon bus.Address
66+var BusAddress bus.Address = bus.Address{
67+ Interface: "org.freedesktop.NetworkManager",
68+ Path: "/org/freedesktop/NetworkManager",
69+ Name: "org.freedesktop.NetworkManager",
70+}
71+
72+/*****************************************************************
73+ * NetworkManager (and its implementation)
74+ */
75+
76+type NetworkManager interface {
77+ // GetState fetches and returns NetworkManager's current state
78+ GetState() State
79+ // WatchState listens for changes to NetworkManager's state, and sends
80+ // them out over the channel returned.
81+ WatchState() (<-chan State, error)
82+}
83+
84+type networkManager struct {
85+ bus bus.Endpoint
86+ log logger.Logger
87+}
88+
89+// New returns a new NetworkManager that'll use the provided bus.Endpoint
90+func New(endp bus.Endpoint, log logger.Logger) NetworkManager {
91+ return &networkManager{endp, log}
92+}
93+
94+var _ NetworkManager = &networkManager{}
95+
96+/*
97+ public methods
98+*/
99+
100+func (nm *networkManager) GetState() State {
101+ s, err := nm.bus.Call("state")
102+
103+ if err != nil {
104+ nm.log.Errorf("Failed gettting current state: %s", err)
105+ nm.log.Debugf("Defaulting state to Unknown")
106+ return Unknown
107+ }
108+
109+ return State(s.(uint32))
110+}
111+
112+func (nm *networkManager) WatchState() (<-chan State, error) {
113+ ch := make(chan State)
114+ err := nm.bus.WatchSignal("StateChanged",
115+ func(n interface{}) { ch <- State(n.(uint32)) },
116+ func() { close(ch) })
117+ if err != nil {
118+ nm.log.Debugf("Failed to set up the watch: %s", err)
119+ return nil, err
120+ }
121+
122+ return ch, nil
123+}
124
125=== added file 'networkmanager/networkmanager_test.go'
126--- networkmanager/networkmanager_test.go 1970-01-01 00:00:00 +0000
127+++ networkmanager/networkmanager_test.go 2014-01-20 13:45:52 +0000
128@@ -0,0 +1,100 @@
129+/*
130+ Copyright 2013-2014 Canonical Ltd.
131+
132+ This program is free software: you can redistribute it and/or modify it
133+ under the terms of the GNU General Public License version 3, as published
134+ by the Free Software Foundation.
135+
136+ This program is distributed in the hope that it will be useful, but
137+ WITHOUT ANY WARRANTY; without even the implied warranties of
138+ MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
139+ PURPOSE. See the GNU General Public License for more details.
140+
141+ You should have received a copy of the GNU General Public License along
142+ with this program. If not, see <http://www.gnu.org/licenses/>.
143+*/
144+
145+package networkmanager
146+
147+import (
148+ "io/ioutil"
149+ . "launchpad.net/gocheck"
150+ testingbus "launchpad.net/ubuntu-push/bus/testing"
151+ "launchpad.net/ubuntu-push/logger"
152+ "launchpad.net/ubuntu-push/testing/condition"
153+ "testing"
154+)
155+
156+// hook up gocheck
157+func Test(t *testing.T) { TestingT(t) }
158+
159+type NMSuite struct{}
160+
161+var _ = Suite(&NMSuite{})
162+
163+var nullog = logger.NewSimpleLogger(ioutil.Discard, "error")
164+
165+// TestNames checks that networkmanager.State objects serialize
166+// correctly, to a point.
167+func (s *NMSuite) TestNames(c *C) {
168+ var i State
169+ for i = 0; i < _max_state; i += 10 {
170+ c.Check(names[i], Equals, i.String())
171+ }
172+ i = _max_state
173+ c.Check(i.String(), Equals, "Unknown")
174+}
175+
176+// TestNew doesn't test much at all. If this fails, all is wrong in the world.
177+func (s *NMSuite) TestNew(c *C) {
178+ nm := New(testingbus.NewTestingEndpoint(condition.Work(true)), nullog)
179+ c.Check(nm, NotNil)
180+}
181+
182+// GetState returns the right state when everything works
183+func (s *NMSuite) TestGetState(c *C) {
184+ nm := New(testingbus.NewTestingEndpoint(condition.Work(true), uint32(ConnectedGlobal)), nullog)
185+ state := nm.GetState()
186+ c.Check(state, Equals, ConnectedGlobal)
187+}
188+
189+// GetState returns the right state when dbus fails
190+func (s *NMSuite) TestGetStateFail(c *C) {
191+ nm := New(testingbus.NewTestingEndpoint(condition.Work(false), uint32(ConnectedGlobal)), nullog)
192+ state := nm.GetState()
193+ c.Check(state, Equals, Unknown)
194+}
195+
196+// GetState returns the right state when dbus works but delivers rubbish
197+func (s *NMSuite) TestGetStateRubbish(c *C) {
198+ nm := New(testingbus.NewTestingEndpoint(condition.Work(false), 42), nullog)
199+ state := nm.GetState()
200+ c.Check(state, Equals, Unknown)
201+}
202+
203+// WatchState sends a stream of States over the channel
204+func (s *NMSuite) TestWatchState(c *C) {
205+ tc := testingbus.NewTestingEndpoint(condition.Work(true), uint32(Unknown), uint32(Asleep), uint32(ConnectedGlobal))
206+ nm := New(tc, nullog)
207+ ch, err := nm.WatchState()
208+ c.Check(err, IsNil)
209+ l := []State{<-ch, <-ch, <-ch}
210+ c.Check(l, DeepEquals, []State{Unknown, Asleep, ConnectedGlobal})
211+}
212+
213+// WatchState returns on error if the dbus call fails
214+func (s *NMSuite) TestWatchStateFails(c *C) {
215+ nm := New(testingbus.NewTestingEndpoint(condition.Work(false)), nullog)
216+ _, err := nm.WatchState()
217+ c.Check(err, NotNil)
218+}
219+
220+// WatchState calls close on its channel when the watch bails
221+func (s *NMSuite) TestWatchClosesOnWatchBail(c *C) {
222+ tc := testingbus.NewTestingEndpoint(condition.Work(true))
223+ nm := New(tc, nullog)
224+ ch, err := nm.WatchState()
225+ c.Check(err, IsNil)
226+ _, ok := <-ch
227+ c.Check(ok, Equals, false)
228+}
229
230=== added file 'networkmanager/state.go'
231--- networkmanager/state.go 1970-01-01 00:00:00 +0000
232+++ networkmanager/state.go 2014-01-20 13:45:52 +0000
233@@ -0,0 +1,52 @@
234+/*
235+ Copyright 2013-2014 Canonical Ltd.
236+
237+ This program is free software: you can redistribute it and/or modify it
238+ under the terms of the GNU General Public License version 3, as published
239+ by the Free Software Foundation.
240+
241+ This program is distributed in the hope that it will be useful, but
242+ WITHOUT ANY WARRANTY; without even the implied warranties of
243+ MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
244+ PURPOSE. See the GNU General Public License for more details.
245+
246+ You should have received a copy of the GNU General Public License along
247+ with this program. If not, see <http://www.gnu.org/licenses/>.
248+*/
249+
250+package networkmanager
251+
252+type State uint32
253+
254+// the NetworkManager states, as per
255+// https://wiki.gnome.org/Projects/NetworkManager/DBusInterface/LatestDBusAPI
256+const (
257+ Unknown State = iota * 10
258+ Asleep
259+ Disconnected
260+ Disconnecting
261+ Connecting
262+ ConnectedLocal
263+ ConnectedSite
264+ ConnectedGlobal
265+ _max_state
266+)
267+
268+var names = map[State]string{
269+ Unknown: "Unknown",
270+ Asleep: "Asleep",
271+ Disconnected: "Disconnected",
272+ Disconnecting: "Disconnecting",
273+ Connecting: "Connecting",
274+ ConnectedLocal: "Connected Local",
275+ ConnectedSite: "Connected Site",
276+ ConnectedGlobal: "Connected Global",
277+}
278+
279+// give its state a descriptive stringification
280+func (state State) String() string {
281+ if s, ok := names[state]; ok {
282+ return s
283+ }
284+ return names[Unknown]
285+}

Subscribers

People subscribed via source and target branches