#9 module_diff without PDC
Merged 5 years ago by mcurlej. Opened 5 years ago by fivaldi.
fivaldi/module_diff master  into  master

module_diff without PDC
Filip Valder • 5 years ago  
file modified
+6 -4
@@ -1,8 +1,10 @@ 

- *.swp

- report.xml

- .ropeproject/

- .cache/

  *.egg-info/

  *__pycache__/

+ .cache/

+ .ropeproject/

  .tox/

+ *.pyc

+ *.pytest_cache/

+ *.swp

  module_diffc

+ report.xml

file modified
+4 -9
@@ -1,10 +1,8 @@ 

  # module_diff

  

- Creates diffs between 2 versions of module. Written in Python 3, but is compatible with python 2.7. 

+ Creates diffs between two versions of a module. Written in Python 3, but is compatible with Python 2.7.

  

- # Development

- 

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

+ ## Development

  

  To install the tool do:

  
@@ -12,18 +10,15 @@ 

  python setup.py install

  ```

  

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

+ For development create a venv and do:

  

  ```

  python setup.py develop

  ```

  

- # Tests

+ ## Tests

  

  To run tests do:

  ```

  tox -e py27,py36,flake8

  ```

- 

- 

- 

file modified
+13 -12
@@ -1,4 +1,4 @@ 

- #!/bin/env python3

+ #!/bin/env python

  

  import argparse

  from module_diff import module_diff
@@ -6,23 +6,24 @@ 

  

  def main():

      args = parse_arguments()

-     module_diff(args.org_nsv, args.diff_nsv, json=args.json, dist=args.dist, reused=args.reused)

+     module_diff(args.src_nsvc, args.dst_nsvc, json=args.json, dist=args.dist, reused=args.reused)

  

  

  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.")

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

+                         help="The NSVC of a source module to compare 'from'")

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

+                         help="The NSVC of a destination module to compare 'to'")

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

+                         help="The module diff will be 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__":

      main()

file modified
+12 -9
@@ -1,5 +1,7 @@ 

  import json

- from module_diff.pdc import PDC

+ 

+ from module_diff.mbs import MBS

+ from module_diff.module import Module

  

  

  class CliColors:
@@ -13,12 +15,12 @@ 

      UNDERLINE = '\033[4m'

  

  

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

-     pdc = PDC()

-     org_module = pdc.get_module(org_nsv)

-     diff_module = pdc.get_module(diff_nsv)

+ def module_diff(src_nsvc, dst_nsvc, json=False, dist=False, reused=False):

+     mbs = MBS()

+     src_module = Module(mbs.get_module(src_nsvc), dist, reused)

+     dst_module = Module(mbs.get_module(dst_nsvc), dist, reused)

  

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

+     diff = src_module.get_diff(dst_module)

      if json:

          jsonify_diff(diff)

      else:
@@ -29,9 +31,10 @@ 

      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("NSVC: %s, # of RPMs: %s" % (stats["src_module"]["nsvc"],

+                                        stats["src_module"]["num_rpms"]))

+     print("NSVC: %s, # of RPMs: %s" % (stats["dst_module"]["nsvc"],

+                                        stats["dst_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"])

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

+ import requests

+ 

+ 

+ class MBS(object):

+ 

+     def __init__(self):

+         self.mbs_url = ('https://mbs.fedoraproject.org'

+                         '/module-build-service/1/module-builds/')

+         self.params = {'verbose': 'true'}

+ 

+     def get_module(self, nsvc):

+         name = nsvc.split("-")[0:-3]

+         stream = nsvc.split("-")[-3]

+         version = nsvc.split("-")[-2]

+         context = nsvc.split("-")[-1]

+         params = dict(self.params)

+         params.update({'name': name, 'stream': stream, 'version': version, 'context': context})

+         res = requests.get(self.mbs_url, params=params)

+ 

+         if not res.ok:

+             raise requests.HTTPError(

+                 "Couldn't get module data. Check the URL: %s" % res.url)

+ 

+         try:

+             module_data = res.json()

do we need a try/except blog here? as if the res.json failed then there would more problems like only wrong request. You are checking the request above. Also when you reraise you are losing the original traceback. Removet the excetpiont.

+         except Exception:

+             raise RuntimeError(

+                 "Couldn't process module data. Check the response: %s" % res.text)

+ 

+         if not module_data['meta']['total'] == 1:

Is there a possibility you could have more than 1 match when searching by all parameters (name, stream, version, context). And if yes shouldnt we return the latest one? Also what will happen if we dont found the NSVC? Shouldnt we say that the module was not found?

+             raise RuntimeError('We need exactly one module in response from MBS.'

+                                ' Check the URL: %s' % res.url)

+ 

+         return module_data["items"][0]

file modified
+103 -79
@@ -1,58 +1,65 @@ 

  import re

  

+ from itertools import product

  from kobo.rpmlib import parse_nvr, compare_nvr

- 

  from modulemd import ModuleMetadata

  

  

+ DISTAG_PATTERN = r"\.(module\_[0-9a-f]+)$"

+ 

+ 

  class Module(object):

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

  

-     def __init__(self, pdc_module_data):

+     def __init__(self, module_data, dist=False, reused=False):

          """

          Args:

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

+             module_data (dict): the module data from MBS 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.dist = dist

+         self.reused = reused

+ 

+         self.name = module_data["name"]

+         self.stream = module_data["stream"]

+         self.version = module_data["version"]

+         self.context = module_data["context"]

+         self.nsvc = "-".join((self.name,

+                               self.stream,

+                               self.version,

+                               self.context))

          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"])

+         self.modulemd = module_data["modulemd"]

+         self.rpms = set([v["nvr"] for k, v in module_data["tasks"]["rpms"].items()])

  

      @property

-     def modulemd(self):

+     def mmd(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

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

+             self._mmd = ModuleMetadata()

+             self._mmd.loads(self.modulemd)

+         return self._mmd

  

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

+     def get_diff(self, dst_module):

          """

          Makes a diff between 2 modules.

          Args:

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

+             dst_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:

+         if self.name != dst_module.name and \

+                 self.stream != dst_module.stream:

              # 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))

+                        % (self.nsvc, dst_module.nsvc))

              raise ValueError(message)

  

-         diff = {}

-         diff["stats"] = {}

          added_rpms = []

          removed_rpms = []

          upgraded_rpms = []
@@ -60,18 +67,19 @@ 

          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)

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

+         # from previous builds

+         for src_rpm in self.rpms:

+             if src_rpm in dst_module.rpms:

+                 reused_rpms.append(src_rpm)

              else:

-                 removed_rpms.append(org_rpm)

+                 removed_rpms.append(src_rpm)

  

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

+         added_rpms = list(dst_module.rpms - self.rpms)

  

-         # 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.

+         # 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 = []
@@ -83,48 +91,65 @@ 

              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:

+             for rpms in product(removed_rpm_md, added_rpm_md):

+                 rem_rpm, add_rpm = rpms

+                 # 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 not rem_rpm["name"] == add_rpm["name"]:

+                     continue

+ 

+                 # we compare the versions of the rpms

+                 result = compare_nvr(rem_rpm, add_rpm)

+                 dist_only_changed = (

+                     rem_rpm["full_name"].rpartition(rem_rpm["dist_tag"])[0] ==

+                     add_rpm["full_name"].rpartition(add_rpm["dist_tag"])[0])

+ 

+                 if dist_only_changed:

+                     # 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"]))

+                 elif result == -1:

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

+                                           add_rpm["full_name"]))

+                 elif result == 1:

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

+                                             add_rpm["full_name"]))

+                 else:

+                     raise ValueError(

+                         "Couldn't handle version comparision: %s -> %s" % (

+                             rem_rpm["full_name"], add_rpm["full_name"]))

+ 

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

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

+ 

+         diff = {

+             "stats": {

+                 "num_added": len(added_rpms),

+                 "num_removed": len(removed_rpms),

+                 "num_upgraded": len(upgraded_rpms),

+                 "num_downgraded": len(downgraded_rpms),

+                 "src_module": {

+                     "num_rpms": len(self.rpms),

+                     "nsvc": self.nsvc

+                 },

+                 "dst_module": {

+                     "num_rpms": len(dst_module.rpms),

+                     "nsvc": dst_module.nsvc

+                 }

+             },

+             "added_rpms": added_rpms,

+             "removed_rpms": removed_rpms,

+             "upgraded_rpms": upgraded_rpms,

+             "downgraded_rpms": downgraded_rpms

+         }

+ 

+         if self.reused:

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

              diff["reused_rpms"] = reused_rpms

  

-         if dist:

+         if self.dist:

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

              diff["changed_distag_rpms"] = changed_distag_rpms

  
@@ -138,20 +163,19 @@ 

          Returns:

              (dict): metadata for a given rpm

          """

+         name, epoch_version, release = rpm.rsplit("-", 2)

+         if not self.dist:

+             release = re.sub(DISTAG_PATTERN, "", release)

+         nvr = '-'.join((name, epoch_version, release))

          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)

+         # 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(DISTAG_PATTERN, rpm)

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

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

  

          return md

  

      def diff_modulemd(self):

-         pass

+         raise NotImplementedError

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

- 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 modified
+4 -2
@@ -1,2 +1,4 @@ 

- modulemd==1.3.2

- pdc-client==1.7.0

+ kobo

+ koji

+ modulemd

+ requests

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

        scripts=["bin/module_diff"],

        data_files=[],

        )

- 

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

- mock==2.0.0

- pytest==3.2.5

- requests-mock==1.3.0

+ mock

+ pytest

+ requests-mock

file modified
+206 -74
@@ -1,82 +1,214 @@ 

- import copy

+ import json

  import pytest

  

  

  @pytest.fixture

- def pdc_json_res():

-     """ Mock for module PDC response data """

+ def mbs_json_res():

+     """ Mock MBS response (JSON) """

  

-     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",

-                 ]

-             }

-         ]

+     mbs_data_text = (r'''

+ {

+   "items": [

+     {

+       "build_context": null,

+       "component_builds": [

+         20692,

+         20691,

+         20693,

+         20697,

+         20696,

+         20695,

+         20698,

+         20694,

+         20699,

+         20701,

+         20688,

+         20690,

+         20687,

+         20689

+       ],

+       "context": "00000000",

+       "id": 476,

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

+       "modulemd": "data:\n  api:\n    rpms: [mariadb]\n  components:\n    rpms:\n      checkpolicy: {buildorder: 4, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/checkpolicy',\n        rationale: Dep of selinux-policy  package., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/checkpolicy'}\n      compat-openssl10: {buildorder: 5, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/compat-openssl10',\n        rationale: A dependency of mariadb., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/compat-openssl10'}\n      dbus-glib: {buildorder: 3, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/dbus-glib',\n        rationale: Dep of policycoreutils  package., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/dbus-glib'}\n      desktop-file-utils: {buildorder: 3, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/desktop-file-utils',\n        rationale: Dep of policycoreutils  package., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/desktop-file-utils'}\n      libaio: {buildorder: 5, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/libaio',\n        rationale: A dependency of mariadb., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/libaio'}\n      libcgroup: {buildorder: 3, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/libcgroup',\n        rationale: Dep of policycoreutils  package., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/libcgroup'}\n      libedit: {buildorder: 5, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/libedit',\n        rationale: A dependency of mariadb., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/libedit'}\n      libselinux: {buildorder: 3, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/libselinux',\n        rationale: Dep of policycoreutils  package., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/libselinux'}\n      mariadb: {buildorder: 10, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/mariadb',\n        rationale: MariaDB  package., ref: private-f26-modules-mariadb-notests, repository: 'git://pkgs.fedoraproject.org/rpms/mariadb'}\n      policycoreutils: {buildorder: 4, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/policycoreutils',\n        rationale: Dep of selinux-policy  package., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/policycoreutils'}\n      selinux-policy: {buildorder: 5, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/selinux-policy',\n        rationale: A dependency of mariadb., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/selinux-policy'}\n      systemtap: {buildorder: 5, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/systemtap',\n        rationale: MariaDB  package., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/systemtap'}\n      time: {buildorder: 5, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/time',\n        rationale: A dependency of mariadb., ref: f26, repository: 'git://pkgs.fedoraproject.org/rpms/time'}\n  dependencies:\n    buildrequires: {bootstrap: f26, common-build-dependencies: f26, perl: f26, shared-userspace: f26}\n    requires: {base-runtime: f26, perl: f26, shared-userspace: f26}\n  description: MariaDB is a community developed branch of MySQL. MariaDB is a multi-user,\n    multi-threaded SQL database server. It is a client/server implementation consisting\n    of a server daemon (mysqld) and many different client programs and libraries.\n    The base package contains the standard MariaDB/MySQL client programs and generic\n    MySQL files.\n  license:\n    module: [GPLv2 with exceptions and LGPLv2 and BSD]\n  name: mariadb\n  profiles:\n    default:\n      rpms: [mariadb]\n  references: {community: 'https://fedoraproject.org/wiki/Modularity', documentation: 'https://fedoraproject.org/wiki/Fedora_Packaging_Guidelines_for_Modules',\n    tracker: 'https://taiga.fedorainfracloud.org/project/modularity'}\n  stream: f26\n  summary: MariaDB Module\n  version: 20170517122119\n  xmd:\n    mbs:\n      buildrequires:\n        bootstrap: {ref: ae993ba84f4bce554471382ccba917ef16265f11, stream: f26, version: '1'}\n        common-build-dependencies: {ref: 2960891d23f52d4008b6722142331451b66d88cf,\n          stream: f26, version: '20170516122017'}\n        perl: {ref: 634417c4c8d86fd473056b3aeab29be91c23812f, stream: f26, version: '20170515072053'}\n        shared-userspace: {ref: 8eb98a0a79acce4eca1e129fd6bf270257eede16, stream: f26,\n          version: '20170514220210'}\n      commit: 7723b4e3c3cd105b274a88c4bc15aea848090114\n      rpms:\n        checkpolicy: {ref: 269e7db87e9501371a78c6a7d8dcc84d86aa7fb0}\n        compat-openssl10: {ref: d59ab7262d0937c4064e5e42e066e8cfa330c6ef}\n        dbus-glib: {ref: 109eff38b1821950e70c3872e5d29ef70ad499d1}\n        desktop-file-utils: {ref: 8b09dcec35eb34cc54b7c7a2dc78a33ccc3aaf6f}\n        libaio: {ref: db11cf2785cee8d274c6640edf9a7078c2509012}\n        libcgroup: {ref: f5d7f93633504ad8dde5bcbe55d6b7c12a435eda}\n        libedit: {ref: 3858b5775f5a3eef75fdff5239a20782ad259f94}\n        libselinux: {ref: ea9eee161ed07911c9c672b0e598509e39cac679}\n        mariadb: {ref: 7b7238abd85d6f9c6737756b9de8639e8a710906}\n        policycoreutils: {ref: b185f8151d518e94376a442b9609fc95b7213bf4}\n        selinux-policy: {ref: 1501d1ef8cad25b51add67498e91a9c0cf9615f6}\n        systemtap: {ref: 43d514b85622d4b7362e4f5e1b7937f924a65b3a}\n        time: {ref: 0e9df1c2aa4fa7454bba05cfc33e2785baadc0ac}\n      scmurl: git://pkgs.fedoraproject.org/modules/mariadb?#7723b4e3c3cd105b274a88c4bc15aea848090114\ndocument: modulemd\nversion: 1\n",'''  # noqa: E501

+ '''

+       "name": "mariadb",

+       "owner": "mkocka",

+       "rebuild_strategy": "changed-and-after",

+       "ref_build_context": "5f901835774db773d663641a6c55c2b6a272928d",

+       "runtime_context": null,

+       "scmurl": "git://pkgs.fedoraproject.org/modules/mariadb?#7723b4e3c3cd105b274a88c4bc15aea848090114",'''  # noqa: E501

+ '''

+       "siblings": [],

+       "state": 5,

+       "state_name": "ready",

+       "state_reason": null,

+       "state_trace": [

+         {

+           "reason": null,

+           "state": 1,

+           "state_name": "wait",

+           "time": "2017-05-17T12:21:47Z"

+         },

+         {

+           "reason": null,

+           "state": 1,

+           "state_name": "wait",

+           "time": "2017-05-17T12:22:19Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T12:22:19Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T13:42:28Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T13:43:57Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T14:03:42Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T14:04:17Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T14:13:41Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T14:14:20Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T14:42:57Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T14:44:29Z"

+         },

+         {

+           "reason": null,

+           "state": 2,

+           "state_name": "build",

+           "time": "2017-05-17T15:37:53Z"

+         },

+         {

+           "reason": null,

+           "state": 3,

+           "state_name": "done",

+           "time": "2017-05-17T15:39:00Z"

+         },

+         {

+           "reason": null,

+           "state": 3,

+           "state_name": "done",

+           "time": "2017-05-17T15:39:00Z"

+         },

+         {

+           "reason": null,

+           "state": 5,

+           "state_name": "ready",

+           "time": "2017-05-17T15:39:00Z"

+         },

+         {

+           "reason": null,

+           "state": 5,

+           "state_name": "ready",

+           "time": "2017-05-17T15:39:01Z"

+         }

+       ],

+       "state_url": "/module-build-service/1/module-builds/476",

+       "stream": "f26",

+       "tasks": {

+         "rpms": {

+           "mariadb-debugsource": {

+             "nvr": "mariadb-debugsource-3:10.2.9-3.module_629c669e"

+           },

+           "mariadb-connect-engine-debuginfo": {

+             "nvr": "mariadb-connect-engine-debuginfo-3:10.2.9-3.module_629c669e"

+           },

+           "mariadb-debuginfo": {

+             "nvr": "mariadb-debuginfo-3:10.2.9-3.module_629c669e"

+           },

+           "mariadb": {

+             "nvr": "mariadb-3:10.2.9-3.module_629c669e"

+           },

+           "mariadb-devel": {

+             "nvr": "mariadb-devel-3:10.2.9-3.module_629c669e"

+           },

+           "mariadb-connect-engine": {

+             "nvr": "mariadb-connect-engine-3:10.2.9-3.module_629c669e"

+           }

+         }

+       },

+       "time_completed": "2017-05-17T15:39:00Z",

+       "time_modified": "2017-05-17T15:39:00Z",

+       "time_submitted": "2017-05-17T12:21:44Z",

+       "version": "20170517122119"

      }

+   ],

+   "meta": {

+     "first": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?verbose=True&stream=f26&version=20170517122119&context=00000000&per_page=10&page=1&name=mariadb",'''  # noqa: E501

+ '''

+     "last": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?verbose=True&stream=f26&version=20170517122119&context=00000000&per_page=10&page=1&name=mariadb",'''  # noqa: E501

+ '''

+     "next": null,

+     "page": 1,

+     "pages": 1,

+     "per_page": 10,

+     "prev": null,

+     "total": 1

+   }

+ }

+ ''')

+ 

+     return json.loads(mbs_data_text)

+ 

+ 

+ @pytest.fixture

+ def mbs_json_res_no_match():

+     """ Mock MBS response (JSON) - no match """

  

-     # 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)

+     mbs_data_text = ('''

+ {

+   "items": [],

+   "meta": {

+     "first": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?verbose=True&stream=f26&version=20010101000000&context=00000000&per_page=10&page=1&name=mariadb",'''  # noqa: E501

+ '''

+     "last": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?verbose=True&stream=f26&version=20010101000000&context=00000000&per_page=10&page=0&name=mariadb",'''  # noqa: E501

+ '''

+     "next": null,

+     "page": 1,

+     "pages": 0,

+     "per_page": 10,

+     "prev": null,

+     "total": 0

+   }

+ }

+ ''')

  

-     return PDCDataFactory()

+     return json.loads(mbs_data_text)

file modified
+69 -75
@@ -1,47 +1,74 @@ 

+ import copy

  import json

  import mock

  import imp

  # importing the bin script as source through imp

  imp.load_source("module_diff_bin", "bin/module_diff") # noqa

  import requests_mock

+ 

  from module_diff_bin import main

  

- 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")

- 

- 

- def generate_module_res(pdc_json_res):

-     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"

-     ]

+ 

+ module1_url = ("https://mbs.fedoraproject.org/module-build-service/1/module-builds/"

+                "?verbose=true&name=mariadb&stream=10.2&version=20171019133930&context=00000000")

+ 

+ module2_url = ("https://mbs.fedoraproject.org/module-build-service/1/module-builds/"

+                "?verbose=true&name=mariadb&stream=10.2&version=20171103103655&context=00000000")

+ 

+ 

+ def generate_module_res(mbs_json_res):

+     module1_res = copy.deepcopy(mbs_json_res)

+     module2_res = copy.deepcopy(mbs_json_res)

+     del module1_res["items"][0]["tasks"]["rpms"]["mariadb-connect-engine"]

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

+     module2_res["items"][0]["tasks"]["rpms"] = {

+         "mariadb-debugsource": {

+             "nvr": "mariadb-debugsource-3:10.2.9-3.module_629c669e",

+         },

+         "mariadb-connect-engine-debuginfo": {

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

+         },

+         "mariadb-debuginfo": {

+             "nvr": "mariadb-debuginfo-3:11.2.9-3.module_15d35d06",

+         },

+         "mariadb": {

+             "nvr": "mariadb-3:10.2.9-3.module_629c669e",

+         },

+         "mariadb-devel": {

+             "nvr": "mariadb-devel-3:9.2.9-3.module_15d35d06",

+         },

+         "mariadb-connect-engine": {

+             "nvr": "mariadb-connect-engine-3:10.2.9-3.module_15d35d06"

+         },

+     }

  

      return module1_res, module2_res

  

  

+ def check_common_output(output):

+     assert "Compared modules" in output

+     assert "NSVC:" in output

+     assert "# of RPMs:" in output

+     assert "# of RPMs added:" in output

+     assert "# of RPMs removed:" in output

+     assert "# of RPMs upgraded:" in output

+     assert "# of RPMs downgraded:" in output

+     assert "RPMs Added" in output

+     assert "RPMs Added" in output

+     assert "RPMs Removed" in output

+     assert "RPMs Upgraded" in output

+     assert "RPMs Downgraded" in output

+ 

+ 

  class TestCli(object):

      """

      Tests for the cli of the module_diff tool

      """

  

-     def test_cli_required_options(self, pdc_json_res, capsys):

+     def test_cli_required_options(self, mbs_json_res, capsys):

          """ Testing output with minimum required options """

  

-         module1_res, module2_res = generate_module_res(pdc_json_res)

+         module1_res, module2_res = generate_module_res(mbs_json_res)

  

          with requests_mock.mock() as mock_http:

              mock_http.register_uri("GET", module1_url, json=module1_res)
@@ -49,35 +76,24 @@ 

  

              cli_cmd = [

                  'module_diff',

-                 'mariadb-10.2-20171019133930',

-                 'mariadb-10.2-20171103103655'

+                 'mariadb-10.2-20171019133930-00000000',

+                 'mariadb-10.2-20171103103655-00000000'

              ]

  

              with mock.patch("sys.argv", cli_cmd):

                  main()

                  output = capsys.readouterr()[0]

  

-             assert "Compared modules" in output

-             assert "NSV:" in output

-             assert "# of RPMs:" in output

-             assert "# of RPMs added:" in output

-             assert "# of RPMs removed:" in output

-             assert "# of RPMs upgraded:" in output

-             assert "# of RPMs downgraded:" in output

-             assert "RPMs Added" in output

-             assert "RPMs Added" in output

-             assert "RPMs Removed" in output

-             assert "RPMs Upgraded" in output

-             assert "RPMs Downgraded" in output

+             check_common_output(output)

              assert "RPMs which dist tag changed" not in output

              assert "RPMs Reused" not in output

  

-     def test_cli_dist_option(self, pdc_json_res, capsys):

+     def test_cli_dist_option(self, mbs_json_res, capsys):

          """

          Testing option --dist which displays RPMs which changed their dist tag.

          """

  

-         module1_res, module2_res = generate_module_res(pdc_json_res)

+         module1_res, module2_res = generate_module_res(mbs_json_res)

  

          with requests_mock.mock() as mock_http:

              mock_http.register_uri("GET", module1_url, json=module1_res)
@@ -85,8 +101,8 @@ 

  

              cli_cmd = [

                  'module_diff',

-                 'mariadb-10.2-20171019133930',

-                 'mariadb-10.2-20171103103655',

+                 'mariadb-10.2-20171019133930-00000000',

+                 'mariadb-10.2-20171103103655-00000000',

                  '--dist'

              ]

  
@@ -94,26 +110,15 @@ 

                  main()

                  output = capsys.readouterr()[0]

  

-             assert "Compared modules" in output

-             assert "NSV:" in output

-             assert "# of RPMs:" in output

-             assert "# of RPMs added:" in output

-             assert "# of RPMs removed:" in output

-             assert "# of RPMs upgraded:" in output

-             assert "# of RPMs downgraded:" in output

-             assert "RPMs Added" in output

-             assert "RPMs Added" in output

-             assert "RPMs Removed" in output

-             assert "RPMs Upgraded" in output

-             assert "RPMs Downgraded" in output

+             check_common_output(output)

              assert "RPMs which dist tag changed" in output

              assert "RPMs Reused" not in output

  

-     def test_cli_reused_option(self, pdc_json_res, capsys):

+     def test_cli_reused_option(self, mbs_json_res, capsys):

          """

          Testing option --reused which displays RPMs which where reused from previous build.

          """

-         module1_res, module2_res = generate_module_res(pdc_json_res)

+         module1_res, module2_res = generate_module_res(mbs_json_res)

  

          with requests_mock.mock() as mock_http:

              mock_http.register_uri("GET", module1_url, json=module1_res)
@@ -121,8 +126,8 @@ 

  

              cli_cmd = [

                  'module_diff',

-                 'mariadb-10.2-20171019133930',

-                 'mariadb-10.2-20171103103655',

+                 'mariadb-10.2-20171019133930-00000000',

+                 'mariadb-10.2-20171103103655-00000000',

                  '--reused'

              ]

  
@@ -130,26 +135,15 @@ 

                  main()

                  output = capsys.readouterr()[0]

  

-             assert "Compared modules" in output

-             assert "NSV:" in output

-             assert "# of RPMs:" in output

-             assert "# of RPMs added:" in output

-             assert "# of RPMs removed:" in output

-             assert "# of RPMs upgraded:" in output

-             assert "# of RPMs downgraded:" in output

-             assert "RPMs Added" in output

-             assert "RPMs Added" in output

-             assert "RPMs Removed" in output

-             assert "RPMs Upgraded" in output

-             assert "RPMs Downgraded" in output

+             check_common_output(output)

              assert "RPMs which dist tag changed" not in output

              assert "RPMs Reused" in output

  

-     def test_cli_json_option(self, pdc_json_res, capsys):

+     def test_cli_json_option(self, mbs_json_res, capsys):

          """

          Testing option --json which displays the output as a json string.

          """

-         module1_res, module2_res = generate_module_res(pdc_json_res)

+         module1_res, module2_res = generate_module_res(mbs_json_res)

  

          with requests_mock.mock() as mock_http:

              mock_http.register_uri("GET", module1_url, json=module1_res)
@@ -157,8 +151,8 @@ 

  

              cli_cmd = [

                  'module_diff',

-                 'mariadb-10.2-20171019133930',

-                 'mariadb-10.2-20171103103655',

+                 'mariadb-10.2-20171019133930-00000000',

+                 'mariadb-10.2-20171103103655-00000000',

                  '--json'

              ]

  

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

+ import pytest

+ import requests_mock

+ 

+ from module_diff.mbs import MBS

+ 

+ 

+ class TestMBS(object):

+ 

+     def test_get_module(self, mbs_json_res):

+         api_url = ("https://mbs.fedoraproject.org/module-build-service/1/module-builds/"

+                    "?verbose=true&name=mariadb&stream=f26&version=20170517122119&context=00000000")

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.get(api_url, json=mbs_json_res)

+             mbs = MBS()

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

+ 

+         assert module == mbs_json_res["items"][0]

+ 

+     def test_get_module_no_match(self, mbs_json_res_no_match):

+         api_url = ("https://mbs.fedoraproject.org/module-build-service/1/module-builds/"

+                    "?verbose=True&name=mariadb&stream=f26&version=20010101000000&context=00000000")

+ 

+         with requests_mock.mock() as mock_http:

+             mock_http.get(api_url, json=mbs_json_res_no_match)

+             with pytest.raises(RuntimeError) as ex:

+                 mbs = MBS()

+                 mbs.get_module("mariadb-f26-20010101000000-00000000")

+ 

+             assert str(ex.value).startswith(

+                 "We need exactly one module in response from MBS. Check the URL: ")

file modified
+153 -117
@@ -1,222 +1,258 @@ 

+ import copy

  import pytest

  import requests_mock

  

- from module_diff.pdc import PDC

+ from module_diff.mbs import MBS

+ from module_diff.module import Module

  

  

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

-                "/unreleasedvariants/"

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

+ module1_url = ("https://mbs.fedoraproject.org/module-build-service/1/module-builds/"

+                "?verbose=true&name=mariadb&stream=10.2&version=20171019133930&context=00000000")

  

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

-                "/unreleasedvariants/"

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

+ module2_url = ("https://mbs.fedoraproject.org/module-build-service/1/module-builds/"

+                "?verbose=true&name=mariadb&stream=10.2&version=20171103103655&context=00000000")

  

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

-                       "/unreleasedvariants/"

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

+ module_diff_ns_url = (

+     "https://mbs.fedoraproject.org/module-build-service/1/module-builds/"

+     "?verbose=true&name=platform&stream=f27&version=20171011150016&context=00000000")

  

  

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

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

  class TestModule(object):

      """

      Tests for the Module Class

      """

  

-     def test_get_diff_no_diff(self, pdc_json_res):

+     def test_get_diff_no_diff(self, mbs_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"

+         module1_res = copy.deepcopy(mbs_json_res)

+         module2_res = copy.deepcopy(mbs_json_res)

+         module2_res["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")

+             mbs = MBS()

+             module1 = Module(mbs.get_module("mariadb-10.2-20171019133930-00000000"))

+             module2 = Module(mbs.get_module("mariadb-10.2-20171103103655-00000000"))

  

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

+         module1.reused = True

+         diff = module1.get_diff(module2)

  

          assert diff["added_rpms"] == []

          assert diff["removed_rpms"] == []

          assert diff["upgraded_rpms"] == []

          assert diff["downgraded_rpms"] == []

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

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

  

-     def test_get_diff(self, pdc_json_res):

+     def test_get_diff(self, mbs_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"

-         ]

+         module1_res = copy.deepcopy(mbs_json_res)

+         module2_res = copy.deepcopy(mbs_json_res)

+         del module1_res["items"][0]["tasks"]["rpms"]["mariadb-connect-engine"]

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

+         module2_res["items"][0]["tasks"]["rpms"] = {

+             "mariadb-debugsource": {

+                 "nvr": "mariadb-debugsource-3:10.2.9-3.module_629c669e",

+             },

+             "mariadb-connect-engine-debuginfo": {

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

+             },

+             "mariadb-debuginfo": {

+                 "nvr": "mariadb-debuginfo-3:11.2.9-3.module_15d35d06",

+             },

+             "mariadb-devel": {

+                 "nvr": "mariadb-devel-3:9.2.9-3.module_15d35d06",

+             },

+             "mariadb-connect-engine": {

+                 "nvr": "mariadb-connect-engine-3:10.2.9-3.module_15d35d06",

+             },

+         }

  

          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")

+             mbs = MBS()

+             module1 = Module(mbs.get_module("mariadb-10.2-20171019133930-00000000"))

+             module2 = Module(mbs.get_module("mariadb-10.2-20171103103655-00000000"))

  

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

+         module1.reused = True

+         diff = module1.get_diff(module2)

  

          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"]

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

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

          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')]

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

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

          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

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

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

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

  

-     def test_get_diff_rpm_version_change(self, pdc_json_res):

+     def test_get_diff_rpm_version_change(self, mbs_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"

-         ]

+         module1_res = copy.deepcopy(mbs_json_res)

+         module2_res = copy.deepcopy(mbs_json_res)

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

+         module2_res["items"][0]["tasks"]["rpms"] = {

+             "mariadb": {

+                 "nvr": "mariadb-3:10.2.9-3.module_629c669e",

+             },

+             "mariadb-debugsource": {

+                 "nvr": "mariadb-debugsource-3:11.2.9-3.module_15d35d06",

+             },

+             "mariadb-connect-engine-debuginfo": {

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

+             },

+             "mariadb-debuginfo": {

+                 "nvr": "mariadb-debuginfo-3:10.2.9-3.module_629c669e",

+             },

+             "mariadb-devel": {

+                 "nvr": "mariadb-devel-3:10.2.9-3.module_629c669e",

+             },

+             "mariadb-connect-engine": {

+                 "nvr": "mariadb-connect-engine-3:10.2.9-3.module_629c669e"

+             },

+         }

  

          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")

+             mbs = MBS()

+             module1 = Module(mbs.get_module("mariadb-10.2-20171019133930-00000000"))

+             module2 = Module(mbs.get_module("mariadb-10.2-20171103103655-00000000"))

  

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

+         module1.reused = True

+         diff = module1.get_diff(module2)

  

          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')]

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

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

          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

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

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

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

  

-     def test_get_diff_rpm_removed(self, pdc_json_res):

+     def test_get_diff_rpm_removed(self, mbs_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")

+         module1_res = copy.deepcopy(mbs_json_res)

+         module2_res = copy.deepcopy(mbs_json_res)

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

+         del module2_res["items"][0]["tasks"]["rpms"]["mariadb"]

  

          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")

+             mbs = MBS()

+             module1 = Module(mbs.get_module("mariadb-10.2-20171019133930-00000000"))

+             module2 = Module(mbs.get_module("mariadb-10.2-20171103103655-00000000"))

  

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

+         module1.reused = True

+         diff = module1.get_diff(module2)

  

          assert diff["added_rpms"] == []

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

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

          assert diff["upgraded_rpms"] == []

          assert diff["downgraded_rpms"] == []

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

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

  

-     def test_get_diff_different_ns(self, pdc_json_res):

+     def test_get_diff_different_ns(self, mbs_json_res):

          """

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

+         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"

+         module1_res = copy.deepcopy(mbs_json_res)

+         module2_res = copy.deepcopy(mbs_json_res)

+         module2_res["items"][0]["nsvc"] = "platform-f27-20171011150016"

+         module2_res["items"][0]["name"] = "platform"

+         module2_res["items"][0]["stream"] = "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")

+             mbs = MBS()

+             module1 = Module(mbs.get_module("mariadb-10.2-20171019133930-00000000"))

+             module2 = Module(mbs.get_module("platform-f27-20171011150016-00000000"))

  

          with pytest.raises(ValueError):

              module1.get_diff(module2)

  

-     def test_get_diff_change_dist_tag(self, pdc_json_res):

+     def test_get_diff_change_dist_tag(self, mbs_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"

-         ]

+         module1_res = copy.deepcopy(mbs_json_res)

+         module2_res = copy.deepcopy(mbs_json_res)

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

+         module2_res["items"][0]["tasks"]["rpms"] = {

+             "mariadb": {

+                 "nvr": "mariadb-3:10.2.9-3.module_629c669e",

+             },

+             "mariadb-debugsource": {

+                 "nvr": "mariadb-debugsource-3:10.2.9-3.module_15d35d06",

+             },

+             "mariadb-connect-engine-debuginfo": {

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

+             },

+             "mariadb-debuginfo": {

+                 "nvr": "mariadb-debuginfo-3:10.2.9-3.module_629c669e",

+             },

+             "mariadb-devel": {

+                 "nvr": "mariadb-devel-3:10.2.9-3.module_629c669e",

+             },

+             "mariadb-connect-engine": {

+                 "nvr": "mariadb-connect-engine-3:10.2.9-3.module_629c669e"

+             },

+         }

  

          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")

+             mbs = MBS()

+             module1 = Module(mbs.get_module("mariadb-10.2-20171019133930-00000000"))

+             module2 = Module(mbs.get_module("mariadb-10.2-20171103103655-00000000"))

  

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

+         module1.reused = True

+         module1.dist = True

+         diff = module1.get_diff(module2)

  

          assert diff["added_rpms"] == []

          assert diff["removed_rpms"] == []

          assert diff["upgraded_rpms"] == []

          assert diff["downgraded_rpms"] == []

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

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

          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")]

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

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

  

-     def test_get_rpm_md(self, pdc_json_res):

+     def test_get_rpm_md(self, mbs_json_res):

          """

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

          """

-         module1_res = pdc_json_res.get()

+         module1_res = copy.deepcopy(mbs_json_res)

  

          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")

+             mbs = MBS()

+             module1 = Module(mbs.get_module("mariadb-10.2-20171019133930-00000000"))

  

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

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

  

          md = module1.get_rpm_md(rpm)

  

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

-                        'dist_tag': 'module_80d712e7',

+         expected_md = {'dist_tag': 'module_80d712e7',

                         'epoch': '0',

                         'full_name': ('python3-hawkey-debuginfo-0:0.10.1-2'

-                                      '.module_80d712e7.modularity.1.x86_64.rpm'),

+                                      '.module_80d712e7'),

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

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

+                        'release': '2',

                         'version': '0.10.1'}

  

          assert md == expected_md

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

- 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")

file modified
+1 -2
@@ -5,7 +5,7 @@ 

  max-line-length = 100

  

  [testenv]

- sitepackages = True

+ usedevelop = true

  deps = -r{toxinidir}/test-requirements.txt

  commands = py.test {posargs}

  
@@ -15,4 +15,3 @@ 

  deps = flake8

  commands = flake8 --ignore E731 --exclude .tox,.git module_diff/ tests/

  ignore_outcome = True

- 

This PR switches from PDC to MBS API (data from internal database). It required major code re-factoring, thus some minor improvements are included as well.

  py27: commands succeeded
  py36: commands succeeded
  flake8: commands succeeded
  congratulations :)

rebased onto 0c1b62f

5 years ago

rebased onto d7dc54a

5 years ago

2 new commits added

  • module_diff without PDC (WiP)
  • module_diff without PDC (WiP)
5 years ago

rebased onto a512ac9

5 years ago

@mcurlej Can you take a look, please?
/cc @ralph

do we need a try/except blog here? as if the res.json failed then there would more problems like only wrong request. You are checking the request above. Also when you reraise you are losing the original traceback. Removet the excetpiont.

Is there a possibility you could have more than 1 match when searching by all parameters (name, stream, version, context). And if yes shouldnt we return the latest one? Also what will happen if we dont found the NSVC? Shouldnt we say that the module was not found?

I will merge it now and will file an issue for the MBS API error handling, ok? I will submit a PR for it subsequently.

Pull-Request has been merged by mcurlej

5 years ago