From 669318f1fde71ef614c362786a5f1cdb44a8b642 Mon Sep 17 00:00:00 2001 From: Brendan Reilly Date: Wed, 26 May 2021 15:37:30 -0400 Subject: [PATCH] Exclude specific platform streams from stream expansion Fixes: #1639 --- module_build_service/common/config.py | 6 + module_build_service/common/resolve.py | 6 +- tests/test_web/test_mse.py | 196 ++++++++++++++++++++++++- 3 files changed, 205 insertions(+), 3 deletions(-) diff --git a/module_build_service/common/config.py b/module_build_service/common/config.py index 22d55de7..e76bba80 100644 --- a/module_build_service/common/config.py +++ b/module_build_service/common/config.py @@ -448,6 +448,12 @@ class Config(object): "considered by MBS as possible buildrequirement. When False, modules " "built against any base module stream can be used as a buildrequire.", }, + "base_module_stream_exclusions": { + "type": list, + "default": [], + "desc": + "List of base module streams to exclude from stream expansion" + }, "koji_cg_tag_build": { "type": bool, "default": True, diff --git a/module_build_service/common/resolve.py b/module_build_service/common/resolve.py index ef08375c..a4f47577 100644 --- a/module_build_service/common/resolve.py +++ b/module_build_service/common/resolve.py @@ -43,7 +43,11 @@ def expand_single_mse_streams( raise StreamAmbigous("There are multiple streams to choose from for module %s." % name) else: builds = models.ModuleBuild.get_last_build_in_all_streams(db_session, name) - expanded_streams = [build.stream for build in builds] + if name in conf.base_module_names and conf.base_module_stream_exclusions: + expanded_streams = [build.stream for build in builds + if build.stream not in conf.base_module_stream_exclusions] + else: + expanded_streams = [build.stream for build in builds] else: expanded_streams = [] for stream in streams: diff --git a/tests/test_web/test_mse.py b/tests/test_web/test_mse.py index b8111f1a..a1ec3d86 100644 --- a/tests/test_web/test_mse.py +++ b/tests/test_web/test_mse.py @@ -3,7 +3,7 @@ from __future__ import absolute_import import pytest - +from mock import patch, PropertyMock from module_build_service.common.errors import StreamAmbigous, ValidationError from module_build_service.scheduler.db_session import db_session from module_build_service.web.mse import ( @@ -53,6 +53,24 @@ class TestModuleStreamExpansion: make_module_in_db("foo:2:0:c5", f29_deps, base_module=platform_f29) make_module_in_db("app:1:0:c6", f29_deps, base_module=platform_f29) + def _generate_eln_modules(self): + """ + Generates gtk:1, gtk:2, foo:1 and foo:2 modules requiring the + platform:eln module. + """ + platform_eln = make_module_in_db("platform:eln:0:c12") + + eln_deps = [{ + "requires": {"platform": ["eln"]}, + "buildrequires": {"platform": ["eln"]} + }] + + make_module_in_db("gtk:1:0:c7", eln_deps, base_module=platform_eln) + make_module_in_db("gtk:2:0:c8", eln_deps, base_module=platform_eln) + make_module_in_db("foo:1:0:c7", eln_deps, base_module=platform_eln) + make_module_in_db("foo:2:0:c8", eln_deps, base_module=platform_eln) + make_module_in_db("app:1:0:c9", eln_deps, base_module=platform_eln) + def test_generate_expanded_mmds_context(self): self._generate_default_modules() module_build = make_module_in_db( @@ -264,6 +282,109 @@ class TestModuleStreamExpansion: assert requires_per_mmd == expected + @pytest.mark.parametrize( + "module_deps,expected", + [ + ( + [{"requires": {}, "buildrequires": {"platform": [], "gtk": ["1", "2"]}}], + [ + "platform:f29:0:c11", + "gtk:2:0:c4", + "gtk:2:0:c5", + "gtk:2:0:c8", + "platform:f28:0:c10", + "gtk:1:0:c2", + "gtk:1:0:c3", + "gtk:1:0:c7", + "platform:eln:0:c12", + ], + ), + ( + [{ + "requires": {}, + "buildrequires": {"platform": [], "gtk": ["1"], "foo": ["1"]} + }], + [ + "platform:f28:0:c10", + "gtk:1:0:c2", + "gtk:1:0:c3", + "gtk:1:0:c7", + "foo:1:0:c2", + "foo:1:0:c3", + "foo:1:0:c7", + "platform:f29:0:c11", + "platform:eln:0:c12", + ], + ), + ( + [{ + "requires": {}, + "buildrequires": {"gtk": ["1"], "foo": ["1"], "platform": ["f28"]} + }], + ["platform:f28:0:c10", "gtk:1:0:c2", "foo:1:0:c2"], + ), + ( + [ + { + "requires": {}, + "buildrequires": {"platform": [], "gtk": ["1"], "foo": ["1"]} + }, + { + "requires": {}, + "buildrequires": {"platform": [], "gtk": ["2"], "foo": ["2"]}, + } + ], + [ + "foo:1:0:c2", + "foo:1:0:c3", + "foo:1:0:c7", + "foo:2:0:c4", + "foo:2:0:c5", + "foo:2:0:c8", + "platform:f28:0:c10", + "platform:f29:0:c11", + "platform:eln:0:c12", + "gtk:1:0:c2", + "gtk:1:0:c3", + "gtk:1:0:c7", + "gtk:2:0:c4", + "gtk:2:0:c5", + "gtk:2:0:c8", + ], + ), + ( + [{ + "requires": {}, + "buildrequires": {"platform": [], "gtk": ["-2"], "foo": ["-2"]}, + }], + [ + "foo:1:0:c2", + "foo:1:0:c3", + "foo:1:0:c7", + "platform:f29:0:c11", + "platform:f28:0:c10", + "platform:eln:0:c12", + "gtk:1:0:c2", + "gtk:1:0:c3", + "gtk:1:0:c7", + ], + ), + ], + ) + def test_get_required_modules_simple( + self, module_deps, expected + ): + module_build = make_module_in_db("app:1:0:c1", module_deps) + self._generate_default_modules() + self._generate_eln_modules() + nsvcs = self._get_mmds_required_by_module_recursively(module_build, db_session) + assert set(nsvcs) == set(expected) + + @patch( + "module_build_service.common.config.Config.base_module_stream_exclusions", + new_callable=PropertyMock, + return_value=["eln"], + ) @pytest.mark.parametrize( "module_deps,expected", [ @@ -339,9 +460,80 @@ class TestModuleStreamExpansion: ), ], ) - def test_get_required_modules_simple(self, module_deps, expected): + def test_get_required_modules_exclusion( + self, mocked_base_module_stream_exclusions, module_deps, expected + ): module_build = make_module_in_db("app:1:0:c1", module_deps) self._generate_default_modules() + self._generate_eln_modules() + nsvcs = self._get_mmds_required_by_module_recursively(module_build, db_session) + assert set(nsvcs) == set(expected) + + @patch( + "module_build_service.common.config.Config.base_module_stream_exclusions", + new_callable=PropertyMock, + return_value=["eln"], + ) + @pytest.mark.parametrize( + "module_deps,expected", + [ + ( + [{"requires": {}, "buildrequires": {"platform": ["eln"], "gtk": ["1", "2"]}}], + [ + "platform:eln:0:c12", + "gtk:1:0:c7", + "gtk:2:0:c8", + ], + ), + ( + [{ + "requires": {}, + "buildrequires": {"platform": ["eln"], "gtk": ["1"], "foo": ["1"]} + }], + [ + "platform:eln:0:c12", + "gtk:1:0:c7", + "foo:1:0:c7", + ], + ), + ( + [ + { + "requires": {}, + "buildrequires": {"platform": ["eln"], "gtk": ["1"], "foo": ["1"]} + }, + { + "requires": {}, + "buildrequires": {"platform": ["eln"], "gtk": ["2"], "foo": ["2"]}, + } + ], + [ + "foo:1:0:c7", + "foo:2:0:c8", + "gtk:1:0:c7", + "gtk:2:0:c8", + "platform:eln:0:c12", + ], + ), + ( + [{ + "requires": {}, + "buildrequires": {"platform": ["eln"], "gtk": ["-2"], "foo": ["-2"]}, + }], + [ + "platform:eln:0:c12", + "foo:1:0:c7", + "gtk:1:0:c7", + ], + ), + ], + ) + def test_get_required_modules_explicit_dep( + self, mocked_base_module_stream_exclusions, module_deps, expected + ): + module_build = make_module_in_db("app:1:0:c1", module_deps) + self._generate_default_modules() + self._generate_eln_modules() nsvcs = self._get_mmds_required_by_module_recursively(module_build, db_session) assert set(nsvcs) == set(expected)