mirror of
https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
synced 2025-02-23 19:31:55 +00:00
inst-tester: Correctly handle unresolved essential choices
Britney has a special case for essential packages to ensure that any package that with essential packages are not installable. This check did not account for a case, where a package is not co-installable with two or more pseudo-essential package part of the same OR dependency. A contrived example based on real world data: Package: foo # Conflict with all providers of "awk" Conflicts: mawk | gawk | original-awk This alone is actually not sufficient to trigger the bug, as _get_min_pseudo_ess_set is in theory some times smart enough to pick an "obvious" solution between the pseudo-essential option. When it does, one of the above ends up in the (de-facto) essential set and then the installability tester correctly rejects "foo". Though, even with the fix above, the handling for this is probably not correct if the essential set is not (fully co-)installable. However, that basically only happens if we are bootstrapping an architecture (or testing is royally broken, in which case this is the least of our worries). Signed-off-by: Niels Thykier <niels@thykier.net>
This commit is contained in:
parent
337d548edb
commit
42be17ad26
@ -300,9 +300,9 @@ class InstallabilityTester(object):
|
||||
if t.architecture not in self._cache_ess:
|
||||
# The minimal essential set cache is not present -
|
||||
# compute it now.
|
||||
(start, ess_never) = self._get_min_pseudo_ess_set(t.architecture)
|
||||
(start, ess_never, ess_choices) = self._get_min_pseudo_ess_set(t.architecture)
|
||||
else:
|
||||
(start, ess_never) = self._cache_ess[t.architecture]
|
||||
(start, ess_never, ess_choices) = self._cache_ess[t.architecture]
|
||||
|
||||
if t in ess_never:
|
||||
# t conflicts with something in the essential set or the essential
|
||||
@ -313,6 +313,7 @@ class InstallabilityTester(object):
|
||||
return False
|
||||
musts.update(start)
|
||||
never.update(ess_never)
|
||||
choices.update(ess_choices)
|
||||
|
||||
# curry check_loop
|
||||
check_loop = partial(self._check_loop, universe, testing,
|
||||
@ -630,7 +631,7 @@ class InstallabilityTester(object):
|
||||
|
||||
for x in start:
|
||||
ess_never.update(universe[x][1])
|
||||
self._cache_ess[arch] = (frozenset(start), frozenset(ess_never))
|
||||
self._cache_ess[arch] = (frozenset(start), frozenset(ess_never), frozenset(ess_choices))
|
||||
|
||||
return self._cache_ess[arch]
|
||||
|
||||
|
@ -49,6 +49,31 @@ class TestInstTester(unittest.TestCase):
|
||||
universe.add_testing_binary(pkg_awk)
|
||||
assert universe.is_installable(pkg_lintian)
|
||||
|
||||
def test_basic_essential_conflict(self):
|
||||
builder = new_pkg_universe_builder()
|
||||
pseudo_ess1 = builder.new_package('pseudo-essential1')
|
||||
pseudo_ess2 = builder.new_package('pseudo-essential2')
|
||||
essential_simple = builder.new_package('essential-simple').is_essential()
|
||||
essential_with_deps = builder.new_package('essential-with-deps').is_essential().\
|
||||
depends_on_any_of(pseudo_ess1, pseudo_ess2)
|
||||
conflict1 = builder.new_package('conflict1').conflicts_with(essential_simple)
|
||||
conflict2 = builder.new_package('conflict2').conflicts_with(pseudo_ess1, pseudo_ess2)
|
||||
conflict_installable1 = builder.new_package('conflict-inst1').conflicts_with(pseudo_ess1)
|
||||
conflict_installable2 = builder.new_package('conflict-inst2').conflicts_with(pseudo_ess2)
|
||||
|
||||
universe = builder.build()
|
||||
|
||||
assert universe.is_installable(essential_simple.pkg_id)
|
||||
assert universe.is_installable(essential_with_deps.pkg_id)
|
||||
assert universe.is_installable(conflict_installable1.pkg_id)
|
||||
assert universe.is_installable(conflict_installable2.pkg_id)
|
||||
assert not universe.is_installable(conflict1.pkg_id)
|
||||
assert not universe.is_installable(conflict2.pkg_id)
|
||||
|
||||
for line in universe.stats.stats():
|
||||
print(line)
|
||||
assert universe.stats.conflicts_essential == 1
|
||||
|
||||
def test_basic_simple_choice(self):
|
||||
builder = new_pkg_universe_builder()
|
||||
root_pkg = builder.new_package('root')
|
||||
|
Loading…
x
Reference in New Issue
Block a user