Merge #1395 Reuse the latest module build found.

This commit is contained in:
Jan Kaluža
2019-08-30 05:48:25 +00:00
2 changed files with 68 additions and 0 deletions

View File

@@ -94,6 +94,10 @@ def get_reusable_module(db_session, module):
previous_module_build = None
base_mmds = get_base_module_mmds(db_session, mmd)["ready"]
# Sort the base_mmds based on the stream version, higher version first.
base_mmds.sort(
key=lambda mmd: models.ModuleBuild.get_stream_version(mmd.get_stream_name(), False),
reverse=True)
for base_mmd in base_mmds:
mbs_xmd = mmd.get_xmd()["mbs"]
if base_mmd.get_module_name() not in mbs_xmd["buildrequires"]:

View File

@@ -26,6 +26,7 @@ from shutil import copyfile, rmtree
from datetime import datetime
from werkzeug.datastructures import FileStorage
from mock import patch
from sqlalchemy.orm.session import make_transient
from module_build_service.utils.general import load_mmd_file, mmd_to_str
import module_build_service.utils
import module_build_service.scm
@@ -1614,3 +1615,66 @@ class TestUtilsModuleReuse:
assert build_module.reused_module
assert reusable_module.id == build_module.reused_module_id
assert reusable_module.id == reused_module.id
@patch(
"module_build_service.config.Config.allow_only_compatible_base_modules",
new_callable=mock.PropertyMock, return_value=False
)
def test_get_reusable_module_use_latest_build(self, cfg, db_session):
"""
Test that the `get_reusable_module` tries to reuse the latest module in case when
multiple modules can be reused.
"""
# Set "fedora" virtual stream to platform:f28.
platform_f28 = db_session.query(models.ModuleBuild).filter_by(name="platform").one()
mmd = platform_f28.mmd()
xmd = mmd.get_xmd()
xmd["mbs"]["virtual_streams"] = ["fedora"]
mmd.set_xmd(xmd)
platform_f28.modulemd = mmd_to_str(mmd)
platform_f28.update_virtual_streams(db_session, ["fedora"])
# Create platform:f29 with "fedora" virtual stream.
mmd = load_mmd(read_staged_data("platform"))
mmd = mmd.copy("platform", "f29")
xmd = mmd.get_xmd()
xmd["mbs"]["virtual_streams"] = ["fedora"]
mmd.set_xmd(xmd)
platform_f29 = module_build_service.utils.import_mmd(db_session, mmd)[0]
# Create another copy of `testmodule:master` which should be reused, because its
# stream version will be higher than the previous one. Also set its buildrequires
# to platform:f29.
latest_module = db_session.query(models.ModuleBuild).filter_by(
name="testmodule").filter_by(state=models.BUILD_STATES["ready"]).one()
# This is used to clone the ModuleBuild SQLAlchemy object without recreating it from
# scratch.
db_session.expunge(latest_module)
make_transient(latest_module)
# Change the platform:f28 buildrequirement to platform:f29 and recompute the build_context.
mmd = latest_module.mmd()
xmd = mmd.get_xmd()
xmd["mbs"]["buildrequires"]["platform"]["stream"] = "f29"
mmd.set_xmd(xmd)
latest_module.modulemd = mmd_to_str(mmd)
latest_module.build_context = module_build_service.models.ModuleBuild.contexts_from_mmd(
latest_module.modulemd
).build_context
latest_module.buildrequires = [platform_f29]
# Set the `id` to None, so new one is generated by SQLAlchemy.
latest_module.id = None
db_session.add(latest_module)
db_session.commit()
module = db_session.query(models.ModuleBuild)\
.filter_by(name="testmodule")\
.filter_by(state=models.BUILD_STATES["build"])\
.one()
db_session.commit()
reusable_module = module_build_service.utils.get_reusable_module(
db_session, module)
assert reusable_module.id == latest_module.id