Resolve stream collision with modules added to ursine content

This resolve the stream collision by adding specific RPMs to
module-build-macros SRPM as Conflicts.

For more information about module stream collision, please refer to
docstring in utils/ursine.py

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
This commit is contained in:
Chenxiong Qi
2018-09-30 17:29:45 +08:00
parent 086ed4a3f3
commit 917c06ad0c
14 changed files with 1012 additions and 101 deletions

View File

@@ -38,7 +38,7 @@ import module_build_service.scheduler.handlers.components
from module_build_service.builder.base import GenericBuilder
from module_build_service.builder.KojiModuleBuilder import KojiModuleBuilder
from module_build_service import glib, Modulemd
from tests import app
from tests import app, make_module
BASE_DIR = path.abspath(path.dirname(__file__))
@@ -1093,3 +1093,124 @@ class TestLocalBuilds:
assert len(local_modules) == 1
assert local_modules[0].koji_tag.endswith(
"/module-platform-f28-3/results")
class TestRecordFilteredRPMs:
"""Test submit.record_filtered_rpms"""
def setup_method(self):
clean_database(add_platform_module=False)
# Prepare fake data for resolver.get_module_modulemds
xmd = {
'mbs': {
'buildrequires': {
# This module has its own filtered_rpms, which should be unchanged.
'modulea': {'stream': '201808', 'version': '2', 'context': '00000000',
'filtered_rpms': ['pkg-1.0-1.fc28']},
# Whereas no filtered_rpms in this module, filtered rpms should be
# injected eventually.
'moduleb': {'stream': '7', 'version': '2', 'context': '00000000'},
# For test recording rpms included in stream collision modules
'platform': {'stream': 'f28', 'version': '2', 'context': '00000000',
# Don't care about platform module's filtered rpms here
'filtered_rpms': [],
'stream_collision_modules': ['foo:master:1:00000000',
'bar:master:2:00000000']},
}
}
}
self.mmd = make_module('cool-module:201809:1:00000000', xmd=xmd, store_to_db=False)
# Store buildrequires modules into database in order to be queried in the test
for module_name, md_dict in xmd['mbs']['buildrequires'].items():
br_module_nsvc = (module_name, md_dict['stream'],
md_dict['version'], md_dict['context'])
br_module_xmd = {
'mbs': {
'koji_tag': 'module-{}-{}-{}-{}'.format(*br_module_nsvc),
}
}
br_module_filtered_rpms = None
if module_name == 'moduleb':
# Add this RPM to filter section.
# Test will verify if this package is listed in final filtered_rpms list.
br_module_filtered_rpms = ['foo']
# Modules have to be created in database whose NSVC appears in
# stream_collision_modules. This is for testing recording rpms
# built for stream collision modules.
if module_name == 'platform':
for nsvc in md_dict['stream_collision_modules']:
make_module(nsvc, xmd={'mbs': {
'koji_tag': 'module-{}-{}-{}-{}'.format(*nsvc.split(':'))
}})
make_module('{}:{}:{}:{}'.format(*br_module_nsvc),
filtered_rpms=br_module_filtered_rpms,
xmd=br_module_xmd)
def teardown_method(self):
clean_database()
# For simplicity, test just queries database. So, no need to code more for
# mocking remote MBS service.
@patch.object(module_build_service.conf, 'resolver', new='db')
@patch('module_build_service.builder.KojiModuleBuilder.KojiModuleBuilder.get_session')
def test_generate_and_store_filtered_rpms(self, get_session):
def mocklistTaggedRPMs(tag, latest):
# Result returned from listTaggedRPMs should contain two lists.
# The second one is the build, which is not used in test and
# omitted here.
rpms = {
'module-modulea-201808-2-00000000': [
[
{'name': 'pkg1', 'version': '1.0', 'release': '1.fc28'},
{'name': 'pkg2', 'version': '2.34', 'release': '1.fc28'},
],
],
'module-moduleb-7-2-00000000': [
[
{'name': 'foo', 'version': '2.0', 'release': '1.fc28'},
{'name': 'bar', 'version': '1.0', 'release': '1.fc28'},
],
],
# These rpms are built for stream collision modules. See above
# in setup_method.
'module-foo-master-1-00000000': [
[
{'name': 'foo-a', 'version': '1.0', 'release': '1.fc28'},
{'name': 'foo-a-devel', 'version': '1.0', 'release': '1.fc28'},
],
],
'module-bar-master-2-00000000': [
[
{'name': 'bar-a', 'version': '0.2', 'release': '2.fc28'},
{'name': 'bar-a-devel', 'version': '0.2', 'release': '2.fc28'},
],
]
}
return rpms[tag]
get_session.return_value.listTaggedRPMS.side_effect = mocklistTaggedRPMs
mmd = module_build_service.utils.submit.record_filtered_rpms(self.mmd)
xmd_mbs = mmd.get_xmd()['mbs'].unpack()
assert ['pkg-1.0-1.fc28'] == xmd_mbs['buildrequires']['modulea']['filtered_rpms']
assert ['foo-0:2.0-1.fc28'] == xmd_mbs['buildrequires']['moduleb']['filtered_rpms']
expected_ursine_rpms = [
'foo-a-0:1.0-1.fc28', 'foo-a-devel-0:1.0-1.fc28',
'bar-a-0:0.2-2.fc28', 'bar-a-devel-0:0.2-2.fc28',
]
expected_ursine_rpms.sort()
found_ursine_rpms = xmd_mbs['buildrequires']['platform']['ursine_rpms']
found_ursine_rpms.sort()
assert expected_ursine_rpms == found_ursine_rpms