Make InstallabilityTester suite agnostic

Signed-off-by: Niels Thykier <niels@thykier.net>
ubuntu/rebased
Niels Thykier 6 years ago
parent ced7b7b413
commit 7124313aa6
No known key found for this signature in database
GPG Key ID: A65B78DBE67C7AAC

@ -334,7 +334,7 @@ class Britney(object):
if not self.options.nuninst_cache:
self.logger.info("Building the list of non-installable packages for the full archive")
self._inst_tester.compute_testing_installability()
self._inst_tester.compute_installability()
nuninst = compile_nuninst(target_suite,
self.options.architectures,
self.options.nobreakall_arches)
@ -2110,7 +2110,7 @@ class Britney(object):
self.logger.info("> Update complete - Verifying non-installability counters")
cached_nuninst = self.nuninst_orig
self._inst_tester.compute_testing_installability()
self._inst_tester.compute_installability()
computed_nuninst = compile_nuninst(self.suite_info.target_suite,
self.options.architectures,
self.options.nobreakall_arches)

@ -80,7 +80,7 @@ class TargetSuite(Suite):
:param pkg_ids: A set of BinaryPackageId
:return: True if any of the packages in pkgs are currently in the suite
"""
return self.inst_tester.any_of_these_are_in_testing(pkg_ids)
return self.inst_tester.any_of_these_are_in_the_suite(pkg_ids)
def is_pkg_in_the_suite(self, pkg_id):
"""Test if the package of is in testing
@ -88,7 +88,7 @@ class TargetSuite(Suite):
:param pkg_id: A BinaryPackageId
:return: True if the pkg is currently in the suite
"""
return self.inst_tester.is_pkg_in_testing(pkg_id)
return self.inst_tester.is_pkg_in_the_suite(pkg_id)
def is_installable(self, pkg_id):
"""Determine whether the given package can be installed in the suite

@ -142,7 +142,7 @@ class InstallabilitySolver(object):
self.logger = logging.getLogger(logger_name)
def solve_groups(self, groups):
sat_in_testing = self._inst_tester.any_of_these_are_in_testing
sat_in_testing = self._inst_tester.any_of_these_are_in_the_suite
universe = self._universe
result = []
emitted = set()

@ -58,51 +58,51 @@ class InstallabilityTester(object):
# on one of them
self._cache_ess = {}
def compute_testing_installability(self):
"""Computes the installability of packages in testing
def compute_installability(self):
"""Computes the installability of all the packages in the suite
This method computes the installability of all packages in
testing and caches the result. This has the advantage of
the suite and caches the result. This has the advantage of
making "is_installable" queries very fast for all packages
in testing.
in the suite.
"""
universe = self._universe
check_inst = self._check_inst
cbroken = self._cache_broken
cache_inst = self._cache_inst
testing = self._suite_contents
tcopy = [x for x in testing]
suite_contents = self._suite_contents
tcopy = [x for x in suite_contents]
for t in filterfalse(cache_inst.__contains__, tcopy):
if t in cbroken:
continue
res = check_inst(t)
if t in universe.equivalent_packages:
eqv = (x for x in universe.packages_equivalent_to(t) if x in testing)
eqv = (x for x in universe.packages_equivalent_to(t) if x in suite_contents)
if res:
cache_inst.update(eqv)
else:
eqv_set = frozenset(eqv)
testing -= eqv_set
suite_contents -= eqv_set
cbroken |= eqv_set
@property
def stats(self):
return self._stats
def any_of_these_are_in_testing(self, pkgs):
"""Test if at least one package of a given set is in testing
def any_of_these_are_in_the_suite(self, pkgs):
"""Test if at least one package of a given set is in the suite
:param pkgs: A set of package ids (as defined in the constructor)
:return: True if any of the packages in pkgs are currently in testing
:return: True if any of the packages in pkgs are currently in the suite
"""
return not self._suite_contents.isdisjoint(pkgs)
def is_pkg_in_testing(self, pkg_id):
"""Test if the package of is in testing
def is_pkg_in_the_suite(self, pkg_id):
"""Test if the package of is in the suite
:param pkg_id: A package id (as defined in the constructor)
:return: True if the pkg is currently in testing
:return: True if the pkg is currently in the suite
"""
return pkg_id in self._suite_contents
@ -168,8 +168,8 @@ class InstallabilityTester(object):
def is_installable(self, pkg_id):
"""Test if a package is installable in this package set
The package is assumed to be in "testing" and only packages in
"testing" can be used to satisfy relations.
The package is assumed to be in the suite and only packages in
the suite can be used to satisfy relations.
:param pkg_id The id of the package
Returns True iff the package is installable.
@ -196,7 +196,7 @@ class InstallabilityTester(object):
# See the explanation of musts, never and choices below.
stats = self._stats
universe = self._universe
testing = self._suite_contents
suite_contents = self._suite_contents
cbroken = self._cache_broken
# Our installability verdict - start with "yes" and change if
@ -220,7 +220,7 @@ class InstallabilityTester(object):
check = [t]
if len(musts) == 1:
# Include the essential packages in testing as a starting point.
# Include the essential packages in the suite as a starting point.
if t.architecture not in self._cache_ess:
# The minimal essential set cache is not present -
# compute it now.
@ -232,7 +232,7 @@ class InstallabilityTester(object):
# t conflicts with something in the essential set or the essential
# set conflicts with t - either way, t is f***ed
cbroken.add(t)
testing.remove(t)
suite_contents.remove(t)
stats.conflicts_essential += 1
return False
musts.update(start)
@ -240,7 +240,7 @@ class InstallabilityTester(object):
choices.update(ess_choices)
# curry check_loop
check_loop = partial(self._check_loop, universe, testing,
check_loop = partial(self._check_loop, universe, suite_contents,
stats, musts, never, cbroken)
# Useful things to remember:
@ -281,7 +281,7 @@ class InstallabilityTester(object):
for choice in filter(musts.isdisjoint, choices):
# cbroken is needed here because (in theory) it could
# have changed since the choice was discovered and it
# is smaller than testing (so presumably faster)
# is smaller than suite_contents (so presumably faster)
remain = choice - never - cbroken
if len(remain) == 1:
@ -338,7 +338,7 @@ class InstallabilityTester(object):
def resolve_choices(self, check, musts, never, choices):
universe = self._universe
testing = self._suite_contents
suite_contents = self._suite_contents
stats = self._stats
cbroken = self._cache_broken
@ -355,7 +355,7 @@ class InstallabilityTester(object):
check_tmp = [p]
# _check_loop assumes that "musts" is up to date
musts_copy.add(p)
if not self._check_loop(universe, testing,
if not self._check_loop(universe, suite_contents,
stats, musts_copy, never_tmp,
cbroken, choices_tmp,
check_tmp):
@ -407,7 +407,7 @@ class InstallabilityTester(object):
stats.backtrace_last_option += 1
return False
def _check_loop(self, universe, testing, stats, musts, never,
def _check_loop(self, universe, suite_contents, stats, musts, never,
cbroken, choices, check, len=len,
frozenset=frozenset):
"""Finds all guaranteed dependencies via "check".
@ -437,7 +437,7 @@ class InstallabilityTester(object):
return False
# We must install cur for the package to be installable,
# so "obviously" we can never choose any of its conflicts
never.update(relations.negative_dependencies & testing)
never.update(relations.negative_dependencies & suite_contents)
# depgroup can be satisfied by picking something that is
# already in musts - lets pick that (again). :)
@ -445,20 +445,20 @@ class InstallabilityTester(object):
# Of all the packages listed in the relation remove those that
# are either:
# - not in testing
# - not in the suite
# - known to be broken (by cache)
# - in never
candidates = (depgroup & testing) - never
candidates = (depgroup & suite_contents) - never
if not candidates:
# We got no candidates to satisfy it - this
# package cannot be installed with the current
# testing
# (version of the) suite
if cur not in cbroken and depgroup.isdisjoint(never):
# cur's dependency cannot be satisfied even if never was empty.
# This means that cur itself is broken (as well).
cbroken.add(cur)
testing.remove(cur)
suite_contents.remove(cur)
return False
if len(candidates) == 1:
# only one possible solution to this choice and we
@ -504,19 +504,19 @@ class InstallabilityTester(object):
if arch not in self._cache_ess:
# The minimal essential set cache is not present -
# compute it now.
testing = self._suite_contents
suite_contents = self._suite_contents
cbroken = self._cache_broken
universe = self._universe
stats = self._stats
ess_base = [x for x in self._universe.essential_packages if x.architecture == arch and x in testing]
ess_base = [x for x in self._universe.essential_packages if x.architecture == arch and x in suite_contents]
start = set(ess_base)
ess_never = set()
ess_choices = set()
not_satisfied = partial(filter, start.isdisjoint)
while ess_base:
self._check_loop(universe, testing, stats,
self._check_loop(universe, suite_contents, stats,
start, ess_never, cbroken,
ess_choices, ess_base)
if ess_choices:

@ -25,14 +25,14 @@ class TestInstTester(unittest.TestCase):
pkg_perl_base = builder.pkg_id('perl-base')
assert inst_tester.is_installable(pkg_lintian)
assert inst_tester.is_installable(pkg_perl)
assert inst_tester.any_of_these_are_in_testing((pkg_lintian, pkg_perl))
assert inst_tester.any_of_these_are_in_the_suite((pkg_lintian, pkg_perl))
assert not inst_tester.is_installable(pkg_awk)
assert not inst_tester.any_of_these_are_in_testing((pkg_awk,))
assert not inst_tester.any_of_these_are_in_the_suite((pkg_awk,))
inst_tester.remove_binary(pkg_perl)
assert not inst_tester.any_of_these_are_in_testing((pkg_perl,))
assert inst_tester.any_of_these_are_in_testing((pkg_lintian,))
assert not inst_tester.is_pkg_in_testing(pkg_perl)
assert inst_tester.is_pkg_in_testing(pkg_lintian)
assert not inst_tester.any_of_these_are_in_the_suite((pkg_perl,))
assert inst_tester.any_of_these_are_in_the_suite((pkg_lintian,))
assert not inst_tester.is_pkg_in_the_suite(pkg_perl)
assert inst_tester.is_pkg_in_the_suite(pkg_lintian)
assert not inst_tester.is_installable(pkg_lintian)
assert not inst_tester.is_installable(pkg_perl)
inst_tester.add_binary(pkg_perl)

@ -124,7 +124,7 @@ def build_sources_from_universe_and_inst_tester(policy, pkg_universe, inst_teste
pkg_name = pkg_id.package_name
src_universe[pkg_id] = create_source_package(pkg_id.version, binaries=[pkg_id])
bin_universe[pkg_id] = create_bin_package(pkg_id)
if inst_tester.is_pkg_in_testing(pkg_id):
if inst_tester.is_pkg_in_the_suite(pkg_id):
if pkg_name in suite_info.target_suite.sources:
# sanity check, this shouldn't happen
raise(KeyError)

Loading…
Cancel
Save