summaryrefslogtreecommitdiff
diff options
authorPMR <pmr@pmr-lander>2020-02-07 16:56:09 +0000
committerPMR <pmr@pmr-lander>2020-02-07 16:56:09 +0000
commit4c53a3fe68a4f9fd0345b4823f7c79d4ed9c036f (patch)
treeb6c8dce5031762d8dc958e03f2f415e76bb510d1
parente2a8daf98c82d8a7ffcf6c817649a04e623538bd (diff)
parentb5801fcb1d27b900c2a87d6059b34f2e498b262a (diff)
Merge #378753 from ~jocave/plainbox-provider-checkbox:dkms-info-deguac
-rwxr-xr-xbin/dkms_info.py (renamed from bin/dkms_info)206
-rw-r--r--tests/test_dkms_info.py158
-rw-r--r--tests/test_recovery_info.py4
-rw-r--r--units/info/jobs.pxu2
-rw-r--r--units/submission/jobs.pxu2
5 files changed, 191 insertions, 181 deletions
diff --git a/bin/dkms_info b/bin/dkms_info.py
index 9b36a282..9addc2d9 100755
--- a/bin/dkms_info
+++ b/bin/dkms_info.py
@@ -4,6 +4,7 @@
# Written by:
# Shawn Wang <shawn.wang@canonical.com>
# Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
+# Jonathan Cave <jonathan.cave@canonical.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3,
@@ -30,6 +31,7 @@ supported output format:
- dumps: json output (fully information)
"""
+import argparse
import fnmatch
import functools
import email.parser
@@ -39,14 +41,7 @@ import logging
import os
import subprocess
import sys
-import unittest
-from guacamole import Command
-
-try:
- from unittest import mock
-except ImportError:
- from plainbox.vendor import mock
_logger = logging.getLogger(None)
@@ -158,99 +153,6 @@ def match_patterns(patterns):
return matched
-class SystemInfoTests(unittest.TestCase):
-
- """Tests for System Information Parsing and Collection."""
-
- _proc_modules = """\
-xt_REDIRECT 16384 3 - Live 0x0000000000000000
-nf_nat_redirect 16384 1 xt_REDIRECT, Live 0x0000000000000000
-xt_hl 16384 3 - Live 0x0000000000000000
-hid_generic 16384 0 - Live 0x0000000000000000
-usbhid 53248 0 - Live 0x0000000000000000
-hid 110592 2 hid_generic,usbhid, Live 0x0000000000000000
-overlay 45056 1 - Live 0x0000000000000000
-"""
- _modalias = """\
-usb:v1D6Bp0003d0319dc09dsc00dp03ic09isc00ip00in00
-"""
-
- def setUp(self):
- """Common setup code."""
- get_system_module_list.cache_clear()
- get_system_modaliases.cache_clear()
-
- @mock.patch('io.open', mock.mock_open(read_data=_proc_modules))
- def test_get_module_list__calls_and_parses_lsmod(self):
- """Ensure that get_module_list() parses lsmod output."""
- # NOTE: Return value was loaded from my system running kernel 4.0.
- # The first few and last rows to be precise.
- modules = get_system_module_list()
- self.assertEqual(modules, [
- 'xt_REDIRECT', 'nf_nat_redirect', 'xt_hl', 'hid_generic',
- 'usbhid', 'hid', 'overlay'])
-
- @mock.patch('io.open', mock.mock_open(read_data=_proc_modules))
- def test_get_module_list_is_cached(self):
- """Ensure that get_module_list() cache works."""
- modules1 = get_system_module_list()
- modules2 = get_system_module_list()
- self.assertIn('xt_REDIRECT', modules1)
- self.assertIn('overlay', modules2)
- self.assertEqual(modules1, modules2)
-
- @mock.patch('os.walk')
- @mock.patch('io.open', mock.mock_open(read_data=_modalias))
- def test_get_system_modalias(self, mock_os_walk):
- """test_get_system_modalias."""
- mock_os_walk.return_value = [
- ("/sys/devices/pci0000:00/0000:00:14.0/usb2/2-0:1.0/modalias",
- ["driver", "subsystem"],
- ["modalias", "uevent"]),
- ]
-
- """fetch hw_modaliases from machine and check modalis types."""
- modaliases = get_system_modaliases()
- self.assertEqual(len(modaliases), 1)
- self.assertIn("usb", modaliases)
-
- @mock.patch('os.uname')
- @mock.patch('os.walk')
- def test_get_installed_dkms_modules(self, mock_os_walk, mock_os_uname):
- """test_get_installed_dkms_modules."""
- mock_os_walk.return_value = [
- ("/var/lib/dkms/hello/0.1",
- ["3.19.0-15-generic", "build", "source"],
- []),
- ]
- o = mock.Mock()
- o.release = "3.19.0-15-generic"
- mock_os_uname.return_value = o
- self.assertEqual([['hello', '0.1']],
- get_installed_dkms_modules())
-
- @mock.patch('__main__.get_system_modaliases')
- def test_match_patterns(self, mock_get_system_modaliases):
- """Test of match_patterns."""
- mock_get_system_modaliases.return_value = {
- "pci": ["v0000168Cd00000036sv0000103Csd0000217Fbc02sc80i00",
- "v00008086d00008C26sv0000103Csd000022D9bc0Csc03i20"],
- "usb": ["v8087p8000d0005dc09dsc00dp01ic09isc00ip00in00",
- "v1D6Bp0002d0319dc09dsc00dp00ic09isc00ip00in00"],
- }
- pkg_modalieses = ["pci:v00008086d00008C26sv*sd*bc*sc*i*",
- "usb:v07B4p010Ad0102dc*dsc*dp*ic*isc*ip*in*",
- "oemalias:test"]
- matched_modalieses = match_patterns(tuple(pkg_modalieses))
- # match_patterns
- self.assertIn("pci:v00008086d00008C26sv*sd*bc*sc*i*",
- matched_modalieses)
- self.assertIn("oemalias:test",
- matched_modalieses)
- self.assertNotIn("usb:v07B4p010Ad0102dc*dsc*dp*ic*isc*ip*in*",
- matched_modalieses)
-
-
class DkmsPackage(object):
"""
@@ -295,9 +197,9 @@ class DkmsPackage(object):
if not fn.endswith(".list"):
continue
with io.open(os.path.join(dpkg_info_root, fn), 'rt',
- encoding='UTF-8') as stream:
+ encoding='UTF-8') as stream:
if path in stream.read():
- return fn[:-len(".list")]
+ return fn[:-len(".list")]
return None
def _list_modules(self):
@@ -350,6 +252,7 @@ class DkmsPackage(object):
install_mods[m] = match_patterns(tuple(aliases))
return install_mods
+
def _headers_to_dist(pkg_str):
"""
Convert rft822 headers string to dict.
@@ -366,6 +269,7 @@ def _headers_to_dist(pkg_str):
target[key.lower()] = header[key]
return target
+
class DebianPackageHandler(object):
"""Use rtf822(email) to handle the package information from file_object."""
@@ -396,7 +300,6 @@ class DebianPackageHandler(object):
for pkg_str in self._file_object.read().split('\n\n'):
yield pkg_str
-
def _get_device_pkgs(self):
"""
Only device packages have debian package header 'Modaliases'.
@@ -409,23 +312,21 @@ class DebianPackageHandler(object):
"""
_logger.info("Looking for packages providing modaliases")
- _modalias_pkgs = {}
- target_str = ""
result = {}
for pkg_str in self._gen_all_pkg_strs():
for pkg in self.extra_pkgs:
- if pkg.pkg_name is None:
- continue
- pstr = "Package: {}".format(pkg.pkg_name)
- if pstr in pkg_str:
- _logger.info("Gathering information of package, {}".format(
- pkg.pkg_name))
- pkg.pkg = _headers_to_dist(pkg_str)
- break
+ if pkg.pkg_name is None:
+ continue
+ pstr = "Package: {}".format(pkg.pkg_name)
+ if pstr in pkg_str:
+ _logger.info("Gathering information of package, {}".format(
+ pkg.pkg_name))
+ pkg.pkg = _headers_to_dist(pkg_str)
+ break
else:
- if "Modaliases:" in pkg_str:
+ if "Modaliases:" in pkg_str:
pkg = _headers_to_dist(pkg_str)
(modalias_header, pattern_str) = \
@@ -434,15 +335,17 @@ class DebianPackageHandler(object):
patterns.sort()
pkg['match_patterns'] = match_patterns(tuple(patterns))
- with io.open("/var/lib/dpkg/info/{}.list".format(pkg['package']),
- 'rt', encoding='UTF-8') as stream:
+ dpkgf = "/var/lib/dpkg/info/{}.list".format(pkg['package'])
+ with io.open(dpkgf, 'rt', encoding='UTF-8') as stream:
if "/dkms.conf" in stream.read():
- pkg['unused_dkms'] = True
+ pkg['unused_dkms'] = True
result[pkg['package']] = pkg
return result
def to_json(self):
- return json.dumps({ "dkms": self.extra_pkgs, "non-dkms": self.pkgs }, default=lambda o: o.__dict__, sort_keys=True, indent=4)
+ return json.dumps(
+ {"dkms": self.extra_pkgs, "non-dkms": self.pkgs},
+ default=lambda o: o.__dict__, sort_keys=True, indent=4)
def to_outline(self):
result = ""
@@ -467,48 +370,7 @@ class DebianPackageHandler(object):
return result
-class DebianPackageHandlerTest(unittest.TestCase):
-
- """Test of DebianPackageHandler."""
-
- _var_lib_dpkg_status = """\
-Package: foo
-Status: install ok installed
-Modaliases: hwe(pci:v000099DDd00000036sv*sd*bc*sc*i*)
-
-Package: foo1
-Status: install ok installed
-Modaliases: hwe(pci:v0000AADDd00000036sv*sd*bc*sc*i*)
-
-Package: foo2
-Status: install ok installed
-
-Package: foo3
-Status: install ok installed
-
-Package: bar
-Status: install ok installed
-
-"""
-
-
- @mock.patch('io.open', mock.mock_open(read_data=_var_lib_dpkg_status))
- @mock.patch('__main__.get_system_modaliases')
- def test_get_pkgs(self, mock_get_system_modaliases):
- """Test of test_get_pkgs."""
- mock_get_system_modaliases.return_value = {
- "pci": ["v0000168Cd00000036sv0000103Csd0000217Fbc02sc80i00",
- "v00008086d00008C26sv0000103Csd000022D9bc0Csc03i20"],
- "usb": ["v8087p8000d0005dc09dsc00dp01ic09isc00ip00in00",
- "v1D6Bp0002d0319dc09dsc00dp00ic09isc00ip00in00"],
- }
-
- self.pkg_handler = DebianPackageHandler(
- file_object=io.StringIO(self._var_lib_dpkg_status))
- self.assertEqual(len(self.pkg_handler.pkgs), 2)
-
-
-class DeviceInfo(Command):
+class DeviceInfo():
"""
Implementation of the dkms-info command.
@@ -529,37 +391,35 @@ class DeviceInfo(Command):
- dumps: json output (fully information)
"""
- def register_arguments(self, parser):
- """Register command line arguments for dkms-info."""
-
+ def main(self):
+ """Invoke dkms-info."""
+ parser = argparse.ArgumentParser()
parser.add_argument(
'--format', default="onelines",
choices=["summary", "json"],
help=("Choose output format type: "
"summary (one line per packages) "
"or json (json format, fully information)"))
-
parser.add_argument(
'--output', default=None,
help=("Output filename to store the output date"))
+ args = parser.parse_args()
- def invoked(self, ctx):
- """Invoke dkms-info."""
logging.basicConfig(
level=logging.INFO, format='[%(relativeCreated)06dms] %(message)s')
_logger.info("Started")
- dkms_pkgs = []
+ dkms_pkgs = []
for (dkms_name, dkms_ver) in get_installed_dkms_modules():
dkms_pkg = DkmsPackage(dkms_name, dkms_ver)
dkms_pkgs.append(dkms_pkg)
output = sys.stdout
- if ctx.args.output is not None:
- output = open(ctx.args.output, 'wt', encoding='UTF-8')
+ if args.output is not None:
+ output = open(args.output, 'wt', encoding='UTF-8')
pkg_handler = DebianPackageHandler(extra_pkgs=dkms_pkgs)
- if ctx.args.format == "summary":
+ if args.format == "summary":
output.write(pkg_handler.to_outline())
else:
output.write(pkg_handler.to_json())
@@ -567,8 +427,4 @@ class DeviceInfo(Command):
if __name__ == '__main__':
- if '--test' in sys.argv:
- sys.argv.remove('--test')
- unittest.main()
- else:
- DeviceInfo().main()
+ DeviceInfo().main()
diff --git a/tests/test_dkms_info.py b/tests/test_dkms_info.py
new file mode 100644
index 00000000..30f3ae48
--- /dev/null
+++ b/tests/test_dkms_info.py
@@ -0,0 +1,158 @@
+#!/usr/bin/env python3
+# encoding: utf-8
+# Copyright 2015 Canonical Ltd.
+# Written by:
+# Shawn Wang <shawn.wang@canonical.com>
+# Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
+# Jonathan Cave <jonathan.cave@canonical.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3,
+# as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import io
+import unittest
+from unittest import mock
+
+import dkms_info
+
+
+class SystemInfoTests(unittest.TestCase):
+
+ """Tests for System Information Parsing and Collection."""
+
+ _proc_modules = """\
+xt_REDIRECT 16384 3 - Live 0x0000000000000000
+nf_nat_redirect 16384 1 xt_REDIRECT, Live 0x0000000000000000
+xt_hl 16384 3 - Live 0x0000000000000000
+hid_generic 16384 0 - Live 0x0000000000000000
+usbhid 53248 0 - Live 0x0000000000000000
+hid 110592 2 hid_generic,usbhid, Live 0x0000000000000000
+overlay 45056 1 - Live 0x0000000000000000
+"""
+ _modalias = """\
+usb:v1D6Bp0003d0319dc09dsc00dp03ic09isc00ip00in00
+"""
+
+ def setUp(self):
+ """Common setup code."""
+ dkms_info.get_system_module_list.cache_clear()
+ dkms_info.get_system_modaliases.cache_clear()
+
+ @mock.patch('io.open', mock.mock_open(read_data=_proc_modules))
+ def test_get_module_list__calls_and_parses_lsmod(self):
+ """Ensure that get_module_list() parses lsmod output."""
+ # NOTE: Return value was loaded from my system running kernel 4.0.
+ # The first few and last rows to be precise.
+ modules = dkms_info.get_system_module_list()
+ self.assertEqual(modules, [
+ 'xt_REDIRECT', 'nf_nat_redirect', 'xt_hl', 'hid_generic',
+ 'usbhid', 'hid', 'overlay'])
+
+ @mock.patch('io.open', mock.mock_open(read_data=_proc_modules))
+ def test_get_module_list_is_cached(self):
+ """Ensure that get_module_list() cache works."""
+ modules1 = dkms_info.get_system_module_list()
+ modules2 = dkms_info.get_system_module_list()
+ self.assertIn('xt_REDIRECT', modules1)
+ self.assertIn('overlay', modules2)
+ self.assertEqual(modules1, modules2)
+
+ @mock.patch('os.walk')
+ @mock.patch('io.open', mock.mock_open(read_data=_modalias))
+ def test_get_system_modalias(self, mock_os_walk):
+ """test_get_system_modalias."""
+ mock_os_walk.return_value = [
+ ("/sys/devices/pci0000:00/0000:00:14.0/usb2/2-0:1.0/modalias",
+ ["driver", "subsystem"],
+ ["modalias", "uevent"]),
+ ]
+
+ """fetch hw_modaliases from machine and check modalis types."""
+ modaliases = dkms_info.get_system_modaliases()
+ self.assertEqual(len(modaliases), 1)
+ self.assertIn("usb", modaliases)
+
+ @mock.patch('os.uname')
+ @mock.patch('os.walk')
+ def test_get_installed_dkms_modules(self, mock_os_walk, mock_os_uname):
+ """test_get_installed_dkms_modules."""
+ mock_os_walk.return_value = [
+ ("/var/lib/dkms/hello/0.1",
+ ["3.19.0-15-generic", "build", "source"],
+ []),
+ ]
+ o = mock.Mock()
+ o.release = "3.19.0-15-generic"
+ mock_os_uname.return_value = o
+ self.assertEqual([['hello', '0.1']],
+ dkms_info.get_installed_dkms_modules())
+
+ @mock.patch('dkms_info.get_system_modaliases')
+ def test_match_patterns(self, mock_get_system_modaliases):
+ """Test of match_patterns."""
+ mock_get_system_modaliases.return_value = {
+ "pci": ["v0000168Cd00000036sv0000103Csd0000217Fbc02sc80i00",
+ "v00008086d00008C26sv0000103Csd000022D9bc0Csc03i20"],
+ "usb": ["v8087p8000d0005dc09dsc00dp01ic09isc00ip00in00",
+ "v1D6Bp0002d0319dc09dsc00dp00ic09isc00ip00in00"],
+ }
+ pkg_modalieses = ["pci:v00008086d00008C26sv*sd*bc*sc*i*",
+ "usb:v07B4p010Ad0102dc*dsc*dp*ic*isc*ip*in*",
+ "oemalias:test"]
+ matched_modalieses = dkms_info.match_patterns(tuple(pkg_modalieses))
+ # match_patterns
+ self.assertIn("pci:v00008086d00008C26sv*sd*bc*sc*i*",
+ matched_modalieses)
+ self.assertIn("oemalias:test",
+ matched_modalieses)
+ self.assertNotIn("usb:v07B4p010Ad0102dc*dsc*dp*ic*isc*ip*in*",
+ matched_modalieses)
+
+
+class DebianPackageHandlerTest(unittest.TestCase):
+
+ """Test of DebianPackageHandler."""
+
+ _var_lib_dpkg_status = """\
+Package: foo
+Status: install ok installed
+Modaliases: hwe(pci:v000099DDd00000036sv*sd*bc*sc*i*)
+
+Package: foo1
+Status: install ok installed
+Modaliases: hwe(pci:v0000AADDd00000036sv*sd*bc*sc*i*)
+
+Package: foo2
+Status: install ok installed
+
+Package: foo3
+Status: install ok installed
+
+Package: bar
+Status: install ok installed
+
+"""
+
+ @mock.patch('io.open', mock.mock_open(read_data=_var_lib_dpkg_status))
+ @mock.patch('dkms_info.get_system_modaliases')
+ def test_get_pkgs(self, mock_get_system_modaliases):
+ """Test of test_get_pkgs."""
+ mock_get_system_modaliases.return_value = {
+ "pci": ["v0000168Cd00000036sv0000103Csd0000217Fbc02sc80i00",
+ "v00008086d00008C26sv0000103Csd000022D9bc0Csc03i20"],
+ "usb": ["v8087p8000d0005dc09dsc00dp01ic09isc00ip00in00",
+ "v1D6Bp0002d0319dc09dsc00dp00ic09isc00ip00in00"],
+ }
+
+ self.pkg_handler = dkms_info.DebianPackageHandler(
+ file_object=io.StringIO(self._var_lib_dpkg_status))
+ self.assertEqual(len(self.pkg_handler.pkgs), 2)
diff --git a/tests/test_recovery_info.py b/tests/test_recovery_info.py
index 53cb1daa..19658712 100644
--- a/tests/test_recovery_info.py
+++ b/tests/test_recovery_info.py
@@ -18,14 +18,10 @@
import os
import unittest
-# try:
from unittest import mock
from unittest.mock import patch
import sys
-# except ImportError:
-# from plainbox.vendor import mock
-
import recovery_info
diff --git a/units/info/jobs.pxu b/units/info/jobs.pxu
index 48a71dfb..e1d56aea 100644
--- a/units/info/jobs.pxu
+++ b/units/info/jobs.pxu
@@ -218,7 +218,7 @@ plugin: attachment
category_id: com.canonical.plainbox::info
requires:
package.name == 'dkms'
-command: dkms_info --format json
+command: dkms_info.py --format json
_description: Attaches json dumps of installed dkms package information.
_summary: Attaches json dumps of installed dkms package information.
diff --git a/units/submission/jobs.pxu b/units/submission/jobs.pxu
index 7a9b2aae..e0829b63 100644
--- a/units/submission/jobs.pxu
+++ b/units/submission/jobs.pxu
@@ -2,7 +2,7 @@ id: dkms_info_json
plugin: attachment
category_id: com.canonical.plainbox::info
command:
- dkms_info --format json | python3 -m plainbox dev parse dkms-info | \
+ dkms_info.py --format json | python3 -m plainbox dev parse dkms-info | \
jq '.dkms_info'
_description: Attaches json dumps of installed dkms package information.
_summary: Attaches json dumps of installed dkms package information.