mirror of
				https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
				synced 2025-11-04 10:34:05 +00:00 
			
		
		
		
	Make InstallabilityTester suite agnostic
Signed-off-by: Niels Thykier <niels@thykier.net>
This commit is contained in:
		
							parent
							
								
									ced7b7b413
								
							
						
					
					
						commit
						7124313aa6
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user