From 60478759536000eb1e8fb6fde3b2c14aa269dd41 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Sun, 5 Apr 2015 23:31:13 +0200 Subject: [PATCH] inst-tester: Fix bug "choices" would not be updated In some scenarios, it was possible to trigger a bug in the installability tester, where it would fail to update the "choices" set. The requirements for triggering this seems to be something like: * Obtain a choice that is possible to solve. * Resolve the choice without recursing (with a backtrack point) * Obtain a second choice that is impossible to solve. After the two first steps, the installability tester would fail to update the "choices" set (or, rather, changes would be invisible to the "_pick_choice" function). Fortunately, most packages are either trivially installable or trivially uninstallable, so the bug seems to be rather rare if triggred at all. Signed-off-by: Niels Thykier --- installability/tester.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/installability/tester.py b/installability/tester.py index 37c200b..e148c62 100644 --- a/installability/tester.py +++ b/installability/tester.py @@ -274,8 +274,7 @@ class InstallabilityTester(object): # curry check_loop check_loop = partial(self._check_loop, universe, testing, - eqv_table, stats, musts, never, choices, - cbroken) + eqv_table, stats, musts, never, cbroken) # Useful things to remember: # @@ -310,7 +309,7 @@ class InstallabilityTester(object): rebuild. """ - # We already satisfied/chosen at least one of the litterals + # We already satisfied/chosen at least one of the literals # in the choice, so the choice is gone for choice in filter(musts.isdisjoint, choices): # cbroken is needed here because (in theory) it could @@ -363,7 +362,7 @@ class InstallabilityTester(object): check_tmp = set([p]) if not self._check_loop(universe, testing, eqv_table, stats, musts_copy, never_tmp, - choices_tmp, cbroken, + cbroken, choices_tmp, check_tmp): # p cannot be chosen/is broken (unlikely, but ...) continue @@ -417,7 +416,7 @@ class InstallabilityTester(object): # END _pick_choice while check: - if not check_loop(check): + if not check_loop(choices, check): verdict = False break @@ -444,7 +443,7 @@ class InstallabilityTester(object): return verdict def _check_loop(self, universe, testing, eqv_table, stats, musts, never, - choices, cbroken, check, len=len, + cbroken, choices, check, len=len, frozenset=frozenset): """Finds all guaranteed dependencies via "check". @@ -475,7 +474,7 @@ class InstallabilityTester(object): # so "obviously" we can never choose any of its conflicts never.update(cons & testing) - # depgroup can be satisifed by picking something that is + # depgroup can be satisfied by picking something that is # already in musts - lets pick that (again). :) for depgroup in not_satisfied(deps): @@ -552,8 +551,8 @@ class InstallabilityTester(object): while ess_base: self._check_loop(universe, testing, eqv_table, stats, - start, ess_never, ess_choices, - cbroken, ess_base) + start, ess_never, cbroken, + ess_choices, ess_base) if ess_choices: # Try to break choices where possible nchoice = set()