diff options
author | Zac Medico <zmedico@gentoo.org> | 2017-03-08 14:25:56 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2017-03-09 11:33:54 -0800 |
commit | c01f3fbd23def329eb1d1b0fc8f79959119a8a82 (patch) | |
tree | 09a4cf40ba11fcab505f2db57e6d2b8165a7eef4 | |
parent | depgraph: fix backtracking for slot operator rebuilds (bug 612042) (diff) | |
download | portage-c01f3fbd.tar.gz portage-c01f3fbd.tar.bz2 portage-c01f3fbd.zip |
depgraph: fix runtime package mask interaction with slot operator rebuilds (bug 612094)
In some cases the backtracking runtime package mask can interact badly
with slot operator rebuilds, preventing a solution from being found.
This patch fixes the problem, which is demonstrated by the included
unit test.
X-Gentoo-bug: 612094
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=612094
Acked-by: Brian Dolbec <dolsen@gentoo.org>
-rw-r--r-- | pym/_emerge/depgraph.py | 28 | ||||
-rw-r--r-- | pym/portage/tests/resolver/test_slot_operator_runtime_pkg_mask.py | 136 |
2 files changed, 152 insertions, 12 deletions
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index bb3e307f0..1379b0563 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -1597,9 +1597,6 @@ class depgraph(object): atom.package and atom.slot_operator_built): continue - if pkg not in conflict_pkgs: - continue - for other_pkg in slot_nodes: if other_pkg in conflict_pkgs: continue @@ -2569,18 +2566,25 @@ class depgraph(object): # runtime_pkg_mask, since that would trigger an # infinite backtracking loop. if self._dynamic_config._allow_backtracking: - if dep.parent in self._dynamic_config._runtime_pkg_mask: - if debug: - writemsg( - "!!! backtracking loop detected: %s %s\n" % \ - (dep.parent, - self._dynamic_config._runtime_pkg_mask[ - dep.parent]), noiselevel=-1) - elif dep.atom.package and dep.atom.slot_operator_built and \ - self._slot_operator_unsatisfied_probe(dep): + if (dep.parent not in self._dynamic_config._runtime_pkg_mask and + dep.atom.package and dep.atom.slot_operator_built and + self._slot_operator_unsatisfied_probe(dep)): self._slot_operator_unsatisfied_backtrack(dep) return 1 else: + # This is for backward-compatibility with previous + # behavior, so that installed packages with unsatisfied + # dependencies trigger an error message but do not + # cause the dependency calculation to fail. Only do + # this if the parent is already in the runtime package + # mask, since otherwise we need to backtrack. + if (dep.parent.installed and + dep.parent in self._dynamic_config._runtime_pkg_mask and + not any(self._iter_match_pkgs_any( + dep.parent.root_config, dep.atom))): + self._dynamic_config._initially_unsatisfied_deps.append(dep) + return 1 + # Do not backtrack if only USE have to be changed in # order to satisfy the dependency. Note that when # want_restart_for_use_change sets the need_restart diff --git a/pym/portage/tests/resolver/test_slot_operator_runtime_pkg_mask.py b/pym/portage/tests/resolver/test_slot_operator_runtime_pkg_mask.py new file mode 100644 index 000000000..0a5a7fa78 --- /dev/null +++ b/pym/portage/tests/resolver/test_slot_operator_runtime_pkg_mask.py @@ -0,0 +1,136 @@ +# Copyright 2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +from portage.tests import TestCase +from portage.tests.resolver.ResolverPlayground import ( + ResolverPlayground, + ResolverPlaygroundTestCase, +) + +class SlotOperatorRuntimePkgMaskTestCase(TestCase): + + def testSlotOperatorRuntimePkgMask(self): + + ebuilds = { + "app-misc/meta-pkg-2" : { + "EAPI": "6", + "DEPEND": "=app-misc/B-2 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-2", + "RDEPEND": "=app-misc/B-2 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-2", + }, + + "app-misc/meta-pkg-1" : { + "EAPI": "6", + "DEPEND": "=app-misc/B-1 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-1", + "RDEPEND": "=app-misc/B-1 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-1", + }, + + "app-misc/B-1" : { + "EAPI": "6", + "DEPEND": "dev-libs/foo:=", + "RDEPEND": "dev-libs/foo:=", + }, + + "app-misc/B-2" : { + "EAPI": "6", + "DEPEND": "dev-libs/foo:=", + "RDEPEND": "dev-libs/foo:=", + }, + + "app-misc/C-1" : { + "EAPI": "6", + "DEPEND": "dev-libs/foo:=", + "RDEPEND": "dev-libs/foo:=", + }, + + "app-misc/C-2" : { + "EAPI": "6", + "DEPEND": "dev-libs/foo:=", + "RDEPEND": "dev-libs/foo:=", + }, + + "app-misc/D-1" : { + "EAPI": "6", + "DEPEND": "dev-libs/foo:=", + "RDEPEND": "dev-libs/foo:=", + }, + + "app-misc/D-2" : { + "EAPI": "6", + "DEPEND": "dev-libs/foo:=", + "RDEPEND": "dev-libs/foo:=", + }, + + "dev-libs/foo-1" : { + "EAPI": "6", + "SLOT": "0/1", + }, + + "dev-libs/foo-2" : { + "EAPI": "6", + "SLOT": "0/2", + }, + } + + installed = { + "app-misc/meta-pkg-1" : { + "EAPI": "6", + "DEPEND": "=app-misc/B-1 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-1", + "RDEPEND": "=app-misc/B-1 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-1", + }, + + "app-misc/B-1" : { + "EAPI": "6", + "DEPEND": "dev-libs/foo:0/1=", + "RDEPEND": "dev-libs/foo:0/1=", + }, + + "app-misc/C-1" : { + "EAPI": "6", + "DEPEND": "dev-libs/foo:0/1=", + "RDEPEND": "dev-libs/foo:0/1=", + }, + + "app-misc/D-1" : { + "EAPI": "6", + "DEPEND": "dev-libs/foo:0/1=", + "RDEPEND": "dev-libs/foo:0/1=", + }, + + "dev-libs/foo-1" : { + "EAPI": "6", + "SLOT": "0/1", + }, + } + + world = ( + "app-misc/meta-pkg", + ) + + test_cases = ( + ResolverPlaygroundTestCase( + ["=app-misc/meta-pkg-2"], + options = { + "--backtrack": 5, + }, + success = True, + ambiguous_merge_order = True, + mergelist = [ + 'dev-libs/foo-2', + ('app-misc/D-1', 'app-misc/C-1', 'app-misc/B-2'), + 'app-misc/meta-pkg-2', + ] + ), + ) + + playground = ResolverPlayground(debug=False, + ebuilds=ebuilds, installed=installed, + world=world) + try: + for test_case in test_cases: + playground.run_TestCase(test_case) + self.assertEqual(test_case.test_success, True, + test_case.fail_msg) + finally: + # Disable debug so that cleanup works. + playground.debug = False + playground.cleanup() |