diff options
author | PMR <pmr@pmr-lander> | 2020-02-07 16:56:09 +0000 |
---|---|---|
committer | PMR <pmr@pmr-lander> | 2020-02-07 16:56:09 +0000 |
commit | 4c53a3fe68a4f9fd0345b4823f7c79d4ed9c036f (patch) | |
tree | b6c8dce5031762d8dc958e03f2f415e76bb510d1 | |
parent | e2a8daf98c82d8a7ffcf6c817649a04e623538bd (diff) | |
parent | b5801fcb1d27b900c2a87d6059b34f2e498b262a (diff) |
Merge #378753 from ~jocave/plainbox-provider-checkbox:dkms-info-deguac
-rwxr-xr-x | bin/dkms_info.py (renamed from bin/dkms_info) | 206 | ||||
-rw-r--r-- | tests/test_dkms_info.py | 158 | ||||
-rw-r--r-- | tests/test_recovery_info.py | 4 | ||||
-rw-r--r-- | units/info/jobs.pxu | 2 | ||||
-rw-r--r-- | units/submission/jobs.pxu | 2 |
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. |