[Libosinfo] [osinfo-db 2/2] test_media: Add detection test

Fabiano Fidêncio fidencio at redhat.com
Fri Mar 15 15:51:16 UTC 2019


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 at redhat.com>
---
 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




More information about the Libosinfo mailing list