Merge lp:~pete-woods/indicator-network/try-and-make-unit-tests-more-reliable into lp:indicator-network

Proposed by Pete Woods
Status: Merged
Approved by: Antti Kaijanmäki
Approved revision: 633
Merged at revision: 630
Proposed branch: lp:~pete-woods/indicator-network/try-and-make-unit-tests-more-reliable
Merge into: lp:indicator-network
Diff against target: 1038 lines (+914/-15)
5 files modified
CMakeLists.txt (+1/-0)
tests/CMakeLists.txt (+4/-0)
tests/data/networkmanager.py (+878/-0)
tests/integration/indicator-network-test-base.cpp (+2/-1)
tests/unit/secret-agent/test-secret-agent.cpp (+29/-14)
To merge this branch: bzr merge lp:~pete-woods/indicator-network/try-and-make-unit-tests-more-reliable
Reviewer Review Type Date Requested Status
Antti Kaijanmäki (community) Approve
Review via email: mp+307186@code.launchpad.net

Commit message

Try and make the agent unit tests more reliable

Description of the change

Try and make the agent unit tests more reliable

To post a comment you must log in.
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-08-26 09:18:27 +0000
3+++ CMakeLists.txt 2016-09-29 18:11:03 +0000
4@@ -11,6 +11,7 @@
5
6 option(trace_messages "Print debug trace messages." ${TRACE_DEFAULT})
7 option(REMOTE_BUILD "Remote build (skip docs, translations, tests)." FALSE)
8+option(ENABLE_TESTS "Enable tests" TRUE)
9
10 if(${trace_messages})
11 add_definitions(-DINDICATOR_NETWORK_TRACE_MESSAGES)
12
13=== modified file 'tests/CMakeLists.txt'
14--- tests/CMakeLists.txt 2016-08-26 09:18:27 +0000
15+++ tests/CMakeLists.txt 2016-09-29 18:11:03 +0000
16@@ -16,6 +16,10 @@
17 ${TEST_DEPENDENCIES_INCLUDE_DIRS}
18 )
19
20+add_definitions(
21+-DNETWORK_MANAGER_TEMPLATE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/data/networkmanager.py"
22+)
23+
24 add_subdirectory(integration)
25 add_subdirectory(unit)
26 add_subdirectory(utils)
27
28=== added directory 'tests/data'
29=== added file 'tests/data/networkmanager.py'
30--- tests/data/networkmanager.py 1970-01-01 00:00:00 +0000
31+++ tests/data/networkmanager.py 2016-09-29 18:11:03 +0000
32@@ -0,0 +1,878 @@
33+'''NetworkManager mock template
34+
35+This creates the expected methods and properties of the main
36+org.freedesktop.NetworkManager object, but no devices. You can specify any
37+property such as 'NetworkingEnabled', or 'WirelessEnabled' etc. in
38+"parameters".
39+'''
40+
41+# This program is free software; you can redistribute it and/or modify it under
42+# the terms of the GNU Lesser General Public License as published by the Free
43+# Software Foundation; either version 3 of the License, or (at your option) any
44+# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text
45+# of the license.
46+
47+__author__ = 'Iftikhar Ahmad'
48+__email__ = 'iftikhar.ahmad@canonical.com'
49+__copyright__ = '(c) 2012 Canonical Ltd.'
50+__license__ = 'LGPL 3+'
51+
52+import dbus
53+import uuid
54+import binascii
55+
56+from dbusmock import MOCK_IFACE
57+import dbusmock
58+
59+
60+BUS_NAME = 'org.freedesktop.NetworkManager'
61+MAIN_OBJ = '/org/freedesktop/NetworkManager'
62+MAIN_IFACE = 'org.freedesktop.NetworkManager'
63+SETTINGS_OBJ = '/org/freedesktop/NetworkManager/Settings'
64+SETTINGS_IFACE = 'org.freedesktop.NetworkManager.Settings'
65+DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device'
66+WIRELESS_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device.Wireless'
67+ACCESS_POINT_IFACE = 'org.freedesktop.NetworkManager.AccessPoint'
68+CSETTINGS_IFACE = 'org.freedesktop.NetworkManager.Settings.Connection'
69+ACTIVE_CONNECTION_IFACE = 'org.freedesktop.NetworkManager.Connection.Active'
70+AGENT_MANAGER_OBJ = '/org/freedesktop/NetworkManager/AgentManager'
71+AGENT_MANAGER_IFACE = 'org.freedesktop.NetworkManager.AgentManager'
72+SYSTEM_BUS = True
73+
74+
75+class NMState:
76+ '''Global state
77+
78+ As per https://developer.gnome.org/NetworkManager/unstable/spec.html#type-NM_STATE
79+ '''
80+ NM_STATE_UNKNOWN = 0
81+ NM_STATE_ASLEEP = 10
82+ NM_STATE_DISCONNECTED = 20
83+ NM_STATE_DISCONNECTING = 30
84+ NM_STATE_CONNECTING = 40
85+ NM_STATE_CONNECTED_LOCAL = 50
86+ NM_STATE_CONNECTED_SITE = 60
87+ NM_STATE_CONNECTED_GLOBAL = 70
88+
89+
90+class NMConnectivityState:
91+ '''Connectvity state
92+
93+ As per https://developer.gnome.org/NetworkManager/unstable/spec.html#type-NM_CONNECTIVITY
94+ '''
95+ NM_CONNECTIVITY_UNKNOWN = 0
96+ NM_CONNECTIVITY_NONE = 1
97+ NM_CONNECTIVITY_PORTAL = 2
98+ NM_CONNECTIVITY_LIMITED = 3
99+ NM_CONNECTIVITY_FULL = 4
100+
101+
102+class NMActiveConnectionState:
103+ '''Active connection state
104+
105+ As per https://developer.gnome.org/NetworkManager/unstable/spec.html#type-NM_ACTIVE_CONNECTION_STATE
106+ '''
107+ NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0
108+ NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1
109+ NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2
110+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATING = 3
111+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATED = 4
112+
113+
114+class InfrastructureMode:
115+ '''Infrastructure mode
116+
117+ As per https://developer.gnome.org/NetworkManager/unstable/spec.html#type-NM_802_11_MODE
118+ '''
119+ NM_802_11_MODE_UNKNOWN = 0
120+ NM_802_11_MODE_ADHOC = 1
121+ NM_802_11_MODE_INFRA = 2
122+ NM_802_11_MODE_AP = 3
123+
124+ NAME_MAP = {
125+ NM_802_11_MODE_UNKNOWN: 'unknown',
126+ NM_802_11_MODE_ADHOC: 'adhoc',
127+ NM_802_11_MODE_INFRA: 'infrastructure',
128+ NM_802_11_MODE_AP: 'access-point',
129+ }
130+
131+
132+class DeviceState:
133+ '''Device states
134+
135+ As per https://developer.gnome.org/NetworkManager/unstable/spec.html#type-NM_DEVICE_STATE
136+ '''
137+ UNKNOWN = 0
138+ UNMANAGED = 10
139+ UNAVAILABLE = 20
140+ DISCONNECTED = 30
141+ PREPARE = 40
142+ CONFIG = 50
143+ NEED_AUTH = 60
144+ IP_CONFIG = 70
145+ IP_CHECK = 80
146+ SECONDARIES = 90
147+ ACTIVATED = 100
148+ DEACTIVATING = 110
149+ FAILED = 120
150+
151+
152+class NM80211ApSecurityFlags:
153+ '''Security flags
154+
155+ As per https://developer.gnome.org/NetworkManager/unstable/spec.html#type-NM_802_11_AP_SEC
156+ '''
157+ NM_802_11_AP_SEC_NONE = 0x00000000
158+ NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001
159+ NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002
160+ NM_802_11_AP_SEC_PAIR_TKIP = 0x00000004
161+ NM_802_11_AP_SEC_PAIR_CCMP = 0x00000008
162+ NM_802_11_AP_SEC_GROUP_WEP40 = 0x00000010
163+ NM_802_11_AP_SEC_GROUP_WEP104 = 0x00000020
164+ NM_802_11_AP_SEC_GROUP_TKIP = 0x00000040
165+ NM_802_11_AP_SEC_GROUP_CCMP = 0x00000080
166+ NM_802_11_AP_SEC_KEY_MGMT_PSK = 0x00000100
167+ NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x00000200
168+
169+ NAME_MAP = {
170+ NM_802_11_AP_SEC_KEY_MGMT_PSK: {
171+ 'key-mgmt': 'wpa-psk',
172+ 'auth-alg': 'open'
173+ },
174+ }
175+
176+
177+class NM80211ApFlags:
178+ '''Device flags
179+
180+ As per https://developer.gnome.org/NetworkManager/unstable/spec.html#type-NM_802_11_AP_FLAGS
181+ '''
182+ NM_802_11_AP_FLAGS_NONE = 0x00000000
183+ NM_802_11_AP_FLAGS_PRIVACY = 0x00000001
184+
185+
186+def activate_connection(self, conn, dev, ap):
187+ # find a new name
188+ count = 0
189+ active_connections = dbusmock.get_object(MAIN_OBJ).Get(MAIN_IFACE, 'ActiveConnections')
190+ while True:
191+ path = dbus.ObjectPath('/org/freedesktop/NetworkManager/ActiveConnection/' + str(count))
192+ if path not in active_connections:
193+ break
194+ count += 1
195+
196+ state = dbus.UInt32(NMActiveConnectionState.NM_ACTIVE_CONNECTION_STATE_ACTIVATED)
197+ devices = []
198+ if str(dev) != '/':
199+ devices.append(dev)
200+ active_conn = dbus.ObjectPath(AddActiveConnection(self, devices, conn, ap, str(count), state))
201+
202+ return active_conn
203+
204+
205+def deactivate_connection(self, active_conn_path):
206+ NM = dbusmock.get_object(MAIN_OBJ)
207+
208+ for dev_path in NM.GetDevices():
209+ RemoveActiveConnection(self, dev_path, active_conn_path)
210+
211+
212+def add_and_activate_connection(self, conn_conf, dev, ap):
213+ name = ap.rsplit('/', 1)[1]
214+ RemoveWifiConnection(self, dev, '/org/freedesktop/NetworkManager/Settings/' + name)
215+
216+ raw_ssid = ''.join([chr(byte) for byte in conn_conf["802-11-wireless"]["ssid"]])
217+ wifi_conn = dbus.ObjectPath(AddWiFiConnection(self, dev, name, raw_ssid, ""))
218+
219+ active_conn = activate_connection(self, wifi_conn, dev, ap)
220+
221+ return (wifi_conn, active_conn)
222+
223+
224+def load(mock, parameters):
225+ mock.activate_connection = activate_connection
226+ mock.deactivate_connection = deactivate_connection
227+ mock.add_and_activate_connection = add_and_activate_connection
228+ mock.AddMethods(MAIN_IFACE, [
229+ ('GetDevices', '', 'ao',
230+ 'ret = [k for k in objects.keys() if "/Devices" in k]'),
231+ ('GetPermissions', '', 'a{ss}', 'ret = {}'),
232+ ('state', '', 'u', "ret = self.Get('%s', 'State')" % MAIN_IFACE),
233+ ('CheckConnectivity', '', 'u', "ret = self.Get('%s', 'Connectivity')" % MAIN_IFACE),
234+ ('ActivateConnection', 'ooo', 'o', "ret = self.activate_connection(self, args[0], args[1], args[2])"),
235+ ('DeactivateConnection', 'o', '', "self.deactivate_connection(self, args[0])"),
236+ ('AddAndActivateConnection', 'a{sa{sv}}oo', 'oo', "ret = self.add_and_activate_connection("
237+ "self, args[0], args[1], args[2])"),
238+ ])
239+
240+ mock.AddProperties('',
241+ {
242+ 'ActiveConnections': dbus.Array([], signature='o'),
243+ 'Devices': dbus.Array([], signature='o'),
244+ 'NetworkingEnabled': parameters.get('NetworkingEnabled', True),
245+ 'Connectivity': parameters.get('Connectivity', dbus.UInt32(NMConnectivityState.NM_CONNECTIVITY_FULL)),
246+ 'State': parameters.get('State', dbus.UInt32(NMState.NM_STATE_CONNECTED_GLOBAL)),
247+ 'Startup': False,
248+ 'Version': parameters.get('Version', '0.9.6.0'),
249+ 'WimaxEnabled': parameters.get('WimaxEnabled', True),
250+ 'WimaxHardwareEnabled': parameters.get('WimaxHardwareEnabled', True),
251+ 'WirelessEnabled': parameters.get('WirelessEnabled', True),
252+ 'WirelessHardwareEnabled': parameters.get('WirelessHardwareEnabled', True),
253+ 'WwanEnabled': parameters.get('WwanEnabled', False),
254+ 'WwanHardwareEnabled': parameters.get('WwanHardwareEnabled', True)
255+ })
256+
257+ settings_props = {'Hostname': 'hostname',
258+ 'CanModify': True,
259+ 'Connections': dbus.Array([], signature='o')}
260+ settings_methods = [('ListConnections', '', 'ao', "ret = self.Get('%s', 'Connections')" % SETTINGS_IFACE),
261+ ('GetConnectionByUuid', 's', 'o', ''),
262+ ('AddConnection', 'a{sa{sv}}', 'o', 'ret = self.SettingsAddConnection(args[0])'),
263+ ('SaveHostname', 's', '', '')]
264+ mock.AddObject(SETTINGS_OBJ,
265+ SETTINGS_IFACE,
266+ settings_props,
267+ settings_methods)
268+
269+ agent_manager_methods = [('Register', 's', '', ''),
270+ ('RegisterWithCapabilities', 'su', '', ''),
271+ ('Unregister', '', '', '')]
272+ mock.AddObject(AGENT_MANAGER_OBJ,
273+ AGENT_MANAGER_IFACE,
274+ {},
275+ agent_manager_methods)
276+
277+
278+@dbus.service.method(MOCK_IFACE,
279+ in_signature='sssv', out_signature='')
280+def SetProperty(self, path, iface, name, value):
281+ obj = dbusmock.get_object(path)
282+ obj.Set(iface, name, value)
283+ obj.EmitSignal(iface, 'PropertiesChanged', 'a{sv}', [{name: value}])
284+
285+
286+@dbus.service.method(MOCK_IFACE,
287+ in_signature='u', out_signature='')
288+def SetGlobalConnectionState(self, state):
289+ self.SetProperty(MAIN_OBJ, MAIN_IFACE, 'State', dbus.UInt32(state, variant_level=1))
290+ self.EmitSignal(MAIN_IFACE, 'StateChanged', 'u', [state])
291+
292+
293+@dbus.service.method(MOCK_IFACE,
294+ in_signature='u', out_signature='')
295+def SetConnectivity(self, connectivity):
296+ self.SetProperty(MAIN_OBJ, MAIN_IFACE, 'Connectivity', dbus.UInt32(connectivity, variant_level=1))
297+
298+
299+@dbus.service.method(MOCK_IFACE,
300+ in_signature='ss', out_signature='')
301+def SetDeviceActive(self, device_path, active_connection_path):
302+ dev_obj = dbusmock.get_object(device_path)
303+ dev_obj.Set(DEVICE_IFACE, 'ActiveConnection', dbus.ObjectPath(active_connection_path))
304+ old_state = dev_obj.Get(DEVICE_IFACE, 'State')
305+ dev_obj.Set(DEVICE_IFACE, 'State', dbus.UInt32(DeviceState.ACTIVATED))
306+
307+ dev_obj.EmitSignal(DEVICE_IFACE, 'StateChanged', 'uuu', [dbus.UInt32(DeviceState.ACTIVATED), old_state, dbus.UInt32(1)])
308+
309+
310+@dbus.service.method(MOCK_IFACE,
311+ in_signature='s', out_signature='')
312+def SetDeviceDisconnected(self, device_path):
313+ dev_obj = dbusmock.get_object(device_path)
314+ dev_obj.Set(DEVICE_IFACE, 'ActiveConnection', dbus.ObjectPath('/'))
315+ old_state = dev_obj.Get(DEVICE_IFACE, 'State')
316+ dev_obj.Set(DEVICE_IFACE, 'State', dbus.UInt32(DeviceState.DISCONNECTED))
317+
318+ dev_obj.EmitSignal(DEVICE_IFACE, 'StateChanged', 'uuu', [dbus.UInt32(DeviceState.DISCONNECTED), old_state, dbus.UInt32(1)])
319+
320+
321+@dbus.service.method(MOCK_IFACE,
322+ in_signature='ssi', out_signature='s')
323+def AddEthernetDevice(self, device_name, iface_name, state):
324+ '''Add an ethernet device.
325+
326+ You have to specify device_name, device interface name (e. g. eth0), and
327+ state. You can use the predefined DeviceState values (e. g.
328+ DeviceState.ACTIVATED) or supply a numeric value. For valid state values
329+ please visit
330+ http://projects.gnome.org/NetworkManager/developers/api/09/spec.html#type-NM_DEVICE_STATE
331+
332+ Please note that this does not set any global properties.
333+
334+ Returns the new object path.
335+ '''
336+ path = '/org/freedesktop/NetworkManager/Devices/' + device_name
337+ wired_props = {'Carrier': False,
338+ 'HwAddress': dbus.String('78:DD:08:D2:3D:43'),
339+ 'PermHwAddress': dbus.String('78:DD:08:D2:3D:43'),
340+ 'Speed': dbus.UInt32(0)}
341+ self.AddObject(path,
342+ 'org.freedesktop.NetworkManager.Device.Wired',
343+ wired_props,
344+ [])
345+
346+ props = {'DeviceType': dbus.UInt32(1),
347+ 'State': dbus.UInt32(state),
348+ 'Interface': iface_name,
349+ 'ActiveConnection': dbus.ObjectPath('/'),
350+ 'AvailableConnections': dbus.Array([], signature='o'),
351+ 'AutoConnect': False,
352+ 'Managed': True,
353+ 'Driver': 'dbusmock',
354+ 'IpInterface': ''}
355+
356+ obj = dbusmock.get_object(path)
357+ obj.AddProperties(DEVICE_IFACE, props)
358+
359+ devices = self.Get(MAIN_IFACE, 'Devices')
360+ devices.append(path)
361+ self.Set(MAIN_IFACE, 'Devices', devices)
362+
363+ self.EmitSignal('org.freedesktop.NetworkManager', 'DeviceAdded', 'o', [path])
364+
365+ return path
366+
367+
368+@dbus.service.method(MOCK_IFACE,
369+ in_signature='ssi', out_signature='s')
370+def AddWiFiDevice(self, device_name, iface_name, state):
371+ '''Add a WiFi Device.
372+
373+ You have to specify device_name, device interface name (e. g. wlan0) and
374+ state. You can use the predefined DeviceState values (e. g.
375+ DeviceState.ACTIVATED) or supply a numeric value. For valid state values,
376+ please visit
377+ http://projects.gnome.org/NetworkManager/developers/api/09/spec.html#type-NM_DEVICE_STATE
378+
379+ Please note that this does not set any global properties.
380+
381+ Returns the new object path.
382+ '''
383+
384+ path = '/org/freedesktop/NetworkManager/Devices/' + device_name
385+ self.AddObject(path,
386+ WIRELESS_DEVICE_IFACE,
387+ {
388+ 'HwAddress': dbus.String('11:22:33:44:55:66'),
389+ 'PermHwAddress': dbus.String('11:22:33:44:55:66'),
390+ 'Bitrate': dbus.UInt32(5400),
391+ 'Mode': dbus.UInt32(2),
392+ 'WirelessCapabilities': dbus.UInt32(255),
393+ 'AccessPoints': dbus.Array([], signature='o'),
394+ },
395+ [
396+ ('GetAccessPoints', '', 'ao',
397+ 'ret = self.access_points'),
398+ ('GetAllAccessPoints', '', 'ao',
399+ 'ret = self.access_points'),
400+ ('RequestScan', 'a{sv}', '', ''),
401+ ])
402+
403+ dev_obj = dbusmock.get_object(path)
404+ dev_obj.access_points = []
405+ dev_obj.AddProperties(DEVICE_IFACE,
406+ {
407+ 'ActiveConnection': dbus.ObjectPath('/'),
408+ 'AvailableConnections': dbus.Array([], signature='o'),
409+ 'AutoConnect': False,
410+ 'Managed': True,
411+ 'Driver': 'dbusmock',
412+ 'DeviceType': dbus.UInt32(2),
413+ 'State': dbus.UInt32(state),
414+ 'Interface': iface_name,
415+ 'IpInterface': iface_name,
416+ })
417+
418+ devices = self.Get(MAIN_IFACE, 'Devices')
419+ devices.append(path)
420+ self.Set(MAIN_IFACE, 'Devices', devices)
421+
422+ self.EmitSignal('org.freedesktop.NetworkManager', 'DeviceAdded', 'o', [path])
423+
424+ return path
425+
426+
427+@dbus.service.method(MOCK_IFACE,
428+ in_signature='ssssuuuyu', out_signature='s')
429+def AddAccessPoint(self, dev_path, ap_name, ssid, hw_address,
430+ mode, frequency, rate, strength, security):
431+ '''Add an access point to an existing WiFi device.
432+
433+ You have to specify WiFi Device path, Access Point object name,
434+ ssid, hw_address, mode, frequency, rate, strength and security.
435+ For valid access point property values, please visit
436+ http://projects.gnome.org/NetworkManager/developers/api/09/spec.html#org.freedesktop.NetworkManager.AccessPoint
437+
438+ Please note that this does not set any global properties.
439+
440+ Returns the new object path.
441+ '''
442+ dev_obj = dbusmock.get_object(dev_path)
443+ ap_path = '/org/freedesktop/NetworkManager/AccessPoint/' + ap_name
444+ if ap_path in dev_obj.access_points:
445+ raise dbus.exceptions.DBusException(
446+ 'Access point %s on device %s already exists' % (ap_name, dev_path),
447+ name=MAIN_IFACE + '.AlreadyExists')
448+
449+ flags = NM80211ApFlags.NM_802_11_AP_FLAGS_PRIVACY
450+ if security == NM80211ApSecurityFlags.NM_802_11_AP_SEC_NONE:
451+ flags = NM80211ApFlags.NM_802_11_AP_FLAGS_NONE
452+
453+ self.AddObject(ap_path,
454+ ACCESS_POINT_IFACE,
455+ {'Ssid': dbus.ByteArray(ssid.encode('UTF-8')),
456+ 'HwAddress': dbus.String(hw_address),
457+ 'Flags': dbus.UInt32(flags),
458+ 'LastSeen': dbus.Int32(1),
459+ 'Frequency': dbus.UInt32(frequency),
460+ 'MaxBitrate': dbus.UInt32(rate),
461+ 'Mode': dbus.UInt32(mode),
462+ 'RsnFlags': dbus.UInt32(security),
463+ 'WpaFlags': dbus.UInt32(security),
464+ 'Strength': dbus.Byte(strength)},
465+ [])
466+
467+ dev_obj.access_points.append(ap_path)
468+
469+ aps = dev_obj.Get(WIRELESS_DEVICE_IFACE, 'AccessPoints')
470+ aps.append(ap_path)
471+ dev_obj.Set(WIRELESS_DEVICE_IFACE, 'AccessPoints', aps)
472+
473+ dev_obj.EmitSignal(WIRELESS_DEVICE_IFACE, 'AccessPointAdded', 'o', [ap_path])
474+
475+ return ap_path
476+
477+
478+@dbus.service.method(MOCK_IFACE,
479+ in_signature='ssss', out_signature='s')
480+def AddWiFiConnection(self, dev_path, connection_name, ssid_name, key_mgmt):
481+ '''Add an available connection to an existing WiFi device and access point.
482+
483+ You have to specify WiFi Device path, Connection object name,
484+ SSID and key management.
485+
486+ The SSID must match one of the previously created access points.
487+
488+ Please note that this does not set any global properties.
489+
490+ Returns the new object path.
491+ '''
492+
493+ dev_obj = dbusmock.get_object(dev_path)
494+ connection_path = '/org/freedesktop/NetworkManager/Settings/' + connection_name
495+ connections = dev_obj.Get(DEVICE_IFACE, 'AvailableConnections')
496+
497+ settings_obj = dbusmock.get_object(SETTINGS_OBJ)
498+ main_connections = settings_obj.ListConnections()
499+
500+ ssid = ssid_name.encode('UTF-8')
501+
502+ # Find the access point by ssid
503+ access_point = None
504+ access_points = dev_obj.access_points
505+ for ap_path in access_points:
506+ ap = dbusmock.get_object(ap_path)
507+ if ap.Get(ACCESS_POINT_IFACE, 'Ssid') == ssid:
508+ access_point = ap
509+ break
510+
511+ if not access_point:
512+ raise dbus.exceptions.DBusException(
513+ 'Access point with SSID [%s] could not be found' % (ssid_name),
514+ name=MAIN_IFACE + '.DoesNotExist')
515+
516+ hw_address = access_point.Get(ACCESS_POINT_IFACE, 'HwAddress')
517+ mode = access_point.Get(ACCESS_POINT_IFACE, 'Mode')
518+ security = access_point.Get(ACCESS_POINT_IFACE, 'WpaFlags')
519+
520+ if connection_path in connections or connection_path in main_connections:
521+ raise dbus.exceptions.DBusException(
522+ 'Connection %s on device %s already exists' % (connection_name, dev_path),
523+ name=MAIN_IFACE + '.AlreadyExists')
524+
525+ # Parse mac address string into byte array
526+ mac_bytes = binascii.unhexlify(hw_address.replace(':', ''))
527+
528+ settings = {
529+ '802-11-wireless': {
530+ 'seen-bssids': [hw_address],
531+ 'ssid': dbus.ByteArray(ssid),
532+ 'mac-address': dbus.ByteArray(mac_bytes),
533+ 'mode': InfrastructureMode.NAME_MAP[mode]
534+ },
535+ 'connection': {
536+ 'timestamp': dbus.UInt64(1374828522),
537+ 'type': '802-11-wireless',
538+ 'id': ssid_name,
539+ 'uuid': str(uuid.uuid4())
540+ },
541+ }
542+
543+ if security != NM80211ApSecurityFlags.NM_802_11_AP_SEC_NONE:
544+ settings['802-11-wireless']['security'] = '802-11-wireless-security'
545+ settings['802-11-wireless-security'] = NM80211ApSecurityFlags.NAME_MAP[security]
546+
547+ self.AddObject(connection_path,
548+ CSETTINGS_IFACE,
549+ {
550+ 'Unsaved': False
551+ },
552+ [
553+ ('Delete', '', '', 'self.ConnectionDelete(self)'),
554+ ('GetSettings', '', 'a{sa{sv}}', 'ret = self.ConnectionGetSettings(self)'),
555+ ('GetSecrets', 's', 'a{sa{sv}}', 'ret = self.ConnectionGetSecrets(self, args[0])'),
556+ ('Update', 'a{sa{sv}}', '', 'self.ConnectionUpdate(self, args[0])'),
557+ ])
558+
559+ connection_obj = dbusmock.get_object(connection_path)
560+ connection_obj.settings = settings
561+ connection_obj.connection_path = connection_path
562+ connection_obj.ConnectionDelete = ConnectionDelete
563+ connection_obj.ConnectionGetSettings = ConnectionGetSettings
564+ connection_obj.ConnectionGetSecrets = ConnectionGetSecrets
565+ connection_obj.ConnectionUpdate = ConnectionUpdate
566+
567+ connections.append(dbus.ObjectPath(connection_path))
568+ dev_obj.Set(DEVICE_IFACE, 'AvailableConnections', connections)
569+
570+ main_connections.append(connection_path)
571+ settings_obj.Set(SETTINGS_IFACE, 'Connections', main_connections)
572+
573+ settings_obj.EmitSignal(SETTINGS_IFACE, 'NewConnection', 'o', [ap_path])
574+
575+ return connection_path
576+
577+
578+@dbus.service.method(MOCK_IFACE,
579+ in_signature='assssu', out_signature='s')
580+def AddActiveConnection(self, devices, connection_device, specific_object, name, state):
581+ '''Add an active connection to an existing WiFi device.
582+
583+ You have to a list of the involved WiFi devices, the connection path,
584+ the access point path, ActiveConnection object name and connection
585+ state.
586+
587+ Please note that this does not set any global properties.
588+
589+ Returns the new object path.
590+ '''
591+
592+ conn_obj = dbusmock.get_object(connection_device)
593+ settings = conn_obj.settings
594+ conn_uuid = settings['connection']['uuid']
595+ conn_type = settings['connection']['type']
596+
597+ device_objects = [dbus.ObjectPath(dev) for dev in devices]
598+
599+ active_connection_path = '/org/freedesktop/NetworkManager/ActiveConnection/' + name
600+ self.AddObject(active_connection_path,
601+ ACTIVE_CONNECTION_IFACE,
602+ {
603+ 'Devices': device_objects,
604+ 'Default6': False,
605+ 'Default': True,
606+ 'Type': conn_type,
607+ 'Vpn': (conn_type == 'vpn'),
608+ 'Connection': dbus.ObjectPath(connection_device),
609+ 'Master': dbus.ObjectPath('/'),
610+ 'SpecificObject': dbus.ObjectPath(specific_object),
611+ 'Uuid': conn_uuid,
612+ 'State': state,
613+ },
614+ [])
615+
616+ for dev_path in devices:
617+ self.SetDeviceActive(dev_path, active_connection_path)
618+
619+ active_connections = self.Get(MAIN_IFACE, 'ActiveConnections')
620+ active_connections.append(dbus.ObjectPath(active_connection_path))
621+ self.SetProperty(MAIN_OBJ, MAIN_IFACE, 'ActiveConnections', active_connections)
622+
623+ return active_connection_path
624+
625+
626+@dbus.service.method(MOCK_IFACE,
627+ in_signature='ss', out_signature='')
628+def RemoveAccessPoint(self, dev_path, ap_path):
629+ '''Remove the specified access point.
630+
631+ You have to specify the device to remove the access point from, and the
632+ path of the access point.
633+
634+ Please note that this does not set any global properties.
635+ '''
636+
637+ dev_obj = dbusmock.get_object(dev_path)
638+
639+ aps = dev_obj.Get(WIRELESS_DEVICE_IFACE, 'AccessPoints')
640+ aps.remove(ap_path)
641+ dev_obj.Set(WIRELESS_DEVICE_IFACE, 'AccessPoints', aps)
642+
643+ dev_obj.access_points.remove(ap_path)
644+
645+ dev_obj.EmitSignal(WIRELESS_DEVICE_IFACE, 'AccessPointRemoved', 'o', [ap_path])
646+
647+ self.RemoveObject(ap_path)
648+
649+
650+@dbus.service.method(MOCK_IFACE,
651+ in_signature='ss', out_signature='')
652+def RemoveWifiConnection(self, dev_path, connection_path):
653+ '''Remove the specified WiFi connection.
654+
655+ You have to specify the device to remove the connection from, and the
656+ path of the Connection.
657+
658+ Please note that this does not set any global properties.
659+ '''
660+
661+ dev_obj = dbusmock.get_object(dev_path)
662+ settings_obj = dbusmock.get_object(SETTINGS_OBJ)
663+
664+ connections = dev_obj.Get(DEVICE_IFACE, 'AvailableConnections')
665+ main_connections = settings_obj.ListConnections()
666+
667+ if connection_path not in connections and connection_path not in main_connections:
668+ return
669+
670+ connections.remove(dbus.ObjectPath(connection_path))
671+ dev_obj.Set(DEVICE_IFACE, 'AvailableConnections', connections)
672+
673+ main_connections.remove(connection_path)
674+ settings_obj.Set(SETTINGS_IFACE, 'Connections', main_connections)
675+
676+ settings_obj.EmitSignal(SETTINGS_IFACE, 'ConnectionRemoved', 'o', [connection_path])
677+
678+ connection_obj = dbusmock.get_object(connection_path)
679+ connection_obj.EmitSignal(CSETTINGS_IFACE, 'Removed', '', [])
680+
681+ self.RemoveObject(connection_path)
682+
683+
684+@dbus.service.method(MOCK_IFACE,
685+ in_signature='ss', out_signature='')
686+def RemoveActiveConnection(self, dev_path, active_connection_path):
687+ '''Remove the specified ActiveConnection.
688+
689+ You have to specify the device to remove the connection from, and the
690+ path of the ActiveConnection.
691+
692+ Please note that this does not set any global properties.
693+ '''
694+ self.SetDeviceDisconnected(dev_path)
695+
696+ active_connections = self.Get(MAIN_IFACE, 'ActiveConnections')
697+
698+ if active_connection_path not in active_connections:
699+ return
700+
701+ active_connections.remove(dbus.ObjectPath(active_connection_path))
702+ self.SetProperty(MAIN_OBJ, MAIN_IFACE, 'ActiveConnections', active_connections)
703+
704+ self.RemoveObject(active_connection_path)
705+
706+
707+@dbus.service.method(SETTINGS_IFACE,
708+ in_signature='a{sa{sv}}', out_signature='o')
709+def SettingsAddConnection(self, connection_settings):
710+ '''Add a connection.
711+
712+ connection_settings is a String String Variant Map Map. See
713+ https://developer.gnome.org/NetworkManager/0.9/spec.html
714+ #type-String_String_Variant_Map_Map
715+
716+ If you omit uuid, this method adds one for you.
717+ '''
718+
719+ if 'uuid' not in connection_settings['connection']:
720+ connection_settings['connection']['uuid'] = str(uuid.uuid4())
721+
722+ NM = dbusmock.get_object(MAIN_OBJ)
723+ settings_obj = dbusmock.get_object(SETTINGS_OBJ)
724+ main_connections = settings_obj.ListConnections()
725+
726+ # Mimic how NM names connections
727+ count = 0
728+ while True:
729+ connection_obj_path = dbus.ObjectPath(SETTINGS_OBJ + '/' + str(count))
730+ if connection_obj_path not in main_connections:
731+ break
732+ count += 1
733+ connection_path = str(connection_obj_path)
734+
735+ self.AddObject(connection_path,
736+ CSETTINGS_IFACE,
737+ {
738+ 'Unsaved': False
739+ },
740+ [
741+ ('Delete', '', '', 'self.ConnectionDelete(self)'),
742+ ('GetSettings', '', 'a{sa{sv}}', 'ret = self.ConnectionGetSettings(self)'),
743+ ('GetSecrets', 's', 'a{sa{sv}}', 'ret = self.ConnectionGetSecrets(self, args[0])'),
744+ ('Update', 'a{sa{sv}}', '', 'self.ConnectionUpdate(self, args[0])'),
745+ ])
746+
747+ connection_obj = dbusmock.get_object(connection_path)
748+ connection_obj.settings = connection_settings
749+ connection_obj.connection_path = connection_path
750+ connection_obj.ConnectionDelete = ConnectionDelete
751+ connection_obj.ConnectionGetSettings = ConnectionGetSettings
752+ connection_obj.ConnectionGetSecrets = ConnectionGetSecrets
753+ connection_obj.ConnectionUpdate = ConnectionUpdate
754+
755+ main_connections.append(connection_path)
756+ settings_obj.Set(SETTINGS_IFACE, 'Connections', main_connections)
757+
758+ settings_obj.EmitSignal(SETTINGS_IFACE, 'NewConnection', 'o', [connection_path])
759+
760+ auto_connect = False
761+ if 'autoconnect' in connection_settings['connection']:
762+ auto_connect = connection_settings['connection']['autoconnect']
763+
764+ if auto_connect:
765+ dev = None
766+ devices = NM.GetDevices()
767+
768+ # Grab the first device.
769+ if len(devices) > 0:
770+ dev = devices[0]
771+
772+ if dev:
773+ activate_connection(NM, connection_path, dev, connection_path)
774+
775+ return connection_path
776+
777+
778+def ConnectionUpdate(self, settings):
779+ '''Update settings on a connection.
780+
781+ settings is a String String Variant Map Map. See
782+ https://developer.gnome.org/NetworkManager/0.9/spec.html
783+ #type-String_String_Variant_Map_Map
784+ '''
785+ connection_path = self.connection_path
786+
787+ NM = dbusmock.get_object(MAIN_OBJ)
788+ settings_obj = dbusmock.get_object(SETTINGS_OBJ)
789+
790+ main_connections = settings_obj.ListConnections()
791+
792+ if connection_path not in main_connections:
793+ raise dbus.exceptions.DBusException(
794+ 'Connection %s does not exist' % connection_path,
795+ name=MAIN_IFACE + '.DoesNotExist',)
796+
797+ # Take care not to overwrite the secrets
798+ for setting_name in settings:
799+ setting = settings[setting_name]
800+ for k in setting:
801+ if setting_name not in self.settings:
802+ self.settings[setting_name] = {}
803+ self.settings[setting_name][k] = setting[k]
804+
805+ self.EmitSignal(CSETTINGS_IFACE, 'Updated', '', [])
806+
807+ auto_connect = False
808+ if 'autoconnect' in settings['connection']:
809+ auto_connect = settings['connection']['autoconnect']
810+
811+ if auto_connect:
812+ dev = None
813+ devices = NM.GetDevices()
814+
815+ # Grab the first device.
816+ if len(devices) > 0:
817+ dev = devices[0]
818+
819+ if dev:
820+ activate_connection(NM, connection_path, dev, connection_path)
821+
822+ return connection_path
823+
824+
825+def ConnectionGetSettings(self):
826+ # Deep copy the settings with the secrets stripped
827+ # out. (NOTE: copy.deepcopy doesn't work with dbus
828+ # types).
829+ settings = {}
830+ for setting_name in self.settings:
831+ setting = self.settings[setting_name]
832+ for k in setting:
833+ if k != 'secrets':
834+ if setting_name not in settings:
835+ settings[setting_name] = {}
836+ settings[setting_name][k] = setting[k]
837+
838+ return settings
839+
840+
841+def ConnectionGetSecrets(self, setting):
842+ settings = self.settings[setting]
843+
844+ if 'secrets' in settings:
845+ secrets = {setting: {'secrets': settings['secrets']}}
846+ else:
847+ secrets = {setting: {'secrets': {'no-secrets': True}}}
848+
849+ return secrets
850+
851+
852+def ConnectionDelete(self):
853+ '''Deletes a connection.
854+
855+ This also
856+ * removes the deleted connection from any device,
857+ * removes any active connection(s) it might be associated with,
858+ * removes it from the Settings interface,
859+ * as well as deletes the object from the mock.
860+
861+ Note: If this was the only active connection, we change the global
862+ connection state.
863+ '''
864+ connection_path = self.connection_path
865+
866+ NM = dbusmock.get_object(MAIN_OBJ)
867+ settings_obj = dbusmock.get_object(SETTINGS_OBJ)
868+
869+ # Find the associated active connection(s).
870+ active_connections = NM.Get(MAIN_IFACE, 'ActiveConnections')
871+ associated_active_connections = []
872+ for ac in active_connections:
873+ ac_obj = dbusmock.get_object(ac)
874+ ac_con = ac_obj.Get(ACTIVE_CONNECTION_IFACE, 'Connection')
875+ if ac_con == connection_path:
876+ associated_active_connections.append(ac)
877+
878+ # We found that the connection we are deleting are associated to all
879+ # active connections and subsequently set the global state to
880+ # disconnected.
881+ if len(active_connections) == len(associated_active_connections):
882+ self.SetGlobalConnectionState(NMState.NM_STATE_DISCONNECTED)
883+
884+ # Remove the connection from all associated devices.
885+ # We also remove all associated active connections.
886+ for dev_path in NM.GetDevices():
887+ dev_obj = dbusmock.get_object(dev_path)
888+ connections = dev_obj.Get(DEVICE_IFACE, 'AvailableConnections')
889+
890+ for ac in associated_active_connections:
891+ NM.RemoveActiveConnection(dev_path, ac)
892+
893+ if connection_path not in connections:
894+ continue
895+
896+ connections.remove(dbus.ObjectPath(connection_path))
897+ dev_obj.Set(DEVICE_IFACE, 'AvailableConnections', connections)
898+
899+ # Remove the connection from the settings interface
900+ main_connections = settings_obj.ListConnections()
901+ if connection_path not in main_connections:
902+ return
903+ main_connections.remove(connection_path)
904+ settings_obj.Set(SETTINGS_IFACE, 'Connections', main_connections)
905+ settings_obj.EmitSignal(SETTINGS_IFACE, 'ConnectionRemoved', 'o', [connection_path])
906+
907+ # Remove the connection from the mock
908+ connection_obj = dbusmock.get_object(connection_path)
909+ connection_obj.EmitSignal(CSETTINGS_IFACE, 'Removed', '', [])
910+ self.RemoveObject(connection_path)
911
912=== modified file 'tests/integration/indicator-network-test-base.cpp'
913--- tests/integration/indicator-network-test-base.cpp 2016-06-06 11:57:38 +0000
914+++ tests/integration/indicator-network-test-base.cpp 2016-09-29 18:11:03 +0000
915@@ -66,7 +66,8 @@
916 QStringList{"-y", testDir.filePath(QString("%1-%2").arg(test_info->name(), "system.log"))})));
917 }
918
919- dbusMock.registerNetworkManager();
920+ qDebug() << NETWORK_MANAGER_TEMPLATE_PATH;
921+ dbusMock.registerTemplate(NM_DBUS_SERVICE, NETWORK_MANAGER_TEMPLATE_PATH, {}, QDBusConnection::SystemBus);
922 dbusMock.registerNotificationDaemon();
923 // By default the ofono mock starts with one modem
924 dbusMock.registerOfono({{"no_modem", true}});
925
926=== modified file 'tests/unit/secret-agent/test-secret-agent.cpp'
927--- tests/unit/secret-agent/test-secret-agent.cpp 2016-05-26 16:58:15 +0000
928+++ tests/unit/secret-agent/test-secret-agent.cpp 2016-09-29 18:11:03 +0000
929@@ -46,7 +46,7 @@
930 DBusTypes::registerMetaTypes();
931
932 dbusMock.registerNotificationDaemon();
933- dbusMock.registerNetworkManager();
934+ dbusMock.registerTemplate(NM_DBUS_SERVICE, NETWORK_MANAGER_TEMPLATE_PATH, {}, QDBusConnection::SystemBus);
935 dbusTestRunner.startServices();
936
937 QProcessEnvironment env(QProcessEnvironment::systemEnvironment());
938@@ -171,17 +171,20 @@
939
940 QSignalSpy notificationSpy(notificationsInterface.data(),
941 SIGNAL(MethodCalled(const QString &, const QVariantList &)));
942- notificationSpy.wait();
943+ if (notificationSpy.empty())
944+ {
945+ ASSERT_TRUE(notificationSpy.wait());
946+ }
947
948 ASSERT_EQ(1, notificationSpy.size());
949 const QVariantList &call(notificationSpy.at(0));
950- ASSERT_EQ("Notify", call.at(0));
951+ EXPECT_EQ("Notify", call.at(0).toString().toStdString());
952
953 QVariantList args(call.at(1).toList());
954 transform(args);
955
956 ASSERT_EQ(8, args.size());
957- EXPECT_EQ("indicator-network", args.at(0));
958+ EXPECT_EQ("indicator-network", args.at(0).toString().toStdString());
959 EXPECT_EQ("Connect to “the ssid”", args.at(3).toString().toStdString());
960
961 QVariantMap hints(args.at(6).toMap());
962@@ -215,7 +218,7 @@
963 shared_ptr<GSimpleAction> o(g_simple_action_new("a", NULL), &mh::g_object_deleter);
964 mh::waitForCore(G_OBJECT(o.get()), "activate", 100);
965
966- ASSERT_EQ("Password received", secretAgent.readAll().trimmed());
967+ EXPECT_EQ("Password received", secretAgent.readAll().trimmed().toStdString());
968 }
969
970 notificationsInterface->EmitSignal(
971@@ -281,18 +284,21 @@
972
973 ASSERT_EQ(1, notificationSpy.size());
974 const QVariantList &call(notificationSpy.at(0));
975- ASSERT_EQ("Notify", call.at(0));
976+ EXPECT_EQ("Notify", call.at(0).toString().toStdString());
977
978 notificationSpy.clear();
979
980 agentInterface->CancelGetSecrets(QDBusObjectPath("/connection/foo"),
981 SecretAgent::NM_WIRELESS_SECURITY_SETTING_NAME);
982
983- notificationSpy.wait();
984+ if (notificationSpy.empty())
985+ {
986+ ASSERT_TRUE(notificationSpy.wait());
987+ }
988
989 ASSERT_EQ(1, notificationSpy.size());
990 const QVariantList &closecall(notificationSpy.at(0));
991- ASSERT_EQ("CloseNotification", closecall.at(0));
992+ EXPECT_EQ("CloseNotification", closecall.at(0).toString().toStdString());
993 }
994
995 /* Ensures that if we request secrets twice we close the notification
996@@ -306,11 +312,14 @@
997 SecretAgent::NM_WIRELESS_SECURITY_SETTING_NAME, QStringList(),
998 5);
999
1000- notificationSpy.wait();
1001+ if (notificationSpy.empty())
1002+ {
1003+ ASSERT_TRUE(notificationSpy.wait());
1004+ }
1005
1006 ASSERT_EQ(1, notificationSpy.size());
1007 const QVariantList &call(notificationSpy.at(0));
1008- ASSERT_EQ("Notify", call.at(0));
1009+ EXPECT_EQ("Notify", call.at(0).toString().toStdString());
1010
1011 notificationSpy.clear();
1012
1013@@ -320,15 +329,21 @@
1014 SecretAgent::NM_WIRELESS_SECURITY_SETTING_NAME, QStringList(),
1015 5);
1016
1017- notificationSpy.wait();
1018- notificationSpy.wait();
1019+ if (notificationSpy.empty())
1020+ {
1021+ ASSERT_TRUE(notificationSpy.wait());
1022+ }
1023+ if (notificationSpy.size() == 1)
1024+ {
1025+ ASSERT_TRUE(notificationSpy.wait());
1026+ }
1027
1028 ASSERT_EQ(2, notificationSpy.size());
1029 const QVariantList &closecall(notificationSpy.at(1));
1030- ASSERT_EQ("CloseNotification", closecall.at(0));
1031+ EXPECT_EQ("CloseNotification", closecall.at(0).toString().toStdString());
1032
1033 const QVariantList &newnotify(notificationSpy.at(0));
1034- ASSERT_EQ("Notify", newnotify.at(0));
1035+ EXPECT_EQ("Notify", newnotify.at(0).toString().toStdString());
1036 }
1037
1038 TEST_F(TestSecretAgent, SaveSecrets) {

Subscribers

People subscribed via source and target branches