#1 initial commit
Merged 8 years ago by mcurlej. Opened 8 years ago by mcurlej.
mcurlej/module_diff initial_commit  into  master

file added
+6
@@ -0,0 +1,6 @@ 

+ *.swp

+ report.xml

+ .ropeproject/

+ .cache/

+ *.egg-info/

+ *__pycache__/

file modified
+27 -1
@@ -1,3 +1,29 @@ 

  # module_diff

  

- Creates diffs between 2 versions of  module. 

\ No newline at end of file

+ Creates diffs between 2 versions of module. Written in Python 3.

+ 

+ # Development

+ 

+ Has external dependencies (koji, rpm etc.) so you need to enable site-packages when creating venv.

+ 

+ To install the tool do:

+ 

+ ```

+ python setup.py install

+ ```

+ 

+ For development create a venv with site-packages enabled and do:

+ 

+ ```

+ python setup.py develop

+ ```

+ 

+ # Tests

+ 

+ To run tests do:

+ ```

+ python -m pytest -s

+ ```

+ 

+ 

+ 

file added
+28
@@ -0,0 +1,28 @@ 

+ #!/bin/env python3

+ 

+ import argparse

+ from module_diff import module_diff

+ 

+ 

+ def main(org_nsv, diff_nsv, json=False, dist=False, reused=False):

+     module_diff(org_nsv, diff_nsv, json=json)

+ 

+ 

+ def parse_arguments():

+     parser = argparse.ArgumentParser()

+     parser.add_argument("org_nsv", action="store",

+                         help="The NSV of a module we are comparing to.")

+     parser.add_argument("diff_nsv", action="store",

+                         help="The NSV of a module we want to compare.")

+     parser.add_argument("-j", "--json",  action="store_true",

+                         help="The module diff will returned as json.")

+     parser.add_argument("-d", "--dist",  action="store_true",

+                         help="Will display also rpms with changed only dist tag")

+     parser.add_argument("-r", "--reused",  action="store_true",

+                         help="Will display also rpms which where reused between versions.")

+ 

+     return parser.parse_args()

+ 

+ if __name__ == "__main__":

+     args = parse_arguments()

+     main(args.org_nsv, args.diff_nsv, json=args.json, dist=args.dist, reused=args.reused)

@@ -0,0 +1,69 @@ 

+ import json

+ from module_diff.pdc import PDC

+ 

+ 

+ class CliColors:

+     HEADER = '\033[95m'

+     OKBLUE = '\033[94m'

+     OKGREEN = '\033[92m'

+     WARNING = '\033[93m'

+     FAIL = '\033[91m'

+     ENDC = '\033[0m'

+     BOLD = '\033[1m'

+     UNDERLINE = '\033[4m'

+ 

+ 

+ def module_diff(org_nsv, diff_nsv, json=False, dist=False, reused=False):

+     pdc = PDC()

+     # TODO is check for not found module needed?

+     org_module = pdc.get_module(org_nsv)

+     diff_module = pdc.get_module(diff_nsv)

+ 

+     diff = org_module.get_diff(diff_module, dist=dist, reused=reused)

+     if json:

+         jsonify_diff(diff)

+     else:

+         human_readable_diff(diff, reused=reused, dist=dist)

+ 

+ 

+ def human_readable_diff(diff, reused=False, dist=False):

+     print("---- Stats ----\n")

+     stats = diff["stats"]

+     print("Compared modules:")

+     print("NSV: %s, # of RPMs: %s" % (stats["org_module"]["nsv"], stats["org_module"]["num_rpms"]))

+     print("NSV: %s, # of RPMs: %s" % (stats["diff_module"]["nsv"], stats["diff_module"]["num_rpms"]))

+     print("# of RPMs added: %s" % stats["num_added"])

+     print("# of RPMs removed: %s" % stats["num_removed"])

+     print("# of RPMs upgraded: %s" % stats["num_upgraded"])

+     print("# of RPMs downgraded: %s" % stats["num_downgraded"])

+ 

+     if reused:

+         print("# of RPMs reused: %s" % stats["num_reused"])

+ 

+     if dist:

+         print("# of RPMs which dist tag changed: %s" % stats["changed_distag_rpms"])

+ 

+     print("---- RPMs Added ----\n")

+     for rpm in diff["added_rpms"]:

+         print("%s+ %s%s" % (CliColors.OKGREEN, rpm, CliColors.ENDC))

+     print("\n---- RPMs Removed ----\n")

+     for rpm in diff["removed_rpms"]:

+         print("%s- %s%s" % (CliColors.FAIL, rpm, CliColors.ENDC))

+     print("\n---- RPMs Upgraded ----\n")

+     for rpm in diff["upgraded_rpms"]:

+         print("U %s -> %s" % (rpm[0], rpm[1]))

+     print("\n---- RPMs Downgraded ----\n")

+     for rpm in diff["downgraded_rpms"]:

+         print("D %s -> %s" % (rpm[0], rpm[1]))

+     if reused:

+         print("\n---- RPMs Reused ----\n")

+         for rpm in diff["reused_rpms"]:

+             print("R %s" % rpm)

+ 

+     if dist:

+         print("\n---- RPMs which dist tag changed ----\n")

+         for rpm in diff["changed_distag_rpms"]:

+             print("C %s -> %s" % (rpm[0], rpm[1]))

+ 

+ def jsonify_diff(diff):

+     print(json.dumps(diff))

file added
+157
@@ -0,0 +1,157 @@ 

+ import re

+ 

+ from kobo.rpmlib import parse_nvr, compare_nvr

+ 

+ from modulemd import ModuleMetadata

+ 

+ 

+ class Module(object):

+     """ Represents a Module for diff purposes. """

+ 

+     def __init__(self, pdc_module_data):

+         """

+         Args:

+             pdc_module_data (dict): the module data PDC response.

+         """

+         module_data = pdc_module_data["results"][0]

+         self.variant_uid = module_data["variant_uid"]

+         self.variant_name = module_data["variant_name"]

+         self.variant_version = module_data["variant_version"]

+         self.variant_release = module_data["variant_release"]

+         self.koji_tag = module_data["koji_tag"]

+         self.dist_tag = module_data["koji_tag"][0:15].replace("-", "_")

+         self.pdc_modulemd = module_data["modulemd"]

+         self.rpms_set = set(module_data["rpms"])

+ 

+     @property

+     def modulemd(self):

+         """

+         returns:

+             (ModuleMetadata): Metadata of the current module.

+         """

+         if not hasattr(self, "mmd"):

+             self.mmd = ModuleMetadata()

+             self.mmd.loads(self.pdc_modulemd)

+         return self.mmd

+ 

+     def get_diff(self, diff_module, dist=False, reused=False):

+         """

+         Makes a diff between 2 modules.

+         Args:

+             diff_module (Module): Other Module object which we want to diff.

+ 

+         Returns:

+             (dict): returns a dict with the results of a diff

+         """

+ 

+         if self.variant_name != diff_module.variant_name and \

+                 self.variant_version != diff_module.variant_version:

+             # NOTE Should we allow between stream diff?

+             message = ("Module %s and %s don't have the same name and stream! Can't diff!"

+                        % (self.variant_uid, diff_module.variant_uid))

+             raise ValueError(message)

+ 

+         diff = {}

+         diff["stats"] = {}

+         added_rpms = []

+         removed_rpms = []

+         upgraded_rpms = []

+         downgraded_rpms = []

+         reused_rpms = []

+         changed_distag_rpms = []

+ 

+         # first search for full matches, so we can remove reused rpms from previous builds

+         for org_rpm in self.rpms_set:

+             if org_rpm in diff_module.rpms_set:

+                 reused_rpms.append(org_rpm)

+             else:

+                 removed_rpms.append(org_rpm)

+ 

+         added_rpms = list(diff_module.rpms_set - self.rpms_set)

+ 

+         # now when we have reused rpms out of the way, we will inspect the removed and added rpms

+         # closely what changes where made to them. We need to have both lists with elements or we

+         # can't compare.

+         if removed_rpms and added_rpms:

+             removed_rpm_md = []

+             added_rpm_md = []

+ 

+             # get metadata from both lists

+             for rpm in removed_rpms:

+                 removed_rpm_md.append(self.get_rpm_md(rpm))

+ 

+             for rpm in added_rpms:

+                 added_rpm_md.append(self.get_rpm_md(rpm))

+ 

+             for rem_rpm in removed_rpm_md:

+                 for add_rpm in added_rpm_md:

+                     # if we have a match between removed and added lists it means that the the rpm

+                     # was not removed/added but there was some other change i. e. version change.

+                     if rem_rpm["name"] == add_rpm["name"] and rem_rpm["arch"] == add_rpm["arch"]:

+                         # we compare the versions of the rpms

+                         result = compare_nvr(rem_rpm, add_rpm)

+ 

+                         if result == -1:

+                             upgraded_rpms.append((rem_rpm["full_name"], add_rpm["full_name"]))

+                             removed_rpms.remove(rem_rpm["full_name"])

+                             added_rpms.remove(add_rpm["full_name"])

+                         elif result == 1:

+                             downgraded_rpms.append((rem_rpm["full_name"], add_rpm["full_name"]))

+                             removed_rpms.remove(rem_rpm["full_name"])

+                             added_rpms.remove(add_rpm["full_name"])

+                         else:

+                             # if the modules have the same version the only change is the dist tag.

+                             changed_distag_rpms.append((rem_rpm["full_name"], add_rpm["full_name"]))

+                             removed_rpms.remove(rem_rpm["full_name"])

+                             added_rpms.remove(add_rpm["full_name"])

+ 

+         diff["stats"]["org_module"] = {}

+         diff["stats"]["org_module"]["num_rpms"] = len(self.rpms_set)

+         diff["stats"]["org_module"]["nsv"] = self.variant_uid

+         diff["stats"]["diff_module"] = {}

+         diff["stats"]["diff_module"]["num_rpms"] = len(diff_module.rpms_set)

+         diff["stats"]["diff_module"]["nsv"] = diff_module.variant_uid

+         diff["stats"]["num_added"] = len(added_rpms)

+         diff["stats"]["num_removed"] = len(removed_rpms)

+         diff["stats"]["num_upgraded"] = len(upgraded_rpms)

+         diff["stats"]["num_downgraded"] = len(downgraded_rpms)

+         diff["added_rpms"] = added_rpms

+         diff["removed_rpms"] = removed_rpms

+         diff["upgraded_rpms"] = upgraded_rpms

+         diff["downgraded_rpms"] = downgraded_rpms

+ 

+         if reused:

+             diff["stats"]["num_reused"] = len(reused_rpms)

+             diff["reused_rpms"] = reused_rpms

+ 

+         if dist:

+             diff["stats"]["num_changed_dist"] = len(changed_distag_rpms)

+             diff["changed_distag_rpms"] = changed_distag_rpms

+ 

+         return diff

+ 

+     def get_rpm_md(self, rpm):

+         """

+         Args:

+             rpm (str): full name of the rpm.

+ 

+         Returns:

+             (dict): metadata for a given rpm

+         """

+         md = {}

+         nvr_md = rpm.rsplit(".", 3)

+         # NOTE we are creating an NVR here without the module dist tag. As kobo.rpmlib.parse_nvr is

+         # not able to work with modules and will be not able to compare the rpms correctly.

+         nvr = "".join(nvr_md[0:1] + nvr_md[2:])

+         md = parse_nvr(nvr)

+         md["full_name"] = rpm

+         # The release can be different for each rpm. We are using regex as we are not able to

+         # extract the dist tag other way.

+         match = re.search("\.(module\_\w+)\.", rpm)

+         md["dist_tag"] = match.group(1)

+         md["arch"] = nvr_md[2]

+ 

+         return md

+ 

+     def diff_modulemd(self):

+         pass

file added
+20
@@ -0,0 +1,20 @@ 

+ import pdc_client

+ 

+ from module_diff.module import Module

+ 

+ 

+ class PDC(object):

+ 

+     def __init__(self):

+         self.module_namespace = "unreleasedvariants/"

+         self.pdc_url = "https://pdc.fedoraproject.org/rest_api/v1"

+         self.ssl_verify = False

+         self.develop = True

+         self.client = pdc_client.PDCClient(server=self.pdc_url, develop=self.develop,

+                                            ssl_verify=self.ssl_verify)

+ 

+     def get_module(self, nsv):

+         pdc_module_data = self.client[self.module_namespace](page_size=1, **{"variant_uid": nsv})

+         if not len(pdc_module_data["results"]):

+             raise Exception("No data found for module '%s' in PDC" % nsv)

+         return Module(pdc_module_data)

file added
+2
@@ -0,0 +1,2 @@ 

+ modulemd==1.3.2

+ pdc-client==1.7.0

file added
+30
@@ -0,0 +1,30 @@ 

+ from setuptools import setup, find_packages

+ 

+ with open('requirements.txt') as f:

+     requirements = f.readlines()

+ 

+ with open('test-requirements.txt') as f:

+     test_requirements = f.readlines()

+ 

+ setup(name='module_diff',

+       description='Diffing tool for modules.',

+       version='1.0',

+       classifiers=[

+           "Programming Language :: Python",

+           "Topic :: Software Development :: Build Tools"

+       ],

+       keywords='module build service utils fedora modularity koji mock rpm',

+       author='The Factory 2.0 Team',

+       author_email='mcurlej@redhat.com',

+       url='',

+       license='MIT',

+       packages=find_packages(),

+       include_package_data=True,

+       zip_safe=False,

+       install_requires=requirements,

+       tests_require=test_requirements,

+       entry_points={},

+       scripts=["bin/module_diff"],

+       data_files=[],

+       )

+ 

@@ -0,0 +1,2 @@ 

+ pytest==3.2.5

+ requests-mock==1.3.0

file added
+82
@@ -0,0 +1,82 @@ 

+ import copy

+ import pytest

+ 

+ 

+ @pytest.fixture

+ def pdc_json_res():

+     """ Mock for module PDC response data """

+ 

+     dummy_mmd = ('data:\n  components:\n    rpms:\n      mariadb:\n        rationale: mariadb\n'

+                  '        ref: master\n  dependencies:\n    buildrequires:\n      host: master\n'

+                  '      platform: master\n    requires:\n      platform: master\n  description: '

+                  'desc\n  license:\n    module:\n    - MIT\n  references:\n    community: '

+                  'modularity\n    documentation: wiki\n  summary: dummy\ndocument: modulemd'

+                  '\nversion: 1\n')

+ 

+     pdc_data = {

+         "count": 1,

+         "next": None,

+         "previous": None,

+         "results": [

+             {

+                 "variant_id": "mariadb",

+                 "variant_uid": "mariadb-f26-20170517122119",

+                 "variant_name": "mariadb",

+                 "variant_type": "module",

+                 "variant_version": "f26",

+                 "variant_release": "20170517122119",

+                 "koji_tag": "module-629c669e304b6950",

+                 "modulemd": dummy_mmd,

+                 "active": True,

+                 "runtime_deps": [

+                     {

+                         "dependency": "perl",

+                         "stream": "f26"

+                     },

+                     {

+                         "dependency": "shared-userspace",

+                         "stream": "f26"

+                     },

+                     {

+                         "dependency": "base-runtime",

+                         "stream": "f26"

+                     }

+                 ],

+                 "build_deps": [

+                     {

+                         "dependency": "perl",

+                         "stream": "f26"

+                     },

+                     {

+                         "dependency": "common-build-dependencies",

+                         "stream": "f26"

+                     },

+                     {

+                         "dependency": "shared-userspace",

+                         "stream": "f26"

+                     },

+                     {

+                         "dependency": "bootstrap",

+                         "stream": "f26"

+                     }

+                 ],

+                 "rpms": [

+                     "mariadb-3:10.2.9-3.module_629c669e.src.rpm",

+                     "mariadb-debugsource-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                     "mariadb-connect-engine-debuginfo-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                     "mariadb-debuginfo-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                     "mariadb-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                     "mariadb-devel-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                     "mariadb-connect-engine-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 ]

+             }

+         ]

+     }

+ 

+     # using the same data for multiple testcases, we are modifying it heavilly so we need a copy

+     # everytime

+     class PDCDataFactory(object):

+         def get(self):

+             return copy.deepcopy(pdc_data)

+ 

+     return PDCDataFactory()

file added
+221
@@ -0,0 +1,221 @@ 

+ import pytest

+ import requests_mock

+ 

+ from module_diff.pdc import PDC

+ 

+ 

+ module1_url = ("https://pdc.fedoraproject.org/rest_api/v1"

+                "/unreleasedvariants/"

+                "?page_size=1&variant_uid=mariadb-10.2-20171019133930")

+ 

+ module2_url = ("https://pdc.fedoraproject.org/rest_api/v1"

+                "/unreleasedvariants/"

+                "?page_size=1&variant_uid=mariadb-10.2-20171103103655")

+ 

+ module_diff_ns_url = ("https://pdc.fedoraproject.org/rest_api/v1"

+                       "/unreleasedvariants/"

+                       "?page_size=1&variant_uid=platform-f27-20171011150016")

+ 

+ 

+ @pytest.mark.usefixtures("pdc_json_res")

+ class TestModule(object):

+     """

+     Test for the Module Class

+     """

+ 

+     def test_get_diff_no_diff(self, pdc_json_res):

+         """ Test if we dont have any diff between modules. """

+ 

+         module1_res = pdc_json_res.get()

+         module2_res = pdc_json_res.get()

+         module2_res["results"][0]["koji_tag"] = "module-15d35d06c29b1848"

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.register_uri("GET", module1_url, json=module1_res)

+             mock_http.register_uri("GET", module2_url, json=module2_res)

+             pdc = PDC()

+             module1 = pdc.get_module("mariadb-10.2-20171019133930")

+             module2 = pdc.get_module("mariadb-10.2-20171103103655")

+ 

+         diff = module1.get_diff(module2, reused=True)

+ 

+         assert diff["added_rpms"] == []

+         assert diff["removed_rpms"] == []

+         assert diff["upgraded_rpms"] == []

+         assert diff["downgraded_rpms"] == []

+         assert len(diff["reused_rpms"]) == 7

+ 

+     def test_get_diff(self, pdc_json_res):

+         """ Testing different kinds of changes in modules """

+ 

+         module1_res = pdc_json_res.get()

+         module2_res = pdc_json_res.get()

+         module1_res["results"][0]["rpms"].remove(

+             "mariadb-connect-engine-3:10.2.9-3.module_629c669e.x86_64.rpm")

+         module2_res["results"][0]["koji_tag"] = "module-15d35d06c29b1848"

+         module2_res["results"][0]["rpms"] = [

+                 "mariadb-debugsource-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-connect-engine-debuginfo-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-debuginfo-3:11.2.9-3.module_15d35d06.x86_64.rpm",

+                 "mariadb-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-devel-3:9.2.9-3.module_15d35d06.x86_64.rpm",

+                 "mariadb-connect-engine-3:10.2.9-3.module_15d35d06.x86_64.rpm"

+         ]

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.register_uri("GET", module1_url, json=module1_res)

+             mock_http.register_uri("GET", module2_url, json=module2_res)

+             pdc = PDC()

+             module1 = pdc.get_module("mariadb-10.2-20171019133930")

+             module2 = pdc.get_module("mariadb-10.2-20171103103655")

+ 

+         diff = module1.get_diff(module2, reused=True)

+ 

+         assert diff["added_rpms"] == [

+             "mariadb-connect-engine-3:10.2.9-3.module_15d35d06.x86_64.rpm"]

+         assert diff["removed_rpms"] == ["mariadb-3:10.2.9-3.module_629c669e.src.rpm"]

+         assert diff["upgraded_rpms"] == [

+             ('mariadb-debuginfo-3:10.2.9-3.module_629c669e.x86_64.rpm',

+              'mariadb-debuginfo-3:11.2.9-3.module_15d35d06.x86_64.rpm')]

+         assert diff["downgraded_rpms"] == [

+             ('mariadb-devel-3:10.2.9-3.module_629c669e.x86_64.rpm',

+              'mariadb-devel-3:9.2.9-3.module_15d35d06.x86_64.rpm')]

+         assert len(diff["reused_rpms"]) == 3

+ 

+     def test_get_diff_rpm_version_change(self, pdc_json_res):

+         """ Testing if a version changes """

+ 

+         module1_res = pdc_json_res.get()

+         module2_res = pdc_json_res.get()

+         module2_res["results"][0]["koji_tag"] = "module-15d35d06c29b1848"

+         module2_res["results"][0]["rpms"] = [

+                 "mariadb-3:10.2.9-3.module_629c669e.src.rpm",

+                 "mariadb-debugsource-3:11.2.9-3.module_15d35d06.x86_64.rpm",

+                 "mariadb-connect-engine-debuginfo-3:10.2.8-3.module_15d35d06.x86_64.rpm",

+                 "mariadb-debuginfo-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-devel-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-connect-engine-3:10.2.9-3.module_629c669e.x86_64.rpm"

+         ]

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.register_uri("GET", module1_url, json=module1_res)

+             mock_http.register_uri("GET", module2_url, json=module2_res)

+             pdc = PDC()

+             module1 = pdc.get_module("mariadb-10.2-20171019133930")

+             module2 = pdc.get_module("mariadb-10.2-20171103103655")

+ 

+         diff = module1.get_diff(module2, reused=True)

+ 

+         assert diff["added_rpms"] == []

+         assert diff["removed_rpms"] == []

+         assert diff["upgraded_rpms"] == [

+             ('mariadb-debugsource-3:10.2.9-3.module_629c669e.x86_64.rpm',

+              'mariadb-debugsource-3:11.2.9-3.module_15d35d06.x86_64.rpm')]

+         assert diff["downgraded_rpms"] == [

+             ('mariadb-connect-engine-debuginfo-3:10.2.9-3.module_629c669e.x86_64.rpm',

+              'mariadb-connect-engine-debuginfo-3:10.2.8-3.module_15d35d06.x86_64.rpm')]

+         assert len(diff["reused_rpms"]) == 5

+ 

+     def test_get_diff_rpm_removed(self, pdc_json_res):

+         """ Testing if the module changes of an RPM """

+ 

+         module1_res = pdc_json_res.get()

+         module2_res = pdc_json_res.get()

+         module2_res["results"][0]["koji_tag"] = "module-15d35d06c29b1848"

+         module2_res["results"][0]["rpms"].remove("mariadb-3:10.2.9-3.module_629c669e.src.rpm")

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.register_uri("GET", module1_url, json=module1_res)

+             mock_http.register_uri("GET", module2_url, json=module2_res)

+             pdc = PDC()

+             module1 = pdc.get_module("mariadb-10.2-20171019133930")

+             module2 = pdc.get_module("mariadb-10.2-20171103103655")

+ 

+         diff = module1.get_diff(module2, reused=True)

+ 

+         assert diff["added_rpms"] == []

+         assert diff["removed_rpms"] == ["mariadb-3:10.2.9-3.module_629c669e.src.rpm"]

+         assert diff["upgraded_rpms"] == []

+         assert diff["downgraded_rpms"] == []

+         assert len(diff["reused_rpms"]) == 6

+ 

+     def test_get_diff_different_ns(self, pdc_json_res):

+         """

+         If we have different name and stream between compared modules an error should be raised

+         """

+         module1_res = pdc_json_res.get()

+         module2_res = pdc_json_res.get()

+         module2_res["results"][0]["variant_uid"] = "platform-f27-20171011150016"

+         module2_res["results"][0]["variant_name"] = "platform"

+         module2_res["results"][0]["variant_version"] = "f27"

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.register_uri("GET", module1_url, json=module1_res)

+             mock_http.register_uri("GET", module_diff_ns_url, json=module2_res)

+             pdc = PDC()

+             module1 = pdc.get_module("mariadb-10.2-20171019133930")

+             module2 = pdc.get_module("platform-f27-20171011150016")

+ 

+         with pytest.raises(ValueError):

+             module1.get_diff(module2)

+ 

+     def test_get_diff_change_dist_tag(self, pdc_json_res):

+         """

+         Testing if a distag changes between modules

+         """

+         module1_res = pdc_json_res.get()

+         module2_res = pdc_json_res.get()

+         module2_res["results"][0]["koji_tag"] = "module-15d35d06c29b1848"

+         module2_res["results"][0]["rpms"] = [

+                 "mariadb-3:10.2.9-3.module_629c669e.src.rpm",

+                 "mariadb-debugsource-3:10.2.9-3.module_15d35d06.x86_64.rpm",

+                 "mariadb-connect-engine-debuginfo-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-debuginfo-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-devel-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                 "mariadb-connect-engine-3:10.2.9-3.module_629c669e.x86_64.rpm"

+         ]

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.register_uri("GET", module1_url, json=module1_res)

+             mock_http.register_uri("GET", module2_url, json=module2_res)

+             pdc = PDC()

+             module1 = pdc.get_module("mariadb-10.2-20171019133930")

+             module2 = pdc.get_module("mariadb-10.2-20171103103655")

+ 

+         diff = module1.get_diff(module2, reused=True, dist=True)

+ 

+         assert diff["added_rpms"] == []

+         assert diff["removed_rpms"] == []

+         assert diff["upgraded_rpms"] == []

+         assert diff["downgraded_rpms"] == []

+         assert len(diff["reused_rpms"]) == 6

+         assert diff["changed_distag_rpms"] == [

+                 ("mariadb-debugsource-3:10.2.9-3.module_629c669e.x86_64.rpm",

+                  "mariadb-debugsource-3:10.2.9-3.module_15d35d06.x86_64.rpm")]

+ 

+     def test_get_rpm_md(self, pdc_json_res):

+         """

+         Testing to get correct metadata from name of a rpm file.

+         """

+         module1_res = pdc_json_res.get()

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.register_uri("GET", module1_url, json=module1_res)

+             pdc = PDC()

+             module1 = pdc.get_module("mariadb-10.2-20171019133930")

+ 

+         rpm = "python3-hawkey-debuginfo-0:0.10.1-2.module_80d712e7.modularity.1.x86_64.rpm"

+ 

+         md = module1.get_rpm_md(rpm)

+ 

+         expected_md = {'arch': 'x86_64',

+             'dist_tag': 'module_80d712e7',

+             'epoch': '0',

+             'full_name': 'python3-hawkey-debuginfo-0:0.10.1-2.module_80d712e7.modularity.1.x86_64.rpm',

+             'name': 'python3-hawkey-debuginfo',

+             'release': '2.module_80d712e7.modularityx86_64rpm',

+             'version': '0.10.1'}

+ 

+         assert md == expected_md

file added
+43
@@ -0,0 +1,43 @@ 

+ import requests_mock

+ import pytest

+ 

+ from modulemd import ModuleMetadata

+ 

+ from module_diff.pdc import PDC

+ from module_diff.module import Module

+ 

+ 

+ @pytest.mark.usefixtures("pdc_json_res")

+ class TestPDC(object):

+ 

+     def test_get_module(self, pdc_json_res):

+         api_url = ("https://pdc.fedoraproject.org/rest_api/v1"

+                    "/unreleasedvariants/"

+                    "?page_size=1&variant_uid=mariadb-f26-20170517122119")

+ 

+         json = pdc_json_res.get()

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.get(api_url, json=json)

+             pdc = PDC()

+             module = pdc.get_module("mariadb-f26-20170517122119")

+ 

+         assert isinstance(module, Module)

+         assert isinstance(module.modulemd, ModuleMetadata)

+ 

+     def test_get_module_not_found(self, pdc_json_res):

+         api_url = ("https://pdc.fedoraproject.org/rest_api/v1"

+                    "/unreleasedvariants/"

+                    "?page_size=1&variant_uid=mariadb-f26-20170517122119")

+ 

+         json = pdc_json_res.get()

+         json["results"] = []

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.get(api_url, json=json)

+             pdc = PDC()

+             with pytest.raises(Exception) as ex:

+                 pdc.get_module("mariadb-f26-20170517122119")

+ 

+             assert ex.value.args[0] == ("No data found for module 'mariadb-f26-20170517122119'"

+                                         " in PDC")