diff --git a/module_build_service/builder/KojiContentGenerator.py b/module_build_service/builder/KojiContentGenerator.py index d9987ce6..3b52440f 100644 --- a/module_build_service/builder/KojiContentGenerator.py +++ b/module_build_service/builder/KojiContentGenerator.py @@ -203,7 +203,9 @@ class KojiContentGenerator(object): ret = {} ret[u'name'] = self.module.name ret[u'version'] = self.module.stream.replace("-", "_") - ret[u'release'] = self.module.version + # Append the context to the version to make NVRs of modules unique in the event of + # module stream expansion + ret[u'release'] = '{0}.{1}'.format(self.module.version, self.module.context) ret[u'source'] = self.module.scmurl ret[u'start_time'] = calendar.timegm( self.module.time_submitted.utctimetuple()) @@ -217,7 +219,8 @@ class KojiContentGenerator(object): u"modulemd_str": self.module.modulemd, u"name": self.module.name, u"stream": self.module.stream, - u"version": self.module.version + u"version": self.module.version, + u"context": self.module.context } } } diff --git a/module_build_service/builder/KojiModuleBuilder.py b/module_build_service/builder/KojiModuleBuilder.py index 3a42f3ce..457cd5ab 100644 --- a/module_build_service/builder/KojiModuleBuilder.py +++ b/module_build_service/builder/KojiModuleBuilder.py @@ -156,6 +156,7 @@ class KojiModuleBuilder(GenericBuilder): """ self.owner = owner self.module_str = module.name + self.module = module self.mmd = module.mmd() self.config = config self.tag_name = tag_name @@ -563,7 +564,7 @@ chmod 644 %buildroot/%_sysconfdir/rpm/macros.zz-modules # If the build cannot be found in the tags, it may be untagged as a result # of some earlier inconsistent situation. Let's find the task_info # based on the list of untagged builds - release = module_build_service.utils.get_rpm_release_from_mmd(self.mmd) + release = module_build_service.utils.get_rpm_release(self.module) untagged = self.koji_session.untaggedBuilds(name=component_build.package) for untagged_build in untagged: if untagged_build["release"].endswith(release): diff --git a/module_build_service/migrations/versions/9ca1c166f426_contexts.py b/module_build_service/migrations/versions/9ca1c166f426_contexts.py new file mode 100644 index 00000000..b3087247 --- /dev/null +++ b/module_build_service/migrations/versions/9ca1c166f426_contexts.py @@ -0,0 +1,83 @@ +"""Adds the context columns + +Revision ID: 9ca1c166f426 +Revises: f5b1c5203cce +Create Date: 2018-01-09 16:55:43.416631 + +""" + +# revision identifiers, used by Alembic. +revision = '9ca1c166f426' +down_revision = 'f5b1c5203cce' + +from alembic import op +import sqlalchemy as sa + +# Data migration imports +import modulemd +import hashlib +import json +from collections import OrderedDict + + +modulebuild = sa.Table( + 'module_builds', + sa.MetaData(), + sa.Column('id', sa.Integer, primary_key=True), + sa.Column('modulemd', sa.String()), + sa.Column('build_context', sa.String()), + sa.Column('runtime_context', sa.String()), +) + + +def upgrade(): + connection = op.get_bind() + + op.add_column('module_builds', sa.Column('build_context', sa.String())) + op.add_column('module_builds', sa.Column('runtime_context', sa.String())) + + # Determine what the contexts should be based on the modulemd + for build in connection.execute(modulebuild.select()): + if not build.modulemd: + continue + mmd = modulemd.ModuleMetadata() + try: + mmd.loads(build.modulemd) + except Exception: + # If the modulemd isn't parseable then skip this build + continue + + mbs_xmd = mmd.xmd.get('mbs', {}) + contexts = {} + for property_name in ['buildrequires', 'requires']: + # It's possible this module build was built before MBS filled out xmd or before MBS + # filled out the requires in xmd + if property_name not in mbs_xmd: + break + mmd_property = getattr(mmd, property_name) + if mbs_xmd[property_name].keys() != mmd_property.keys(): + break + mmd_formatted_property = { + dep: info['ref'] for dep, info in mbs_xmd[property_name].items()} + property_json = json.dumps(OrderedDict(sorted(mmd_formatted_property.items()))) + contexts[property_name] = hashlib.sha1(property_json).hexdigest() + + # Update the database now + if len(contexts) == 2: + connection.execute( + modulebuild.update().where(modulebuild.c.id == build.id).values( + build_context=contexts['buildrequires'], runtime_context=contexts['requires'])) + elif 'buildrequires' in contexts: + connection.execute( + modulebuild.update().where(modulebuild.c.id == build.id).values( + build_context=contexts['buildrequires'])) + elif 'requires' in contexts: + connection.execute( + modulebuild.update().where(modulebuild.c.id == build.id).values( + runtime_context=contexts['requires'])) + + +def downgrade(): + with op.batch_alter_table('module_builds') as b: + b.drop_column('build_context') + b.drop_column('runtime_context') diff --git a/module_build_service/models.py b/module_build_service/models.py index e8a2d81e..44ffdac0 100644 --- a/module_build_service/models.py +++ b/module_build_service/models.py @@ -27,8 +27,10 @@ """ import contextlib - +import json +from collections import OrderedDict from datetime import datetime +import hashlib from sqlalchemy import engine_from_config, event from sqlalchemy.orm import validates, scoped_session, sessionmaker from flask import has_app_context @@ -147,6 +149,8 @@ class ModuleBuild(MBSBase): name = db.Column(db.String, nullable=False) stream = db.Column(db.String, nullable=False) version = db.Column(db.String, nullable=False) + build_context = db.Column(db.String) + runtime_context = db.Column(db.String) state = db.Column(db.Integer, nullable=False) state_reason = db.Column(db.String) modulemd = db.Column(db.String, nullable=False) @@ -255,6 +259,35 @@ class ModuleBuild(MBSBase): raise ValueError("%r is not a module message." % type(event).__name__) + @staticmethod + def contexts_from_mmd(mmd_str): + mmd = _modulemd.ModuleMetadata() + mmd.loads(mmd_str) + mbs_xmd = mmd.xmd.get('mbs', {}) + rv = [] + for property_name in ['buildrequires', 'requires']: + if property_name not in mbs_xmd: + raise ValueError('The module\'s modulemd hasn\'t been formatted by MBS') + mmd_property = getattr(mmd, property_name) + if mbs_xmd[property_name].keys() != mmd_property.keys(): + raise ValueError('The dependencies.{0} section of the modulemd doesn\'t match ' + 'what is in xmd'.format(property_name)) + mmd_formatted_property = { + dep: info['ref'] for dep, info in mbs_xmd[property_name].items()} + property_json = json.dumps(OrderedDict(sorted(mmd_formatted_property.items()))) + rv.append(hashlib.sha1(property_json).hexdigest()) + return tuple(rv) + + @property + def context(self): + if self.build_context and self.runtime_context: + combined_hashes = '{0}:{1}'.format(self.build_context, self.runtime_context) + return hashlib.sha1(combined_hashes).hexdigest()[:8] + else: + # We can't compute the context because the necessary data isn't there, so return a + # default value + return '00000000' + @classmethod def create(cls, session, conf, name, stream, version, modulemd, scmurl, username, copr_owner=None, copr_project=None, rebuild_strategy=None, publish_msg=True): @@ -391,6 +424,7 @@ class ModuleBuild(MBSBase): 'stream': self.stream, 'version': self.version, 'name': self.name, + 'context': self.context, } def json(self): @@ -421,7 +455,9 @@ class ModuleBuild(MBSBase): state_url = get_url_for('module_build', id=self.id) json.update({ 'component_builds': [build.id for build in self.component_builds], + 'build_context': self.build_context, 'modulemd': self.modulemd, + 'runtime_context': self.runtime_context, 'state_trace': [{'time': _utc_datetime_to_iso(record.state_time), 'state': record.state, 'state_name': INVERSE_BUILD_STATES[record.state], diff --git a/module_build_service/scheduler/handlers/modules.py b/module_build_service/scheduler/handlers/modules.py index 758a1de3..de2023fd 100644 --- a/module_build_service/scheduler/handlers/modules.py +++ b/module_build_service/scheduler/handlers/modules.py @@ -31,7 +31,7 @@ import module_build_service.messaging from module_build_service.utils import ( attempt_to_reuse_all_components, record_component_builds, - get_rpm_release_from_mmd) + get_rpm_release) from module_build_service.errors import UnprocessableEntity, Forbidden, ValidationError from module_build_service.builder.KojiContentGenerator import KojiContentGenerator @@ -139,6 +139,8 @@ def init(config, session, msg): try: mmd = build.mmd() record_component_builds(mmd, build, session=session) + build.build_context, build.runtime_context = build.contexts_from_mmd(mmd.dumps()) + mmd.context = build.context build.modulemd = mmd.dumps() build.transition(conf, models.BUILD_STATES["wait"]) # Catch custom exceptions that we can expose to the user @@ -309,7 +311,7 @@ def wait(config, session, msg): further_work = [] if not component_build: srpm = builder.get_disttag_srpm( - disttag=".%s" % get_rpm_release_from_mmd(build.mmd()), + disttag=".%s" % get_rpm_release(build), module_build=build) component_build = models.ComponentBuild( module_id=build.id, diff --git a/module_build_service/utils.py b/module_build_service/utils.py index d5194638..4886e6b4 100644 --- a/module_build_service/utils.py +++ b/module_build_service/utils.py @@ -1417,15 +1417,14 @@ def validate_koji_tag(tag_arg_names, pre='', post='-', dict_key='name'): return validation_decorator -def get_rpm_release_from_mmd(mmd): +def get_rpm_release(module_build): """ - Returns the dist tag based on the modulemd metadata and MBS configuration. + Generates the dist tag for the specified module + :param module_build: a models.ModuleBuild object + :return: a string of the module's dist tag """ - - if not mmd.name or not mmd.stream or not mmd.version: - raise ValueError("Modulemd name, stream, and version are required.") - - dist_str = '.'.join([mmd.name, mmd.stream, str(mmd.version)]) + dist_str = '.'.join([module_build.name, module_build.stream, str(module_build.version), + str(module_build.context)]) dist_hash = hashlib.sha1(dist_str).hexdigest()[:8] return conf.default_dist_tag_prefix + dist_hash diff --git a/requirements.txt b/requirements.txt index 04170af2..70038bb7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,7 @@ ldap3 m2crypto m2ext mock -modulemd>=1.2.0,<2.0.0 +modulemd>=1.3.3,<2.0.0 moksha.hub munch pdc-client diff --git a/tests/__init__.py b/tests/__init__.py index fc2116a1..9ac0ce6c 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -22,14 +22,17 @@ import os import tarfile -import module_build_service - from datetime import datetime, timedelta + +import modulemd + +import module_build_service +import module_build_service.pdc from module_build_service import db +from module_build_service.utils import get_rpm_release from module_build_service.config import init_config from module_build_service.models import ModuleBuild, ComponentBuild, make_session -import modulemd -import module_build_service.pdc + base_dir = os.path.dirname(__file__) app = module_build_service.app @@ -76,6 +79,7 @@ def init_data(): build_one.time_completed = \ datetime(2016, 9, 3, 11, 25, 32) + timedelta(minutes=(index * 10)) build_one.rebuild_strategy = 'changed-and-after' + build_one_component_release = get_rpm_release(build_one) component_one_build_one = ComponentBuild() component_one_build_one.package = 'nginx' @@ -85,7 +89,7 @@ def init_data(): component_one_build_one.format = 'rpms' component_one_build_one.task_id = 12312345 + index component_one_build_one.state = 1 - component_one_build_one.nvr = 'nginx-1.10.1-2.module_nginx_1_2' + component_one_build_one.nvr = 'nginx-1.10.1-2.{0}'.format(build_one_component_release) component_one_build_one.batch = 1 component_one_build_one.module_id = 1 + index * 3 component_one_build_one.tagged = True @@ -100,7 +104,7 @@ def init_data(): component_two_build_one.task_id = 12312321 + index component_two_build_one.state = 1 component_two_build_one.nvr = \ - 'module-build-macros-01-1.module_nginx_1_2' + 'module-build-macros-01-1.{0}'.format(build_one_component_release) component_two_build_one.batch = 2 component_two_build_one.module_id = 1 + index * 3 component_two_build_one.tagged = True @@ -124,6 +128,7 @@ def init_data(): build_two.time_completed = \ datetime(2016, 9, 3, 11, 27, 19) + timedelta(minutes=(index * 10)) build_two.rebuild_strategy = 'changed-and-after' + build_two_component_release = get_rpm_release(build_two) component_one_build_two = ComponentBuild() component_one_build_two.package = 'postgresql' @@ -133,7 +138,7 @@ def init_data(): component_one_build_two.format = 'rpms' component_one_build_two.task_id = 2433433 + index component_one_build_two.state = 1 - component_one_build_two.nvr = 'postgresql-9.5.3-4.module_postgresql_1_2' + component_one_build_two.nvr = 'postgresql-9.5.3-4.{0}'.format(build_two_component_release) component_one_build_two.batch = 2 component_one_build_two.module_id = 2 + index * 3 component_one_build_two.tagged = True @@ -148,7 +153,7 @@ def init_data(): component_two_build_two.task_id = 47383993 + index component_two_build_two.state = 1 component_two_build_two.nvr = \ - 'module-build-macros-01-1.module_postgresql_1_2' + 'module-build-macros-01-1.{0}'.format(build_two_component_release) component_two_build_two.batch = 1 component_two_build_two.module_id = 2 + index * 3 component_one_build_two.tagged = True @@ -171,6 +176,7 @@ def init_data(): datetime(2016, 9, 3, 12, 28, 40) + timedelta(minutes=(index * 10)) build_three.time_completed = None build_three.rebuild_strategy = 'changed-and-after' + build_three_component_release = get_rpm_release(build_three) component_one_build_three = ComponentBuild() component_one_build_three.package = 'rubygem-rails' @@ -180,7 +186,8 @@ def init_data(): component_one_build_three.format = 'rpms' component_one_build_three.task_id = 2433433 + index component_one_build_three.state = 3 - component_one_build_three.nvr = 'postgresql-9.5.3-4.module_postgresql_1_2' + component_one_build_three.nvr = \ + 'postgresql-9.5.3-4.{0}'.format(build_three_component_release) component_one_build_three.batch = 2 component_one_build_three.module_id = 3 + index * 3 @@ -193,7 +200,7 @@ def init_data(): component_two_build_three.task_id = 47383993 + index component_two_build_three.state = 1 component_two_build_three.nvr = \ - 'module-build-macros-01-1.module_postgresql_1_2' + 'module-build-macros-01-1.{0}'.format(build_three_component_release) component_two_build_three.batch = 1 component_two_build_three.module_id = 3 + index * 3 component_two_build_three.tagged = True @@ -236,6 +243,7 @@ def scheduler_init_data(communicator_state=None): build_one.time_submitted = datetime(2016, 12, 9, 11, 23, 20) build_one.time_modified = datetime(2016, 12, 9, 11, 25, 32) build_one.rebuild_strategy = 'changed-and-after' + build_one_component_release = get_rpm_release(build_one) component_one_build_one = module_build_service.models.ComponentBuild() component_one_build_one.package = 'communicator' @@ -248,7 +256,7 @@ def scheduler_init_data(communicator_state=None): if component_one_build_one.state == 1: component_one_build_one.tagged = True component_one_build_one.tagged_in_final = True - component_one_build_one.nvr = 'communicator-1.10.1-2.module_starcommand_1_3' + component_one_build_one.nvr = 'communicator-1.10.1-2.{0}'.format(build_one_component_release) component_one_build_one.batch = 2 component_one_build_one.module_id = 1 @@ -264,7 +272,7 @@ def scheduler_init_data(communicator_state=None): component_two_build_one.tagged = True component_two_build_one.tagged_in_final = True component_two_build_one.nvr = \ - 'module-build-macros-01-1.module_starcommand_1_3' + 'module-build-macros-01-1.{0}'.format(build_one_component_release) component_two_build_one.batch = 2 component_two_build_one.module_id = 1 @@ -289,6 +297,8 @@ def test_reuse_component_init_data(): build_one.stream = 'master' build_one.version = 20170109091357 build_one.state = 5 + build_one.build_context = 'ac4de1c346dcf09ce77d38cd4e75094ec1c08eb0' + build_one.runtime_context = 'ac4de1c346dcf09ce77d38cd4e75094ec1c08eb0' build_one.modulemd = yaml build_one.koji_tag = 'module-testmodule-master-20170109091357' build_one.scmurl = ('git://pkgs.stg.fedoraproject.org/modules/testmodule.' @@ -299,6 +309,7 @@ def test_reuse_component_init_data(): build_one.time_modified = datetime(2017, 2, 15, 16, 19, 35) build_one.time_completed = datetime(2017, 2, 15, 16, 19, 35) build_one.rebuild_strategy = 'changed-and-after' + build_one_component_release = get_rpm_release(build_one) component_one_build_one = module_build_service.models.ComponentBuild() component_one_build_one.package = 'perl-Tangerine' @@ -309,7 +320,7 @@ def test_reuse_component_init_data(): component_one_build_one.task_id = 90276227 component_one_build_one.state = 1 component_one_build_one.nvr = \ - 'perl-Tangerine-0.23-1.module_testmodule_master_20170109091357' + 'perl-Tangerine-0.23-1.{0}'.format(build_one_component_release) component_one_build_one.batch = 2 component_one_build_one.module_id = 1 component_one_build_one.ref = '4ceea43add2366d8b8c5a622a2fb563b625b9abf' @@ -325,7 +336,7 @@ def test_reuse_component_init_data(): component_two_build_one.task_id = 90276228 component_two_build_one.state = 1 component_two_build_one.nvr = \ - 'perl-List-Compare-0.53-5.module_testmodule_master_20170109091357' + 'perl-List-Compare-0.53-5.{0}'.format(build_one_component_release) component_two_build_one.batch = 2 component_two_build_one.module_id = 1 component_two_build_one.ref = '76f9d8c8e87eed0aab91034b01d3d5ff6bd5b4cb' @@ -341,7 +352,7 @@ def test_reuse_component_init_data(): component_three_build_one.task_id = 90276315 component_three_build_one.state = 1 component_three_build_one.nvr = \ - 'tangerine-0.22-3.module_testmodule_master_20170109091357' + 'tangerine-0.22-3.{0}'.format(build_one_component_release) component_three_build_one.batch = 3 component_three_build_one.module_id = 1 component_three_build_one.ref = 'fbed359411a1baa08d4a88e0d12d426fbf8f602c' @@ -357,7 +368,7 @@ def test_reuse_component_init_data(): component_four_build_one.task_id = 90276181 component_four_build_one.state = 1 component_four_build_one.nvr = \ - 'module-build-macros-0.1-1.module_testmodule_master_20170109091357' + 'module-build-macros-0.1-1.{0}'.format(build_one_component_release) component_four_build_one.batch = 1 component_four_build_one.module_id = 1 component_four_build_one.tagged = True @@ -371,6 +382,8 @@ def test_reuse_component_init_data(): build_two.stream = 'master' build_two.version = 20170219191323 build_two.state = 2 + build_two.build_context = 'ac4de1c346dcf09ce77d38cd4e75094ec1c08eb0' + build_two.runtime_context = 'ac4de1c346dcf09ce77d38cd4e75094ec1c08eb0' build_two.modulemd = mmd.dumps() build_two.koji_tag = 'module-testmodule' build_two.scmurl = ('git://pkgs.stg.fedoraproject.org/modules/testmodule.' @@ -380,6 +393,7 @@ def test_reuse_component_init_data(): build_two.time_submitted = datetime(2017, 2, 19, 16, 8, 18) build_two.time_modified = datetime(2017, 2, 19, 16, 8, 18) build_two.rebuild_strategy = 'changed-and-after' + build_two_component_release = get_rpm_release(build_two) component_one_build_two = module_build_service.models.ComponentBuild() component_one_build_two.package = 'perl-Tangerine' @@ -420,7 +434,7 @@ def test_reuse_component_init_data(): component_four_build_two.task_id = 90276186 component_four_build_two.state = 1 component_four_build_two.nvr = \ - 'module-build-macros-0.1-1.module_testmodule_master_20170219191323' + 'module-build-macros-0.1-1.{0}'.format(build_two_component_release) component_four_build_two.batch = 1 component_four_build_two.module_id = 2 component_four_build_two.tagged = True @@ -459,6 +473,8 @@ def test_reuse_shared_userspace_init_data(): build_one.name = mmd.name build_one.stream = mmd.stream build_one.version = mmd.version + build_one.build_context = 'e046b867a400a06a3571f3c71142d497895fefbe' + build_one.runtime_context = '50dd3eb5dde600d072e45d4120e1548ce66bc94a' build_one.state = 5 build_one.modulemd = yaml build_one.koji_tag = 'module-testmodule-master-20170109091357' @@ -509,6 +525,8 @@ def test_reuse_shared_userspace_init_data(): build_one.name = mmd.name build_one.stream = mmd.stream build_one.version = mmd.version + build_one.build_context = 'e046b867a400a06a3571f3c71142d497895fefbe' + build_one.runtime_context = '50dd3eb5dde600d072e45d4120e1548ce66bc94a' build_one.state = 3 build_one.modulemd = yaml build_one.koji_tag = 'module-testmodule-master-20170109091357' diff --git a/tests/staged_data/formatted_starcommand.yaml b/tests/staged_data/formatted_starcommand.yaml index 80a24795..59c3dbc4 100644 --- a/tests/staged_data/formatted_starcommand.yaml +++ b/tests/staged_data/formatted_starcommand.yaml @@ -15,7 +15,8 @@ data: base-runtime: master xmd: mbs: - buildrequires: {base-runtime: {ref: ae993ba84f4bce554471382ccba917ef16265f11, stream: master, version: 20170315134803}} + buildrequires: {base-runtime: {ref: ae993ba84f4bce554471382ccba917ef16265f11, stream: master, version: '20170315134803', 'filtered_rpms': []}} + requires: {base-runtime: {ref: ae993ba84f4bce554471382ccba917ef16265f11, stream: master, version: '20170315134803', 'filtered_rpms': []}} commit: 7fea453bc362cc8e5aa41e129e689baea853653d scmurl: git://pkgs.stg.fedoraproject.org/modules/starcommand.git?#7fea453 references: diff --git a/tests/staged_data/formatted_testmodule.yaml b/tests/staged_data/formatted_testmodule.yaml index 5177bf3b..69da9f83 100644 --- a/tests/staged_data/formatted_testmodule.yaml +++ b/tests/staged_data/formatted_testmodule.yaml @@ -32,6 +32,7 @@ data: xmd: mbs: buildrequires: {base-runtime: {ref: ae993ba84f4bce554471382ccba917ef16265f11, stream: master, version: 20170315134803, 'filtered_rpms': []}} + requires: {base-runtime: {ref: ae993ba84f4bce554471382ccba917ef16265f11, stream: master, version: 20170315134803, 'filtered_rpms': []}} commit: 7fea453bc362cc8e5aa41e129e689baea853653d scmurl: git://pkgs.stg.fedoraproject.org/modules/testmodule.git?#7fea453 document: modulemd diff --git a/tests/staged_data/shared-userspace-570.yaml b/tests/staged_data/shared-userspace-570.yaml index f6a91fa6..e4bbe41b 100644 --- a/tests/staged_data/shared-userspace-570.yaml +++ b/tests/staged_data/shared-userspace-570.yaml @@ -347,6 +347,9 @@ data: common-build-dependencies: {ref: efe284a9c846412d36bee10bd034a833e49a2f3e, stream: f26, version: '20170531160555'} perl: {ref: 634417c4c8d86fd473056b3aeab29be91c23812f, stream: f26, version: '20170515072053'} + requires: + base-runtime: {ref: be993ba94f4bce554472382ccba917ef16265f12, stream: f26, version: '1'} + perl: {ref: 634417c4c8d86fd473056b3aeab29be91c23812f, stream: f26, version: '20170515072053'} commit: 8efb24e89c26ca6d0c991a16dfbc28930bb3210f rpms: PyYAML: {ref: f17d9a7c1f1c473779751401b5eb617abf452dbe} diff --git a/tests/staged_data/shared-userspace-577.yaml b/tests/staged_data/shared-userspace-577.yaml index f8828f79..3af6f6b3 100644 --- a/tests/staged_data/shared-userspace-577.yaml +++ b/tests/staged_data/shared-userspace-577.yaml @@ -347,6 +347,9 @@ data: common-build-dependencies: {ref: efe284a9c846412d36bee10bd034a833e49a2f3e, stream: f26, version: '20170531160555'} perl: {ref: 634417c4c8d86fd473056b3aeab29be91c23812f, stream: f26, version: '20170515072053'} + requires: + base-runtime: {ref: be993ba94f4bce554472382ccba917ef16265f12, stream: f26, version: '1'} + perl: {ref: 634417c4c8d86fd473056b3aeab29be91c23812f, stream: f26, version: '20170515072053'} commit: 7886687b3a64fc0c5473460e09bc2c7a26f19d5f rpms: PyYAML: {ref: f17d9a7c1f1c473779751401b5eb617abf452dbe} diff --git a/tests/staged_data/testmodule_dependencies.yaml b/tests/staged_data/testmodule_dependencies.yaml new file mode 100644 index 00000000..087ea422 --- /dev/null +++ b/tests/staged_data/testmodule_dependencies.yaml @@ -0,0 +1,60 @@ +data: + api: + rpms: [tangerine, perl-Tangerine] + components: + rpms: + perl-List-Compare: {cache: 'http://pkgs.fedoraproject.org/repo/pkgs/perl-List-Compare', + rationale: A dependency of tangerine., ref: 76f9d8c8e87eed0aab91034b01d3d5ff6bd5b4cb, + repository: 'git://pkgs.fedoraproject.org/rpms/perl-List-Compare'} + perl-Tangerine: {cache: 'http://pkgs.fedoraproject.org/repo/pkgs/perl-Tangerine', + rationale: Provides API for this module and is a dependency of tangerine., + ref: 4ceea43add2366d8b8c5a622a2fb563b625b9abf, repository: 'git://pkgs.fedoraproject.org/rpms/perl-Tangerine'} + tangerine: {buildorder: 10, cache: 'http://pkgs.fedoraproject.org/repo/pkgs/tangerine', + rationale: Provides API for this module., ref: fbed359411a1baa08d4a88e0d12d426fbf8f602c, + repository: 'git://pkgs.fedoraproject.org/rpms/tangerine'} + dependencies: + buildrequires: + zebra: stripes + base-runtime: master + fluffy: slippers + requires: + fidget: spinner + base-runtime: master + silly: puddy + glass: water + description: This module demonstrates how to write simple modulemd files And can + be used for testing the build and release pipeline. + filter: {} + license: + module: [MIT] + name: testmodule + profiles: + default: + rpms: [tangerine] + references: {community: 'https://fedoraproject.org/wiki/Modularity', documentation: 'https://fedoraproject.org/wiki/Fedora_Packaging_Guidelines_for_Modules', + tracker: 'https://taiga.fedorainfracloud.org/project/modularity'} + stream: master + summary: A test module in all its beautiful beauty + version: 20170109091357 + xmd: + mbs: + buildrequires: + zebra: + ref: 08f8671f5925ecbd7c55d83e8368dd0be81ef8ed + base-runtime: + ref: ae993ba84f4bce554471382ccba917ef16265f11 + fluffy: + ref: ea83325b231f64c575ea104bb698e9d43b80469a + requires: + fidget: + ref: 5aa32bd61aadaec8295ef90f79daaf190e387509 + base-runtime: + ref: ae993ba84f4bce554471382ccba917ef16265f11 + silly: + ref: 0e2a1f9246118180d61aad731923ebd85154bc6e + glass: + ref: ea8753e832974dd5b0d95cd6bb7d26727d2ba742 + commit: 7fea453bc362cc8e5aa41e129e689baea853653d + scmurl: git://pkgs.stg.fedoraproject.org/modules/testmodule.git?#7fea453 +document: modulemd +version: 1 diff --git a/tests/test_build/test_build.py b/tests/test_build/test_build.py index 402da46d..dd2aef6e 100644 --- a/tests/test_build/test_build.py +++ b/tests/test_build/test_build.py @@ -40,6 +40,7 @@ from module_build_service import db, models, conf, build_logs from mock import patch, PropertyMock, Mock import kobo +from modulemd import ModuleMetadata from tests import app, test_reuse_component_init_data, clean_database import json @@ -259,8 +260,8 @@ class FakeModuleBuilder(GenericBuilder): def recover_orphaned_artifact(self, component_build): msgs = [] if self.INSTANT_COMPLETE: - disttag = module_build_service.utils.get_rpm_release_from_mmd( - component_build.module_build.mmd()) + disttag = module_build_service.utils.get_rpm_release( + component_build.module_build) # We don't know the version or release, so just use a random one here nvr = '{0}-1.0-1.{1}'.format(component_build.package, disttag) component_build.state = koji.BUILD_STATES['COMPLETE'] @@ -780,9 +781,9 @@ class TestBuild(unittest.TestCase): # Check that components are tagged after the batch is built. tag_groups = [] tag_groups.append(set( - ['perl-Tangerine-0.23-1.module_testmodule_master_20170109091357', - 'perl-List-Compare-0.53-5.module_testmodule_master_20170109091357', - 'tangerine-0.22-3.module_testmodule_master_20170109091357'])) + ['perl-Tangerine-0.23-1.module+814cfa39', + 'perl-List-Compare-0.53-5.module+814cfa39', + 'tangerine-0.22-3.module+814cfa39'])) def on_tag_artifacts_cb(cls, artifacts, dest_tag=True): if dest_tag is True: @@ -791,9 +792,9 @@ class TestBuild(unittest.TestCase): buildtag_groups = [] buildtag_groups.append(set( - ['perl-Tangerine-0.23-1.module_testmodule_master_20170109091357', - 'perl-List-Compare-0.53-5.module_testmodule_master_20170109091357', - 'tangerine-0.22-3.module_testmodule_master_20170109091357'])) + ['perl-Tangerine-0.23-1.module+814cfa39', + 'perl-List-Compare-0.53-5.module+814cfa39', + 'tangerine-0.22-3.module+814cfa39'])) def on_buildroot_add_artifacts_cb(cls, artifacts, install): self.assertEqual(buildtag_groups.pop(0), set(artifacts)) @@ -840,9 +841,9 @@ class TestBuild(unittest.TestCase): # Check that components are tagged after the batch is built. tag_groups = [] tag_groups.append(set( - ['perl-Tangerine-0.23-1.module_testmodule_master_20170109091357', - 'perl-List-Compare-0.53-5.module_testmodule_master_20170109091357', - 'tangerine-0.22-3.module_testmodule_master_20170109091357'])) + ['perl-Tangerine-0.23-1.module+814cfa39', + 'perl-List-Compare-0.53-5.module+814cfa39', + 'tangerine-0.22-3.module+814cfa39'])) def on_tag_artifacts_cb(cls, artifacts, dest_tag=True): if dest_tag is True: @@ -851,9 +852,9 @@ class TestBuild(unittest.TestCase): buildtag_groups = [] buildtag_groups.append(set( - ['perl-Tangerine-0.23-1.module_testmodule_master_20170109091357', - 'perl-List-Compare-0.53-5.module_testmodule_master_20170109091357', - 'tangerine-0.22-3.module_testmodule_master_20170109091357'])) + ['perl-Tangerine-0.23-1.module+814cfa39', + 'perl-List-Compare-0.53-5.module+814cfa39', + 'tangerine-0.22-3.module+814cfa39'])) def on_buildroot_add_artifacts_cb(cls, artifacts, install): self.assertEqual(buildtag_groups.pop(0), set(artifacts)) @@ -886,6 +887,8 @@ class TestBuild(unittest.TestCase): build_one.name = 'testmodule' build_one.stream = 'master' build_one.version = 1 + build_one.build_context = 'ac4de1c346dcf09ce77d38cd4e75094ec1c08eb0' + build_one.runtime_context = 'ac4de1c346dcf09ce77d38cd4e75094ec1c08eb0' build_one.state = models.BUILD_STATES['failed'] current_dir = os.path.dirname(__file__) formatted_testmodule_yml_path = os.path.join( @@ -1006,6 +1009,8 @@ class TestBuild(unittest.TestCase): build_one.name = 'testmodule' build_one.stream = 'master' build_one.version = 1 + build_one.build_context = 'ac4de1c346dcf09ce77d38cd4e75094ec1c08eb0' + build_one.runtime_context = 'ac4de1c346dcf09ce77d38cd4e75094ec1c08eb0' build_one.state = models.BUILD_STATES['failed'] current_dir = os.path.dirname(__file__) formatted_testmodule_yml_path = os.path.join( diff --git a/tests/test_builder/test_koji.py b/tests/test_builder/test_koji.py index e044d0c6..a40974d9 100644 --- a/tests/test_builder/test_koji.py +++ b/tests/test_builder/test_koji.py @@ -126,17 +126,18 @@ class TestKojiBuilder(unittest.TestCase): builder.module_tag = {"name": "module-foo", "id": 1} builder.module_build_tag = {"name": "module-foo-build", "id": 2} + dist_tag = 'module+b8661ee4' # Set listTagged to return test data builder.koji_session.listTagged.side_effect = [[], [], []] untagged = [{ "id": 9000, "name": "foo", "version": "1.0", - "release": "1.module+e0095747", + "release": "1.{0}".format(dist_tag), }] builder.koji_session.untaggedBuilds.return_value = untagged build_info = { - 'nvr': 'foo-1.0-1.module+e0095747', + 'nvr': 'foo-1.0-1.{0}'.format(dist_tag), 'task_id': 12345, 'build_id': 91 } @@ -155,12 +156,13 @@ class TestKojiBuilder(unittest.TestCase): self.assertEquals(actual[0].build_new_state, koji.BUILD_STATES['COMPLETE']) self.assertEquals(actual[0].build_name, 'rubygem-rails') self.assertEquals(actual[0].build_version, '1.0') - self.assertEquals(actual[0].build_release, '1.module+e0095747') + self.assertEquals( + actual[0].build_release, '1.{0}'.format(dist_tag)) self.assertEquals(actual[0].module_build_id, 30) self.assertEqual(component_build.state, koji.BUILD_STATES['COMPLETE']) self.assertEqual(component_build.task_id, 12345) self.assertEqual(component_build.state_reason, 'Found existing build') - builder.koji_session.tagBuild.assert_called_once_with(2, 'foo-1.0-1.module+e0095747') + builder.koji_session.tagBuild.assert_called_once_with(2, 'foo-1.0-1.{0}'.format(dist_tag)) def test_recover_orphaned_artifact_when_nothing_exists(self): """ Test recover_orphaned_artifact when the build is not found diff --git a/tests/test_content_generator.py b/tests/test_content_generator.py index 8e7e1a6c..21dd7dfd 100644 --- a/tests/test_content_generator.py +++ b/tests/test_content_generator.py @@ -172,7 +172,7 @@ class TestBuild(unittest.TestCase): self.cg._tag_cg_build() koji_session.getTag.assert_called_once_with(self.cg.module.cg_build_koji_tag) - koji_session.tagBuild.assert_called_once_with(123, "nginx-1-2") + koji_session.tagBuild.assert_called_once_with(123, "nginx-1-2.00000000") @patch("module_build_service.builder.KojiModuleBuilder.KojiModuleBuilder.get_session") def test_tag_cg_build_fallback_to_default_tag(self, get_session): @@ -186,7 +186,7 @@ class TestBuild(unittest.TestCase): self.assertEqual(koji_session.getTag.mock_calls, [call(self.cg.module.cg_build_koji_tag), call(conf.koji_cg_default_build_tag)]) - koji_session.tagBuild.assert_called_once_with(123, "nginx-1-2") + koji_session.tagBuild.assert_called_once_with(123, "nginx-1-2.00000000") @patch("module_build_service.builder.KojiModuleBuilder.KojiModuleBuilder.get_session") def test_tag_cg_build_no_tag_set(self, get_session): diff --git a/tests/test_get_generator_json_expected_output.json b/tests/test_get_generator_json_expected_output.json index a33c9f98..e7da3604 100644 --- a/tests/test_get_generator_json_expected_output.json +++ b/tests/test_get_generator_json_expected_output.json @@ -641,11 +641,12 @@ "version": "1", "end_time": 1472901932, "name": "nginx", - "release": "2", + "release": "2.00000000", "extra": { "typeinfo": { "module": { "name": "nginx", + "context": "00000000", "stream": "1", "version": "2", "module_build_service_id": 1, diff --git a/tests/test_get_generator_json_expected_output_with_log.json b/tests/test_get_generator_json_expected_output_with_log.json index 24f8f8f0..92465d28 100644 --- a/tests/test_get_generator_json_expected_output_with_log.json +++ b/tests/test_get_generator_json_expected_output_with_log.json @@ -650,11 +650,12 @@ "version": "1", "end_time": 1472901932, "name": "nginx", - "release": "2", + "release": "2.00000000", "extra": { "typeinfo": { "module": { "name": "nginx", + "context": "00000000", "stream": "1", "version": "2", "module_build_service_id": 1, diff --git a/tests/test_models/test_models.py b/tests/test_models/test_models.py index db72607d..c4fba4b6 100644 --- a/tests/test_models/test_models.py +++ b/tests/test_models/test_models.py @@ -20,11 +20,14 @@ # # Written by Ralph Bean +import os import unittest +import modulemd + from tests.test_models import init_data from module_build_service import conf -from module_build_service.models import ComponentBuild, make_session +from module_build_service.models import ComponentBuild, ModuleBuild, make_session class TestModels(unittest.TestCase): @@ -56,3 +59,17 @@ class TestModels(unittest.TestCase): self.assertEquals(c.component_builds_trace[0].state, 1) self.assertEquals(c.component_builds_trace[0].state_reason, None) self.assertEquals(c.component_builds_trace[0].task_id, 999999999) + + def test_context_functions(self): + """ Test that the build_context, runtime_context, and context hashes are correctly + determined""" + build = ModuleBuild.query.filter_by(id=1).one() + mmd = modulemd.ModuleMetadata() + yaml_path = os.path.join( + os.path.dirname(__file__), '..', 'staged_data', 'testmodule_dependencies.yaml') + mmd.load(yaml_path) + build.modulemd = mmd.dumps() + build.build_context, build.runtime_context = ModuleBuild.contexts_from_mmd(build.modulemd) + self.assertEqual(build.build_context, 'f6e2aeec7576196241b9afa0b6b22acf2b6873d7') + self.assertEqual(build.runtime_context, '1739827b08388842fc90ccc0b6070c59b7d856fc') + self.assertEqual(build.context, 'e7a3d35e') diff --git a/tests/test_scheduler/test_poller.py b/tests/test_scheduler/test_poller.py index 1c33e2db..e69abb14 100644 --- a/tests/test_scheduler/test_poller.py +++ b/tests/test_scheduler/test_poller.py @@ -385,10 +385,10 @@ class TestPoller(unittest.TestCase): self.assertEqual(module_build_two.state, models.BUILD_STATES['failed']) # Make sure the builds were untagged builder.untag_artifacts.assert_called_once_with([ - 'perl-Tangerine-0.23-1.module_testmodule_master_20170109091357', - 'perl-List-Compare-0.53-5.module_testmodule_master_20170109091357', - 'tangerine-0.22-3.module_testmodule_master_20170109091357', - 'module-build-macros-0.1-1.module_testmodule_master_20170109091357' + 'perl-Tangerine-0.23-1.module+814cfa39', + 'perl-List-Compare-0.53-5.module+814cfa39', + 'tangerine-0.22-3.module+814cfa39', + 'module-build-macros-0.1-1.module+814cfa39' ]) def test_cleanup_stale_failed_builds_no_components(self, create_builder, koji_get_session, diff --git a/tests/test_utils/test_utils.py b/tests/test_utils/test_utils.py index ef993e4d..cc7c6ac6 100644 --- a/tests/test_utils/test_utils.py +++ b/tests/test_utils/test_utils.py @@ -83,149 +83,149 @@ class TestUtils(unittest.TestCase): def setUp(self): self.filtered_rpms = [ - u'glibc-utils-0:2.25-4.module_5ccf9229', - u'glibc-benchtests-0:2.25-4.module_5ccf9229', - u'systemd-journal-remote-0:233-3.module_5ccf9229', - u'openldap-servers-0:2.4.44-8.module_5ccf9229', - u'kernel-debug-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', - u'python-perf-0:4.11.0-0.rc7.git0.1.module_5ccf9229', - u'kernel-tools-0:4.11.0-0.rc7.git0.1.module_5ccf9229', - u'perf-0:4.11.0-0.rc7.git0.1.module_5ccf9229', - u'kernel-tools-libs-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', - u'kernel-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', - u'kernel-PAE-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', - u'kernel-PAEdebug-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', - u'kernel-lpae-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', - u'libcroco-devel-0:0.6.11-3.module_5ccf9229', - u'dbus-x11-1:1.11.10-2.module_5ccf9229', - u'qgpgme-0:1.9.0-1.module_5ccf9229', - u'qgpgme-devel-0:1.9.0-1.module_5ccf9229', - u'python2-gpg-0:1.9.0-1.module_5ccf9229', - u'libssh2-devel-0:1.8.0-2.module_5ccf9229', - u'python3-test-0:3.6.0-21.module_5ccf9229', - u'python3-debug-0:3.6.0-21.module_5ccf9229', - u'python3-tkinter-0:3.6.0-21.module_5ccf9229', - u'python3-tools-0:3.6.0-21.module_5ccf9229', - u'grub2-starfield-theme-1:2.02-0.38.module_5ccf9229', - u'libbabeltrace-devel-0:1.5.2-2.module_5ccf9229', - u'libidn-javadoc-0:1.33-2.module_5ccf9229', - u'libidn-java-0:1.33-2.module_5ccf9229', - u'cyrus-sasl-sql-0:2.1.26-30.module_5ccf9229', - u'python2-solv-0:0.6.26-1.module_5ccf9229', - u'perl-solv-0:0.6.26-1.module_5ccf9229', - u'python2-packaging-0:16.8-4.module_5ccf9229', - u'freetype-demos-0:2.7.1-2.module_5ccf9229', - u'util-linux-user-0:2.29.1-2.module_5ccf9229', - u'syslinux-perl-0:6.04-0.2.module_5ccf9229', - u'gnutls-utils-0:3.5.10-1.module_5ccf9229', - u'gnutls-guile-0:3.5.10-1.module_5ccf9229', - u'gnutls-devel-0:3.5.10-1.module_5ccf9229', - u'gnutls-dane-0:3.5.10-1.module_5ccf9229', - u'python-pwquality-0:1.3.0-8.module_5ccf9229', - u'openssl-perl-1:1.1.0e-1.module_5ccf9229', - u'glib2-fam-0:2.52.0-1.module_5ccf9229', - u'glib2-static-0:2.52.0-1.module_5ccf9229', - u'glib2-devel-0:2.52.0-1.module_5ccf9229', - u'libselinux-ruby-0:2.6-2.module_5ccf9229', - u'libselinux-python-0:2.6-2.module_5ccf9229', - u'cmirror-0:2.02.168-4.module_5ccf9229', - u'lvm2-cluster-standalone-0:2.02.168-4.module_5ccf9229', - u'lvm2-dbusd-0:2.02.168-4.module_5ccf9229', - u'lvm2-python-libs-0:2.02.168-4.module_5ccf9229', - u'lvm2-cluster-0:2.02.168-4.module_5ccf9229', - u'cmirror-standalone-0:2.02.168-4.module_5ccf9229', - u'lvm2-lockd-0:2.02.168-4.module_5ccf9229', - u'python2-pip-0:9.0.1-7.module_5ccf9229', - u'python-magic-0:5.30-5.module_5ccf9229', - u'cracklib-python-0:2.9.6-5.module_5ccf9229', - u'hfsutils-x11-0:3.2.6-31.module_5ccf9229', - u'kernel-rpm-macros-0:63-1.module_5ccf9229', - u'cryptsetup-python-0:1.7.3-3.module_5ccf9229', - u'python2-rpm-0:4.13.0.1-3.module_5ccf9229', - u'rpm-cron-0:4.13.0.1-3.module_5ccf9229', - u'texinfo-0:6.3-2.module_5ccf9229', - u'texinfo-tex-0:6.3-2.module_5ccf9229', - u'qt5-0:5.8.0-2.module_5ccf9229', - u'qt5-devel-0:5.8.0-2.module_5ccf9229', - u'qt5-rpm-macros-0:5.8.0-2.module_5ccf9229', - u'gnupg2-smime-0:2.1.18-2.module_5ccf9229', - u'emacs-nox-1:25.2-0.1.rc2.module_5ccf9229', - u'emacs-terminal-1:25.2-0.1.rc2.module_5ccf9229', - u'emacs-common-1:25.2-0.1.rc2.module_5ccf9229', - u'emacs-1:25.2-0.1.rc2.module_5ccf9229', + u'sqlite-tcl-0:3.17.0-2.module_5ccf9229', + u'sqlite-analyzer-0:3.17.0-2.module_5ccf9229', + u'emacs-gettext-0:0.19.8.1-8.module_5ccf9229', + u'msghack-0:0.19.8.1-8.module_5ccf9229', + u'modeline2fb-0:2.1-40.module_5ccf9229', + u'audit-libs-python-0:2.7.3-1.module_5ccf9229', + u'audit-libs-python3-0:2.7.3-1.module_5ccf9229', + u'audispd-plugins-zos-0:2.7.3-1.module_5ccf9229', + u'audit-0:2.7.3-1.module_5ccf9229', + u'audispd-plugins-0:2.7.3-1.module_5ccf9229', + u'librepo-devel-0:1.7.20-3.module_5ccf9229', + u'python2-librepo-0:1.7.20-3.module_5ccf9229', + u'libcap-ng-python-0:0.7.8-3.module_5ccf9229', + u'iptables-compat-0:1.6.1-2.module_5ccf9229', + u'gobject-introspection-devel-0:1.52.0-1.module_5ccf9229', + u'ntsysv-0:1.9-1.module_5ccf9229', + u'pyparsing-0:2.1.10-3.module_5ccf9229', + u'python2-pyparsing-0:2.1.10-3.module_5ccf9229', + u'python2-appdirs-0:1.4.0-10.module_5ccf9229', + u'krb5-server-ldap-0:1.15-9.module_5ccf9229', + u'krb5-server-0:1.15-9.module_5ccf9229', + u'python-libxml2-0:2.9.4-2.module_5ccf9229', + u'libsemanage-python-0:2.6-2.module_5ccf9229', + u'python2-setuptools-0:34.3.0-1.module_5ccf9229', + u'libpeas-loader-python-0:1.20.0-5.module_5ccf9229', + u'libpeas-devel-0:1.20.0-5.module_5ccf9229', + u'libpeas-loader-python3-0:1.20.0-5.module_5ccf9229', + u'libpeas-gtk-0:1.20.0-5.module_5ccf9229', + u'python2-six-0:1.10.0-8.module_5ccf9229', + u'libtool-0:2.4.6-17.module_5ccf9229', + u'libverto-tevent-0:0.2.6-7.module_5ccf9229', u'libverto-libevent-devel-0:0.2.6-7.module_5ccf9229', u'libverto-tevent-devel-0:0.2.6-7.module_5ccf9229', u'libverto-libevent-0:0.2.6-7.module_5ccf9229', - u'libverto-tevent-0:0.2.6-7.module_5ccf9229', - u'libtool-0:2.4.6-17.module_5ccf9229', - u'libpeas-loader-python3-0:1.20.0-5.module_5ccf9229', - u'libpeas-devel-0:1.20.0-5.module_5ccf9229', - u'libpeas-gtk-0:1.20.0-5.module_5ccf9229', - u'libpeas-loader-python-0:1.20.0-5.module_5ccf9229', - u'python2-setuptools-0:34.3.0-1.module_5ccf9229', - u'libsemanage-python-0:2.6-2.module_5ccf9229', - u'python-libxml2-0:2.9.4-2.module_5ccf9229', - u'krb5-server-ldap-0:1.15-9.module_5ccf9229', - u'krb5-server-0:1.15-9.module_5ccf9229', - u'python2-six-0:1.10.0-8.module_5ccf9229', - u'python2-appdirs-0:1.4.0-10.module_5ccf9229', - u'pyparsing-0:2.1.10-3.module_5ccf9229', - u'python2-pyparsing-0:2.1.10-3.module_5ccf9229', - u'ntsysv-0:1.9-1.module_5ccf9229', - u'audit-0:2.7.3-1.module_5ccf9229', - u'audit-libs-python-0:2.7.3-1.module_5ccf9229', - u'audispd-plugins-0:2.7.3-1.module_5ccf9229', - u'audispd-plugins-zos-0:2.7.3-1.module_5ccf9229', - u'audit-libs-python3-0:2.7.3-1.module_5ccf9229', - u'modeline2fb-0:2.1-40.module_5ccf9229', - u'msghack-0:0.19.8.1-8.module_5ccf9229', - u'emacs-gettext-0:0.19.8.1-8.module_5ccf9229', - u'python2-hawkey-0:0.8.2-1.module_987f08f4', + u'emacs-nox-1:25.2-0.1.rc2.module_5ccf9229', + u'emacs-common-1:25.2-0.1.rc2.module_5ccf9229', + u'emacs-1:25.2-0.1.rc2.module_5ccf9229', + u'emacs-terminal-1:25.2-0.1.rc2.module_5ccf9229', + u'python2-rpm-0:4.13.0.1-3.module_5ccf9229', + u'rpm-cron-0:4.13.0.1-3.module_5ccf9229', + u'cryptsetup-python-0:1.7.3-3.module_5ccf9229', + u'kernel-rpm-macros-0:63-1.module_5ccf9229', + u'cracklib-python-0:2.9.6-5.module_5ccf9229', + u'gnupg2-smime-0:2.1.18-2.module_5ccf9229', + u'qt5-rpm-macros-0:5.8.0-2.module_5ccf9229', + u'qt5-devel-0:5.8.0-2.module_5ccf9229', + u'qt5-0:5.8.0-2.module_5ccf9229', + u'texinfo-0:6.3-2.module_5ccf9229', + u'texinfo-tex-0:6.3-2.module_5ccf9229', + u'python-magic-0:5.30-5.module_5ccf9229', + u'lvm2-dbusd-0:2.02.168-4.module_5ccf9229', + u'cmirror-standalone-0:2.02.168-4.module_5ccf9229', + u'lvm2-python-libs-0:2.02.168-4.module_5ccf9229', + u'lvm2-cluster-0:2.02.168-4.module_5ccf9229', + u'cmirror-0:2.02.168-4.module_5ccf9229', + u'lvm2-cluster-standalone-0:2.02.168-4.module_5ccf9229', + u'lvm2-lockd-0:2.02.168-4.module_5ccf9229', + u'libselinux-ruby-0:2.6-2.module_5ccf9229', + u'libselinux-python-0:2.6-2.module_5ccf9229', + u'hfsutils-x11-0:3.2.6-31.module_5ccf9229', + u'glib2-fam-0:2.52.0-1.module_5ccf9229', + u'glib2-static-0:2.52.0-1.module_5ccf9229', + u'glib2-devel-0:2.52.0-1.module_5ccf9229', + u'syslinux-perl-0:6.04-0.2.module_5ccf9229', + u'perl-solv-0:0.6.26-1.module_5ccf9229', + u'python2-solv-0:0.6.26-1.module_5ccf9229', + u'cyrus-sasl-sql-0:2.1.26-30.module_5ccf9229', + u'openssl-perl-1:1.1.0e-1.module_5ccf9229', + u'libidn-java-0:1.33-2.module_5ccf9229', + u'libidn-javadoc-0:1.33-2.module_5ccf9229', + u'libbabeltrace-devel-0:1.5.2-2.module_5ccf9229', + u'grub2-starfield-theme-1:2.02-0.38.module_5ccf9229', + u'util-linux-user-0:2.29.1-2.module_5ccf9229', + u'freetype-demos-0:2.7.1-2.module_5ccf9229', + u'python2-packaging-0:16.8-4.module_5ccf9229', + u'python-pwquality-0:1.3.0-8.module_5ccf9229', + u'python2-pip-0:9.0.1-7.module_5ccf9229', + u'gnutls-devel-0:3.5.10-1.module_5ccf9229', + u'gnutls-guile-0:3.5.10-1.module_5ccf9229', + u'gnutls-utils-0:3.5.10-1.module_5ccf9229', + u'gnutls-dane-0:3.5.10-1.module_5ccf9229', + u'python3-tkinter-0:3.6.0-21.module_5ccf9229', + u'python3-tools-0:3.6.0-21.module_5ccf9229', + u'python3-debug-0:3.6.0-21.module_5ccf9229', + u'python3-test-0:3.6.0-21.module_5ccf9229', + u'libssh2-devel-0:1.8.0-2.module_5ccf9229', + u'python2-gpg-0:1.9.0-1.module_5ccf9229', + u'qgpgme-devel-0:1.9.0-1.module_5ccf9229', + u'qgpgme-0:1.9.0-1.module_5ccf9229', + u'dbus-x11-1:1.11.10-2.module_5ccf9229', + u'libcroco-devel-0:0.6.11-3.module_5ccf9229', + u'kernel-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', + u'python-perf-0:4.11.0-0.rc7.git0.1.module_5ccf9229', + u'perf-0:4.11.0-0.rc7.git0.1.module_5ccf9229', + u'kernel-tools-libs-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', + u'kernel-lpae-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', + u'kernel-tools-0:4.11.0-0.rc7.git0.1.module_5ccf9229', + u'kernel-PAEdebug-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', + u'kernel-PAE-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', + u'kernel-debug-devel-0:4.11.0-0.rc7.git0.1.module_5ccf9229', + u'openldap-servers-0:2.4.44-8.module_5ccf9229', + u'systemd-journal-remote-0:233-3.module_5ccf9229', + u'glibc-utils-0:2.25-4.module_5ccf9229', + u'glibc-benchtests-0:2.25-4.module_5ccf9229', u'libdnf-devel-0:0.8.2-1.module_987f08f4', - u'sqlite-tcl-0:3.17.0-2.module_5ccf9229', - u'sqlite-analyzer-0:3.17.0-2.module_5ccf9229', - u'sssd-0:1.15.2-4.module_47fecbcd', + u'python2-hawkey-0:0.8.2-1.module_987f08f4', u'sssd-nfs-idmap-0:1.15.2-4.module_47fecbcd', - u'sssd-winbind-idmap-0:1.15.2-4.module_47fecbcd', - u'sssd-krb5-0:1.15.2-4.module_47fecbcd', - u'libsss_sudo-0:1.15.2-4.module_47fecbcd', - u'sssd-libwbclient-devel-0:1.15.2-4.module_47fecbcd', - u'sssd-common-pac-0:1.15.2-4.module_47fecbcd', - u'sssd-ipa-0:1.15.2-4.module_47fecbcd', - u'python3-sss-murmur-0:1.15.2-4.module_47fecbcd', - u'libsss_simpleifp-devel-0:1.15.2-4.module_47fecbcd', - u'sssd-common-0:1.15.2-4.module_47fecbcd', - u'sssd-dbus-0:1.15.2-4.module_47fecbcd', - u'libipa_hbac-0:1.15.2-4.module_47fecbcd', - u'sssd-proxy-0:1.15.2-4.module_47fecbcd', - u'python2-sss-murmur-0:1.15.2-4.module_47fecbcd', - u'python3-sss-0:1.15.2-4.module_47fecbcd', - u'libsss_autofs-0:1.15.2-4.module_47fecbcd', - u'python2-libipa_hbac-0:1.15.2-4.module_47fecbcd', - u'libsss_simpleifp-0:1.15.2-4.module_47fecbcd', - u'libsss_idmap-devel-0:1.15.2-4.module_47fecbcd', - u'sssd-libwbclient-0:1.15.2-4.module_47fecbcd', - u'python2-libsss_nss_idmap-0:1.15.2-4.module_47fecbcd', u'python3-libipa_hbac-0:1.15.2-4.module_47fecbcd', - u'python2-sssdconfig-0:1.15.2-4.module_47fecbcd', - u'libipa_hbac-devel-0:1.15.2-4.module_47fecbcd', + u'sssd-ipa-0:1.15.2-4.module_47fecbcd', + u'libsss_simpleifp-devel-0:1.15.2-4.module_47fecbcd', + u'python2-libipa_hbac-0:1.15.2-4.module_47fecbcd', + u'sssd-libwbclient-0:1.15.2-4.module_47fecbcd', + u'python3-sss-murmur-0:1.15.2-4.module_47fecbcd', u'libsss_nss_idmap-devel-0:1.15.2-4.module_47fecbcd', u'python2-sss-0:1.15.2-4.module_47fecbcd', + u'libsss_simpleifp-0:1.15.2-4.module_47fecbcd', u'sssd-ldap-0:1.15.2-4.module_47fecbcd', - u'sssd-ad-0:1.15.2-4.module_47fecbcd', + u'python3-sss-0:1.15.2-4.module_47fecbcd', + u'sssd-common-0:1.15.2-4.module_47fecbcd', + u'sssd-krb5-0:1.15.2-4.module_47fecbcd', + u'sssd-libwbclient-devel-0:1.15.2-4.module_47fecbcd', + u'libipa_hbac-0:1.15.2-4.module_47fecbcd', + u'sssd-winbind-idmap-0:1.15.2-4.module_47fecbcd', + u'python2-sss-murmur-0:1.15.2-4.module_47fecbcd', u'sssd-tools-0:1.15.2-4.module_47fecbcd', + u'sssd-dbus-0:1.15.2-4.module_47fecbcd', + u'sssd-ad-0:1.15.2-4.module_47fecbcd', u'sssd-krb5-common-0:1.15.2-4.module_47fecbcd', - u'librepo-devel-0:1.7.20-3.module_5ccf9229', - u'python2-librepo-0:1.7.20-3.module_5ccf9229', - u'iproute-tc-0:4.11.0-1.module_d6de39f1', + u'libsss_autofs-0:1.15.2-4.module_47fecbcd', + u'python2-libsss_nss_idmap-0:1.15.2-4.module_47fecbcd', + u'libsss_idmap-devel-0:1.15.2-4.module_47fecbcd', + u'sssd-common-pac-0:1.15.2-4.module_47fecbcd', + u'sssd-0:1.15.2-4.module_47fecbcd', + u'sssd-proxy-0:1.15.2-4.module_47fecbcd', + u'libsss_sudo-0:1.15.2-4.module_47fecbcd', + u'libipa_hbac-devel-0:1.15.2-4.module_47fecbcd', + u'python3-sssdconfig-0:1.15.2-4.module_47fecbcd', + u'python2-sssdconfig-0:1.15.2-4.module_47fecbcd', u'dracut-live-0:044-182.module_bd7491c8', u'dracut-fips-aesni-0:044-182.module_bd7491c8', - u'dracut-fips-0:044-182.module_bd7491c8', u'dracut-network-0:044-182.module_bd7491c8', - u'gobject-introspection-devel-0:1.52.0-1.module_5ccf9229', - u'iptables-compat-0:1.6.1-2.module_5ccf9229', - u'libcap-ng-python-0:0.7.8-3.module_5ccf9229', - u'python3-sssdconfig-0:1.15.2-4.module_47fecbcd' + u'dracut-fips-0:044-182.module_bd7491c8', + u'iproute-tc-0:4.11.0-1.module_d6de39f1' ] def tearDown(self): diff --git a/tests/test_views/test_views.py b/tests/test_views/test_views.py index c44df6a3..18ee08d1 100644 --- a/tests/test_views/test_views.py +++ b/tests/test_views/test_views.py @@ -130,6 +130,7 @@ class TestViews(unittest.TestCase): rv = self.client.get('/module-build-service/1/module-builds/1') data = json.loads(rv.data) self.assertEquals(data['id'], 1) + self.assertEquals(data['context'], '00000000') self.assertEquals(data['name'], 'nginx') self.assertEquals(data['owner'], 'Moe Szyslak') self.assertEquals(data['stream'], '1') @@ -141,13 +142,13 @@ class TestViews(unittest.TestCase): 'task_id': 12312321, 'state': 1, 'state_reason': None, - 'nvr': 'module-build-macros-01-1.module_nginx_1_2', + 'nvr': 'module-build-macros-01-1.module+b8661ee4', }, 'nginx': { 'task_id': 12312345, 'state': 1, 'state_reason': None, - 'nvr': 'nginx-1.10.1-2.module_nginx_1_2', + 'nvr': 'nginx-1.10.1-2.module+b8661ee4', }, }, }) @@ -161,6 +162,7 @@ class TestViews(unittest.TestCase): rv = self.client.get('/module-build-service/1/module-builds/1?short=True') data = json.loads(rv.data) self.assertEquals(data['id'], 1) + self.assertEquals(data['context'], '00000000') self.assertEquals(data['name'], 'nginx') self.assertEquals(data['state'], 3) self.assertEquals(data['state_name'], 'done') @@ -171,6 +173,10 @@ class TestViews(unittest.TestCase): rv = self.client.get('/module-build-service/1/module-builds/1?verbose=true') data = json.loads(rv.data) self.assertEquals(data['component_builds'], [1, 2]) + self.assertEquals(data['context'], '00000000') + # There is no xmd information on this module, so these values should be null + self.assertIsNone(data['build_context']) + self.assertIsNone(data['runtime_context']) self.assertEquals(data['id'], 1) with open(path.join(base_dir, "staged_data", "nginx_mmd.yaml")) as mmd: self.assertEquals(data['modulemd'], mmd.read()) @@ -193,13 +199,13 @@ class TestViews(unittest.TestCase): 'task_id': 12312321, 'state': 1, 'state_reason': None, - 'nvr': 'module-build-macros-01-1.module_nginx_1_2', + 'nvr': 'module-build-macros-01-1.module+b8661ee4', }, 'nginx': { 'task_id': 12312345, 'state': 1, 'state_reason': None, - 'nvr': 'nginx-1.10.1-2.module_nginx_1_2', + 'nvr': 'nginx-1.10.1-2.module+b8661ee4', }, }, }) @@ -242,6 +248,7 @@ class TestViews(unittest.TestCase): expected = [ { 'id': 30, + 'context': '00000000', 'koji_tag': None, 'name': 'testmodule', 'rebuild_strategy': 'changed-and-after', @@ -255,13 +262,13 @@ class TestViews(unittest.TestCase): 'tasks': { 'rpms': { 'module-build-macros': { - 'nvr': 'module-build-macros-01-1.module_postgresql_1_2', + 'nvr': 'module-build-macros-01-1.module+8d3cee59', 'state': 1, 'state_reason': None, 'task_id': 47384002 }, 'rubygem-rails': { - 'nvr': 'postgresql-9.5.3-4.module_postgresql_1_2', + 'nvr': 'postgresql-9.5.3-4.module+8d3cee59', 'state': 3, 'state_reason': None, 'task_id': 2433442 @@ -275,6 +282,7 @@ class TestViews(unittest.TestCase): }, { 'id': 29, + 'context': '00000000', 'koji_tag': 'module-postgressql-1.2', 'name': 'postgressql', 'owner': 'some_user', @@ -288,13 +296,13 @@ class TestViews(unittest.TestCase): 'tasks': { 'rpms': { 'module-build-macros': { - 'nvr': 'module-build-macros-01-1.module_postgresql_1_2', + 'nvr': 'module-build-macros-01-1.module+0557c87d', 'state': 1, 'state_reason': None, 'task_id': 47384002 }, 'postgresql': { - 'nvr': 'postgresql-9.5.3-4.module_postgresql_1_2', + 'nvr': 'postgresql-9.5.3-4.module+0557c87d', 'state': 1, 'state_reason': None, 'task_id': 2433442 @@ -382,9 +390,8 @@ class TestViews(unittest.TestCase): self.assertEquals(data['meta']['total'], 40) def test_query_component_builds_filter_nvr(self): - rv = self.client.get( - '/module-build-service/1/component-builds/?nvr=nginx-1.10.1-2.module_nginx_1_2' - ) + rv = self.client.get('/module-build-service/1/component-builds/?nvr=nginx-1.10.1-2.' + 'module%2Bb8661ee4') data = json.loads(rv.data) self.assertEquals(data['meta']['total'], 10) diff --git a/tests/vcr-request-data.tar.gz b/tests/vcr-request-data.tar.gz index 35a5dd9d..c37e8539 100644 Binary files a/tests/vcr-request-data.tar.gz and b/tests/vcr-request-data.tar.gz differ