mirror of
https://pagure.io/fm-orchestrator.git
synced 2026-04-23 18:21:42 +08:00
Added the ability to build modules with static contexts
This is a fix and feature in one. This patch enables to use static contexts instead of module stream expansion. This fixes the issue with upgrade path issue in dnf. Signed-off-by: Martin Curlej <mcurlej@redhat.com>
This commit is contained in:
@@ -4,10 +4,11 @@ from __future__ import absolute_import
|
||||
|
||||
import pytest
|
||||
|
||||
from module_build_service.common.errors import StreamAmbigous
|
||||
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 (
|
||||
expand_mse_streams, generate_expanded_mmds, get_mmds_required_by_module_recursively
|
||||
expand_mse_streams, generate_expanded_mmds, get_mmds_required_by_module_recursively,
|
||||
generate_mmds_from_static_contexts
|
||||
)
|
||||
from tests import make_module_in_db
|
||||
|
||||
@@ -461,3 +462,242 @@ class TestModuleStreamExpansion:
|
||||
self._generate_default_modules_modules_multiple_stream_versions()
|
||||
nsvcs = self._get_mmds_required_by_module_recursively(module_build, db_session)
|
||||
assert set(nsvcs) == set(expected)
|
||||
|
||||
def test_generate_expanded_mmds_static_context(self):
|
||||
"""
|
||||
Tests if generate_expanded_mmds will not change the context of a module if provided
|
||||
with a static one.
|
||||
"""
|
||||
module_deps = [{
|
||||
"requires": {"gtk": ["1"], "foo": ["1"]},
|
||||
"buildrequires": {"platform": ["f28"], "gtk": ["1"], "foo": ["1"]},
|
||||
}]
|
||||
self._generate_default_modules()
|
||||
module_build = make_module_in_db("app:1:0:static", module_deps)
|
||||
|
||||
mmds = generate_expanded_mmds(db_session, module_build.mmd(), static_context=True)
|
||||
|
||||
assert type(mmds) is list
|
||||
assert len(mmds) == 1
|
||||
|
||||
current_context = mmds[0].get_context()
|
||||
|
||||
assert current_context == "static"
|
||||
|
||||
def test_generate_mmds_from_static_context(self):
|
||||
self._generate_default_modules()
|
||||
module_build = make_module_in_db(
|
||||
"app:1:0:c1",
|
||||
dependencies=[{
|
||||
"requires": {"gtk": ["1", "2"]},
|
||||
"buildrequires": {
|
||||
"platform": ["f28"],
|
||||
"gtk": ["1", "2"]
|
||||
}}],
|
||||
xmd={
|
||||
"mbs": {},
|
||||
"mbs_options": {
|
||||
"contexts": {
|
||||
"context1": {
|
||||
"requires": {
|
||||
"gtk": "1"
|
||||
},
|
||||
"buildrequires": {
|
||||
"platform": "f28",
|
||||
"gtk": "1",
|
||||
}
|
||||
},
|
||||
"context2": {
|
||||
"requires": {
|
||||
"gtk": "2"
|
||||
},
|
||||
"buildrequires": {
|
||||
"platform": "f28",
|
||||
"gtk": "2",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
mmds = generate_mmds_from_static_contexts(module_build.mmd())
|
||||
|
||||
expected_contexts = ["context1", "context2"]
|
||||
expected_deps = {
|
||||
"context1": {
|
||||
"buildrequires": {
|
||||
"platform": ["f28"],
|
||||
"gtk": ["1"],
|
||||
},
|
||||
"requires": {
|
||||
"gtk": ["1"],
|
||||
},
|
||||
},
|
||||
"context2": {
|
||||
"buildrequires": {
|
||||
"platform": ["f28"],
|
||||
"gtk": ["2"],
|
||||
},
|
||||
"requires": {
|
||||
"gtk": ["2"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert type(mmds) is list
|
||||
assert len(mmds) == 2
|
||||
|
||||
for mmd in mmds:
|
||||
current_context = mmd.get_context()
|
||||
current_xmd = mmd.get_xmd()
|
||||
|
||||
assert current_context in expected_contexts
|
||||
assert "contexts" not in current_xmd
|
||||
|
||||
deps = mmd.get_dependencies()
|
||||
|
||||
assert len(deps) == 1
|
||||
|
||||
buildrequires = deps[0].get_buildtime_modules()
|
||||
|
||||
for module in buildrequires:
|
||||
current_stream = deps[0].get_buildtime_streams(module)
|
||||
assert len(current_stream) == 1
|
||||
assert expected_deps[current_context]["buildrequires"][module] == current_stream
|
||||
|
||||
requires = deps[0].get_runtime_modules()
|
||||
|
||||
for module in requires:
|
||||
current_stream = deps[0].get_runtime_streams(module)
|
||||
assert len(current_stream) == 1
|
||||
assert expected_deps[current_context]["requires"][module] == current_stream
|
||||
|
||||
def test_generate_expanded_mmds_static_context_empty_xmd(self):
|
||||
module_build = make_module_in_db(
|
||||
"app:1:0:c1",
|
||||
xmd={})
|
||||
mmd = module_build.mmd()
|
||||
mmd.set_xmd({})
|
||||
with pytest.raises(ValidationError):
|
||||
generate_mmds_from_static_contexts(mmd)
|
||||
|
||||
def test_generate_expanded_mmds_static_context_no_contexts(self):
|
||||
module_build = make_module_in_db(
|
||||
"app:1:0:c1",
|
||||
xmd={"mbs": {}, "mbs_options": {}})
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
generate_mmds_from_static_contexts(module_build.mmd())
|
||||
|
||||
def test_generate_expanded_mmds_static_context_missing_buildrequires(self):
|
||||
xmd = {
|
||||
"mbs": {},
|
||||
"mbs_options": {
|
||||
"contexts": {"context1": {"requires": {"gtk": ["1"]}}}
|
||||
}
|
||||
}
|
||||
|
||||
module_build = make_module_in_db(
|
||||
"app:1:0:c1",
|
||||
xmd=xmd)
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
generate_mmds_from_static_contexts(module_build.mmd())
|
||||
|
||||
def test_generate_expanded_mmds_static_context_missing_requires(self):
|
||||
xmd = {
|
||||
"mbs": {},
|
||||
"mbs_options": {
|
||||
"contexts": {"context1": {"buildrequires": {"platform": ["f28"]}}}
|
||||
}
|
||||
}
|
||||
|
||||
module_build = make_module_in_db(
|
||||
"app:1:0:c1",
|
||||
xmd=xmd)
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
generate_mmds_from_static_contexts(module_build.mmd())
|
||||
|
||||
def test_generate_expanded_mmds_static_context_wrong_type(self):
|
||||
xmd = {"mbs": {}, "mbs_options": {"contexts": []}}
|
||||
module_build = make_module_in_db(
|
||||
"app:1:0:c1",
|
||||
xmd=xmd)
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
generate_mmds_from_static_contexts(module_build.mmd())
|
||||
|
||||
def test_generate_expanded_mmds_static_context_missing_stream(self):
|
||||
xmd = {
|
||||
"mbs": {},
|
||||
"mbs_options": {
|
||||
"contexts": {
|
||||
"context1": {
|
||||
"buildrequires": {"platform": "f28"},
|
||||
"requires": {"gtk": None},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module_build = make_module_in_db(
|
||||
"app:1:0:c1", xmd=xmd)
|
||||
|
||||
with pytest.raises(ValidationError) as ex:
|
||||
generate_mmds_from_static_contexts(module_build.mmd())
|
||||
err_msg = ex.value.args[0]
|
||||
assert "gtk" in err_msg
|
||||
assert "requires" in err_msg
|
||||
assert "context1" in err_msg
|
||||
|
||||
def test_generate_expanded_mmds_static_context_stream_invalid_type(self):
|
||||
xmd = {
|
||||
"mbs": {},
|
||||
"mbs_options": {
|
||||
"contexts": {
|
||||
"context1": {
|
||||
"buildrequires": {"platform": "f28"},
|
||||
"requires": {"gtk": {"dict": "1"}},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module_build = make_module_in_db(
|
||||
"app:1:0:c1",
|
||||
xmd=xmd)
|
||||
|
||||
with pytest.raises(ValidationError) as ex:
|
||||
generate_mmds_from_static_contexts(module_build.mmd())
|
||||
err_msg = ex.value.args[0]
|
||||
assert "gtk" in err_msg
|
||||
assert "requires" in err_msg
|
||||
assert "context1" in err_msg
|
||||
assert "dict" in err_msg
|
||||
assert "str" in err_msg
|
||||
|
||||
def test_generate_expanded_mmds_static_context_used_mse(self):
|
||||
xmd = {
|
||||
"mbs": {},
|
||||
"mbs_options": {
|
||||
"contexts": {
|
||||
"context1": {
|
||||
"buildrequires": {"platform": "f28"},
|
||||
"requires": {"gtk": "-f28"},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
module_build = make_module_in_db(
|
||||
"app:1:0:c1",
|
||||
xmd=xmd)
|
||||
|
||||
with pytest.raises(ValidationError) as ex:
|
||||
generate_mmds_from_static_contexts(module_build.mmd())
|
||||
err_msg = ex.value.args[0]
|
||||
assert "gtk" in err_msg
|
||||
assert "requires" in err_msg
|
||||
assert "context1" in err_msg
|
||||
assert "-f28" in err_msg
|
||||
|
||||
@@ -12,7 +12,7 @@ from werkzeug.datastructures import FileStorage
|
||||
|
||||
from module_build_service.common import models
|
||||
from module_build_service.common.errors import ValidationError
|
||||
from module_build_service.common.utils import mmd_to_str
|
||||
from module_build_service.common.utils import mmd_to_str, load_mmd
|
||||
from module_build_service.scheduler.db_session import db_session
|
||||
from module_build_service.web.submit import (
|
||||
get_prefixed_version, submit_module_build, submit_module_build_from_yaml
|
||||
@@ -25,7 +25,6 @@ from tests import (
|
||||
|
||||
|
||||
class TestSubmit:
|
||||
|
||||
def test_get_prefixed_version_f28(self):
|
||||
scheduler_init_data(1)
|
||||
build_one = models.ModuleBuild.get_by_id(db_session, 2)
|
||||
@@ -42,6 +41,110 @@ class TestSubmit:
|
||||
v = get_prefixed_version(mmd)
|
||||
assert v == 7000120180205135154
|
||||
|
||||
def test_submit_build_static_context(self):
|
||||
"""
|
||||
Test that we can now build modules with static contexts. The contexts are defined in
|
||||
the `xmd` property by the `contexts` property of the initial modulemd yaml file. The
|
||||
`contexts` is not pressent in the resulting module build. The generated contexts of a
|
||||
module is overridden by the static context defined by the user and the `mse` property
|
||||
is set to False.
|
||||
"""
|
||||
|
||||
yaml_str = """
|
||||
document: modulemd
|
||||
version: 2
|
||||
data:
|
||||
name: app
|
||||
stream: test
|
||||
summary: "A test module"
|
||||
description: >
|
||||
"A test module stream"
|
||||
license:
|
||||
module: [ MIT ]
|
||||
dependencies:
|
||||
- buildrequires:
|
||||
platform: []
|
||||
gtk: []
|
||||
requires:
|
||||
platform: []
|
||||
gtk: []
|
||||
xmd:
|
||||
mbs_options:
|
||||
contexts:
|
||||
context1:
|
||||
buildrequires:
|
||||
platform: f28
|
||||
requires:
|
||||
platform: f28
|
||||
gtk: 1
|
||||
context2:
|
||||
buildrequires:
|
||||
platform: f28
|
||||
requires:
|
||||
platform: f28
|
||||
gtk: 2
|
||||
"""
|
||||
mmd = load_mmd(yaml_str)
|
||||
|
||||
builds = submit_module_build(db_session, "app", mmd, {})
|
||||
|
||||
expected_context = ["context1", "context2"]
|
||||
|
||||
assert len(builds) == 2
|
||||
|
||||
for build in builds:
|
||||
assert build.context in expected_context
|
||||
mmd = build.mmd()
|
||||
xmd = mmd.get_xmd()
|
||||
assert "mbs_options" not in xmd
|
||||
assert xmd["mbs"]["static_context"]
|
||||
|
||||
def test_submit_build_static_context_preserve_mbs_options(self):
|
||||
"""
|
||||
This tests that the `mbs_options` will be preserved after static context build if there
|
||||
are more options configured then `contexts` option..
|
||||
"""
|
||||
|
||||
yaml_str = """
|
||||
document: modulemd
|
||||
version: 2
|
||||
data:
|
||||
name: app
|
||||
stream: test1
|
||||
summary: "A test module"
|
||||
description: >
|
||||
"A test module stream"
|
||||
license:
|
||||
module: [ MIT ]
|
||||
dependencies:
|
||||
- buildrequires:
|
||||
platform: []
|
||||
gtk: []
|
||||
requires:
|
||||
platform: []
|
||||
gtk: []
|
||||
xmd:
|
||||
mbs_options:
|
||||
contexts:
|
||||
context1:
|
||||
buildrequires:
|
||||
platform: f28
|
||||
requires:
|
||||
platform: f28
|
||||
gtk: 1
|
||||
another_option: "test"
|
||||
"""
|
||||
mmd = load_mmd(yaml_str)
|
||||
|
||||
builds = submit_module_build(db_session, "app", mmd, {})
|
||||
|
||||
assert len(builds) == 1
|
||||
mmd = builds[0].mmd()
|
||||
xmd = mmd.get_xmd()
|
||||
assert "mbs_options" in xmd
|
||||
assert "another_option" in xmd["mbs_options"]
|
||||
assert "test" == xmd["mbs_options"]["another_option"]
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("reuse_component_init_data")
|
||||
class TestUtilsComponentReuse:
|
||||
|
||||
Reference in New Issue
Block a user