Merge ~jocave/plainbox-provider-resource:net-if-mgmt-master-mode into plainbox-provider-resource:master

Proposed by Jonathan Cave
Status: Merged
Approved by: Jonathan Cave
Approved revision: c92db09904ab1b9cd0f047602390ae13aa779508
Merged at revision: b5faa49df57d7bbdf6b913d16003a4cd998aa36a
Proposed branch: ~jocave/plainbox-provider-resource:net-if-mgmt-master-mode
Merge into: plainbox-provider-resource:master
Diff against target: 210 lines (+80/-23)
2 files modified
bin/net_if_management.py (+58/-12)
tests/test_net_if_management.py (+22/-11)
Reviewer Review Type Date Requested Status
Kristin Chuang (community) Approve
Review via email: mp+400444@code.launchpad.net

Description of the change

Extend the features of the net_if_management resource job to indicate what snap should be used to test the master mode function of wifi interfaces.

This will allow the NetworkManager master mode tests to be added to the existing master mode nested test plans.

To post a comment you must log in.
Revision history for this message
Kristin Chuang (kristinchuang) wrote :

+1
Along with https://code.launchpad.net/~jocave/plainbox-provider-checkbox/+git/plainbox-provider-checkbox/+merge/400446, the current logic works in the following trial runs:

* UC16 enablement project, wifi-AP & network-manager pre-installed
[Expected] wifi-ap jobs run (its pass/fail status unrelated to this MR), nmcli jobs skipped
[Actual] OK, see https://pastebin.canonical.com/p/GHVhyYxQJC/

* rpi 2b, stock rpi armhf UC20, network-manager manually installed
[Expected] wifi-ap jobs skipped, nmcli jobs run (its pass/fail status unrelated to this MR)
[Actual] OK, see https://pastebin.canonical.com/p/jkTc6KQw8c/

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/bin/net_if_management.py b/bin/net_if_management.py
index b7daa9b..48fc453 100755
--- a/bin/net_if_management.py
+++ b/bin/net_if_management.py
@@ -59,6 +59,10 @@ def is_netplan_available():
59 return which('netplan') is not None59 return which('netplan') is not None
6060
6161
62def is_wifiap_available():
63 return which('wifi-ap.config') is not None
64
65
62class NmInterfaceState():66class NmInterfaceState():
6367
64 def __init__(self):68 def __init__(self):
@@ -80,13 +84,40 @@ class States(Enum):
80 nm = 'NetworkManager'84 nm = 'NetworkManager'
8185
8286
87class MasterMode(Enum):
88 na = 'not-applicable'
89 unspecified = 'unspecified'
90 error = 'error'
91 wifiap = 'wifi-ap'
92 nm = 'NetworkManager'
93
94
83def identify_managers(interfaces=None,95def identify_managers(interfaces=None,
84 has_netplan=True, netplan_yaml=None,96 has_netplan=True, netplan_yaml=None,
85 has_nm=True, nm_device_state=None):97 has_nm=True, nm_device_state=None,
98 has_wifiap=False):
99 results = {}
86 if interfaces is None:100 if interfaces is None:
87 interfaces = UdevInterfaceLister(['NETWORK', 'WIRELESS']).names101 # normal operation
88102 wired = UdevInterfaceLister(['NETWORK']).names
89 results = dict.fromkeys(interfaces, States.unspecified)103 results.update(dict.fromkeys(wired, {
104 'manager': States.unspecified,
105 'mastermode': MasterMode.na
106 }))
107 wireless = UdevInterfaceLister(['WIRELESS']).names
108 results.update(dict.fromkeys(wireless, {
109 'manager': States.unspecified,
110 'mastermode': MasterMode.unspecified
111 }))
112 else:
113 # testing
114 for i in interfaces:
115 if i.startswith('e'):
116 results[i] = {'manager': States.unspecified,
117 'mastermode': MasterMode.na}
118 elif i.startswith('w'):
119 results[i] = {'manager': States.unspecified,
120 'mastermode': MasterMode.unspecified}
90121
91 if has_nm:122 if has_nm:
92 nm_conf = NmInterfaceState()123 nm_conf = NmInterfaceState()
@@ -113,6 +144,10 @@ def identify_managers(interfaces=None,
113 category_scope_manager = netplan_conf.ethernets.get(144 category_scope_manager = netplan_conf.ethernets.get(
114 'renderer', States.unspecified.value)145 'renderer', States.unspecified.value)
115146
147 if results[n]['mastermode'] != MasterMode.na and has_wifiap:
148 log('has wifi-ap')
149 results[n]['mastermode'] = MasterMode.wifiap
150
116 # Netplan config indcates NM151 # Netplan config indcates NM
117 if (global_scope_manager == States.nm.value or152 if (global_scope_manager == States.nm.value or
118 category_scope_manager == States.nm.value or153 category_scope_manager == States.nm.value or
@@ -122,35 +157,46 @@ def identify_managers(interfaces=None,
122 if not has_nm:157 if not has_nm:
123 log('error: netplan defines NM or there is no netplan, '158 log('error: netplan defines NM or there is no netplan, '
124 'but NM unavailable')159 'but NM unavailable')
125 results[n] = States.error160 results[n]['manager'] = States.error
126 continue161 continue
127 # NM does not know the interface162 # NM does not know the interface
128 if nm_conf.devices.get(n) is None:163 if nm_conf.devices.get(n) is None:
129 log('error: netplan defines NM or there is no netplan, '164 log('error: netplan defines NM or there is no netplan, '
130 'but interface unknown to NM')165 'but interface unknown to NM')
131 results[n] = States.error166 results[n]['manager'] = States.error
132 continue167 continue
133 # NM thinks it doesnt manage the device despite netplan config168 # NM thinks it doesnt manage the device despite netplan config
134 if nm_conf.devices.get(n) == 'unmanaged':169 if nm_conf.devices.get(n) == 'unmanaged':
135 log('error: netplan defines NM or there is no netplan, '170 log('error: netplan defines NM or there is no netplan, '
136 'but NM reports unmanaged')171 'but NM reports unmanaged')
137 results[n] = States.unspecified172 results[n]['manager'] = States.unspecified
138 continue173 continue
139 results[n] = States.nm174
175 results[n]['manager'] = States.nm
176
177 # if NM is managing the interface for wireless connections and
178 # wifi-ap is not installed, NM should be considered for managing
179 # master mode
180 if results[n]['mastermode'] != MasterMode.na and not has_wifiap:
181 # version check?
182 results[n]['mastermode'] = MasterMode.nm
183
140 continue184 continue
141185
142 # has netplan but no renderer specified186 # has netplan but no renderer specified
143 if has_netplan:187 if has_netplan:
144 results[n] = States.networkd188 results[n]['manager'] = States.networkd
145 return results189 return results
146190
147191
148def main():192def main():
149 results = identify_managers(has_netplan=is_netplan_available(),193 results = identify_managers(has_netplan=is_netplan_available(),
150 has_nm=is_nm_available())194 has_nm=is_nm_available(),
151 for interface, state in results.items():195 has_wifiap=is_wifiap_available())
196 for interface, data in results.items():
152 print('device: {}'.format(interface))197 print('device: {}'.format(interface))
153 print('managed_by: {}'.format(state.value))198 print('managed_by: {}'.format(data['manager'].value))
199 print('master_mode_managed_by: {}'.format(data['mastermode'].value))
154 print()200 print()
155201
156202
diff --git a/tests/test_net_if_management.py b/tests/test_net_if_management.py
index 6aa07f1..fb74e31 100644
--- a/tests/test_net_if_management.py
+++ b/tests/test_net_if_management.py
@@ -34,6 +34,7 @@ class NetIfMngrTest():
3434
35 has_netplan = True35 has_netplan = True
36 has_nm = True36 has_nm = True
37 has_wifiap = False
3738
38 @staticmethod39 @staticmethod
39 def get_text(filename):40 def get_text(filename):
@@ -53,7 +54,8 @@ class NetIfMngrTest():
53 self.has_netplan,54 self.has_netplan,
54 self.netplan_yaml,55 self.netplan_yaml,
55 self.has_nm,56 self.has_nm,
56 self.nm_device_state)57 self.nm_device_state,
58 self.has_wifiap)
5759
5860
59class Test_CARA_T(unittest.TestCase, NetIfMngrTest):61class Test_CARA_T(unittest.TestCase, NetIfMngrTest):
@@ -68,10 +70,14 @@ class Test_CARA_T(unittest.TestCase, NetIfMngrTest):
68 nm_device_state = NetIfMngrTest.get_text('CARA_T_nmcli.txt')70 nm_device_state = NetIfMngrTest.get_text('CARA_T_nmcli.txt')
6971
70 def test(self):72 def test(self):
73 self.has_wifiap = True
71 res = self.get_results()74 res = self.get_results()
72 self.assertEqual(res['eth0'].value, 'NetworkManager')75 self.assertEqual(res['eth0']['manager'].value, 'NetworkManager')
73 self.assertEqual(res['eth1'].value, 'NetworkManager')76 self.assertEqual(res['eth0']['mastermode'].value, 'not-applicable')
74 self.assertEqual(res['wlan0'].value, 'NetworkManager')77 self.assertEqual(res['eth1']['manager'].value, 'NetworkManager')
78 self.assertEqual(res['eth1']['mastermode'].value, 'not-applicable')
79 self.assertEqual(res['wlan0']['manager'].value, 'NetworkManager')
80 self.assertEqual(res['wlan0']['mastermode'].value, 'wifi-ap')
7581
7682
77class Test_XENIAL_DESKTOP(unittest.TestCase, NetIfMngrTest):83class Test_XENIAL_DESKTOP(unittest.TestCase, NetIfMngrTest):
@@ -87,8 +93,10 @@ class Test_XENIAL_DESKTOP(unittest.TestCase, NetIfMngrTest):
8793
88 def test(self):94 def test(self):
89 res = self.get_results()95 res = self.get_results()
90 self.assertEqual(res['eth0'].value, 'NetworkManager')96 self.assertEqual(res['eth0']['manager'].value, 'NetworkManager')
91 self.assertEqual(res['wlan0'].value, 'NetworkManager')97 self.assertEqual(res['eth0']['mastermode'].value, 'not-applicable')
98 self.assertEqual(res['wlan0']['manager'].value, 'NetworkManager')
99 self.assertEqual(res['wlan0']['mastermode'].value, 'NetworkManager')
92100
93101
94class Test_CASCADE_500(unittest.TestCase, NetIfMngrTest):102class Test_CASCADE_500(unittest.TestCase, NetIfMngrTest):
@@ -104,8 +112,8 @@ class Test_CASCADE_500(unittest.TestCase, NetIfMngrTest):
104112
105 def test(self):113 def test(self):
106 res = self.get_results()114 res = self.get_results()
107 self.assertEqual(res['eth0'].value, 'NetworkManager')115 self.assertEqual(res['eth0']['manager'].value, 'NetworkManager')
108 self.assertEqual(res['wlan0'].value, 'NetworkManager')116 self.assertEqual(res['wlan0']['manager'].value, 'NetworkManager')
109117
110118
111class Test_RPI2_UC16_CCONF(unittest.TestCase, NetIfMngrTest):119class Test_RPI2_UC16_CCONF(unittest.TestCase, NetIfMngrTest):
@@ -121,7 +129,8 @@ class Test_RPI2_UC16_CCONF(unittest.TestCase, NetIfMngrTest):
121129
122 def test(self):130 def test(self):
123 res = self.get_results()131 res = self.get_results()
124 self.assertEqual(res['eth0'].value, 'networkd')132 self.assertEqual(res['eth0']['manager'].value, 'networkd')
133 self.assertEqual(res['eth0']['mastermode'].value, 'not-applicable')
125134
126135
127class Test_RPI3B_UC16_CLOUDINIT(unittest.TestCase, NetIfMngrTest):136class Test_RPI3B_UC16_CLOUDINIT(unittest.TestCase, NetIfMngrTest):
@@ -137,5 +146,7 @@ class Test_RPI3B_UC16_CLOUDINIT(unittest.TestCase, NetIfMngrTest):
137146
138 def test(self):147 def test(self):
139 res = self.get_results()148 res = self.get_results()
140 self.assertEqual(res['eth0'].value, 'networkd')149 self.assertEqual(res['eth0']['manager'].value, 'networkd')
141 self.assertEqual(res['wlan0'].value, 'networkd')150 self.assertEqual(res['eth0']['mastermode'].value, 'not-applicable')
151 self.assertEqual(res['wlan0']['manager'].value, 'networkd')
152 self.assertEqual(res['wlan0']['mastermode'].value, 'unspecified')

Subscribers

People subscribed via source and target branches