Skip to content

Commit

Permalink
Do not resolve non-modular RPM with modular RPM [RHELDST-18106]
Browse files Browse the repository at this point in the history
TODO
  • Loading branch information
rbikar committed Aug 10, 2023
1 parent d58efe2 commit 469d409
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 30 deletions.
30 changes: 16 additions & 14 deletions tests/test_depsolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
Depsolver,
)

from .utils import create_and_insert_repo
from .utils import create_and_insert_repo, rpmdeps_from_names


def test_what_provides(pulp):
"""tests querying for provides in pulp"""
depsolver = Depsolver(None, None, None)

requires = ["gcc"]
requires = [RpmDependency(name="gcc")]

repo = create_and_insert_repo(id="test_repo_id", pulp=pulp)

Expand Down Expand Up @@ -56,9 +56,9 @@ def test_extract_and_resolve():
depsolver = Depsolver(None, None, None)

# set initial data to depsolver instance
depsolver._requires = {"pkg_a", "pkg_b"}
depsolver._provides = {"pkg_c", "pkg_d"}
depsolver._unsolved = {"pkg_a", "pkg_b"}
depsolver._requires = rpmdeps_from_names("pkg_a", "pkg_b")
depsolver._provides = rpmdeps_from_names("pkg_c", "pkg_d")
depsolver._unsolved = rpmdeps_from_names("pkg_a", "pkg_b")

unit = RpmUnit(
name="test",
Expand All @@ -73,11 +73,13 @@ def test_extract_and_resolve():
depsolver.extract_and_resolve([unit])
# internal state of depsolver should change
# pkg_f, pkg_g and pkg_h are new requirements that are added to the requires set
assert depsolver._requires == {"pkg_a", "pkg_b", "pkg_f", "pkg_g", "pkg_h"}
assert depsolver._requires == rpmdeps_from_names(
"pkg_a", "pkg_b", "pkg_f", "pkg_g", "pkg_h"
)
# pkg_e and pkg_b are added to the provides set
assert depsolver._provides == {"pkg_c", "pkg_d", "pkg_e", "pkg_b"}
assert depsolver._provides == rpmdeps_from_names("pkg_c", "pkg_d", "pkg_e", "pkg_b")
# pkg_b is resolved but pkg_f, pkg_g and pkg_h are added as new unsolved requirement
assert depsolver._unsolved == {"pkg_a", "pkg_f", "pkg_g", "pkg_h"}
assert depsolver._unsolved == rpmdeps_from_names("pkg_a", "pkg_f", "pkg_g", "pkg_h")


def test_get_base_packages(pulp):
Expand Down Expand Up @@ -232,7 +234,7 @@ def test_run(pulp):

# check internal state of depsolver object
# provides set holds all capabilities that we went through during depsolving
assert depsolver._provides == {
assert depsolver._provides == rpmdeps_from_names(
"gcc",
"jq",
"apr",
Expand All @@ -244,10 +246,10 @@ def test_run(pulp):
"lib.e",
"lib.f",
"lib.z",
}
)

# requires set holds all requires that we went through during depsolving
assert depsolver._requires == {
assert depsolver._requires == rpmdeps_from_names(
"blacklisted-package",
"lib.a",
"lib.b",
Expand All @@ -259,7 +261,7 @@ def test_run(pulp):
"lib.z",
"pkgX(abc)",
"capY(xyz)",
}
)

# unsolved set should be empty after depsolving finishes
# it will be emptied even if we have unsolvable dependency
Expand All @@ -268,13 +270,13 @@ def test_run(pulp):
# there are unsolved requires, we can get those by
unsolved = depsolver._requires - depsolver._provides
# there is exactly two unresolved deps, lib_exclude is unsolved due to blacklisting
assert unsolved == {
assert unsolved == rpmdeps_from_names(
"pkgX(abc)",
"capY(xyz)",
"lib.g",
"lib_exclude",
"blacklisted-package",
}
)

# checking correct rpm and srpm names and its associate source repo id
output = [
Expand Down
129 changes: 127 additions & 2 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
ModulemdDependency,
ModulemdUnit,
RpmUnit,
RpmDependency,
)

from ubi_manifest.worker.tasks.depsolver.models import PackageToExclude, UbiUnit
Expand All @@ -22,9 +23,10 @@
parse_bool_deps,
split_filename,
vercmp_sort,
is_requirement_resolved,
)

from .utils import MockLoader
from .utils import MockLoader, rpmdeps_from_names


def get_ubi_unit(klass, repo_id, **kwargs):
Expand Down Expand Up @@ -317,7 +319,7 @@ def test_parse_bool_deps(clause, result):
test parsing bool/rich dependencies, the function extracts only names of packages
"""
parsed = parse_bool_deps(clause)
assert parsed == result
assert parsed == rpmdeps_from_names(*result)


def test_create_or_criteria():
Expand Down Expand Up @@ -481,3 +483,126 @@ def test_get_criteria_for_modules():
[("perl", "5.30"), ("perl", "6.30"), ("perl-YAML", Matcher.exists())],
)
criteria = get_criteria_for_modules([unit1, unit2, unit3])


@pytest.mark.parametrize(
"requirement, provider, expected_result",
[
# no flags
(RpmDependency(name="test-dep"), RpmDependency(name="test-dep"), True),
(RpmDependency(name="test-dep"), RpmDependency(name="test-dep-other"), False),
# flag GT - greater than
(
RpmDependency(
name="test-dep", version="9", release="el10", epoch="0", flags="GT"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
True,
),
(
RpmDependency(
name="test-dep", version="10", release="el10", epoch="0", flags="GT"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
False,
),
(
RpmDependency(
name="test-dep", version="11", release="el10", epoch="0", flags="GT"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
False,
),
# flag GE - greater or equal
(
RpmDependency(
name="test-dep", version="9", release="el10", epoch="0", flags="GE"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
True,
),
(
RpmDependency(
name="test-dep", version="10", release="el10", epoch="0", flags="GE"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
True,
),
(
RpmDependency(
name="test-dep", version="11", release="el10", epoch="0", flags="GE"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
False,
),
# flag EQ - equal
(
RpmDependency(
name="test-dep", version="9", release="el10", epoch="0", flags="EQ"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
False,
),
(
RpmDependency(
name="test-dep", version="10", release="el10", epoch="0", flags="EQ"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
True,
),
(
RpmDependency(
name="test-dep", version="11", release="el10", epoch="0", flags="EQ"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
False,
),
# flag LE - less or equal
(
RpmDependency(
name="test-dep", version="9", release="el10", epoch="0", flags="LE"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
False,
),
(
RpmDependency(
name="test-dep", version="10", release="el10", epoch="0", flags="LE"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
True,
),
(
RpmDependency(
name="test-dep", version="11", release="el10", epoch="0", flags="LE"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
True,
),
# flag LT - less than
(
RpmDependency(
name="test-dep", version="9", release="el10", epoch="0", flags="LT"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
False,
),
(
RpmDependency(
name="test-dep", version="10", release="el10", epoch="0", flags="LT"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
False,
),
(
RpmDependency(
name="test-dep", version="11", release="el10", epoch="0", flags="LT"
),
RpmDependency(name="test-dep", version="10", release="el10", epoch="0"),
True,
),
],
)
def test_is_requirement_resolved(requirement, provider, expected_result):
resolved = is_requirement_resolved(requirement, provider)
assert resolved is expected_result
6 changes: 5 additions & 1 deletion tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import ubiconfig
from attrs import define
from pubtools.pulplib import YumRepository
from pubtools.pulplib import YumRepository, RpmDependency


def create_and_insert_repo(**kwargs):
Expand Down Expand Up @@ -50,3 +50,7 @@ def get(self, key: str) -> str:

def keys(self) -> List[str]:
return list(self.data.keys())


def rpmdeps_from_names(*names):
return {RpmDependency(name=name) for name in names}
27 changes: 18 additions & 9 deletions ubi_manifest/worker/tasks/depsolver/rpm_depsolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
create_or_criteria,
get_n_latest_from_content,
parse_bool_deps,
is_requirement_resolved,
)

_LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -109,19 +110,25 @@ def extract_and_resolve(self, content):
# add parsed bool deps to requires that need solving
_requires |= parse_bool_deps(item.name)
else:
_requires.add(item.name)
_requires.add(item)

for item in rpm.provides:
# add to global provides
self._provides.add(item.name)
self._provides.add(item)

# update global requires
self._requires |= _requires
# add new requires to unsolved
self._unsolved |= _requires
# get solved requires
solved = self._unsolved & self._provides
# and subtract solved requires
self._unsolved -= solved

solved = set()
for prov in self._provides:
for req in self._unsolved:
if prov.name != req.name:
continue
if is_requirement_resolved(req, prov):
solved.add(req)
self._unsolved -= solved

def what_provides(self, list_of_requires, repos, blacklist):
"""
Expand All @@ -131,7 +138,7 @@ def what_provides(self, list_of_requires, repos, blacklist):
# for given requirement. It should be decided which one should get into
# the output. Currently we'll get all matching the query.
crit = create_or_criteria(
["provides.name"], [(item,) for item in list_of_requires]
["provides.name"], [(item.name,) for item in list_of_requires]
)

content = f_proxy(
Expand Down Expand Up @@ -251,7 +258,9 @@ def run(self):
self.srpm_output_set.add(srpm)

# log warnings if depsolving failed
deps_not_found = self._requires - self._provides
deps_not_found = {req.name for req in self._requires} - {
prov.name for prov in self._provides
}
if deps_not_found:
self._log_warnings(deps_not_found, pulp_repos, merged_blacklist)

Expand Down Expand Up @@ -298,7 +307,7 @@ def _requires_names(requires):
out = set()
for item in requires:
if item.name.startswith("("):
out |= parse_bool_deps(item.name)
out |= {dep.name for dep in parse_bool_deps(item.name)}
else:
out.add(item.name)
return out
Expand Down
Loading

0 comments on commit 469d409

Please sign in to comment.