Merge ~jocave/plainbox-provider-checkbox:ethernet-detect-testing into plainbox-provider-checkbox:master

Proposed by Jonathan Cave
Status: Merged
Approved by: Jonathan Cave
Approved revision: 8e6c4d9ec57f120df42f634a91d05722914e93da
Merged at revision: 62e8080b7d05d3e82328972f53e2b00c0cf8dbad
Proposed branch: ~jocave/plainbox-provider-checkbox:ethernet-detect-testing
Merge into: plainbox-provider-checkbox:master
Diff against target: 217 lines (+72/-71)
4 files modified
bin/network_device_info.py (+63/-68)
units/ethernet/jobs.pxu (+4/-2)
units/ethernet/manifest.pxu (+4/-0)
units/info/jobs.pxu (+1/-1)
Reviewer Review Type Date Requested Status
Sylvain Pineau (community) Approve
Review via email: mp+363443@code.launchpad.net

Description of the change

Bug #1815992 raised the question of how the ethernet/detect job should behave, specifically when the system is known to ship without any ethernet adapters.

Most detect jobs are written such that they fail if no devices belonging to their category are found. Expected presence of a device is typically indicated by the presence of a manifest entry. In this case the detect job merely reported information about devices found by udev and compared this to those found by network-manager expect in the case when network-manager wasnt present. The exact same task was repeated in the attachment job info/network_devices.

These changes maintain behaviour of the info/network_devices job so that the info can be collected and reviewed (e.g. in server certification test plans). The ethernet/detect job now just performs the udev search and fails if no adpaters are found. The job is dependent on the new has_ethernet_adpater manifest unit.

To post a comment you must log in.
Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

LGTM, +1 for the new manifest entry

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/bin/network_device_info b/bin/network_device_info.py
2similarity index 74%
3rename from bin/network_device_info
4rename to bin/network_device_info.py
5index 174fbe8..29a4aed 100755
6--- a/bin/network_device_info
7+++ b/bin/network_device_info.py
8@@ -17,7 +17,7 @@
9 # NetworkManager
10 # http://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python
11 #
12-# Copyright (C) 2012 Canonical, Ltd.
13+# Copyright (C) 2012-2019 Canonical, Ltd.
14
15 from subprocess import check_output, CalledProcessError, STDOUT
16 import sys
17@@ -125,7 +125,7 @@ class NetworkingDevice():
18 cmd = ['/sbin/modinfo', driver]
19 try:
20 stream = check_output(cmd, stderr=STDOUT, universal_newlines=True)
21- except CalledProcessError as err:
22+ except CalledProcessError:
23 return None
24
25 if not stream:
26@@ -156,6 +156,35 @@ class NetworkingDevice():
27 return "%d.%d.%d.%d" % (ip[0], ip[1], ip[2], ip[3])
28
29
30+def print_udev_devices():
31+ print("[ Devices found by udev ]".center(80, '-'))
32+ for device in udev_devices:
33+ for attribute in attributes:
34+ value = getattr(device, attribute)
35+ if value is not None:
36+ if attribute == 'driver':
37+ props = {}
38+ props['Driver'] = value
39+ network_dev = NetworkingDevice(
40+ None, props, None, None)
41+ print("%s: %s (ver: %s)" % (
42+ attribute.capitalize(), value,
43+ network_dev._driver_ver))
44+ else:
45+ print("%s: %s" % (attribute.capitalize(), value))
46+ vendor_id = getattr(device, 'vendor_id')
47+ product_id = getattr(device, 'product_id')
48+ subvendor_id = getattr(device, 'subvendor_id')
49+ subproduct_id = getattr(device, 'subproduct_id')
50+ if vendor_id and product_id:
51+ print("ID: [{0:04x}:{1:04x}]".format(
52+ vendor_id, product_id))
53+ if subvendor_id and subproduct_id:
54+ print("Subsystem ID: [{0:04x}:{1:04x}]".format(
55+ subvendor_id, subproduct_id))
56+ print()
57+
58+
59 def get_nm_devices():
60 devices = []
61 bus = dbus.SystemBus()
62@@ -183,30 +212,11 @@ def get_nm_devices():
63 return devices
64
65
66-def match_counts(nm_devices, udev_devices, devtype):
67- """
68- Ensures that the count of devices matching devtype is the same for the
69- two passed in lists, devices from Network Manager and devices from lspci.
70- """
71- # now check that the count (by type) matches
72- nm_type_devices = [dev for dev in nm_devices if dev.gettype() in devtype]
73- udevtype = 'NETWORK'
74- udev_type_devices = [
75- udev
76- for udev in udev_devices
77- if udev.category == udevtype]
78- if len(nm_type_devices) != len(udev_type_devices):
79- print("ERROR: devices missing - udev showed %d %s devices, but "
80- "NetworkManager saw %d devices in %s" %
81- (len(udev_type_devices), udevtype,
82- len(nm_type_devices), devtype),
83- file=sys.stderr)
84- return False
85- else:
86- return True
87-
88-
89-def main(args):
90+def main():
91+ if len(sys.argv) != 2 or sys.argv[1] not in ('detect', 'info'):
92+ raise SystemExit('ERROR: please specify detect or info')
93+ action = sys.argv[1]
94+
95 try:
96 output = check_output(['udevadm', 'info', '--export-db'])
97 except CalledProcessError as err:
98@@ -219,48 +229,33 @@ def main(args):
99 result = UdevResult()
100 udev.run(result)
101
102- if udev_devices:
103- print("[ Devices found by udev ]".center(80, '-'))
104- for device in udev_devices:
105- for attribute in attributes:
106- value = getattr(device, attribute)
107- if value is not None:
108- if attribute == 'driver':
109- props = {}
110- props['Driver'] = value
111- network_dev = NetworkingDevice(None, props, None, None)
112- print("%s: %s (ver: %s)" % (attribute.capitalize(),
113- value, network_dev._driver_ver))
114- else:
115- print("%s: %s" % (attribute.capitalize(), value))
116- vendor_id = getattr(device, 'vendor_id')
117- product_id = getattr(device, 'product_id')
118- subvendor_id = getattr(device, 'subvendor_id')
119- subproduct_id = getattr(device, 'subproduct_id')
120- if vendor_id and product_id:
121- print("ID: [{0:04x}:{1:04x}]".format(vendor_id, product_id))
122- if subvendor_id and subproduct_id:
123- print("Subsystem ID: [{0:04x}:{1:04x}]".format(subvendor_id, subproduct_id))
124- print()
125+ # The detect action should indicate presence of an ethernet adatper and
126+ # cause the job to fail if none present - rely on udev for this
127+ if action == 'detect':
128+ if udev_devices:
129+ print_udev_devices()
130+ else:
131+ raise SystemExit('No devices detected by udev')
132+
133+ # The info action should just gather infomation about any ethernet devices
134+ # found and report for inclusion in e.g. an attachment job
135+ if action == 'info':
136+ # Report udev detected devices first
137+ if udev_devices:
138+ print_udev_devices()
139+
140+ # Attempt to report devices found by NetworkManager - this doesn't
141+ # make sense for server installs so skipping is acceptable
142+ try:
143+ nm_devices = get_nm_devices()
144+ except dbus.exceptions.DBusException:
145+ # server's don't have network manager installed
146+ print('Network Manager not found')
147+ else:
148+ print("[ Devices found by Network Manager ]".center(80, '-'))
149+ for nm_dev in nm_devices:
150+ print(nm_dev)
151
152- try:
153- nm_devices = get_nm_devices()
154- except dbus.exceptions.DBusException as e:
155- # server's don't have network manager installed
156- print("Warning: Exception while talking to Network Manager over dbus."
157- " Skipping the remainder of this test. If this is a server, this"
158- " is expected.", file=sys.stderr)
159- print("The Error Generated was:\n %s" % e, file=sys.stderr)
160- return 0
161-
162- print("[ Devices found by Network Manager ]".center(80, '-'))
163- for nm_dev in nm_devices:
164- print(nm_dev)
165-
166- if not match_counts(nm_devices, udev_devices, "Ethernet"):
167- return 1
168- else:
169- return 0
170
171 if __name__ == "__main__":
172- sys.exit(main(sys.argv[1:]))
173+ main()
174diff --git a/units/ethernet/jobs.pxu b/units/ethernet/jobs.pxu
175index cf1c02b..15625a5 100644
176--- a/units/ethernet/jobs.pxu
177+++ b/units/ethernet/jobs.pxu
178@@ -2,13 +2,15 @@ plugin: shell
179 category_id: com.canonical.plainbox::ethernet
180 id: ethernet/detect
181 flags: also-after-suspend
182-command: network_device_info
183+command: network_device_info.py detect
184 estimated_duration: 2.0
185 _summary:
186- Report info about available network devices
187+ Detect if at least one ethernet device is detected
188 _description:
189 Test to detect and return information about available network controllers on
190 the system under test.
191+imports: from com.canonical.plainbox import manifest
192+requires: manifest.has_ethernet_adapter == 'True'
193
194 plugin: shell
195 category_id: com.canonical.plainbox::ethernet
196diff --git a/units/ethernet/manifest.pxu b/units/ethernet/manifest.pxu
197new file mode 100644
198index 0000000..6936344
199--- /dev/null
200+++ b/units/ethernet/manifest.pxu
201@@ -0,0 +1,4 @@
202+unit: manifest entry
203+id: has_ethernet_adapter
204+_name: An Ethernet Adapter
205+value-type: bool
206diff --git a/units/info/jobs.pxu b/units/info/jobs.pxu
207index 3170566..93ccd92 100644
208--- a/units/info/jobs.pxu
209+++ b/units/info/jobs.pxu
210@@ -310,7 +310,7 @@ _description: Lists the device driver and version for all audio devices.
211 plugin: attachment
212 category_id: com.canonical.plainbox::info
213 id: info/network_devices
214-command: network_device_info
215+command: network_device_info.py info
216 estimated_duration: 0.550
217 _description: Provides information about network devices
218

Subscribers

People subscribed via source and target branches