The detection test is similar to test-isodetect from libosinfo, apart that it doesn't check for the filled-up languages in the matching media, as we're not using libosinfo API to actually have a OsinfoMedia entity. A new dependency has been introduced, python3-regex, as the built-in regex module for python doesn't cope with POSIX regex (which are used as part of our db). Signed-off-by: Fabiano Fidêncio <fidencio@xxxxxxxxxx> --- tests/unit/osinfo.py | 40 +++++++++++++++++++ tests/unit/test_media.py | 65 ++++++++++++++++++++++++++++--- tests/unit/util.py | 84 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 5 deletions(-) diff --git a/tests/unit/osinfo.py b/tests/unit/osinfo.py index b2d14c9..0b5e199 100644 --- a/tests/unit/osinfo.py +++ b/tests/unit/osinfo.py @@ -35,6 +35,11 @@ class Os(): return shortid.text shortid = property(_get_shortid) + def _get_distro(self): + distro = self._root.find('distro') + return distro.text + distro = property(_get_distro) + class Image(): def __init__(self, root): @@ -57,6 +62,41 @@ class Media(): return URL(url.text) url = property(_get_url) + def _get_iso(self): + iso = self._root.find('iso') + if iso is not None: + return ISO(iso) + iso = property(_get_iso) + + +class ISO(): + def __init__(self, root): + self._root = root + + def _get_value(self, name, type=str, default=''): + entry = self._root.find(name) + return type(entry.text) if entry is not None else default + + def _get_volumeid(self): + return self._get_value('volume-id') + volumeid = property(_get_volumeid) + + def _get_publisherid(self): + return self._get_value('publisher-id') + publisherid = property(_get_publisherid) + + def _get_applicationid(self): + return self._get_value('application-id') + applicationid = property(_get_applicationid) + + def _get_systemid(self): + return self._get_value('system-id') + systemid = property(_get_systemid) + + def _get_volumesize(self): + return self._get_value('volume-size', int, 0) + volumesize = property(_get_volumesize) + class Tree(): def __init__(self, root): diff --git a/tests/unit/test_media.py b/tests/unit/test_media.py index f779aaa..890174e 100644 --- a/tests/unit/test_media.py +++ b/tests/unit/test_media.py @@ -2,19 +2,74 @@ import os import pytest +import logging +import regex from . import util class TestMedia(): oses = util.oses() - def os_id(os): - return os.shortid + def os_id(osinfoos): + return osinfoos.shortid - @pytest.mark.parametrize('os', [*oses], ids=os_id) + @pytest.mark.parametrize('osinfoos', [*oses], ids=os_id) @pytest.mark.skipif(os.environ.get('OSINFO_DB_NETWORK_TESTS') is None, reason='Network related tests are not enabled') - def test_media_url(self, os): - for media in os.medias: + def test_media_url(self, osinfoos): + for media in osinfoos.medias: if media.url: assert(media.url.check()) + + @pytest.mark.parametrize('osinfoos', [*oses], ids=os_id) + def test_media_detection(self, osinfoos): + def match_iso(iso, isodata): + if iso.volumeid == '' and \ + iso.systemid == '' and \ + iso.publisherid == '' and \ + iso.applicationid == '' and \ + iso.volumesize == 0: + return False + + isovolsize = iso.volumesize + if isovolsize == 0: + isovolsize = isodata.volumesize + + if bool(regex.match(iso.volumeid, isodata.volumeid)) and \ + bool(regex.match(iso.publisherid, isodata.publisherid)) and \ + bool(regex.match(iso.applicationid, isodata.applicationid)) and \ + bool(regex.match(iso.systemid, isodata.systemid)) and \ + isovolsize == isodata.volumesize: + return True + return False + + isodata_medias = util.isodata_medias(osinfoos) + medias = osinfoos.medias + + for isodata_media in isodata_medias: + detected = [] + for o in self.oses: + for media in o.medias: + if match_iso(media.iso, isodata_media): + if o.shortid != osinfoos.shortid: + logging.warning( + 'ISO \'%s\' was matched by OS \'%s\' ' + 'while it should only be matched by OS ' + '\'%s\'' % + (isodata_media.filename, o.shortid, + osinfoos.shortid)) + else: + logging.info('ISO \'%s\' matched by OS \'%s\'' % + (isodata_media.filename, o.shortid)) + # For several distros we do not have the volume-size + # set as part of our DB, thus multiple detections may + # occur. Although this case is not the optimal, as long + # as we detect the very same distro it's okay-ish. + if not o.shortid in detected: + detected.append(o.shortid) + + if len(detected) != 1: + logging.warning('Some ISOs have been matched several times by ' + 'the different OSes, which indicates an issue ' + 'in the DB entries.') + assert(len(detected) == 1) diff --git a/tests/unit/util.py b/tests/unit/util.py index cdb657e..4a6b837 100644 --- a/tests/unit/util.py +++ b/tests/unit/util.py @@ -35,3 +35,87 @@ def oses(): for f in files: oses.append(osinfo.Os(_get_os(f))) return oses + + +class _IsoDataMedia(): + def __init__(self, filename, shortid, volumeid, publisherid, systemid, + applicationid, volumesize): + self.filename = filename + self.shortid = shortid + self.volumeid = volumeid if volumeid is not None else '' + self.publisherid = publisherid if publisherid is not None else '' + self.systemid = systemid if systemid is not None else '' + self.applicationid = applicationid \ + if applicationid is not None else '' + self.volumesize = volumesize if volumesize is not None else 0 + +def isodata_medias(osinfoos): + def _get_value(string, prefix, type=str): + if string.startswith(prefix): + return type(string.split(': ')[-1].strip()) + + def _get_volumeid(string): + return _get_value(string, 'Volume id: ') + + def _get_publisherid(string): + return _get_value(string, 'Publisher id: ') + + def _get_systemid(string): + return _get_value(string, 'System id: ') + + def _get_applicationid(string): + return _get_value(string, 'Application id: ') + + def _get_logicalblock(string): + return _get_value(string, 'Logical block size is: ', int) + + def _get_volumesize(string): + return _get_value(string, 'Volume size is: ', int) + + def _get_isodatamedia(filepath, shortid): + volumeid = None + publisherid = None + systemid = None + applicationid = None + logicalblock = None + volumesize = None + + with open(filepath, 'r') as f: + for line in f.readlines(): + if volumeid is None: + volumeid = _get_volumeid(line) + if publisherid is None: + publisherid = _get_publisherid(line) + if systemid is None: + systemid = _get_systemid(line) + if applicationid is None: + applicationid = _get_applicationid(line) + if logicalblock is None: + logicalblock = _get_logicalblock(line) + if volumesize is None: + volumesize = _get_volumesize(line) + + if logicalblock is not None and volumesize is not None: + volumesize *= logicalblock + else: + volumesize = None + + return _IsoDataMedia(filepath, shortid, volumeid, publisherid, + systemid, applicationid, volumesize) + + isodata_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + 'isodata') + shortid_path = os.path.join(isodata_path, + osinfoos.distro, osinfoos.shortid) + medias = [] + if not os.path.exists(shortid_path): + return [] + + for f in os.listdir(shortid_path): + path = os.path.join(shortid_path, f) + if not os.path.exists(path): + continue + + medias.append(_get_isodatamedia(path, osinfoos.shortid)) + return medias -- 2.20.1 _______________________________________________ Libosinfo mailing list Libosinfo@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libosinfo