def testUnnecessarySlotUpgrade(self): ebuilds = { "app-misc/a-1": { "EAPI": "8", "RDEPEND": "|| ( dev-lang/python:3.10 dev-lang/python:3.9 ) || ( dev-lang/python:3.10 dev-lang/python:3.9 )", }, "dev-lang/python-3.9": { "SLOT": "3.9" }, "dev-lang/python-3.10": { "SLOT": "3.10" }, } installed = { "dev-lang/python-3.9": { "SLOT": "3.9" }, } test_cases = ( # Test bug 828136, where an unnecessary python slot upgrade # was triggered. ResolverPlaygroundTestCase( [ "app-misc/a", ], success=True, mergelist=("app-misc/a-1", ), ), ResolverPlaygroundTestCase( [ "app-misc/a", ], success=True, mergelist=( "dev-lang/python-3.10", "app-misc/a-1", ), options={ "--deep": True, "--update": True, }, ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds, installed=installed) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testVirtualDevManager(self): ebuilds = { 'sys-fs/eudev-3.1.5': {}, 'sys-fs/static-dev-0.1': {}, 'sys-fs/udev-233': {}, 'virtual/dev-manager-0': { 'RDEPEND': ''' || ( virtual/udev sys-fs/static-dev )''' }, 'virtual/udev-0': { 'RDEPEND': ''' || ( >=sys-fs/eudev-2.1.1 >=sys-fs/udev-217 )''' }, } test_cases = ( # Test bug 645190, where static-dev was pulled in instead # of eudev. ResolverPlaygroundTestCase( [ 'virtual/dev-manager', ], success=True, mergelist=( 'sys-fs/eudev-3.1.5', 'virtual/udev-0', 'virtual/dev-manager-0', ), ), # Test static-dev preference. ResolverPlaygroundTestCase( [ 'sys-fs/static-dev', 'virtual/dev-manager', ], all_permutations=True, success=True, mergelist=( 'sys-fs/static-dev-0.1', 'virtual/dev-manager-0', ), ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameUnsatisfiable(self): binpkgs = { "app-misc/A-1": { "EAPI": "5", "PROVIDES": "x86_32: libA.so.1", }, "app-misc/B-1": { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.2", }, "app-misc/B-0": { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.1", }, } installed = { "app-misc/A-1": { "EAPI": "5", "PROVIDES": "x86_32: libA.so.1", }, "app-misc/B-0": { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.1", }, } world = ["app-misc/B"] test_cases = ( # Skip update due to unsatisfied soname dependency. ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[], ), ) playground = ResolverPlayground( binpkgs=binpkgs, debug=False, 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()
def testAutounmaskBinpkgUse(self): ebuilds = { "dev-libs/A-1": { "EAPI": "6", "DEPEND": "dev-libs/B[foo]", "RDEPEND": "dev-libs/B[foo]", }, "dev-libs/B-1": { "EAPI": "6", "IUSE": "foo", }, } binpkgs = { "dev-libs/A-1": { "EAPI": "6", "DEPEND": "dev-libs/B[foo]", "RDEPEND": "dev-libs/B[foo]", }, "dev-libs/B-1": { "EAPI": "6", "IUSE": "foo", "USE": "foo", }, } installed = {} test_cases = ( # Bug 619626: Test for unnecessary rebuild due # to rejection of binary packages that would # be acceptable after appplication of autounmask # USE changes. ResolverPlaygroundTestCase( ["dev-libs/A"], all_permutations=True, success=True, options={ "--usepkg": True, }, mergelist=[ "[binary]dev-libs/B-1", "[binary]dev-libs/A-1", ], use_changes={"dev-libs/B-1": { "foo": True }}, ), ) playground = ResolverPlayground(ebuilds=ebuilds, binpkgs=binpkgs, installed=installed, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testVirtualRust(self): ebuilds = { 'dev-lang/rust-1.19.0': {}, 'dev-lang/rust-1.23.0': {}, 'dev-lang/rust-bin-1.19.0': {}, 'virtual/rust-1.19.0': { 'RDEPEND': '|| ( =dev-lang/rust-1.19.0* =dev-lang/rust-bin-1.19.0* )' }, } installed = { 'dev-lang/rust-1.19.0': {}, 'virtual/rust-1.19.0': { 'RDEPEND': '|| ( =dev-lang/rust-1.19.0* =dev-lang/rust-bin-1.19.0* )' }, } world = ['virtual/rust'] test_cases = ( # Test bug 645416, where rust-bin-1.19.0 was pulled in # inappropriately due to the rust-1.23.0 update being # available. ResolverPlaygroundTestCase( ['virtual/rust'], options={'--update': True, '--deep': True}, success=True, mergelist=[] ), # Test upgrade to rust-1.23.0, which is only possible # if rust-bin-1.19.0 is installed in order to satisfy # virtual/rust-1.19.0. ResolverPlaygroundTestCase( ['=dev-lang/rust-1.23.0', 'virtual/rust'], options={'--update': True, '--deep': True}, all_permutations=True, success=True, ambiguous_merge_order=True, mergelist=( ( 'dev-lang/rust-1.23.0', 'dev-lang/rust-bin-1.19.0', ), ), ), ) 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: playground.debug = False playground.cleanup()
def testVirtualRust(self): ebuilds = { 'dev-lang/rust-1.19.0': {}, 'dev-lang/rust-1.23.0': {}, 'dev-lang/rust-bin-1.19.0': {}, 'virtual/rust-1.19.0': { 'RDEPEND': '|| ( =dev-lang/rust-1.19.0* =dev-lang/rust-bin-1.19.0* )' }, } installed = { 'dev-lang/rust-1.19.0': {}, 'virtual/rust-1.19.0': { 'RDEPEND': '|| ( =dev-lang/rust-1.19.0* =dev-lang/rust-bin-1.19.0* )' }, } world = ['virtual/rust'] test_cases = ( # Test bug 645416, where rust-bin-1.19.0 was pulled in # inappropriately due to the rust-1.23.0 update being # available. ResolverPlaygroundTestCase( ['virtual/rust'], options={'--update': True, '--deep': True}, success=True, mergelist=[] ), # Test upgrade to rust-1.23.0, which is only possible # if rust-bin-1.19.0 is installed in order to satisfy # virtual/rust-1.19.0. ResolverPlaygroundTestCase( ['=dev-lang/rust-1.23.0', 'virtual/rust'], options={'--update': True, '--deep': True}, all_permutations=True, success=True, ambiguous_merge_order=True, mergelist=( ( 'dev-lang/rust-1.23.0', 'dev-lang/rust-bin-1.19.0', ), ), ), ) 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: playground.debug = False playground.cleanup()
def testAutounmaskBinpkgUse(self): ebuilds = { "dev-libs/A-1": { "EAPI": "6", "DEPEND": "dev-libs/B[foo]", "RDEPEND": "dev-libs/B[foo]", }, "dev-libs/B-1": { "EAPI": "6", "IUSE": "foo", }, } binpkgs = { "dev-libs/A-1": { "EAPI": "6", "DEPEND": "dev-libs/B[foo]", "RDEPEND": "dev-libs/B[foo]", }, "dev-libs/B-1": { "EAPI": "6", "IUSE": "foo", "USE": "foo", }, } installed = { } test_cases = ( # Bug 619626: Test for unnecessary rebuild due # to rejection of binary packages that would # be acceptable after appplication of autounmask # USE changes. ResolverPlaygroundTestCase( ["dev-libs/A"], all_permutations = True, success = True, options = { "--usepkg": True, "--autounmask": True, }, mergelist = [ "[binary]dev-libs/B-1", "[binary]dev-libs/A-1", ], use_changes = {"dev-libs/B-1": {"foo": True}} ), ) playground = ResolverPlayground(ebuilds=ebuilds, binpkgs=binpkgs, installed=installed, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSlotConflictRebuildGolang(self): ebuilds = { "dev-lang/go-1.14.7": { "EAPI": "7", "SLOT": "0/1.14.7" }, "dev-lang/go-1.15": { "EAPI": "7", "SLOT": "0/1.15" }, "net-p2p/syncthing-1.3.4-r1": { "EAPI": "7", "BDEPEND": "=dev-lang/go-1.14* >=dev-lang/go-1.12", }, } installed = { "dev-lang/go-1.14.7": { "EAPI": "7", "SLOT": "0/1.14.7" }, "net-p2p/syncthing-1.3.4-r1": { "EAPI": "7", "BDEPEND": "=dev-lang/go-1.14* >=dev-lang/go-1.12", }, } world = ["dev-lang/go", "net-p2p/syncthing"] test_cases = ( # Demonstrate an unwanted dev-lang/go rebuild triggered by a missed # update due to a slot conflict (bug #439688). ResolverPlaygroundTestCase( ["@world"], options={ "--update": True, "--deep": True }, success=True, mergelist=[], ), ) playground = ResolverPlayground(ebuilds=ebuilds, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testAutounmaskUseSlotConflict(self): self.todo = True ebuilds = { "sci-libs/K-1": { "IUSE": "+foo", "EAPI": 1 }, "sci-libs/L-1": { "DEPEND": "sci-libs/K[-foo]", "EAPI": 2 }, "sci-libs/M-1": { "DEPEND": "sci-libs/K[foo=]", "IUSE": "+foo", "EAPI": 2 }, } installed = {} test_cases = ( # Test bug 615824, where an automask USE change results in # a conflict which is not reported. In order to install L, # foo must be disabled for both K and M, but autounmask # disables foo for K and leaves it enabled for M. ResolverPlaygroundTestCase( ["sci-libs/L", "sci-libs/M"], options={"--backtrack": 0}, success=False, mergelist=[ "sci-libs/L-1", "sci-libs/M-1", "sci-libs/K-1", ], ignore_mergelist_order=True, slot_collision_solutions=[{ "sci-libs/K-1": { "foo": False }, "sci-libs/M-1": { "foo": False } }], ), ) playground = ResolverPlayground(ebuilds=ebuilds, installed=installed) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testOverlapSlotConflict(self): ebuilds = { "app-misc/bar-1": { "EAPI": "6", "RDEPEND": "virtual/foo" }, "virtual/foo-1": { "EAPI": "6", "RDEPEND": "|| ( app-misc/A >=app-misc/B-2 ) || ( <app-misc/B-2 app-misc/C )", }, "app-misc/A-1": { "EAPI": "6", }, "app-misc/B-2": { "EAPI": "6", }, "app-misc/B-1": { "EAPI": "6", }, "app-misc/C-1": { "EAPI": "6", }, } test_cases = ( # Here the ( >=app-misc/B-2 <app-misc/B-2 ) choice is not satisfiable. ResolverPlaygroundTestCase( ["app-misc/bar"], success=True, ambiguous_merge_order=True, mergelist=[ ( "app-misc/C-1", "app-misc/A-1", ), "virtual/foo-1", "app-misc/bar-1", ], ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testOverlapSlotConflict(self): ebuilds = { 'app-misc/bar-1': { 'EAPI': '6', 'RDEPEND': 'virtual/foo' }, 'virtual/foo-1': { 'EAPI': '6', 'RDEPEND': '|| ( app-misc/A >=app-misc/B-2 ) || ( <app-misc/B-2 app-misc/C )' }, 'app-misc/A-1': { 'EAPI': '6', }, 'app-misc/B-2': { 'EAPI': '6', }, 'app-misc/B-1': { 'EAPI': '6', }, 'app-misc/C-1': { 'EAPI': '6', }, } test_cases = ( # Here the ( >=app-misc/B-2 <app-misc/B-2 ) choice is not satisfiable. ResolverPlaygroundTestCase( ['app-misc/bar'], success=True, ambiguous_merge_order=True, mergelist=[ ( 'app-misc/C-1', 'app-misc/A-1', ), 'virtual/foo-1', 'app-misc/bar-1', ] ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameDepclean(self): installed = { "app-misc/A-1" : { "RDEPEND": "dev-libs/B", "DEPEND": "dev-libs/B", "REQUIRES": "x86_32: libB.so.1 libc.so.6", }, "dev-libs/B-1" : { "PROVIDES": "x86_32: libB.so.1", }, "sys-libs/glibc-2.19-r1" : { "PROVIDES": "x86_32: libc.so.6" }, } world = ("app-misc/A",) test_cases = ( ResolverPlaygroundTestCase( [], options={ "--depclean": True, "--ignore-soname-deps": "n", }, success=True, cleanlist=[] ), ResolverPlaygroundTestCase( [], options={ "--depclean": True, "--ignore-soname-deps": "y", }, success=True, cleanlist=["sys-libs/glibc-2.19-r1"] ), ) playground = ResolverPlayground(debug=False, 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()
def testSonameDepclean(self): installed = { "app-misc/A-1": { "RDEPEND": "dev-libs/B", "DEPEND": "dev-libs/B", "REQUIRES": "x86_32: libB.so.1 libc.so.6", }, "dev-libs/B-1": { "PROVIDES": "x86_32: libB.so.1", }, "sys-libs/glibc-2.19-r1": { "PROVIDES": "x86_32: libc.so.6" }, } world = ("app-misc/A", ) test_cases = ( ResolverPlaygroundTestCase( [], options={ "--depclean": True, "--ignore-soname-deps": "n", }, success=True, cleanlist=[], ), ResolverPlaygroundTestCase( [], options={ "--depclean": True, "--ignore-soname-deps": "y", }, success=True, cleanlist=["sys-libs/glibc-2.19-r1"], ), ) playground = ResolverPlayground(debug=False, 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()
def testCircularPypyExe(self): ebuilds = { "dev-python/pypy-7.3.0": { "EAPI": "7", "SLOT": "0/73", "DEPEND": "|| ( dev-python/pypy-exe dev-python/pypy-exe-bin )", }, "dev-python/pypy-exe-7.3.0": { "EAPI": "7", "IUSE": "low-memory", "SLOT": "7.3.0", "BDEPEND": "!low-memory? ( dev-python/pypy )", }, "dev-python/pypy-exe-bin-7.3.0": { "EAPI": "7", "SLOT": "7.3.0", }, } test_cases = ( # Demonstrate bug 705986, where a USE change suggestion was given # even though an || preference adjustment would solve the problem # by pulling in pypy-exe-bin instead of pypy-exe. ResolverPlaygroundTestCase( ["dev-python/pypy"], mergelist=[ "dev-python/pypy-exe-bin-7.3.0", "dev-python/pypy-7.3.0" ], success=True, ), ) playground = ResolverPlayground(ebuilds=ebuilds, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testCircularPypyExe(self): ebuilds = { 'dev-python/pypy-7.3.0': { 'EAPI': '7', 'SLOT': '0/73', 'DEPEND': '|| ( dev-python/pypy-exe dev-python/pypy-exe-bin )' }, 'dev-python/pypy-exe-7.3.0': { 'EAPI': '7', 'IUSE': 'low-memory', 'SLOT': '7.3.0', 'BDEPEND': '!low-memory? ( dev-python/pypy )' }, 'dev-python/pypy-exe-bin-7.3.0': { 'EAPI': '7', 'SLOT': '7.3.0', }, } test_cases = ( # Demonstrate bug 705986, where a USE change suggestion was given # even though an || preference adjustment would solve the problem # by pulling in pypy-exe-bin instead of pypy-exe. ResolverPlaygroundTestCase( ['dev-python/pypy'], mergelist=[ 'dev-python/pypy-exe-bin-7.3.0', 'dev-python/pypy-7.3.0' ], success=True, ), ) playground = ResolverPlayground(ebuilds=ebuilds, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testVirtualWine(self): ebuilds = { 'virtual/wine-0-r6': { 'RDEPEND': '|| ( app-emulation/wine-staging app-emulation/wine-any ) ' '|| ( app-emulation/wine-vanilla app-emulation/wine-staging app-emulation/wine-any )' }, 'app-emulation/wine-staging-4': {}, 'app-emulation/wine-any-4': {}, 'app-emulation/wine-vanilla-4': {}, } test_cases = ( # Test bug 701996, where separate disjunctions where not # converted to DNF, causing both wine-vanilla and # wine-staging to be pulled in. ResolverPlaygroundTestCase( [ 'virtual/wine', ], success=True, mergelist=( 'app-emulation/wine-staging-4', 'virtual/wine-0-r6', ), ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameConflictMissedUpdate(self): binpkgs = { "dev-lang/ocaml-4.02.1": { "EAPI": "5", "PROVIDES": "x86_32: libocaml-4.02.1.so", }, "dev-lang/ocaml-4.01.0": { "EAPI": "5", "PROVIDES": "x86_32: libocaml-4.01.0.so", }, "dev-ml/lablgl-1.05": { "DEPEND": (">=dev-lang/ocaml-3.10.2 " "|| ( dev-ml/labltk <dev-lang/ocaml-4.02 )"), "RDEPEND": (">=dev-lang/ocaml-3.10.2 " "|| ( dev-ml/labltk <dev-lang/ocaml-4.02 )"), "REQUIRES": "x86_32: libocaml-4.02.1.so", }, "dev-ml/labltk-8.06.0": { "EAPI": "5", "SLOT": "0/8.06.0", "DEPEND": ">=dev-lang/ocaml-4.02", "RDEPEND": ">=dev-lang/ocaml-4.02", "REQUIRES": "x86_32: libocaml-4.02.1.so", }, } installed = { "dev-lang/ocaml-4.01.0": { "EAPI": "5", "PROVIDES": "x86_32: libocaml-4.01.0.so", }, "dev-ml/lablgl-1.05": { "DEPEND": (">=dev-lang/ocaml-3.10.2 " "|| ( dev-ml/labltk <dev-lang/ocaml-4.02 )"), "RDEPEND": (">=dev-lang/ocaml-3.10.2 " "|| ( dev-ml/labltk <dev-lang/ocaml-4.02 )"), "REQUIRES": "x86_32: libocaml-4.01.0.so", }, } world = ( "dev-lang/ocaml", "dev-ml/lablgl", ) test_cases = ( # bug #531656: If an ocaml update is desirable, # then we need to pull in dev-ml/labltk. ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[ "[binary]dev-lang/ocaml-4.02.1", "[binary]dev-ml/labltk-8.06.0", "[binary]dev-ml/lablgl-1.05", ], ), ) for binpkg_format in SUPPORTED_GENTOO_BINPKG_FORMATS: with self.subTest(binpkg_format=binpkg_format): print(colorize("HILITE", binpkg_format), end=" ... ") sys.stdout.flush() playground = ResolverPlayground( debug=False, binpkgs=binpkgs, installed=installed, world=world, user_config={ "make.conf": ('BINPKG_FORMAT="%s"' % binpkg_format, ), }, ) 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()
def testBlockerFileCollision(self): debug = False install_something = """ S="${WORKDIR}" src_install() { einfo "installing something..." insinto /usr/lib echo "${PN}" > "${T}/file-collision" doins "${T}/file-collision" } """ ebuilds = { "dev-libs/A-1": { "EAPI": "6", "MISC_CONTENT": install_something, "RDEPEND": "!dev-libs/B", }, "dev-libs/B-1": { "EAPI": "6", "MISC_CONTENT": install_something, "RDEPEND": "!dev-libs/A", }, } playground = ResolverPlayground(ebuilds=ebuilds, debug=debug) settings = playground.settings eprefix = settings["EPREFIX"] eroot = settings["EROOT"] var_cache_edb = os.path.join(eprefix, "var", "cache", "edb") user_config_dir = os.path.join(eprefix, USER_CONFIG_PATH) portage_python = portage._python_interpreter emerge_cmd = (portage_python, "-b", "-Wd", os.path.join(self.bindir, "emerge")) file_collision = os.path.join(eroot, "usr/lib/file-collision") test_commands = ( emerge_cmd + ( "--oneshot", "dev-libs/A", ), (lambda: portage.util.grablines(file_collision) == ["A\n"],), emerge_cmd + ( "--oneshot", "dev-libs/B", ), (lambda: portage.util.grablines(file_collision) == ["B\n"],), emerge_cmd + ( "--oneshot", "dev-libs/A", ), (lambda: portage.util.grablines(file_collision) == ["A\n"],), ({"FEATURES": "parallel-install"},) + emerge_cmd + ( "--oneshot", "dev-libs/B", ), (lambda: portage.util.grablines(file_collision) == ["B\n"],), ({"FEATURES": "parallel-install"},) + emerge_cmd + ( "-Cq", "dev-libs/B", ), (lambda: not os.path.exists(file_collision),), ) fake_bin = os.path.join(eprefix, "bin") portage_tmpdir = os.path.join(eprefix, "var", "tmp", "portage") profile_path = settings.profile_path path = os.environ.get("PATH") if path is not None and not path.strip(): path = None if path is None: path = "" else: path = ":" + path path = fake_bin + path pythonpath = os.environ.get("PYTHONPATH") if pythonpath is not None and not pythonpath.strip(): pythonpath = None if pythonpath is not None and pythonpath.split(":")[0] == PORTAGE_PYM_PATH: pass else: if pythonpath is None: pythonpath = "" else: pythonpath = ":" + pythonpath pythonpath = PORTAGE_PYM_PATH + pythonpath env = { "PORTAGE_OVERRIDE_EPREFIX": eprefix, "PATH": path, "PORTAGE_PYTHON": portage_python, "PORTAGE_REPOSITORIES": settings.repositories.config_string(), "PYTHONDONTWRITEBYTECODE": os.environ.get("PYTHONDONTWRITEBYTECODE", ""), "PYTHONPATH": pythonpath, } if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: env["__PORTAGE_TEST_HARDLINK_LOCKS"] = os.environ[ "__PORTAGE_TEST_HARDLINK_LOCKS" ] dirs = [ playground.distdir, fake_bin, portage_tmpdir, user_config_dir, var_cache_edb, ] true_symlinks = ["chown", "chgrp"] true_binary = find_binary("true") self.assertEqual(true_binary is None, False, "true command not found") try: for d in dirs: ensure_dirs(d) for x in true_symlinks: os.symlink(true_binary, os.path.join(fake_bin, x)) with open(os.path.join(var_cache_edb, "counter"), "wb") as f: f.write(b"100") # non-empty system set keeps --depclean quiet with open(os.path.join(profile_path, "packages"), "w") as f: f.write("*dev-libs/token-system-pkg") if debug: # The subprocess inherits both stdout and stderr, for # debugging purposes. stdout = None else: # The subprocess inherits stderr so that any warnings # triggered by python -Wd will be visible. stdout = subprocess.PIPE for i, args in enumerate(test_commands): if hasattr(args[0], "__call__"): self.assertTrue(args[0](), "callable at index %s failed" % (i,)) continue if isinstance(args[0], dict): local_env = env.copy() local_env.update(args[0]) args = args[1:] else: local_env = env proc = subprocess.Popen(args, env=local_env, stdout=stdout) if debug: proc.wait() else: output = proc.stdout.readlines() proc.wait() proc.stdout.close() if proc.returncode != os.EX_OK: for line in output: sys.stderr.write(_unicode_decode(line)) self.assertEqual( os.EX_OK, proc.returncode, "emerge failed with args %s" % (args,) ) finally: playground.debug = False playground.cleanup()
def testTwoSlots(self): ebuilds = { "dev-libs/glib-1.2.10" : { "SLOT": "1" }, "dev-libs/glib-2.30.2" : { "SLOT": "2" }, "dev-libs/dbus-glib-0.98" : { "EAPI": "1", "DEPEND": "dev-libs/glib:2", "RDEPEND": "dev-libs/glib:2" }, } binpkgs = { "dev-libs/glib-1.2.10" : { "SLOT": "1", "PROVIDES": "x86_32: libglib-1.0.so.0", }, "dev-libs/glib-2.30.2" : { "PROVIDES": "x86_32: libglib-2.0.so.30", "SLOT": "2", }, "dev-libs/glib-2.32.3" : { "PROVIDES": "x86_32: libglib-2.0.so.32", "SLOT": "2", }, "dev-libs/dbus-glib-0.98" : { "EAPI": "1", "DEPEND": "dev-libs/glib:2", "RDEPEND": "dev-libs/glib:2", "REQUIRES": "x86_32: libglib-2.0.so.30", }, } installed = { "dev-libs/glib-1.2.10" : { "PROVIDES": "x86_32: libglib-1.0.so.0", "SLOT": "1", }, "dev-libs/glib-2.32.3" : { "PROVIDES": "x86_32: libglib-2.0.so.32", "SLOT": "2", }, "dev-libs/dbus-glib-0.98" : { "EAPI": "1", "DEPEND": "dev-libs/glib:2", "RDEPEND": "dev-libs/glib:2", "REQUIRES": "x86_32: libglib-2.0.so.32", }, } user_config = { "package.mask" : ( ">=dev-libs/glib-2.32", ), } world = [ "dev-libs/glib:1", "dev-libs/dbus-glib", ] test_cases = ( ResolverPlaygroundTestCase( ["@world"], options = { "--autounmask": "n", "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success = True, mergelist = [ "[binary]dev-libs/glib-2.30.2", "[binary]dev-libs/dbus-glib-0.98" ] ), ) playground = ResolverPlayground(ebuilds=ebuilds, binpkgs=binpkgs, installed=installed, user_config=user_config, world=world, debug=False) 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()
def testSonameSlotConflictMassRebuild(self): """ Bug 486580 Before this bug was fixed, emerge would backtrack for each package that needs a rebuild. This could cause it to hit the backtrack limit and not rebuild all needed packages. """ binpkgs = { "app-misc/A-1": { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-2.so", }, "app-misc/B-1": { "SLOT": "1", "PROVIDES": "x86_32: libB-1.so", }, "app-misc/B-2": { "SLOT": "2", "PROVIDES": "x86_32: libB-2.so", }, } installed = { "app-misc/B-1": { "SLOT": "1", "PROVIDES": "x86_32: libB-1.so", }, } expected_mergelist = ['[binary]app-misc/A-1', '[binary]app-misc/B-2'] for i in range(5): binpkgs["app-misc/C%sC-1" % i] = { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-2.so", } installed["app-misc/C%sC-1" % i] = { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-1.so", } for x in ("DEPEND", "RDEPEND"): binpkgs["app-misc/A-1"][x] += " app-misc/C%sC" % i expected_mergelist.append("[binary]app-misc/C%sC-1" % i) test_cases = (ResolverPlaygroundTestCase( ["app-misc/A"], ignore_mergelist_order=True, all_permutations=True, options={ "--backtrack": 3, "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success=True, mergelist=expected_mergelist), ) world = [] playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameSlotConflictMixedDependencies(self): """ Bug 487198 For parents with mixed >= and < dependencies, we scheduled reinstalls for the >= atom, but in the end didn't install the child update because of the < atom. """ binpkgs = { "cat/slotted-lib-1": { "PROVIDES": "x86_32: lib1.so", "SLOT": "1", }, "cat/slotted-lib-2": { "PROVIDES": "x86_32: lib2.so", "SLOT": "2", }, "cat/slotted-lib-3": { "PROVIDES": "x86_32: lib3.so", "SLOT": "3", }, "cat/slotted-lib-4": { "PROVIDES": "x86_32: lib4.so", "SLOT": "4", }, "cat/slotted-lib-5": { "PROVIDES": "x86_32: lib5.so", "SLOT": "5", }, "cat/user-1": { "DEPEND": ">=cat/slotted-lib-2 <cat/slotted-lib-4", "RDEPEND": ">=cat/slotted-lib-2 <cat/slotted-lib-4", "REQUIRES": "x86_32: lib3.so", }, } installed = { "cat/slotted-lib-3": { "PROVIDES": "x86_32: lib3.so", "SLOT": "3", }, "cat/user-1": { "DEPEND": ">=cat/slotted-lib-2 <cat/slotted-lib-4", "RDEPEND": ">=cat/slotted-lib-2 <cat/slotted-lib-4", "REQUIRES": "x86_32: lib3.so", }, } test_cases = (ResolverPlaygroundTestCase( ["cat/user"], options={ "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[]), ) world = [] playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
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()
def testSonameSkipUpdate(self): binpkgs = { "app-misc/A-1" : { "RDEPEND": "dev-libs/B", "DEPEND": "dev-libs/B", "REQUIRES": "x86_32: libB.so.1", }, "dev-libs/B-2" : { "PROVIDES": "x86_32: libB.so.2", }, "dev-libs/B-1" : { "PROVIDES": "x86_32: libB.so.1", }, } installed = { "app-misc/A-1" : { "RDEPEND": "dev-libs/B", "DEPEND": "dev-libs/B", "REQUIRES": "x86_32: libB.so.1", }, "dev-libs/B-1" : { "PROVIDES": "x86_32: libB.so.1", }, } world = ("app-misc/A",) test_cases = ( # Test that --ignore-soname-deps allows the upgrade, # even though it will break an soname dependency of # app-misc/A-1. ResolverPlaygroundTestCase( ["@world"], options = { "--deep": True, "--ignore-soname-deps": "y", "--update": True, "--usepkgonly": True }, success = True, mergelist = [ "[binary]dev-libs/B-2", ] ), # Test that upgrade to B-2 is skipped with --usepkgonly # because it will break an soname dependency that # cannot be satisfied by the available binary packages. ResolverPlaygroundTestCase( ["@world"], options = { "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True }, success = True, mergelist = [] ), ) playground = ResolverPlayground(debug=False, binpkgs=binpkgs, 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()
def testSonameConflictMissedUpdate(self): binpkgs = { "dev-lang/ocaml-4.02.1" : { "EAPI": "5", "PROVIDES": "x86_32: libocaml-4.02.1.so", }, "dev-lang/ocaml-4.01.0" : { "EAPI": "5", "PROVIDES": "x86_32: libocaml-4.01.0.so", }, "dev-ml/lablgl-1.05" : { "DEPEND": (">=dev-lang/ocaml-3.10.2 " "|| ( dev-ml/labltk <dev-lang/ocaml-4.02 )"), "RDEPEND": (">=dev-lang/ocaml-3.10.2 " "|| ( dev-ml/labltk <dev-lang/ocaml-4.02 )"), "REQUIRES": "x86_32: libocaml-4.02.1.so", }, "dev-ml/labltk-8.06.0" : { "EAPI": "5", "SLOT": "0/8.06.0", "DEPEND": ">=dev-lang/ocaml-4.02", "RDEPEND": ">=dev-lang/ocaml-4.02", "REQUIRES": "x86_32: libocaml-4.02.1.so", }, } installed = { "dev-lang/ocaml-4.01.0" : { "EAPI": "5", "PROVIDES": "x86_32: libocaml-4.01.0.so", }, "dev-ml/lablgl-1.05" : { "DEPEND": (">=dev-lang/ocaml-3.10.2 " "|| ( dev-ml/labltk <dev-lang/ocaml-4.02 )"), "RDEPEND": (">=dev-lang/ocaml-3.10.2 " "|| ( dev-ml/labltk <dev-lang/ocaml-4.02 )"), "REQUIRES": "x86_32: libocaml-4.01.0.so", }, } world = ( "dev-lang/ocaml", "dev-ml/lablgl", ) test_cases = ( # bug #531656: If an ocaml update is desirable, # then we need to pull in dev-ml/labltk. ResolverPlaygroundTestCase( ["@world"], options = { "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True }, success = True, mergelist = [ "[binary]dev-lang/ocaml-4.02.1", "[binary]dev-ml/labltk-8.06.0", "[binary]dev-ml/lablgl-1.05", ] ), ) playground = ResolverPlayground(debug=False, binpkgs=binpkgs, 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()
def testSonameSkipUpdate(self): binpkgs = { "app-misc/A-1": { "RDEPEND": "dev-libs/B", "DEPEND": "dev-libs/B", "REQUIRES": "x86_32: libB.so.1", }, "dev-libs/B-2": { "PROVIDES": "x86_32: libB.so.2", }, "dev-libs/B-1": { "PROVIDES": "x86_32: libB.so.1", }, } installed = { "app-misc/A-1": { "RDEPEND": "dev-libs/B", "DEPEND": "dev-libs/B", "REQUIRES": "x86_32: libB.so.1", }, "dev-libs/B-1": { "PROVIDES": "x86_32: libB.so.1", }, } world = ("app-misc/A", ) test_cases = ( # Test that --ignore-soname-deps allows the upgrade, # even though it will break an soname dependency of # app-misc/A-1. ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--ignore-soname-deps": "y", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[ "[binary]dev-libs/B-2", ], ), # Test that upgrade to B-2 is skipped with --usepkgonly # because it will break an soname dependency that # cannot be satisfied by the available binary packages. ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[], ), ) for binpkg_format in SUPPORTED_GENTOO_BINPKG_FORMATS: with self.subTest(binpkg_format=binpkg_format): print(colorize("HILITE", binpkg_format), end=" ... ") sys.stdout.flush() playground = ResolverPlayground( debug=False, binpkgs=binpkgs, installed=installed, world=world, user_config={ "make.conf": ('BINPKG_FORMAT="%s"' % binpkg_format, ), }, ) 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()
def testOrUpgradeInstalled(self): ebuilds = { 'net-misc/foo-1': { 'EAPI': '6', 'RDEPEND': '|| ( sys-libs/glibc[rpc(-)] net-libs/libtirpc )' }, 'net-libs/libtirpc-1': { 'EAPI': '6', }, 'sys-libs/glibc-2.26': { 'EAPI': '6', 'IUSE': '' }, 'sys-libs/glibc-2.24': { 'EAPI': '6', 'IUSE': '+rpc' }, } installed = { 'sys-libs/glibc-2.24': { 'EAPI': '6', 'IUSE': '+rpc', 'USE': 'rpc', }, } world = ['sys-libs/glibc'] test_cases = ( # Test bug 643974, where we need to install libtirpc # in order to upgrade glibc. ResolverPlaygroundTestCase( ['net-misc/foo', '@world'], options={'--update': True, '--deep': True}, success=True, ambiguous_merge_order=True, mergelist=( ( 'net-libs/libtirpc-1', 'sys-libs/glibc-2.26', 'net-misc/foo-1', ), ) ), ) 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: playground.debug = False playground.cleanup() # In some cases it's necessary to avoid upgrade due to # the package being masked. user_config = { "package.mask" : ( ">=sys-libs/glibc-2.26", ), } test_cases = ( ResolverPlaygroundTestCase( ['net-misc/foo', '@world'], options={'--update': True, '--deep': True}, success=True, mergelist=[ 'net-misc/foo-1', ] ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds, installed=installed, world=world, user_config=user_config) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testDisjunctiveDependOrderTestCase(self): ebuilds = { 'virtual/jre-1.8': { 'EAPI': '6', 'SLOT' : '1.8', 'RDEPEND' : '|| ( dev-java/oracle-jre-bin:1.8 virtual/jdk:1.8 )', }, 'virtual/jdk-1.8': { 'EAPI': '6', 'SLOT' : '1.8', 'RDEPEND' : '|| ( dev-java/icedtea:8 dev-java/oracle-jdk-bin:1.8 )', }, 'dev-java/icedtea-3.6': { 'SLOT' : '8', }, 'dev-java/oracle-jdk-bin-1.8': { 'SLOT' : '1.8', }, 'dev-java/oracle-jre-bin-1.8': { 'SLOT' : '1.8', }, 'dev-db/hsqldb-1.8' : { 'DEPEND' : 'virtual/jdk', 'RDEPEND' : 'virtual/jre', }, } binpkgs = { 'dev-db/hsqldb-1.8' : { 'DEPEND' : 'virtual/jdk', 'RDEPEND' : 'virtual/jre', }, } test_cases = ( # Test bug 639346, where a redundant jre implementation # was pulled in because DEPEND was evaluated after # RDEPEND. ResolverPlaygroundTestCase( ['dev-db/hsqldb'], success=True, mergelist=[ 'dev-java/icedtea-3.6', 'virtual/jdk-1.8', 'virtual/jre-1.8', 'dev-db/hsqldb-1.8', ], ), # The jdk is not needed with --usepkg, so the jre should # be preferred in this case. ResolverPlaygroundTestCase( ['dev-db/hsqldb'], options = { '--usepkg': True }, success=True, mergelist=[ 'dev-java/oracle-jre-bin-1.8', 'virtual/jre-1.8', '[binary]dev-db/hsqldb-1.8', ], ), ) playground = ResolverPlayground(debug=False, binpkgs=binpkgs, ebuilds=ebuilds) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testVirtualPackageManager(self): ebuilds = { 'app-admin/perl-cleaner-2.25': { 'RDEPEND': ''' || ( ( sys-apps/portage app-portage/portage-utils ) sys-apps/pkgcore sys-apps/paludis )''' }, 'app-portage/portage-utils-0.64': {}, 'sys-apps/paludis-2.6.0': {}, 'sys-apps/portage-2.3.19-r1': {}, 'virtual/package-manager-0': { 'RDEPEND': ''' || ( sys-apps/portage sys-apps/paludis sys-apps/pkgcore )''' }, } test_cases = ( # Test bug 645002, where paludis was selected to satisfy a # perl-cleaner dependency because that choice contained fewer # packages than the ( portage portage-utils ) choice which # should have been preferred according to the order of # choices specified in the ebuild. ResolverPlaygroundTestCase( [ 'app-admin/perl-cleaner', 'virtual/package-manager', ], all_permutations=True, success=True, ambiguous_merge_order=True, mergelist=( ( 'sys-apps/portage-2.3.19-r1', 'app-portage/portage-utils-0.64', 'app-admin/perl-cleaner-2.25', 'virtual/package-manager-0', ), ) ), # Test paludis preference. In this case, if paludis is not # included in the argument atoms then the result varies # depending on whether the app-admin/perl-cleaner or # virtual/package-manager dependencies are evaluated first! # Therefore, include paludis in the argument atoms. ResolverPlaygroundTestCase( [ 'app-admin/perl-cleaner', 'virtual/package-manager', 'sys-apps/paludis', ], all_permutations=True, success=True, ambiguous_merge_order=True, mergelist=( 'sys-apps/paludis-2.6.0', ( 'app-admin/perl-cleaner-2.25', 'virtual/package-manager-0', ), ) ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameAutoUnmask(self): binpkgs = { "dev-libs/icu-49" : { "KEYWORDS": "x86", "PROVIDES": "x86_32: libicu.so.49", }, "dev-libs/icu-4.8" : { "KEYWORDS": "x86", "PROVIDES": "x86_32: libicu.so.48", }, "dev-libs/libxml2-2.7.8" : { "KEYWORDS": "~x86", "DEPEND": "dev-libs/icu", "RDEPEND": "dev-libs/icu", "REQUIRES": "x86_32: libicu.so.49", }, } installed = { "dev-libs/icu-4.8" : { "KEYWORDS": "x86", "PROVIDES": "x86_32: libicu.so.48", }, "dev-libs/libxml2-2.7.8" : { "KEYWORDS": "~x86", "DEPEND": "dev-libs/icu", "RDEPEND": "dev-libs/icu", "REQUIRES": "x86_32: libicu.so.48", }, } world = ["dev-libs/libxml2"] test_cases = ( ResolverPlaygroundTestCase( ["dev-libs/icu"], options = { "--autounmask": True, "--ignore-soname-deps": "n", "--oneshot": True, "--usepkgonly": True, }, success = False, mergelist = [ "[binary]dev-libs/icu-49", "[binary]dev-libs/libxml2-2.7.8" ], unstable_keywords = ['dev-libs/libxml2-2.7.8'], ), ResolverPlaygroundTestCase( ["dev-libs/icu"], options = { "--autounmask": True, "--ignore-soname-deps": "y", "--oneshot": True, "--usepkgonly": True, }, success = True, mergelist = [ "[binary]dev-libs/icu-49" ] ), # Test that dev-libs/icu-49 update is skipped due to # dev-libs/libxml2-2.7.8 being masked by KEYWORDS. Note # that this result is questionable, since the installed # dev-libs/libxml2-2.7.8 instance is also masked! ResolverPlaygroundTestCase( ["@world"], options = { "--autounmask": True, "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success = True, mergelist = [], ), ) playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameUnsatisfied(self): binpkgs = { "app-misc/A-1": { "EAPI": "5", "PROVIDES": "x86_32: libA.so.1", }, "app-misc/A-2": { "EAPI": "5", "PROVIDES": "x86_32: libA.so.2", }, "app-misc/B-0": { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.2", }, } installed = { "app-misc/A-2": { "EAPI": "5", "PROVIDES": "x86_32: libA.so.2", }, "app-misc/B-0": { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.1", }, } world = ["app-misc/B"] test_cases = ( # Demonstrate bug #439694, where a broken # soname dependency needs to trigger a reinstall. ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success=True, mergelist=["[binary]app-misc/B-0"], ), # This doesn't trigger a reinstall, since there's no version # change to trigger complete graph mode, and initially # unsatisfied deps are ignored in complete graph mode anyway. ResolverPlaygroundTestCase( ["app-misc/A"], options={ "--ignore-soname-deps": "n", "--oneshot": True, "--usepkgonly": True, }, success=True, mergelist=["[binary]app-misc/A-2"], ), ) playground = ResolverPlayground( binpkgs=binpkgs, debug=False, 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()
def testSonameUnsatisfiable(self): binpkgs = { "app-misc/A-1" : { "EAPI": "5", "PROVIDES": "x86_32: libA.so.1", }, "app-misc/B-1" : { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.2", }, "app-misc/B-0" : { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.1", }, } installed = { "app-misc/A-1" : { "EAPI": "5", "PROVIDES": "x86_32: libA.so.1", }, "app-misc/B-0" : { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.1", }, } world = ["app-misc/B"] test_cases = ( # Skip update due to unsatisfied soname dependency. ResolverPlaygroundTestCase( ["@world"], options = { "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success = True, mergelist = [], ), ) playground = ResolverPlayground(binpkgs=binpkgs, debug=False, 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()
def testCircularPypyExe(self): ebuilds = { "dev-lang/rust-1.47.0-r2": { "EAPI": "7", "SLOT": "stable/1.47", "BDEPEND": "|| ( =dev-lang/rust-1.46* =dev-lang/rust-bin-1.46* =dev-lang/rust-1.47* =dev-lang/rust-bin-1.47* )", }, "dev-lang/rust-1.46.0": { "EAPI": "7", "SLOT": "stable/1.46", "BDEPEND": "|| ( =dev-lang/rust-1.45* =dev-lang/rust-bin-1.45* =dev-lang/rust-1.46* =dev-lang/rust-bin-1.46* )", }, "dev-lang/rust-bin-1.47.0": { "EAPI": "7", }, "dev-lang/rust-bin-1.46.0": { "EAPI": "7", }, } installed = { "dev-lang/rust-1.46.0": { "EAPI": "7", "SLOT": "stable/1.46", "BDEPEND": "|| ( =dev-lang/rust-1.45* =dev-lang/rust-bin-1.45* =dev-lang/rust-1.46* =dev-lang/rust-bin-1.46* )", }, } test_cases = ( # Test bug 756961, where a circular dependency was reported # when a package would replace its own builtime dependency. # This needs to be tested with and without --update, since # that affects package selection logic significantly, # expecially for packages given as arguments. ResolverPlaygroundTestCase( ["=dev-lang/rust-1.46*"], mergelist=["dev-lang/rust-1.46.0"], success=True, ), ResolverPlaygroundTestCase( ["=dev-lang/rust-1.46*"], options={"--update": True}, mergelist=[], success=True, ), ResolverPlaygroundTestCase( ["=dev-lang/rust-1.46*"], options={"--deep": True, "--update": True}, mergelist=[], success=True, ), ResolverPlaygroundTestCase( ["dev-lang/rust"], mergelist=["dev-lang/rust-1.47.0-r2"], success=True, ), ResolverPlaygroundTestCase( ["dev-lang/rust"], options={"--update": True}, mergelist=["dev-lang/rust-1.47.0-r2"], success=True, ), ResolverPlaygroundTestCase( ["@world"], options={"--deep": True, "--update": True}, mergelist=["dev-lang/rust-1.47.0-r2"], success=True, ), ) world = ["dev-lang/rust"] playground = ResolverPlayground( ebuilds=ebuilds, installed=installed, world=world, debug=False ) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testImageMagickUpdate(self): ebuilds = { "app-misc/A-1" : { "EAPI": "6", "DEPEND": "app-misc/B", "RDEPEND": "app-misc/C", }, "app-misc/B-1" : { "EAPI": "6" }, "app-misc/B-2" : { "EAPI": "6", }, "app-misc/C-1" : { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/C-2" : { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/D-1" : { "EAPI": "6", }, "app-misc/D-2" : { "EAPI": "6", }, } installed = { "app-misc/A-1" : { "EAPI": "6", "DEPEND": "app-misc/B", "RDEPEND": "app-misc/C", }, "app-misc/B-1" : { "EAPI": "6", }, "app-misc/C-1" : { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/D-1" : { "EAPI": "6", }, } binpkgs = { "app-misc/A-1" : { "EAPI": "6", "DEPEND": "app-misc/B", "RDEPEND": "app-misc/C", }, "app-misc/B-1" : { "EAPI": "6", }, "app-misc/B-2" : { "EAPI": "6", }, "app-misc/C-1" : { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/C-2" : { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/D-1" : { "EAPI": "6", }, "app-misc/D-2" : { "EAPI": "6", }, } world = ( "app-misc/A", ) test_cases = ( # Enable --with-bdeps automatically when # --usepkg has not been specified. ResolverPlaygroundTestCase( ["@world"], options = { "--update": True, "--deep": True, }, success = True, ambiguous_merge_order = True, mergelist = [ "app-misc/D-2", ("app-misc/B-2", "app-misc/C-2"), ] ), # Use --with-bdeps-auto=n to prevent --with-bdeps # from being enabled automatically. ResolverPlaygroundTestCase( ["@world"], options = { "--update": True, "--deep": True, "--with-bdeps-auto": "n", }, success = True, mergelist = [ "app-misc/D-2", "app-misc/C-2", ] ), # Do not enable --with-bdeps automatically when # --usepkg has been specified, since many users of binary # packages do not want unnecessary build time dependencies # installed. In this case we miss an update to # app-misc/D-2, since DEPEND is not pulled in for # the [binary]app-misc/C-2 update. ResolverPlaygroundTestCase( ["@world"], options = { "--update": True, "--deep": True, "--usepkg": True, }, success = True, mergelist = [ "[binary]app-misc/C-2", ] ), # Use --with-bdeps=y to pull in build-time dependencies of # binary packages. ResolverPlaygroundTestCase( ["@world"], options = { "--update": True, "--deep": True, "--usepkg": True, "--with-bdeps": "y", }, success = True, ambiguous_merge_order = True, mergelist = [ ( "[binary]app-misc/D-2", "[binary]app-misc/B-2", "[binary]app-misc/C-2", ), ] ), # For --depclean, do not remove build-time dependencies by # default. Specify --with-bdeps-auto=n, in order to # demonstrate that it does not affect removal actions. ResolverPlaygroundTestCase( [], options = { "--depclean": True, "--with-bdeps-auto": "n", }, success = True, cleanlist = [], ), # For --depclean, remove build-time dependencies if # --with-bdeps=n has been specified. ResolverPlaygroundTestCase( [], options = { "--depclean": True, "--with-bdeps": "n", }, success = True, ignore_cleanlist_order = True, cleanlist = [ "app-misc/D-1", "app-misc/B-1", ], ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds, installed=installed, binpkgs=binpkgs, 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()
def testSonameSlotConflictForgottenChild(self): """ Similar to testSonameSlotConflictMassRebuild above, but this time the rebuilds are scheduled, but the package causing the rebuild (the child) is not installed. """ binpkgs = { "app-misc/A-2": { "DEPEND": "app-misc/B app-misc/C", "RDEPEND": "app-misc/B app-misc/C", "REQUIRES": "x86_32: libB-2.so", }, "app-misc/B-2": { "PROVIDES": "x86_32: libB-2.so", "SLOT": "2", }, "app-misc/C-1": { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-2.so", }, } installed = { "app-misc/A-1": { "DEPEND": "app-misc/B app-misc/C", "RDEPEND": "app-misc/B app-misc/C", "REQUIRES": "x86_32: libB-1.so", }, "app-misc/B-1": { "PROVIDES": "x86_32: libB-1.so", "SLOT": "1", }, "app-misc/C-1": { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-1.so", }, } test_cases = ( ResolverPlaygroundTestCase(["app-misc/A"], options={ "--ignore-soname-deps": "n", "--usepkgonly": True, }, success=True, mergelist=[ '[binary]app-misc/B-2', '[binary]app-misc/A-2', ]), ResolverPlaygroundTestCase( ["@world"], options={ "--ignore-soname-deps": "n", "--usepkgonly": True, "--update": True, "--deep": True, }, success=True, mergelist=[ '[binary]app-misc/B-2', '[binary]app-misc/C-1', '[binary]app-misc/A-2', ]), ) world = ['app-misc/A'] playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testImageMagickUpdate(self): ebuilds = { "media-gfx/imagemagick-6.9.7.0" : { "EAPI": "6", "SLOT": "0/6.9.7.0", }, "media-gfx/imagemagick-6.9.6.6" : { "EAPI": "6", "SLOT": "0/6.9.6.6", }, "media-gfx/inkscape-0.91-r3" : { "EAPI": "6", "DEPEND": "media-gfx/imagemagick:=", "RDEPEND": "media-gfx/imagemagick:=", }, "media-video/dvdrip-0.98.11-r3" : { "EAPI": "6", "DEPEND": "|| ( media-gfx/graphicsmagick[imagemagick] media-gfx/imagemagick )", "RDEPEND": "|| ( media-gfx/graphicsmagick[imagemagick] media-gfx/imagemagick )", }, "media-gfx/graphicsmagick-1.3.25" : { "EAPI": "6", "SLOT": "0/1.3", "IUSE": "imagemagick", "RDEPEND": "imagemagick? ( !media-gfx/imagemagick )", }, } installed = { "media-gfx/imagemagick-6.9.6.6" : { "EAPI": "6", "SLOT": "0/6.9.6.6", }, "media-gfx/inkscape-0.91-r3" : { "EAPI": "6", "DEPEND": "media-gfx/imagemagick:0/6.9.6.6=", "RDEPEND": "media-gfx/imagemagick:0/6.9.6.6=", }, "media-video/dvdrip-0.98.11-r3" : { "EAPI": "6", "DEPEND": "|| ( media-gfx/graphicsmagick[imagemagick] media-gfx/imagemagick )", "RDEPEND": "|| ( media-gfx/graphicsmagick[imagemagick] media-gfx/imagemagick )", }, "media-gfx/graphicsmagick-1.3.25" : { "EAPI": "6", "SLOT": "0/1.3", "IUSE": "imagemagick", "USE": "", "RDEPEND": "imagemagick? ( !media-gfx/imagemagick )", }, } world = ( "media-gfx/inkscape", "media-video/dvdrip", "media-gfx/graphicsmagick", ) test_cases = ( # bug #554070: imagemagick upgrade triggered erroneous # autounmask USE change for media-gfx/graphicsmagick[imagemagick] ResolverPlaygroundTestCase( ["media-gfx/imagemagick", "@world"], options = {"--update": True, "--deep": True}, success = True, mergelist = [ "media-gfx/imagemagick-6.9.7.0", "media-gfx/inkscape-0.91-r3" ] ), ) 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()
def testSonameSlotConflictReinstall(self): binpkgs = { "app-misc/A-1": { "PROVIDES": "x86_32: libA-1.so", }, "app-misc/A-2": { "PROVIDES": "x86_32: libA-2.so", }, "app-misc/B-0": { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA-2.so", }, "app-misc/C-0": { "EAPI": "5", "DEPEND": "<app-misc/A-2", "RDEPEND": "<app-misc/A-2" }, "app-misc/D-1": { "PROVIDES": "x86_32: libD-1.so", }, "app-misc/D-2": { "PROVIDES": "x86_32: libD-2.so", }, "app-misc/E-0": { "DEPEND": "app-misc/D", "RDEPEND": "app-misc/D", "REQUIRES": "x86_32: libD-2.so", }, } installed = { "app-misc/A-1": { "PROVIDES": "x86_32: libA-1.so", }, "app-misc/B-0": { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA-1.so", }, "app-misc/C-0": { "DEPEND": "<app-misc/A-2", "RDEPEND": "<app-misc/A-2" }, "app-misc/D-1": { "PROVIDES": "x86_32: libD-1.so", }, "app-misc/E-0": { "DEPEND": "app-misc/D", "RDEPEND": "app-misc/D", "REQUIRES": "x86_32: libD-1.so", }, } world = ["app-misc/B", "app-misc/C", "app-misc/E"] test_cases = ( # Test bug #439688, where a slot conflict prevents an # upgrade and we don't want to trigger unnecessary rebuilds. ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, "--backtrack": 10, }, success=True, mergelist=["[binary]app-misc/D-2", "[binary]app-misc/E-0"]), ) playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameSlotConflictMassRebuild(self): """ Bug 486580 Before this bug was fixed, emerge would backtrack for each package that needs a rebuild. This could cause it to hit the backtrack limit and not rebuild all needed packages. """ binpkgs = { "app-misc/A-1" : { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-2.so", }, "app-misc/B-1" : { "SLOT": "1", "PROVIDES": "x86_32: libB-1.so", }, "app-misc/B-2" : { "SLOT": "2", "PROVIDES": "x86_32: libB-2.so", }, } installed = { "app-misc/B-1" : { "SLOT": "1", "PROVIDES": "x86_32: libB-1.so", }, } expected_mergelist = [ '[binary]app-misc/A-1', '[binary]app-misc/B-2' ] for i in range(5): binpkgs["app-misc/C%sC-1" % i] = { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-2.so", } installed["app-misc/C%sC-1" % i] = { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-1.so", } for x in ("DEPEND", "RDEPEND"): binpkgs["app-misc/A-1"][x] += " app-misc/C%sC" % i expected_mergelist.append("[binary]app-misc/C%sC-1" % i) test_cases = ( ResolverPlaygroundTestCase( ["app-misc/A"], ignore_mergelist_order=True, all_permutations=True, options = { "--backtrack": 3, "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success = True, mergelist = expected_mergelist), ) world = [] playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameSlotConflictUpdate(self): binpkgs = { "app-text/podofo-0.9.2" : { "RDEPEND" : "dev-util/boost-build", }, "dev-cpp/libcmis-0.3.1" : { "DEPEND": "dev-libs/boost", "RDEPEND": "dev-libs/boost", "REQUIRES": "x86_32: libboost-1.53.so", }, "dev-libs/boost-1.53.0" : { "PROVIDES": "x86_32: libboost-1.53.so", "RDEPEND" : "=dev-util/boost-build-1.53.0", }, "dev-libs/boost-1.52.0" : { "PROVIDES": "x86_32: libboost-1.52.so", "RDEPEND" : "=dev-util/boost-build-1.52.0", }, "dev-util/boost-build-1.53.0" : { }, "dev-util/boost-build-1.52.0" : { }, } installed = { "app-text/podofo-0.9.2" : { "RDEPEND" : "dev-util/boost-build", }, "dev-cpp/libcmis-0.3.1" : { "DEPEND": "dev-libs/boost", "RDEPEND": "dev-libs/boost", "REQUIRES": "x86_32: libboost-1.52.so", }, "dev-util/boost-build-1.52.0" : { }, "dev-libs/boost-1.52.0" : { "PROVIDES": "x86_32: libboost-1.52.so", "RDEPEND" : "=dev-util/boost-build-1.52.0", }, } world = [ "dev-cpp/libcmis", "dev-libs/boost", "app-text/podofo", ] test_cases = ( ResolverPlaygroundTestCase( world, all_permutations = True, options = { "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success = True, mergelist = [ '[binary]dev-util/boost-build-1.53.0', '[binary]dev-libs/boost-1.53.0', '[binary]dev-cpp/libcmis-0.3.1' ] ), ResolverPlaygroundTestCase( world, all_permutations = True, options = { "--deep": True, "--ignore-soname-deps": "y", "--update": True, "--usepkgonly": True, }, success = True, mergelist = [ '[binary]dev-util/boost-build-1.53.0', '[binary]dev-libs/boost-1.53.0', ] ), ) playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameSlotConflictForgottenChild(self): """ Similar to testSonameSlotConflictMassRebuild above, but this time the rebuilds are scheduled, but the package causing the rebuild (the child) is not installed. """ binpkgs = { "app-misc/A-2" : { "DEPEND": "app-misc/B app-misc/C", "RDEPEND": "app-misc/B app-misc/C", "REQUIRES": "x86_32: libB-2.so", }, "app-misc/B-2" : { "PROVIDES": "x86_32: libB-2.so", "SLOT": "2", }, "app-misc/C-1": { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-2.so", }, } installed = { "app-misc/A-1" : { "DEPEND": "app-misc/B app-misc/C", "RDEPEND": "app-misc/B app-misc/C", "REQUIRES": "x86_32: libB-1.so", }, "app-misc/B-1" : { "PROVIDES": "x86_32: libB-1.so", "SLOT": "1", }, "app-misc/C-1": { "DEPEND": "app-misc/B", "RDEPEND": "app-misc/B", "REQUIRES": "x86_32: libB-1.so", }, } test_cases = ( ResolverPlaygroundTestCase( ["app-misc/A"], options = { "--ignore-soname-deps": "n", "--usepkgonly": True, }, success = True, mergelist = [ '[binary]app-misc/B-2', '[binary]app-misc/A-2', ] ), ResolverPlaygroundTestCase( ["@world"], options = { "--ignore-soname-deps": "n", "--usepkgonly": True, "--update": True, "--deep": True, }, success = True, mergelist = [ '[binary]app-misc/B-2', '[binary]app-misc/C-1', '[binary]app-misc/A-2', ] ), ) world = ['app-misc/A'] playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSingleSlot(self): ebuilds = { "dev-libs/icu-49" : { }, "dev-libs/icu-4.8" : { }, "dev-libs/libxml2-2.7.8" : { "DEPEND": "dev-libs/icu", "RDEPEND": "dev-libs/icu", }, } binpkgs = { "dev-libs/icu-49" : { "PROVIDES": "x86_32: libicu.so.49", }, "dev-libs/icu-4.8" : { "PROVIDES": "x86_32: libicu.so.48", }, "dev-libs/libxml2-2.7.8" : { "DEPEND": "dev-libs/icu", "RDEPEND": "dev-libs/icu", "REQUIRES": "x86_32: libicu.so.48", }, } installed = { "dev-libs/icu-49" : { "PROVIDES": "x86_32: libicu.so.49", }, "dev-libs/libxml2-2.7.8" : { "DEPEND": "dev-libs/icu", "RDEPEND": "dev-libs/icu", "REQUIRES": "x86_32: libicu.so.49", }, } user_config = { "package.mask" : ( ">=dev-libs/icu-49", ), } world = ["dev-libs/libxml2"] test_cases = ( ResolverPlaygroundTestCase( ["dev-libs/icu"], options = { "--autounmask": "n", "--ignore-soname-deps": "n", "--oneshot": True, "--usepkgonly": True }, success = True, mergelist = [ "[binary]dev-libs/icu-4.8", "[binary]dev-libs/libxml2-2.7.8" ] ), ResolverPlaygroundTestCase( ["dev-libs/icu"], options = { "--autounmask": "n", "--ignore-soname-deps": "y", "--oneshot": True, "--usepkgonly": True }, success = True, mergelist = [ "[binary]dev-libs/icu-4.8", ] ), ResolverPlaygroundTestCase( ["@world"], options = { "--autounmask": "n", "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success = True, mergelist = [ "[binary]dev-libs/icu-4.8", "[binary]dev-libs/libxml2-2.7.8" ] ), # In this case, soname dependencies are not respected, # because --usepkgonly is not enabled. This could be # handled differently, by respecting soname dependencies # as long as no unbuilt ebuilds get pulled into the graph. # However, that kind of conditional dependency accounting # would add a significant amount of complexity. ResolverPlaygroundTestCase( ["@world"], options = { "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkg": True, }, success = True, mergelist = [ "[binary]dev-libs/icu-4.8", ] ), ResolverPlaygroundTestCase( ["@world"], options = { "--deep": True, "--update": True, }, success = True, mergelist = [ "dev-libs/icu-4.8", ] ), ) playground = ResolverPlayground(binpkgs=binpkgs, ebuilds=ebuilds, installed=installed, user_config=user_config, world=world, debug=False) 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()
def testSonameSlotConflictMixedDependencies(self): """ Bug 487198 For parents with mixed >= and < dependencies, we scheduled reinstalls for the >= atom, but in the end didn't install the child update because of the < atom. """ binpkgs = { "cat/slotted-lib-1" : { "PROVIDES": "x86_32: lib1.so", "SLOT": "1", }, "cat/slotted-lib-2" : { "PROVIDES": "x86_32: lib2.so", "SLOT": "2", }, "cat/slotted-lib-3" : { "PROVIDES": "x86_32: lib3.so", "SLOT": "3", }, "cat/slotted-lib-4" : { "PROVIDES": "x86_32: lib4.so", "SLOT": "4", }, "cat/slotted-lib-5" : { "PROVIDES": "x86_32: lib5.so", "SLOT": "5", }, "cat/user-1" : { "DEPEND": ">=cat/slotted-lib-2 <cat/slotted-lib-4", "RDEPEND": ">=cat/slotted-lib-2 <cat/slotted-lib-4", "REQUIRES": "x86_32: lib3.so", }, } installed = { "cat/slotted-lib-3" : { "PROVIDES": "x86_32: lib3.so", "SLOT": "3", }, "cat/user-1" : { "DEPEND": ">=cat/slotted-lib-2 <cat/slotted-lib-4", "RDEPEND": ">=cat/slotted-lib-2 <cat/slotted-lib-4", "REQUIRES": "x86_32: lib3.so", }, } test_cases = ( ResolverPlaygroundTestCase( ["cat/user"], options = { "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success = True, mergelist = []), ) world = [] playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testAutounmaskKeepKeywordsTestCase(self): ebuilds = { 'app-misc/A-2': { 'EAPI': '6', 'RDEPEND': 'app-misc/B', }, 'app-misc/A-1': { 'EAPI': '6', 'RDEPEND': 'app-misc/C[foo]', }, 'app-misc/B-1': { 'EAPI': '6', 'KEYWORDS': '~x86', }, 'app-misc/C-1': { 'EAPI': '6', 'IUSE': 'foo', }, } installed = { } test_cases = ( ResolverPlaygroundTestCase( ['app-misc/A'], success = False, options = { "--autounmask": True, '--autounmask-keep-keywords': 'n', }, mergelist = [ 'app-misc/B-1', 'app-misc/A-2', ], unstable_keywords={'app-misc/B-1'}, ), # --autounmask-keep-keywords prefers app-misc/A-1 because # it can be installed without accepting unstable # keywords ResolverPlaygroundTestCase( ['app-misc/A'], success = False, options = { "--autounmask": True, '--autounmask-keep-keywords': 'y', }, mergelist = [ 'app-misc/C-1', 'app-misc/A-1', ], use_changes = {'app-misc/C-1': {'foo': True}}, ), ) playground = ResolverPlayground(ebuilds=ebuilds, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSonameSlotConflictReinstall(self): binpkgs = { "app-misc/A-1" : { "PROVIDES": "x86_32: libA-1.so", }, "app-misc/A-2" : { "PROVIDES": "x86_32: libA-2.so", }, "app-misc/B-0" : { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA-2.so", }, "app-misc/C-0" : { "EAPI": "5", "DEPEND": "<app-misc/A-2", "RDEPEND": "<app-misc/A-2" }, "app-misc/D-1" : { "PROVIDES": "x86_32: libD-1.so", }, "app-misc/D-2" : { "PROVIDES": "x86_32: libD-2.so", }, "app-misc/E-0" : { "DEPEND": "app-misc/D", "RDEPEND": "app-misc/D", "REQUIRES": "x86_32: libD-2.so", }, } installed = { "app-misc/A-1" : { "PROVIDES": "x86_32: libA-1.so", }, "app-misc/B-0" : { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA-1.so", }, "app-misc/C-0" : { "DEPEND": "<app-misc/A-2", "RDEPEND": "<app-misc/A-2" }, "app-misc/D-1" : { "PROVIDES": "x86_32: libD-1.so", }, "app-misc/E-0" : { "DEPEND": "app-misc/D", "RDEPEND": "app-misc/D", "REQUIRES": "x86_32: libD-1.so", }, } world = ["app-misc/B", "app-misc/C", "app-misc/E"] test_cases = ( # Test bug #439688, where a slot conflict prevents an # upgrade and we don't want to trigger unnecessary rebuilds. ResolverPlaygroundTestCase( ["@world"], options = { "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, "--backtrack": 10, }, success = True, mergelist = [ "[binary]app-misc/D-2", "[binary]app-misc/E-0" ] ), ) playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testBlockerFileCollision(self): debug = False install_something = """ S="${WORKDIR}" src_install() { einfo "installing something..." insinto /usr/lib echo "${PN}" > "${T}/file-collision" doins "${T}/file-collision" } """ ebuilds = { "dev-libs/A-1" : { "EAPI": "6", "MISC_CONTENT": install_something, "RDEPEND": "!dev-libs/B", }, "dev-libs/B-1" : { "EAPI": "6", "MISC_CONTENT": install_something, "RDEPEND": "!dev-libs/A", }, } playground = ResolverPlayground(ebuilds=ebuilds, debug=debug) settings = playground.settings eprefix = settings["EPREFIX"] eroot = settings["EROOT"] var_cache_edb = os.path.join(eprefix, "var", "cache", "edb") user_config_dir = os.path.join(eprefix, USER_CONFIG_PATH) portage_python = portage._python_interpreter emerge_cmd = (portage_python, "-b", "-Wd", os.path.join(self.bindir, "emerge")) file_collision = os.path.join(eroot, 'usr/lib/file-collision') test_commands = ( emerge_cmd + ("--oneshot", "dev-libs/A",), (lambda: portage.util.grablines(file_collision) == ["A\n"],), emerge_cmd + ("--oneshot", "dev-libs/B",), (lambda: portage.util.grablines(file_collision) == ["B\n"],), emerge_cmd + ("--oneshot", "dev-libs/A",), (lambda: portage.util.grablines(file_collision) == ["A\n"],), ({"FEATURES":"parallel-install"},) + emerge_cmd + ("--oneshot", "dev-libs/B",), (lambda: portage.util.grablines(file_collision) == ["B\n"],), ({"FEATURES":"parallel-install"},) + emerge_cmd + ("-Cq", "dev-libs/B",), (lambda: not os.path.exists(file_collision),), ) fake_bin = os.path.join(eprefix, "bin") portage_tmpdir = os.path.join(eprefix, "var", "tmp", "portage") profile_path = settings.profile_path path = os.environ.get("PATH") if path is not None and not path.strip(): path = None if path is None: path = "" else: path = ":" + path path = fake_bin + path pythonpath = os.environ.get("PYTHONPATH") if pythonpath is not None and not pythonpath.strip(): pythonpath = None if pythonpath is not None and \ pythonpath.split(":")[0] == PORTAGE_PYM_PATH: pass else: if pythonpath is None: pythonpath = "" else: pythonpath = ":" + pythonpath pythonpath = PORTAGE_PYM_PATH + pythonpath env = { "PORTAGE_OVERRIDE_EPREFIX" : eprefix, "PATH" : path, "PORTAGE_PYTHON" : portage_python, "PORTAGE_REPOSITORIES" : settings.repositories.config_string(), "PYTHONDONTWRITEBYTECODE" : os.environ.get("PYTHONDONTWRITEBYTECODE", ""), "PYTHONPATH" : pythonpath, } if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: env["__PORTAGE_TEST_HARDLINK_LOCKS"] = \ os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"] dirs = [playground.distdir, fake_bin, portage_tmpdir, user_config_dir, var_cache_edb] true_symlinks = ["chown", "chgrp"] true_binary = find_binary("true") self.assertEqual(true_binary is None, False, "true command not found") try: for d in dirs: ensure_dirs(d) for x in true_symlinks: os.symlink(true_binary, os.path.join(fake_bin, x)) with open(os.path.join(var_cache_edb, "counter"), 'wb') as f: f.write(b"100") # non-empty system set keeps --unmerge quiet with open(os.path.join(profile_path, "packages"), 'w') as f: f.write("*dev-libs/token-system-pkg") if debug: # The subprocess inherits both stdout and stderr, for # debugging purposes. stdout = None else: # The subprocess inherits stderr so that any warnings # triggered by python -Wd will be visible. stdout = subprocess.PIPE for i, args in enumerate(test_commands): if hasattr(args[0], '__call__'): self.assertTrue(args[0](), "callable at index %s failed" % (i,)) continue if isinstance(args[0], dict): local_env = env.copy() local_env.update(args[0]) args = args[1:] else: local_env = env proc = subprocess.Popen(args, env=local_env, stdout=stdout) if debug: proc.wait() else: output = proc.stdout.readlines() proc.wait() proc.stdout.close() if proc.returncode != os.EX_OK: for line in output: sys.stderr.write(_unicode_decode(line)) self.assertEqual(os.EX_OK, proc.returncode, "emerge failed with args %s" % (args,)) finally: playground.debug = False playground.cleanup()
def testSlotOperatorCompleteGraph(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:= app-misc/B", "RDEPEND": "dev-libs/foo:= app-misc/B", }, "app-misc/C-2" : { "EAPI": "6", "DEPEND": "dev-libs/foo:= app-misc/B", "RDEPEND": "dev-libs/foo:= app-misc/B", }, "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= app-misc/B", "RDEPEND": "dev-libs/foo:0/1= app-misc/B", }, "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 = ( # Test bug 614390, where the depgraph._complete_graph # method pulled in an installed package that had been # scheduled for rebuild by the previous calculation, # triggering an unsolved slot conflict and preventing # slot operator rebuilds. ResolverPlaygroundTestCase( ["=app-misc/meta-pkg-2", "app-misc/C"], 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()
def testSonameSlotConflictUpdate(self): binpkgs = { "app-text/podofo-0.9.2": { "RDEPEND": "dev-util/boost-build", }, "dev-cpp/libcmis-0.3.1": { "DEPEND": "dev-libs/boost", "RDEPEND": "dev-libs/boost", "REQUIRES": "x86_32: libboost-1.53.so", }, "dev-libs/boost-1.53.0": { "PROVIDES": "x86_32: libboost-1.53.so", "RDEPEND": "=dev-util/boost-build-1.53.0", }, "dev-libs/boost-1.52.0": { "PROVIDES": "x86_32: libboost-1.52.so", "RDEPEND": "=dev-util/boost-build-1.52.0", }, "dev-util/boost-build-1.53.0": {}, "dev-util/boost-build-1.52.0": {}, } installed = { "app-text/podofo-0.9.2": { "RDEPEND": "dev-util/boost-build", }, "dev-cpp/libcmis-0.3.1": { "DEPEND": "dev-libs/boost", "RDEPEND": "dev-libs/boost", "REQUIRES": "x86_32: libboost-1.52.so", }, "dev-util/boost-build-1.52.0": {}, "dev-libs/boost-1.52.0": { "PROVIDES": "x86_32: libboost-1.52.so", "RDEPEND": "=dev-util/boost-build-1.52.0", }, } world = [ "dev-cpp/libcmis", "dev-libs/boost", "app-text/podofo", ] test_cases = ( ResolverPlaygroundTestCase( world, all_permutations=True, options={ "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[ "[binary]dev-util/boost-build-1.53.0", "[binary]dev-libs/boost-1.53.0", "[binary]dev-cpp/libcmis-0.3.1", ], ), ResolverPlaygroundTestCase( world, all_permutations=True, options={ "--deep": True, "--ignore-soname-deps": "y", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[ "[binary]dev-util/boost-build-1.53.0", "[binary]dev-libs/boost-1.53.0", ], ), ) playground = ResolverPlayground(binpkgs=binpkgs, installed=installed, world=world, debug=False) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testConflictMissedUpdate(self): ebuilds = { "dev-lang/ocaml-4.02.1" : { "EAPI": "5", "SLOT": "0/4.02.1", }, "dev-lang/ocaml-4.01.0" : { "EAPI": "5", "SLOT": "0/4.01.0", }, "dev-ml/lablgl-1.05" : { "EAPI": "5", "DEPEND": (">=dev-lang/ocaml-3.10.2:= " "|| ( dev-ml/labltk:= <dev-lang/ocaml-4.02 )"), "RDEPEND": (">=dev-lang/ocaml-3.10.2:= " "|| ( dev-ml/labltk:= <dev-lang/ocaml-4.02 )"), }, "dev-ml/labltk-8.06.0" : { "EAPI": "5", "SLOT": "0/8.06.0", "DEPEND": ">=dev-lang/ocaml-4.02:=", "RDEPEND": ">=dev-lang/ocaml-4.02:=", }, } installed = { "dev-lang/ocaml-4.01.0" : { "EAPI": "5", "SLOT": "0/4.01.0", }, "dev-ml/lablgl-1.05" : { "EAPI": "5", "DEPEND": (">=dev-lang/ocaml-3.10.2:0/4.01.0= " "|| ( dev-ml/labltk:= <dev-lang/ocaml-4.02 )"), "RDEPEND": (">=dev-lang/ocaml-3.10.2:0/4.01.0= " "|| ( dev-ml/labltk:= <dev-lang/ocaml-4.02 )"), }, } world = ( "dev-lang/ocaml", "dev-ml/lablgl", ) test_cases = ( # bug #531656: If an ocaml update is desirable, # then we need to pull in dev-ml/labltk. ResolverPlaygroundTestCase( ["@world"], options = {"--update": True, "--deep": True}, success = True, mergelist = [ "dev-lang/ocaml-4.02.1", "dev-ml/labltk-8.06.0", "dev-ml/lablgl-1.05", ] ), ) 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()
def testVirtualMinimizeChildren(self): ebuilds = { 'app-misc/bar-1': { 'EAPI': '6', 'RDEPEND': 'virtual/foo' }, 'virtual/foo-1': { 'EAPI': '6', 'RDEPEND': '|| ( app-misc/A app-misc/B ) || ( app-misc/B app-misc/C )' }, 'app-misc/A-1': { 'EAPI': '6', }, 'app-misc/B-1': { 'EAPI': '6', }, 'app-misc/C-1': { 'EAPI': '6', }, } test_cases = ( # Test bug 632026, where we want to minimize the number of # packages chosen to satisfy overlapping || deps like # "|| ( foo bar ) || ( bar baz )". ResolverPlaygroundTestCase( ['app-misc/bar'], success=True, mergelist=[ 'app-misc/B-1', 'virtual/foo-1', 'app-misc/bar-1', ], ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup() # If app-misc/A and app-misc/C are installed then # that choice should be preferred over app-misc/B. installed = { 'app-misc/A-1': { 'EAPI': '6', }, 'app-misc/C-1': { 'EAPI': '6', }, } test_cases = ( ResolverPlaygroundTestCase( ['app-misc/bar'], success=True, mergelist=[ 'virtual/foo-1', 'app-misc/bar-1', ], ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds, installed=installed) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSingleSlot(self): ebuilds = { "dev-libs/icu-49": {}, "dev-libs/icu-4.8": {}, "dev-libs/libxml2-2.7.8": { "DEPEND": "dev-libs/icu", "RDEPEND": "dev-libs/icu", }, } binpkgs = { "dev-libs/icu-49": { "PROVIDES": "x86_32: libicu.so.49", }, "dev-libs/icu-4.8": { "PROVIDES": "x86_32: libicu.so.48", }, "dev-libs/libxml2-2.7.8": { "DEPEND": "dev-libs/icu", "RDEPEND": "dev-libs/icu", "REQUIRES": "x86_32: libicu.so.48", }, } installed = { "dev-libs/icu-49": { "PROVIDES": "x86_32: libicu.so.49", }, "dev-libs/libxml2-2.7.8": { "DEPEND": "dev-libs/icu", "RDEPEND": "dev-libs/icu", "REQUIRES": "x86_32: libicu.so.49", }, } user_config = { "package.mask": (">=dev-libs/icu-49", ), } world = ["dev-libs/libxml2"] test_cases = ( ResolverPlaygroundTestCase( ["dev-libs/icu"], options={ "--autounmask": "n", "--ignore-soname-deps": "n", "--oneshot": True, "--usepkgonly": True, }, success=True, mergelist=[ "[binary]dev-libs/icu-4.8", "[binary]dev-libs/libxml2-2.7.8", ], ), ResolverPlaygroundTestCase( ["dev-libs/icu"], options={ "--autounmask": "n", "--ignore-soname-deps": "y", "--oneshot": True, "--usepkgonly": True, }, success=True, mergelist=[ "[binary]dev-libs/icu-4.8", ], ), ResolverPlaygroundTestCase( ["@world"], options={ "--autounmask": "n", "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[ "[binary]dev-libs/icu-4.8", "[binary]dev-libs/libxml2-2.7.8", ], ), # In this case, soname dependencies are not respected, # because --usepkgonly is not enabled. This could be # handled differently, by respecting soname dependencies # as long as no unbuilt ebuilds get pulled into the graph. # However, that kind of conditional dependency accounting # would add a significant amount of complexity. ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkg": True, }, success=True, mergelist=[ "[binary]dev-libs/icu-4.8", ], ), ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--update": True, }, success=True, mergelist=[ "dev-libs/icu-4.8", ], ), ) for binpkg_format in SUPPORTED_GENTOO_BINPKG_FORMATS: with self.subTest(binpkg_format=binpkg_format): print(colorize("HILITE", binpkg_format), end=" ... ") sys.stdout.flush() user_config["make.conf"] = ('BINPKG_FORMAT="%s"' % binpkg_format, ) playground = ResolverPlayground( binpkgs=binpkgs, ebuilds=ebuilds, installed=installed, user_config=user_config, world=world, debug=False, ) 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()
def testOrDowngradeInstalled(self): ebuilds = { 'net-misc/foo-1': { 'EAPI': '6', 'RDEPEND': '|| ( sys-libs/glibc[rpc(-)] net-libs/libtirpc )' }, 'net-libs/libtirpc-1': { 'EAPI': '6', }, 'sys-libs/glibc-2.26': { 'EAPI': '6', 'IUSE': '' }, 'sys-libs/glibc-2.24': { 'EAPI': '6', 'IUSE': '+rpc' }, } installed = { 'sys-libs/glibc-2.26': { 'EAPI': '6', 'IUSE': '' }, } world = ['sys-libs/glibc'] test_cases = ( # Test bug 635540, where we need to install libtirpc # rather than downgrade glibc. ResolverPlaygroundTestCase( ['net-misc/foo'], success=True, mergelist=[ 'net-libs/libtirpc-1', 'net-misc/foo-1', ], ), ) 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: playground.debug = False playground.cleanup() # In some cases it's necessary to downgrade due to # the installed package being masked (glibc is a # not an ideal example because it's usually not # practical to downgrade it). user_config = { "package.mask" : ( ">=sys-libs/glibc-2.26", ), } test_cases = ( ResolverPlaygroundTestCase( ['net-misc/foo'], success=True, mergelist=[ 'sys-libs/glibc-2.24', 'net-misc/foo-1', ], ), ) playground = ResolverPlayground(debug=False, ebuilds=ebuilds, installed=installed, world=world, user_config=user_config) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testSlotOperatorBdepend(self): """ Test regular dev-lang/go upgrade, with rebuild of packages that have dev-lang/go:= in BDEPEND. """ ebuilds = { "app-emulation/buildah-1.16.1": { "EAPI": "7", "BDEPEND": "dev-lang/go:=", }, "app-emulation/libpod-2.1.0": { "EAPI": "7", "BDEPEND": "dev-lang/go:=", }, "dev-lang/go-1.15.5": {"EAPI": "7", "SLOT": "0/1.15.5"}, "dev-lang/go-1.14.12": {"EAPI": "7", "SLOT": "0/1.14.12"}, } binpkgs = { "app-emulation/buildah-1.16.1": { "EAPI": "7", "BDEPEND": "dev-lang/go:0/1.14.12=", }, "app-emulation/libpod-2.1.0": { "EAPI": "7", "BDEPEND": "dev-lang/go:0/1.14.12=", }, "dev-lang/go-1.14.12": {"EAPI": "7", "SLOT": "0/1.14.12"}, } installed = { "app-emulation/buildah-1.16.1": { "EAPI": "7", "BDEPEND": "dev-lang/go:0/1.14.12=", }, "app-emulation/libpod-2.1.0": { "EAPI": "7", "BDEPEND": "dev-lang/go:0/1.14.12=", }, "dev-lang/go-1.14.12": {"EAPI": "7", "SLOT": "0/1.14.12"}, } world = ["app-emulation/buildah", "app-emulation/libpod"] test_cases = ( # Test rebuild triggered by slot operator := dependency in BDEPEND. ResolverPlaygroundTestCase( ["@world"], options={ "--update": True, "--deep": True, }, success=True, mergelist=[ "dev-lang/go-1.15.5", "app-emulation/buildah-1.16.1", "app-emulation/libpod-2.1.0", ], ), # Test the above case with --usepkg --with-bdeps=y. It should not use the # binary packages because rebuild is needed. ResolverPlaygroundTestCase( ["@world"], options={ "--usepkg": True, "--with-bdeps": "y", "--update": True, "--deep": True, }, success=True, mergelist=[ "dev-lang/go-1.15.5", "app-emulation/buildah-1.16.1", "app-emulation/libpod-2.1.0", ], ), ) playground = ResolverPlayground( ebuilds=ebuilds, binpkgs=binpkgs, installed=installed, world=world, debug=False, ) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual(test_case.test_success, True, test_case.fail_msg) finally: playground.debug = False playground.cleanup()
def testAutounmaskBinpkgUse(self): ebuilds = { "dev-libs/A-1": { "EAPI": "6", "DEPEND": "dev-libs/B[foo]", "RDEPEND": "dev-libs/B[foo]", }, "dev-libs/B-1": { "EAPI": "6", "IUSE": "foo", }, } binpkgs = { "dev-libs/A-1": { "EAPI": "6", "DEPEND": "dev-libs/B[foo]", "RDEPEND": "dev-libs/B[foo]", }, "dev-libs/B-1": { "EAPI": "6", "IUSE": "foo", "USE": "foo", }, } installed = {} test_cases = ( # Bug 619626: Test for unnecessary rebuild due # to rejection of binary packages that would # be acceptable after appplication of autounmask # USE changes. ResolverPlaygroundTestCase( ["dev-libs/A"], all_permutations=True, success=True, options={ "--usepkg": True, }, mergelist=[ "[binary]dev-libs/B-1", "[binary]dev-libs/A-1", ], use_changes={"dev-libs/B-1": {"foo": True}}, ), ) for binpkg_format in SUPPORTED_GENTOO_BINPKG_FORMATS: with self.subTest(binpkg_format=binpkg_format): print(colorize("HILITE", binpkg_format), end=" ... ") sys.stdout.flush() playground = ResolverPlayground( ebuilds=ebuilds, binpkgs=binpkgs, installed=installed, debug=False, user_config={ "make.conf": ('BINPKG_FORMAT="%s"' % binpkg_format,), }, ) try: for test_case in test_cases: playground.run_TestCase(test_case) self.assertEqual( test_case.test_success, True, test_case.fail_msg ) finally: playground.debug = False playground.cleanup()
def testImageMagickUpdate(self): ebuilds = { "app-misc/A-1": { "EAPI": "6", "DEPEND": "app-misc/B", "RDEPEND": "app-misc/C", }, "app-misc/B-1": {"EAPI": "6"}, "app-misc/B-2": { "EAPI": "6", }, "app-misc/C-1": { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/C-2": { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/D-1": { "EAPI": "6", }, "app-misc/D-2": { "EAPI": "6", }, } installed = { "app-misc/A-1": { "EAPI": "6", "DEPEND": "app-misc/B", "RDEPEND": "app-misc/C", }, "app-misc/B-1": { "EAPI": "6", }, "app-misc/C-1": { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/D-1": { "EAPI": "6", }, } binpkgs = { "app-misc/A-1": { "EAPI": "6", "DEPEND": "app-misc/B", "RDEPEND": "app-misc/C", }, "app-misc/B-1": { "EAPI": "6", }, "app-misc/B-2": { "EAPI": "6", }, "app-misc/C-1": { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/C-2": { "EAPI": "6", "DEPEND": "app-misc/D", }, "app-misc/D-1": { "EAPI": "6", }, "app-misc/D-2": { "EAPI": "6", }, } world = ("app-misc/A",) test_cases = ( # Enable --with-bdeps automatically when # --usepkg has not been specified. ResolverPlaygroundTestCase( ["@world"], options={ "--update": True, "--deep": True, }, success=True, ambiguous_merge_order=True, mergelist=[ "app-misc/D-2", ("app-misc/B-2", "app-misc/C-2"), ], ), # Use --with-bdeps-auto=n to prevent --with-bdeps # from being enabled automatically. ResolverPlaygroundTestCase( ["@world"], options={ "--update": True, "--deep": True, "--with-bdeps-auto": "n", }, success=True, mergelist=[ "app-misc/D-2", "app-misc/C-2", ], ), # Do not enable --with-bdeps automatically when # --usepkg has been specified, since many users of binary # packages do not want unnecessary build time dependencies # installed. In this case we miss an update to # app-misc/D-2, since DEPEND is not pulled in for # the [binary]app-misc/C-2 update. ResolverPlaygroundTestCase( ["@world"], options={ "--update": True, "--deep": True, "--usepkg": True, }, success=True, mergelist=[ "[binary]app-misc/C-2", ], ), # Use --with-bdeps=y to pull in build-time dependencies of # binary packages. ResolverPlaygroundTestCase( ["@world"], options={ "--update": True, "--deep": True, "--usepkg": True, "--with-bdeps": "y", }, success=True, ambiguous_merge_order=True, mergelist=[ ( "[binary]app-misc/D-2", "[binary]app-misc/B-2", "[binary]app-misc/C-2", ), ], ), # For --depclean, do not remove build-time dependencies by # default. Specify --with-bdeps-auto=n, in order to # demonstrate that it does not affect removal actions. ResolverPlaygroundTestCase( [], options={ "--depclean": True, "--with-bdeps-auto": "n", }, success=True, cleanlist=[], ), # For --depclean, remove build-time dependencies if # --with-bdeps=n has been specified. ResolverPlaygroundTestCase( [], options={ "--depclean": True, "--with-bdeps": "n", }, success=True, ignore_cleanlist_order=True, cleanlist=[ "app-misc/D-1", "app-misc/B-1", ], ), ) for binpkg_format in SUPPORTED_GENTOO_BINPKG_FORMATS: with self.subTest(binpkg_format=binpkg_format): print(colorize("HILITE", binpkg_format), end=" ... ") sys.stdout.flush() playground = ResolverPlayground( debug=False, ebuilds=ebuilds, installed=installed, binpkgs=binpkgs, world=world, user_config={ "make.conf": ('BINPKG_FORMAT="%s"' % binpkg_format,), }, ) 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()
def testSonameReinstall(self): binpkgs = { "app-misc/A-1": { "RDEPEND": "dev-libs/B", "DEPEND": "dev-libs/B", "REQUIRES": "x86_32: libB.so.2", }, "dev-libs/B-2": { "PROVIDES": "x86_32: libB.so.2", }, "dev-libs/B-1": { "PROVIDES": "x86_32: libB.so.1", }, } installed = { "app-misc/A-1": { "RDEPEND": "dev-libs/B", "DEPEND": "dev-libs/B", "REQUIRES": "x86_32: libB.so.1", }, "dev-libs/B-1": { "PROVIDES": "x86_32: libB.so.1", }, } world = ("app-misc/A", ) test_cases = ( # Test that --ignore-soname-deps prevents the above # rebuild from being triggered. ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[ "[binary]dev-libs/B-2", "[binary]app-misc/A-1", ], ), # Test that --ignore-soname-deps prevents the above # reinstall from being triggered. ResolverPlaygroundTestCase( ["@world"], options={ "--deep": True, "--ignore-soname-deps": "y", "--update": True, "--usepkgonly": True, }, success=True, mergelist=[ "[binary]dev-libs/B-2", ], ), ) playground = ResolverPlayground(debug=False, binpkgs=binpkgs, 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()
def testSonameUnsatisfied(self): binpkgs = { "app-misc/A-1" : { "EAPI": "5", "PROVIDES": "x86_32: libA.so.1", }, "app-misc/A-2" : { "EAPI": "5", "PROVIDES": "x86_32: libA.so.2", }, "app-misc/B-0" : { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.2", } } installed = { "app-misc/A-2" : { "EAPI": "5", "PROVIDES": "x86_32: libA.so.2", }, "app-misc/B-0" : { "DEPEND": "app-misc/A", "RDEPEND": "app-misc/A", "REQUIRES": "x86_32: libA.so.1", } } world = ["app-misc/B"] test_cases = ( # Demonstrate bug #439694, where a broken # soname dependency needs to trigger a reinstall. ResolverPlaygroundTestCase( ["@world"], options = { "--deep": True, "--ignore-soname-deps": "n", "--update": True, "--usepkgonly": True, }, success = True, mergelist = [ "[binary]app-misc/B-0" ] ), # This doesn't trigger a reinstall, since there's no version # change to trigger complete graph mode, and initially # unsatisfied deps are ignored in complete graph mode anyway. ResolverPlaygroundTestCase( ["app-misc/A"], options = { "--ignore-soname-deps": "n", "--oneshot": True, "--usepkgonly": True, }, success = True, mergelist = [ "[binary]app-misc/A-2" ] ), ) playground = ResolverPlayground(binpkgs=binpkgs, debug=False, 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()