예제 #1
0
    def testSlotAbiEmerge(self):

        debug = False

        ebuilds = {
            "dev-libs/glib-1.2.10": {
                "SLOT": "1"
            },
            "dev-libs/glib-2.30.2": {
                "EAPI": "4-slot-abi",
                "SLOT": "2/2.30"
            },
            "dev-libs/glib-2.32.3": {
                "EAPI": "4-slot-abi",
                "SLOT": "2/2.32"
            },
            "dev-libs/dbus-glib-0.98": {
                "EAPI": "4-slot-abi",
                "DEPEND": "dev-libs/glib:2=",
                "RDEPEND": "dev-libs/glib:2="
            },
        }
        installed = {
            "dev-libs/glib-1.2.10": {
                "EAPI": "4-slot-abi",
                "SLOT": "1"
            },
            "dev-libs/glib-2.30.2": {
                "EAPI": "4-slot-abi",
                "SLOT": "2/2.30"
            },
            "dev-libs/dbus-glib-0.98": {
                "EAPI": "4-slot-abi",
                "DEPEND": "dev-libs/glib:2/2.30=",
                "RDEPEND": "dev-libs/glib:2/2.30="
            },
        }

        world = ["dev-libs/glib:1", "dev-libs/dbus-glib"]

        playground = ResolverPlayground(ebuilds=ebuilds,
                                        installed=installed,
                                        world=world,
                                        debug=debug)
        settings = playground.settings
        eprefix = settings["EPREFIX"]
        eroot = settings["EROOT"]
        trees = playground.trees
        portdb = trees[eroot]["porttree"].dbapi
        vardb = trees[eroot]["vartree"].dbapi
        portdir = settings["PORTDIR"]
        var_cache_edb = os.path.join(eprefix, "var", "cache", "edb")
        user_config_dir = os.path.join(eprefix, USER_CONFIG_PATH)
        package_mask_path = os.path.join(user_config_dir, "package.mask")

        portage_python = portage._python_interpreter
        ebuild_cmd = (portage_python, "-Wd",
                      os.path.join(PORTAGE_BIN_PATH, "ebuild"))
        emerge_cmd = (portage_python, "-Wd",
                      os.path.join(PORTAGE_BIN_PATH, "emerge"))

        test_ebuild = portdb.findname("dev-libs/dbus-glib-0.98")
        self.assertFalse(test_ebuild is None)

        test_commands = (
            emerge_cmd + (
                "--oneshot",
                "dev-libs/glib",
            ),
            (lambda: "dev-libs/glib:2/2.32=" in vardb.aux_get(
                "dev-libs/dbus-glib-0.98", ["RDEPEND"])[0], ),
            (BASH_BINARY, "-c", "echo %s >> %s" % tuple(
                map(portage._shell_quote, (
                    ">=dev-libs/glib-2.32",
                    package_mask_path,
                )))),
            emerge_cmd + (
                "--oneshot",
                "dev-libs/glib",
            ),
            (lambda: "dev-libs/glib:2/2.30=" in vardb.aux_get(
                "dev-libs/dbus-glib-0.98", ["RDEPEND"])[0], ),
        )

        distdir = playground.distdir
        pkgdir = playground.pkgdir
        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,
            "PYTHONPATH": pythonpath,
        }

        if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ:
            env["__PORTAGE_TEST_HARDLINK_LOCKS"] = \
             os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"]

        dirs = [
            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

                proc = subprocess.Popen(args, env=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.cleanup()
예제 #2
0
    def testCircularJsoncppCmakeBootstrapOrDeps(self):

        ebuilds = {
            'dev-libs/jsoncpp-1.9.2': {
                'EAPI': '7',
                'BDEPEND': '|| ( dev-util/cmake-bootstrap dev-util/cmake )'
            },
            'dev-util/cmake-bootstrap-3.16.2': {
                'EAPI': '7',
            },
            'dev-util/cmake-3.16.2': {
                'EAPI': '7',
                'BDEPEND': '>=dev-libs/jsoncpp-0.6.0_rc2:0=',
            },
        }

        test_cases = (
            # Demonstrate bug 703440. It ignores cmake-bootstrap in order to eliminate redundant packages.
            #
            #  * Error: circular dependencies:
            #
            # (dev-libs/jsoncpp-1.9.2:0/0::test_repo, ebuild scheduled for merge) depends on
            #  (dev-util/cmake-3.16.2:0/0::test_repo, ebuild scheduled for merge) (buildtime)
            #    (dev-libs/jsoncpp-1.9.2:0/0::test_repo, ebuild scheduled for merge) (buildtime_slot_op)
            ResolverPlaygroundTestCase(
                ['dev-util/cmake'],
                options={"--backtrack": 0},
                circular_dependency_solutions={},
                success=False,
            ),
            # Demonstrate that backtracking adjusts || preferences in order to solve bug 703440.
            ResolverPlaygroundTestCase(
                ['dev-util/cmake'],
                mergelist=[
                    'dev-util/cmake-bootstrap-3.16.2',
                    'dev-libs/jsoncpp-1.9.2', 'dev-util/cmake-3.16.2'
                ],
                success=True,
            ),
        )

        playground = ResolverPlayground(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.cleanup()

        test_cases = (
            # Demonstrate elimination of cmake-bootstrap via --depclean.
            ResolverPlaygroundTestCase(
                [],
                options={'--depclean': True},
                success=True,
                cleanlist=['dev-util/cmake-bootstrap-3.16.2'],
            ), )

        playground = ResolverPlayground(ebuilds=ebuilds,
                                        installed=ebuilds,
                                        world=['dev-util/cmake'])
        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.cleanup()
예제 #3
0
    def testPackageMaskOrder(self):

        ebuilds = {
            "dev-libs/A-1": {},
            "dev-libs/B-1": {},
            "dev-libs/C-1": {},
            "dev-libs/D-1": {},
            "dev-libs/E-1": {},
        }

        repo_configs = {
            "test_repo": {
                "package.mask": (
                    "dev-libs/A",
                    "dev-libs/C",
                ),
            }
        }

        profile = {
            "package.mask": (
                "-dev-libs/A",
                "dev-libs/B",
                "-dev-libs/B",
                "dev-libs/D",
            ),
        }

        user_config = {
            "package.mask": (
                "-dev-libs/C",
                "-dev-libs/D",
                "dev-libs/E",
            ),
        }

        test_cases = (
            ResolverPlaygroundTestCase(["dev-libs/A"],
                                       options={"--autounmask": "n"},
                                       success=False),
            ResolverPlaygroundTestCase(["dev-libs/B"],
                                       success=True,
                                       mergelist=["dev-libs/B-1"]),
            ResolverPlaygroundTestCase(["dev-libs/C"],
                                       success=True,
                                       mergelist=["dev-libs/C-1"]),
            ResolverPlaygroundTestCase(["dev-libs/D"],
                                       success=True,
                                       mergelist=["dev-libs/D-1"]),
            ResolverPlaygroundTestCase(["dev-libs/E"],
                                       options={"--autounmask": "n"},
                                       success=False),
        )

        playground = ResolverPlayground(
            ebuilds=ebuilds,
            repo_configs=repo_configs,
            profile=profile,
            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.cleanup()
예제 #4
0
    def testSyncLocal(self):
        debug = False

        skip_reason = self._must_skip()
        if skip_reason:
            self.portage_skip = skip_reason
            self.assertFalse(True, skip_reason)
            return

        repos_conf = textwrap.dedent("""
			[DEFAULT]
			%(default_keys)s
			[test_repo]
			location = %(EPREFIX)s/var/repositories/test_repo
			sync-type = %(sync-type)s
			sync-uri = file:/%(EPREFIX)s/var/repositories/test_repo_sync
			auto-sync = yes
			%(repo_extra_keys)s
		""")

        profile = {
            "eapi": ("5", ),
            "package.use.stable.mask": ("dev-libs/A flag", )
        }

        ebuilds = {"dev-libs/A-0": {}}

        user_config = {'make.conf': ('FEATURES="metadata-transfer"', )}

        playground = ResolverPlayground(ebuilds=ebuilds,
                                        profile=profile,
                                        user_config=user_config,
                                        debug=debug)
        settings = playground.settings
        eprefix = settings["EPREFIX"]
        eroot = settings["EROOT"]
        homedir = os.path.join(eroot, "home")
        distdir = os.path.join(eprefix, "distdir")
        repo = settings.repositories["test_repo"]
        metadata_dir = os.path.join(repo.location, "metadata")

        cmds = {}
        for cmd in ("emerge", "emaint"):
            cmds[cmd] = (portage._python_interpreter, "-b", "-Wd",
                         os.path.join(self.bindir, cmd))

        git_binary = find_binary("git")
        git_cmd = (git_binary, )

        committer_name = "Gentoo Dev"
        committer_email = "*****@*****.**"

        def repos_set_conf(sync_type, dflt_keys=None, xtra_keys=None):
            env["PORTAGE_REPOSITORIES"] = repos_conf % {\
             "EPREFIX": eprefix, "sync-type": sync_type,
             "default_keys": "" if dflt_keys is None else dflt_keys,
             "repo_extra_keys": "" if xtra_keys is None else xtra_keys}

        def alter_ebuild():
            with open(
                    os.path.join(repo.location + "_sync", "dev-libs", "A",
                                 "A-0.ebuild"), "a") as f:
                f.write("\n")
            os.unlink(os.path.join(metadata_dir, 'timestamp.chk'))

        sync_cmds = (
            (homedir, cmds["emerge"] + ("--sync", )),
            (homedir, lambda: self.assertTrue(
                os.path.exists(os.path.join(repo.location, "dev-libs", "A")),
                "dev-libs/A expected, but missing")),
            (homedir, cmds["emaint"] + ("sync", "-A")),
        )

        rename_repo = (
            (homedir,
             lambda: os.rename(repo.location, repo.location + "_sync")), )

        rsync_opts_repos = (
            (homedir, alter_ebuild),
            (homedir, lambda: repos_set_conf(
                "rsync", None,
                "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back"))),
            (homedir, cmds['emerge'] + ("--sync", )),
            (homedir,
             lambda: self.assertTrue(os.path.exists(repo.location + "_back"))),
            (homedir, lambda: shutil.rmtree(repo.location + "_back")),
            (homedir, lambda: repos_set_conf("rsync")),
        )

        rsync_opts_repos_default = (
            (homedir, alter_ebuild),
            (homedir, lambda: repos_set_conf(
                "rsync", "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back"))),
            (homedir, cmds['emerge'] + ("--sync", )),
            (homedir,
             lambda: self.assertTrue(os.path.exists(repo.location + "_back"))),
            (homedir, lambda: shutil.rmtree(repo.location + "_back")),
            (homedir, lambda: repos_set_conf("rsync")),
        )

        rsync_opts_repos_default_ovr = (
            (homedir, alter_ebuild),
            (homedir, lambda: repos_set_conf(
                "rsync", "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back_nowhere"),
                "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back"))),
            (homedir, cmds['emerge'] + ("--sync", )),
            (homedir,
             lambda: self.assertTrue(os.path.exists(repo.location + "_back"))),
            (homedir, lambda: shutil.rmtree(repo.location + "_back")),
            (homedir, lambda: repos_set_conf("rsync")),
        )

        rsync_opts_repos_default_cancel = (
            (homedir, alter_ebuild),
            (homedir, lambda: repos_set_conf(
                "rsync", "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back_nowhere"
                             ), "sync-rsync-extra-opts = ")),
            (homedir, cmds['emerge'] + ("--sync", )),
            (homedir,
             lambda: self.assertFalse(os.path.exists(repo.location + "_back"))
             ),
            (homedir, lambda: repos_set_conf("rsync")),
        )

        delete_sync_repo = ((homedir,
                             lambda: shutil.rmtree(repo.location + "_sync")), )

        git_repo_create = (
            (repo.location, git_cmd + (
                "config",
                "--global",
                "user.name",
                committer_name,
            )),
            (repo.location, git_cmd + (
                "config",
                "--global",
                "user.email",
                committer_email,
            )),
            (repo.location, git_cmd + ("init-db", )),
            (repo.location, git_cmd + ("add", ".")),
            (repo.location,
             git_cmd + ("commit", "-a", "-m", "add whole repo")),
        )

        sync_type_git = ((homedir, lambda: repos_set_conf("git")), )

        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,
            "DISTDIR":
            distdir,
            "GENTOO_COMMITTER_NAME":
            committer_name,
            "GENTOO_COMMITTER_EMAIL":
            committer_email,
            "HOME":
            homedir,
            "PATH":
            os.environ["PATH"],
            "PORTAGE_GRPNAME":
            os.environ["PORTAGE_GRPNAME"],
            "PORTAGE_USERNAME":
            os.environ["PORTAGE_USERNAME"],
            "PYTHONDONTWRITEBYTECODE":
            os.environ.get("PYTHONDONTWRITEBYTECODE", ""),
            "PYTHONPATH":
            pythonpath,
        }
        repos_set_conf("rsync")

        if os.environ.get("SANDBOX_ON") == "1":
            # avoid problems from nested sandbox instances
            env["FEATURES"] = "-sandbox -usersandbox"

        dirs = [homedir, metadata_dir]
        try:
            for d in dirs:
                ensure_dirs(d)

            timestamp_path = os.path.join(metadata_dir, 'timestamp.chk')
            with open(timestamp_path, 'w') as f:
                f.write(time.strftime('%s\n' % TIMESTAMP_FORMAT,
                                      time.gmtime()))

            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 cwd, cmd in rename_repo + sync_cmds + \
             rsync_opts_repos + rsync_opts_repos_default + \
             rsync_opts_repos_default_ovr + rsync_opts_repos_default_cancel + \
             delete_sync_repo + git_repo_create + sync_type_git + \
             rename_repo + sync_cmds:

                if hasattr(cmd, '__call__'):
                    cmd()
                    continue

                abs_cwd = os.path.join(repo.location, cwd)
                proc = subprocess.Popen(cmd,
                                        cwd=abs_cwd,
                                        env=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,
                                 "%s failed in %s" % (
                                     cmd,
                                     cwd,
                                 ))

        finally:
            playground.cleanup()
예제 #5
0
    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()
예제 #6
0
    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()
예제 #7
0
    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()
예제 #8
0
    def testDoebuild(self):
        """
		Invoke portage.doebuild() with the fd_pipes parameter, and
		check that the expected output appears in the pipe. This
		functionality is not used by portage internally, but it is
		supported for API consumers (see bug #475812).
		"""

        output_fd = 200
        ebuild_body = ['S=${WORKDIR}']
        for phase_func in ('pkg_info', 'pkg_nofetch', 'pkg_pretend',
                           'pkg_setup', 'src_unpack', 'src_prepare',
                           'src_configure', 'src_compile', 'src_test',
                           'src_install'):
            ebuild_body.append(('%s() { echo ${EBUILD_PHASE}'
                                ' 1>&%s; }') % (phase_func, output_fd))

        ebuild_body.append('')
        ebuild_body = '\n'.join(ebuild_body)

        ebuilds = {
            'app-misct/foo-1': {
                'EAPI': '5',
                "MISC_CONTENT": ebuild_body,
            }
        }

        # Override things that may be unavailable, or may have portability
        # issues when running tests in exotic environments.
        #   prepstrip - bug #447810 (bash read builtin EINTR problem)
        true_symlinks = ("find", "prepstrip", "sed", "scanelf")
        true_binary = portage.process.find_binary("true")
        self.assertEqual(true_binary is None, False, "true command not found")

        dev_null = open(os.devnull, 'wb')
        playground = ResolverPlayground(ebuilds=ebuilds)
        try:
            QueryCommand._db = playground.trees
            root_config = playground.trees[playground.eroot]['root_config']
            portdb = root_config.trees["porttree"].dbapi
            settings = portage.config(clone=playground.settings)
            if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ:
                settings["__PORTAGE_TEST_HARDLINK_LOCKS"] = \
                 os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"]
                settings.backup_changes("__PORTAGE_TEST_HARDLINK_LOCKS")

            settings.features.add("noauto")
            settings.features.add("test")
            settings['PORTAGE_PYTHON'] = portage._python_interpreter
            settings['PORTAGE_QUIET'] = "1"
            settings['PYTHONDONTWRITEBYTECODE'] = os.environ.get(
                "PYTHONDONTWRITEBYTECODE", "")

            fake_bin = os.path.join(settings["EPREFIX"], "bin")
            portage.util.ensure_dirs(fake_bin)
            for x in true_symlinks:
                os.symlink(true_binary, os.path.join(fake_bin, x))

            settings["__PORTAGE_TEST_PATH_OVERRIDE"] = fake_bin
            settings.backup_changes("__PORTAGE_TEST_PATH_OVERRIDE")

            cpv = 'app-misct/foo-1'
            metadata = dict(
                zip(Package.metadata_keys,
                    portdb.aux_get(cpv, Package.metadata_keys)))

            pkg = Package(built=False,
                          cpv=cpv,
                          installed=False,
                          metadata=metadata,
                          root_config=root_config,
                          type_name='ebuild')
            settings.setcpv(pkg)
            ebuildpath = portdb.findname(cpv)
            self.assertNotEqual(ebuildpath, None)

            for phase in ('info', 'nofetch', 'pretend', 'setup', 'unpack',
                          'prepare', 'configure', 'compile', 'test', 'install',
                          'qmerge', 'clean', 'merge'):

                pr, pw = os.pipe()

                producer = DoebuildProcess(doebuild_pargs=(ebuildpath, phase),
                                           doebuild_kwargs={
                                               "settings":
                                               settings,
                                               "mydbapi":
                                               portdb,
                                               "tree":
                                               "porttree",
                                               "vartree":
                                               root_config.trees["vartree"],
                                               "fd_pipes": {
                                                   1: dev_null.fileno(),
                                                   2: dev_null.fileno(),
                                                   output_fd: pw,
                                               },
                                               "prev_mtimes": {}
                                           })

                consumer = PipeReader(input_files={"producer": pr})

                task_scheduler = TaskScheduler(iter([producer, consumer]),
                                               max_jobs=2)

                try:
                    task_scheduler.start()
                finally:
                    # PipeReader closes pr
                    os.close(pw)

                task_scheduler.wait()
                output = portage._unicode_decode(
                    consumer.getvalue()).rstrip("\n")

                if task_scheduler.returncode != os.EX_OK:
                    portage.writemsg(output, noiselevel=-1)

                self.assertEqual(task_scheduler.returncode, os.EX_OK)

                if phase not in ('clean', 'merge', 'qmerge'):
                    self.assertEqual(phase, output)

        finally:
            dev_null.close()
            playground.cleanup()
            QueryCommand._db = None
예제 #9
0
    def testMergelistOutput(self):
        """
		This test doesn't check if the output is correct, but makes sure
		that we don't backtrace somewhere in the output code.
		"""
        ebuilds = {
            "dev-libs/A-1": {
                "DEPEND": "dev-libs/B dev-libs/C",
                "IUSE": "+foo",
                "EAPI": 1
            },
            "dev-libs/B-1": {
                "DEPEND": "dev-libs/D",
                "IUSE": "foo +bar",
                "EAPI": 1
            },
            "dev-libs/C-1": {
                "DEPEND": "dev-libs/E",
                "IUSE": "foo bar"
            },
            "dev-libs/D-1": {
                "IUSE": ""
            },
            "dev-libs/E-1": {},

            #reinstall for flags
            "dev-libs/Z-1": {
                "IUSE": "+foo",
                "EAPI": 1
            },
            "dev-libs/Y-1": {
                "IUSE": "foo",
                "EAPI": 1
            },
            "dev-libs/X-1": {},
            "dev-libs/W-1": {
                "IUSE": "+foo",
                "EAPI": 1
            },
        }

        installed = {
            "dev-libs/Z-1": {
                "USE": "",
                "IUSE": "foo"
            },
            "dev-libs/Y-1": {
                "USE": "foo",
                "IUSE": "+foo",
                "EAPI": 1
            },
            "dev-libs/X-1": {
                "USE": "foo",
                "IUSE": "+foo",
                "EAPI": 1
            },
            "dev-libs/W-1": {},
        }

        option_cobos = (
            (),
            ("verbose", ),
            ("tree", ),
            (
                "tree",
                "unordered-display",
            ),
            ("verbose", ),
            (
                "verbose",
                "tree",
            ),
            (
                "verbose",
                "tree",
                "unordered-display",
            ),
        )

        test_cases = []
        for options in option_cobos:
            testcase_opts = {}
            for opt in options:
                testcase_opts["--" + opt] = True

            test_cases.append(
                ResolverPlaygroundTestCase(["dev-libs/A"],
                                           options=testcase_opts,
                                           success=True,
                                           ignore_mergelist_order=True,
                                           mergelist=[
                                               "dev-libs/D-1", "dev-libs/E-1",
                                               "dev-libs/C-1", "dev-libs/B-1",
                                               "dev-libs/A-1"
                                           ]))

            test_cases.append(
                ResolverPlaygroundTestCase(["dev-libs/Z"],
                                           options=testcase_opts,
                                           success=True,
                                           mergelist=["dev-libs/Z-1"]))

            test_cases.append(
                ResolverPlaygroundTestCase(["dev-libs/Y"],
                                           options=testcase_opts,
                                           success=True,
                                           mergelist=["dev-libs/Y-1"]))

            test_cases.append(
                ResolverPlaygroundTestCase(["dev-libs/X"],
                                           options=testcase_opts,
                                           success=True,
                                           mergelist=["dev-libs/X-1"]))

            test_cases.append(
                ResolverPlaygroundTestCase(["dev-libs/W"],
                                           options=testcase_opts,
                                           success=True,
                                           mergelist=["dev-libs/W-1"]))

        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.cleanup()
예제 #10
0
    def testSlotConflictUpdate(self):

        ebuilds = {
            "app-text/podofo-0.9.2": {
                "EAPI": "5",
                "RDEPEND": "dev-util/boost-build"
            },
            "dev-cpp/libcmis-0.3.1": {
                "EAPI": "5",
                "RDEPEND": "dev-libs/boost:="
            },
            "dev-libs/boost-1.53.0": {
                "EAPI": "5",
                "SLOT": "0/1.53",
                "RDEPEND": "=dev-util/boost-build-1.53.0",
            },
            "dev-libs/boost-1.52.0": {
                "EAPI": "5",
                "SLOT": "0/1.52",
                "RDEPEND": "=dev-util/boost-build-1.52.0",
            },
            "dev-util/boost-build-1.53.0": {
                "EAPI": "5",
                "SLOT": "0"
            },
            "dev-util/boost-build-1.52.0": {
                "EAPI": "5",
                "SLOT": "0"
            },
        }

        installed = {
            "app-text/podofo-0.9.2": {
                "EAPI": "5",
                "RDEPEND": "dev-util/boost-build"
            },
            "dev-cpp/libcmis-0.3.1": {
                "EAPI": "5",
                "RDEPEND": "dev-libs/boost:0/1.52="
            },
            "dev-util/boost-build-1.52.0": {
                "EAPI": "5",
                "SLOT": "0"
            },
            "dev-libs/boost-1.52.0": {
                "EAPI": "5",
                "SLOT": "0/1.52",
                "RDEPEND": "=dev-util/boost-build-1.52.0",
            },
        }

        world = ["dev-cpp/libcmis", "dev-libs/boost", "app-text/podofo"]

        test_cases = (
            # In order to avoid a missed update, first mask lower
            # versions that conflict with higher versions. Note that
            # this behavior makes SlotConflictMaskUpdateTestCase
            # fail.
            ResolverPlaygroundTestCase(
                ["@world"],
                all_permutations=True,
                options={
                    "--update": True,
                    "--deep": True
                },
                success=True,
                mergelist=[
                    "dev-util/boost-build-1.53.0",
                    "dev-libs/boost-1.53.0",
                    "dev-cpp/libcmis-0.3.1",
                ],
            ), )

        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.cleanup()
예제 #11
0
    def testSimple(self):
        debug = False

        skip_reason = self._must_skip()
        if skip_reason:
            self.portage_skip = skip_reason
            self.assertFalse(True, skip_reason)
            return

        copyright_header = """# Copyright 1999-%s Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
""" % time.gmtime().tm_year

        repo_configs = {
            "test_repo": {
                "layout.conf": ("update-changelog = true", ),
            }
        }

        profiles = (
            ("x86", "default/linux/x86/test_profile", "stable"),
            ("x86", "default/linux/x86/test_dev", "dev"),
            ("x86", "default/linux/x86/test_exp", "exp"),
        )

        profile = {
            "eapi": ("5", ),
            "package.use.stable.mask": ("dev-libs/A flag", )
        }

        ebuilds = {
            "dev-libs/A-0": {
                "COPYRIGHT_HEADER": copyright_header,
                "DESCRIPTION": "Desc goes here",
                "EAPI": "5",
                "HOMEPAGE": "http://example.com",
                "IUSE": "flag",
                "KEYWORDS": "x86",
                "LICENSE": "GPL-2",
                "RDEPEND": "flag? ( dev-libs/B[flag] )",
            },
            "dev-libs/A-1": {
                "COPYRIGHT_HEADER": copyright_header,
                "DESCRIPTION": "Desc goes here",
                "EAPI": "4",
                "HOMEPAGE": "http://example.com",
                "IUSE": "flag",
                "KEYWORDS": "~x86",
                "LICENSE": "GPL-2",
                "RDEPEND": "flag? ( dev-libs/B[flag] )",
            },
            "dev-libs/B-1": {
                "COPYRIGHT_HEADER": copyright_header,
                "DESCRIPTION": "Desc goes here",
                "EAPI": "4",
                "HOMEPAGE": "http://example.com",
                "IUSE": "flag",
                "KEYWORDS": "~x86",
                "LICENSE": "GPL-2",
            },
            "dev-libs/C-0": {
                "COPYRIGHT_HEADER": copyright_header,
                "DESCRIPTION": "Desc goes here",
                "EAPI": "4",
                "HOMEPAGE": "http://example.com",
                "IUSE": "flag",
                # must be unstable, since dev-libs/A[flag] is stable masked
                "KEYWORDS": "~x86",
                "LICENSE": "GPL-2",
                "RDEPEND": "flag? ( dev-libs/A[flag] )",
            },
        }
        licenses = ["GPL-2"]
        arch_list = ["x86"]
        metadata_xsd = os.path.join(REPOMAN_BASE_PATH, "cnf/metadata.xsd")
        metadata_xml_files = (
            (
                "dev-libs/A",
                {
                    "flags":
                    "<flag name='flag' restrict='&gt;=dev-libs/A-0'>Description of how USE='flag' affects this package</flag>",
                },
            ),
            (
                "dev-libs/B",
                {
                    "flags":
                    "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
                },
            ),
            (
                "dev-libs/C",
                {
                    "flags":
                    "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
                },
            ),
        )

        use_desc = (("flag",
                     "Description of how USE='flag' affects packages"), )

        playground = ResolverPlayground(ebuilds=ebuilds,
                                        profile=profile,
                                        repo_configs=repo_configs,
                                        debug=debug)
        settings = playground.settings
        eprefix = settings["EPREFIX"]
        eroot = settings["EROOT"]
        portdb = playground.trees[playground.eroot]["porttree"].dbapi
        homedir = os.path.join(eroot, "home")
        distdir = os.path.join(eprefix, "distdir")
        test_repo_location = settings.repositories["test_repo"].location
        profiles_dir = os.path.join(test_repo_location, "profiles")
        license_dir = os.path.join(test_repo_location, "licenses")

        repoman_cmd = (portage._python_interpreter, "-b", "-Wd",
                       os.path.join(self.bindir, "repoman"))

        git_binary = find_binary("git")
        git_cmd = (git_binary, )

        cp_binary = find_binary("cp")
        self.assertEqual(cp_binary is None, False, "cp command not found")
        cp_cmd = (cp_binary, )

        test_ebuild = portdb.findname("dev-libs/A-1")
        self.assertFalse(test_ebuild is None)

        committer_name = "Gentoo Dev"
        committer_email = "*****@*****.**"

        git_test = (
            ("", repoman_cmd + ("manifest", )),
            ("", git_cmd + (
                "config",
                "--global",
                "user.name",
                committer_name,
            )),
            ("", git_cmd + (
                "config",
                "--global",
                "user.email",
                committer_email,
            )),
            ("", git_cmd + ("init-db", )),
            ("", git_cmd + ("add", ".")),
            ("", git_cmd + ("commit", "-a", "-m", "add whole repo")),
            ("", repoman_cmd + ("full", "-d")),
            ("", cp_cmd + (test_ebuild, test_ebuild[:-8] + "2.ebuild")),
            ("", git_cmd + ("add", test_ebuild[:-8] + "2.ebuild")),
            ("", repoman_cmd + ("commit", "-m", "bump to version 2")),
            ("", cp_cmd + (test_ebuild, test_ebuild[:-8] + "3.ebuild")),
            ("", git_cmd + ("add", test_ebuild[:-8] + "3.ebuild")),
            ("dev-libs", repoman_cmd + ("commit", "-m", "bump to version 3")),
            ("", cp_cmd + (test_ebuild, test_ebuild[:-8] + "4.ebuild")),
            ("", git_cmd + ("add", test_ebuild[:-8] + "4.ebuild")),
            ("dev-libs/A",
             repoman_cmd + ("commit", "-m", "bump to version 4")),
        )

        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,
            "DISTDIR":
            distdir,
            "GENTOO_COMMITTER_NAME":
            committer_name,
            "GENTOO_COMMITTER_EMAIL":
            committer_email,
            "HOME":
            homedir,
            "PATH":
            os.environ["PATH"],
            "PORTAGE_GRPNAME":
            os.environ["PORTAGE_GRPNAME"],
            "PORTAGE_USERNAME":
            os.environ["PORTAGE_USERNAME"],
            "PORTAGE_REPOSITORIES":
            settings.repositories.config_string(),
            "PYTHONDONTWRITEBYTECODE":
            os.environ.get("PYTHONDONTWRITEBYTECODE", ""),
            "PYTHONPATH":
            pythonpath,
        }

        if os.environ.get("SANDBOX_ON") == "1":
            # avoid problems from nested sandbox instances
            env["FEATURES"] = "-sandbox -usersandbox"

        dirs = [homedir, license_dir, profiles_dir, distdir]
        try:
            for d in dirs:
                ensure_dirs(d)
            with open(os.path.join(test_repo_location, "skel.ChangeLog"),
                      'w') as f:
                f.write(copyright_header)
            with open(os.path.join(profiles_dir, "profiles.desc"), 'w') as f:
                for x in profiles:
                    f.write("%s %s %s\n" % x)

            # ResolverPlayground only created the first profile,
            # so create the remaining ones.
            for x in profiles[1:]:
                sub_profile_dir = os.path.join(profiles_dir, x[1])
                ensure_dirs(sub_profile_dir)
                for config_file, lines in profile.items():
                    file_name = os.path.join(sub_profile_dir, config_file)
                    with open(file_name, "w") as f:
                        for line in lines:
                            f.write("%s\n" % line)

            for x in licenses:
                open(os.path.join(license_dir, x), 'wb').close()
            with open(os.path.join(profiles_dir, "arch.list"), 'w') as f:
                for x in arch_list:
                    f.write("%s\n" % x)
            with open(os.path.join(profiles_dir, "use.desc"), 'w') as f:
                for k, v in use_desc:
                    f.write("%s - %s\n" % (k, v))
            for cp, xml_data in metadata_xml_files:
                with open(os.path.join(test_repo_location, cp, "metadata.xml"),
                          'w') as f:
                    f.write(playground.metadata_xml_template % xml_data)
            # Use a symlink to test_repo, in order to trigger bugs
            # involving canonical vs. non-canonical paths.
            test_repo_symlink = os.path.join(eroot, "test_repo_symlink")
            os.symlink(test_repo_location, test_repo_symlink)
            metadata_xsd_dest = os.path.join(
                test_repo_location, 'metadata/xml-schema/metadata.xsd')
            os.makedirs(os.path.dirname(metadata_xsd_dest))
            os.symlink(metadata_xsd, metadata_xsd_dest)

            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 cwd in ("", "dev-libs", "dev-libs/A", "dev-libs/B"):
                abs_cwd = os.path.join(test_repo_symlink, cwd)
                proc = subprocess.Popen(repoman_cmd + ("full", ),
                                        cwd=abs_cwd,
                                        env=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,
                                 "repoman failed in %s" % (cwd, ))

            if git_binary is not None:
                for cwd, cmd in git_test:
                    abs_cwd = os.path.join(test_repo_symlink, cwd)
                    proc = subprocess.Popen(cmd,
                                            cwd=abs_cwd,
                                            env=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,
                                     "%s failed in %s" % (
                                         cmd,
                                         cwd,
                                     ))
        finally:
            playground.cleanup()
예제 #12
0
    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()
예제 #13
0
    def testOrChoices(self):
        ebuilds = {
            "dev-lang/vala-0.20.0": {
                "EAPI": "5",
                "SLOT": "0.20"
            },
            "dev-lang/vala-0.18.0": {
                "EAPI": "5",
                "SLOT": "0.18"
            },
            #"dev-libs/gobject-introspection-1.36.0" : {
            #	"EAPI": "5",
            #	"RDEPEND" : "!<dev-lang/vala-0.20.0",
            #},
            "dev-libs/gobject-introspection-1.34.0": {
                "EAPI": "5"
            },
            "sys-apps/systemd-ui-2": {
                "EAPI": "5",
                "RDEPEND": "|| ( dev-lang/vala:0.20 dev-lang/vala:0.18 )"
            },
        }

        installed = {
            "dev-lang/vala-0.18.0": {
                "EAPI": "5",
                "SLOT": "0.18"
            },
            "dev-libs/gobject-introspection-1.34.0": {
                "EAPI": "5"
            },
            "sys-apps/systemd-ui-2": {
                "EAPI": "5",
                "RDEPEND": "|| ( dev-lang/vala:0.20 dev-lang/vala:0.18 )"
            },
        }

        world = ["dev-libs/gobject-introspection", "sys-apps/systemd-ui"]

        test_cases = (
            # Demonstrate that vala:0.20 update is pulled in, for bug #478188
            ResolverPlaygroundTestCase(["@world"],
                                       options={
                                           "--update": True,
                                           "--deep": True
                                       },
                                       success=True,
                                       all_permutations=True,
                                       mergelist=['dev-lang/vala-0.20.0']),
            # Verify that vala:0.20 is not pulled in without --deep
            ResolverPlaygroundTestCase(["@world"],
                                       options={"--update": True},
                                       success=True,
                                       all_permutations=True,
                                       mergelist=[]),
            # Verify that vala:0.20 is not pulled in without --update
            ResolverPlaygroundTestCase(["@world"],
                                       options={
                                           "--selective": True,
                                           "--deep": True
                                       },
                                       success=True,
                                       all_permutations=True,
                                       mergelist=[]),
        )

        playground = ResolverPlayground(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.cleanup()
예제 #14
0
	def testSimple(self):

		debug = False

		install_something = """
S="${WORKDIR}"

pkg_pretend() {
	einfo "called pkg_pretend for $CATEGORY/$PF"
}

src_install() {
	einfo "installing something..."
	insinto /usr/lib/${P}
	echo "blah blah blah" > "${T}"/regular-file
	doins "${T}"/regular-file
	dosym regular-file /usr/lib/${P}/symlink || die

	# Test CONFIG_PROTECT
	insinto /etc
	newins "${T}"/regular-file ${PN}-${SLOT%/*}

	# Test code for bug #381629, using a copyright symbol encoded with latin-1.
	# We use $(printf "\\xa9") rather than $'\\xa9', since printf apparently
	# works in any case, while $'\\xa9' transforms to \\xef\\xbf\\xbd under
	# some conditions. TODO: Find out why it transforms to \\xef\\xbf\\xbd when
	# running tests for Python 3.2 (even though it's bash that is ultimately
	# responsible for performing the transformation).
	local latin_1_dir=/usr/lib/${P}/latin-1-$(printf "\\xa9")-directory
	insinto "${latin_1_dir}"
	echo "blah blah blah" > "${T}"/latin-1-$(printf "\\xa9")-regular-file || die
	doins "${T}"/latin-1-$(printf "\\xa9")-regular-file
	dosym latin-1-$(printf "\\xa9")-regular-file ${latin_1_dir}/latin-1-$(printf "\\xa9")-symlink || die

	call_has_and_best_version
}

pkg_config() {
	einfo "called pkg_config for $CATEGORY/$PF"
}

pkg_info() {
	einfo "called pkg_info for $CATEGORY/$PF"
}

pkg_preinst() {
	if ! ___eapi_best_version_and_has_version_support_-b_-d_-r; then
		# The BROOT variable is unset during pkg_* phases for EAPI 7,
		# therefore best/has_version -b is expected to fail if we attempt
		# to call it for EAPI 7 here.
		call_has_and_best_version
	fi
}

call_has_and_best_version() {
	local root_arg
	if ___eapi_best_version_and_has_version_support_-b_-d_-r; then
		root_arg="-b"
	else
		root_arg="--host-root"
	fi
	einfo "called ${EBUILD_PHASE_FUNC} for $CATEGORY/$PF"
	einfo "EPREFIX=${EPREFIX}"
	einfo "PORTAGE_OVERRIDE_EPREFIX=${PORTAGE_OVERRIDE_EPREFIX}"
	einfo "ROOT=${ROOT}"
	einfo "EROOT=${EROOT}"
	einfo "SYSROOT=${SYSROOT}"
	einfo "ESYSROOT=${ESYSROOT}"
	einfo "BROOT=${BROOT}"
	# Test that has_version and best_version work correctly with
	# prefix (involves internal ROOT -> EROOT calculation in order
	# to support ROOT override via the environment with EAPIs 3
	# and later which support prefix).
	if has_version $CATEGORY/$PN:$SLOT ; then
		einfo "has_version detects an installed instance of $CATEGORY/$PN:$SLOT"
		einfo "best_version reports that the installed instance is $(best_version $CATEGORY/$PN:$SLOT)"
	else
		einfo "has_version does not detect an installed instance of $CATEGORY/$PN:$SLOT"
	fi
	if [[ ${EPREFIX} != ${PORTAGE_OVERRIDE_EPREFIX} ]] ; then
		if has_version ${root_arg} $CATEGORY/$PN:$SLOT ; then
			einfo "has_version ${root_arg} detects an installed instance of $CATEGORY/$PN:$SLOT"
			einfo "best_version ${root_arg} reports that the installed instance is $(best_version ${root_arg} $CATEGORY/$PN:$SLOT)"
		else
			einfo "has_version ${root_arg} does not detect an installed instance of $CATEGORY/$PN:$SLOT"
		fi
	fi
}

"""

		ebuilds = {
			"dev-libs/A-1": {
				"EAPI" : "5",
				"IUSE" : "+flag",
				"KEYWORDS": "x86",
				"LICENSE": "GPL-2",
				"MISC_CONTENT": install_something,
				"RDEPEND": "flag? ( dev-libs/B[flag] )",
			},
			"dev-libs/B-1": {
				"EAPI" : "5",
				"IUSE" : "+flag",
				"KEYWORDS": "x86",
				"LICENSE": "GPL-2",
				"MISC_CONTENT": install_something,
			},
			"dev-libs/C-1": {
				"EAPI" : "7",
				"KEYWORDS": "~x86",
				"RDEPEND": "dev-libs/D[flag]",
				"MISC_CONTENT": install_something,
			},
			"dev-libs/D-1": {
				"EAPI" : "7",
				"KEYWORDS": "~x86",
				"IUSE" : "flag",
				"MISC_CONTENT": install_something,
			},
			"virtual/foo-0": {
				"EAPI" : "5",
				"KEYWORDS": "x86",
				"LICENSE": "GPL-2",
			},
		}

		installed = {
			"dev-libs/A-1": {
				"EAPI" : "5",
				"IUSE" : "+flag",
				"KEYWORDS": "x86",
				"LICENSE": "GPL-2",
				"RDEPEND": "flag? ( dev-libs/B[flag] )",
				"USE": "flag",
			},
			"dev-libs/B-1": {
				"EAPI" : "5",
				"IUSE" : "+flag",
				"KEYWORDS": "x86",
				"LICENSE": "GPL-2",
				"USE": "flag",
			},
			"dev-libs/depclean-me-1": {
				"EAPI" : "5",
				"IUSE" : "",
				"KEYWORDS": "x86",
				"LICENSE": "GPL-2",
				"USE": "",
			},
			"app-misc/depclean-me-1": {
				"EAPI" : "5",
				"IUSE" : "",
				"KEYWORDS": "x86",
				"LICENSE": "GPL-2",
				"RDEPEND": "dev-libs/depclean-me",
				"USE": "",
			},
		}

		metadata_xml_files = (
			(
				"dev-libs/A",
				{
					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
				},
			),
			(
				"dev-libs/B",
				{
					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
				},
			),
		)

		playground = ResolverPlayground(
			ebuilds=ebuilds, installed=installed, debug=debug)

		loop = asyncio._wrap_loop()
		loop.run_until_complete(asyncio.ensure_future(
			self._async_test_simple(loop, playground, metadata_xml_files), loop=loop))
예제 #15
0
    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 testProfilePackageSet(self):

        repo_configs = {
            "test_repo": {
                "layout.conf": ("profile-formats = profile-set", ),
            }
        }

        profiles = (
            ('default/linux', {
                "eapi": ("5", ),
                "packages": (
                    "*sys-libs/A",
                    "app-misc/A",
                    "app-misc/B",
                    "app-misc/C",
                ),
            }),
            ('default/linux/x86', {
                "eapi": ("5", ),
                "packages": ("-app-misc/B", ),
                "parent": ("..", )
            }),
        )

        ebuilds = {
            "sys-libs/A-1": {
                "EAPI": "5",
            },
            "app-misc/A-1": {
                "EAPI": "5",
            },
            "app-misc/B-1": {
                "EAPI": "5",
            },
            "app-misc/C-1": {
                "EAPI": "5",
            },
        }

        installed = {
            "sys-libs/A-1": {
                "EAPI": "5",
            },
            "app-misc/A-1": {
                "EAPI": "5",
            },
            "app-misc/B-1": {
                "EAPI": "5",
            },
            "app-misc/C-1": {
                "EAPI": "5",
            },
        }

        test_cases = (
            ResolverPlaygroundTestCase(
                ["@world"],
                options={
                    "--update": True,
                    "--deep": True
                },
                mergelist=[],
                success=True,
            ),
            ResolverPlaygroundTestCase([],
                                       options={"--depclean": True},
                                       success=True,
                                       cleanlist=["app-misc/B-1"]),
        )

        playground = ResolverPlayground(debug=False,
                                        ebuilds=ebuilds,
                                        installed=installed,
                                        repo_configs=repo_configs)
        try:
            repo_dir = (playground.settings.repositories.get_location_for_name(
                "test_repo"))
            profile_root = os.path.join(repo_dir, "profiles")

            for p, data in profiles:
                prof_path = os.path.join(profile_root, p)
                ensure_dirs(prof_path)
                for k, v in data.items():
                    with io.open(os.path.join(prof_path, k),
                                 mode="w",
                                 encoding=_encodings["repo.content"]) as f:
                        for line in v:
                            f.write("%s\n" % line)

            # The config must be reloaded in order to account
            # for the above profile customizations.
            playground.reload_config()

            for test_case in test_cases:
                playground.run_TestCase(test_case)
                self.assertEqual(test_case.test_success, True,
                                 test_case.fail_msg)

        finally:
            playground.cleanup()
예제 #17
0
    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()
예제 #18
0
    def testDoebuildSpawn(self):

        ebuild_body = textwrap.dedent("""
			pkg_nofetch() { : ; }
		""")

        ebuilds = {
            'sys-apps/portage-2.1': {
                'EAPI': '2',
                'IUSE': 'build doc epydoc python3 selinux',
                'KEYWORDS': 'x86',
                'LICENSE': 'GPL-2',
                'RDEPEND': '>=app-shells/bash-3.2_p17 >=dev-lang/python-2.6',
                'SLOT': '0',
                "MISC_CONTENT": ebuild_body,
            }
        }

        playground = ResolverPlayground(ebuilds=ebuilds)
        try:
            root_config = playground.trees[playground.eroot]['root_config']
            portdb = root_config.trees["porttree"].dbapi
            settings = config(clone=playground.settings)
            if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ:
                settings["__PORTAGE_TEST_HARDLINK_LOCKS"] = \
                 os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"]
                settings.backup_changes("__PORTAGE_TEST_HARDLINK_LOCKS")

            cpv = 'sys-apps/portage-2.1'
            metadata = dict(
                zip(Package.metadata_keys,
                    portdb.aux_get(cpv, Package.metadata_keys)))

            pkg = Package(built=False,
                          cpv=cpv,
                          installed=False,
                          metadata=metadata,
                          root_config=root_config,
                          type_name='ebuild')
            settings.setcpv(pkg)
            settings['PORTAGE_PYTHON'] = _python_interpreter
            settings['PORTAGE_BUILDDIR'] = os.path.join(
                settings['PORTAGE_TMPDIR'], cpv)
            settings['PYTHONDONTWRITEBYTECODE'] = os.environ.get(
                'PYTHONDONTWRITEBYTECODE', '')
            settings['HOME'] = os.path.join(settings['PORTAGE_BUILDDIR'],
                                            'homedir')
            settings['T'] = os.path.join(settings['PORTAGE_BUILDDIR'], 'temp')
            for x in ('PORTAGE_BUILDDIR', 'HOME', 'T'):
                os.makedirs(settings[x])
            # Create a fake environment, to pretend as if the ebuild
            # has been sourced already.
            open(os.path.join(settings['T'], 'environment'), 'wb').close()

            scheduler = SchedulerInterface(global_event_loop())
            for phase in ('_internal_test', ):

                # Test EbuildSpawnProcess by calling doebuild.spawn() with
                # returnpid=False. This case is no longer used by portage
                # internals since EbuildPhase is used instead and that passes
                # returnpid=True to doebuild.spawn().
                rval = doebuild_spawn("%s %s" % (_shell_quote(
                    os.path.join(settings["PORTAGE_BIN_PATH"],
                                 os.path.basename(EBUILD_SH_BINARY))), phase),
                                      settings,
                                      free=1)
                self.assertEqual(rval, os.EX_OK)

                ebuild_phase = EbuildPhase(background=False,
                                           phase=phase,
                                           scheduler=scheduler,
                                           settings=settings)
                scheduler.run_until_complete(ebuild_phase.async_start())
                ebuild_phase.wait()
                self.assertEqual(ebuild_phase.returncode, os.EX_OK)

            ebuild_phase = MiscFunctionsProcess(background=False,
                                                commands=['success_hooks'],
                                                scheduler=scheduler,
                                                settings=settings)
            scheduler.run_until_complete(ebuild_phase.async_start())
            ebuild_phase.wait()
            self.assertEqual(ebuild_phase.returncode, os.EX_OK)

            spawn_nofetch(portdb, portdb.findname(cpv), settings=settings)
        finally:
            playground.cleanup()
예제 #19
0
    def testSyncLocal(self):
        debug = False

        skip_reason = self._must_skip()
        if skip_reason:
            self.portage_skip = skip_reason
            self.assertFalse(True, skip_reason)
            return

        repos_conf = textwrap.dedent("""
			[DEFAULT]
			%(default_keys)s
			[test_repo]
			location = %(EPREFIX)s/var/repositories/test_repo
			sync-type = %(sync-type)s
			sync-depth = %(sync-depth)s
			sync-uri = file://%(EPREFIX)s/var/repositories/test_repo_sync
			sync-rcu = %(sync-rcu)s
			sync-rcu-store-dir = %(EPREFIX)s/var/repositories/test_repo_rcu_storedir
			auto-sync = %(auto-sync)s
			%(repo_extra_keys)s
		""")

        profile = {
            "eapi": ("5", ),
            "package.use.stable.mask": ("dev-libs/A flag", )
        }

        ebuilds = {"dev-libs/A-0": {}}

        user_config = {'make.conf': ('FEATURES="metadata-transfer"', )}

        playground = ResolverPlayground(ebuilds=ebuilds,
                                        profile=profile,
                                        user_config=user_config,
                                        debug=debug)
        settings = playground.settings
        eprefix = settings["EPREFIX"]
        eroot = settings["EROOT"]
        homedir = os.path.join(eroot, "home")
        distdir = os.path.join(eprefix, "distdir")
        repo = settings.repositories["test_repo"]
        metadata_dir = os.path.join(repo.location, "metadata")
        rcu_store_dir = os.path.join(
            eprefix, 'var/repositories/test_repo_rcu_storedir')

        cmds = {}
        for cmd in ("emerge", "emaint"):
            for bindir in (self.bindir, self.sbindir):
                path = os.path.join(bindir, cmd)
                if os.path.exists(path):
                    cmds[cmd] = (portage._python_interpreter, "-b", "-Wd",
                                 path)
                    break
            else:
                raise AssertionError('%s binary not found in %s or %s' %
                                     (cmd, self.bindir, self.sbindir))

        git_binary = find_binary("git")
        git_cmd = (git_binary, )

        hg_binary = find_binary("hg")
        hg_cmd = (hg_binary, )

        committer_name = "Gentoo Dev"
        committer_email = "*****@*****.**"

        def repos_set_conf(sync_type,
                           dflt_keys=None,
                           xtra_keys=None,
                           auto_sync="yes",
                           sync_rcu=False,
                           sync_depth=None):
            env["PORTAGE_REPOSITORIES"] = repos_conf % {\
             "EPREFIX": eprefix, "sync-type": sync_type,
             "sync-depth": 0 if sync_depth is None else sync_depth,
             "sync-rcu": "yes" if sync_rcu else "no",
             "auto-sync": auto_sync,
             "default_keys": "" if dflt_keys is None else dflt_keys,
             "repo_extra_keys": "" if xtra_keys is None else xtra_keys}

        def alter_ebuild():
            with open(
                    os.path.join(repo.location + "_sync", "dev-libs", "A",
                                 "A-0.ebuild"), "a") as f:
                f.write("\n")
            bump_timestamp()

        def bump_timestamp():
            bump_timestamp.timestamp += datetime.timedelta(seconds=1)
            with open(
                    os.path.join(repo.location + '_sync', 'metadata',
                                 'timestamp.chk'), 'w') as f:
                f.write(
                    bump_timestamp.timestamp.strftime(
                        '%s\n' % TIMESTAMP_FORMAT, ))

        bump_timestamp.timestamp = datetime.datetime.utcnow()

        bump_timestamp_cmds = ((homedir, bump_timestamp), )

        sync_cmds = (
            (homedir, cmds["emerge"] + ("--sync", )),
            (homedir, lambda: self.assertTrue(
                os.path.exists(os.path.join(repo.location, "dev-libs", "A")),
                "dev-libs/A expected, but missing")),
            (homedir, cmds["emaint"] + ("sync", "-A")),
        )

        sync_cmds_auto_sync = (
            (homedir, lambda: repos_set_conf("rsync", auto_sync="no")),
            (homedir, cmds["emerge"] + ("--sync", )),
            (homedir, lambda: self.assertFalse(
                os.path.exists(os.path.join(repo.location, "dev-libs", "A")),
                "dev-libs/A found, expected missing")),
            (homedir, lambda: repos_set_conf("rsync", auto_sync="yes")),
        )

        rename_repo = (
            (homedir,
             lambda: os.rename(repo.location, repo.location + "_sync")), )

        rsync_opts_repos = (
            (homedir, alter_ebuild),
            (homedir, lambda: repos_set_conf(
                "rsync", None,
                "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back"))),
            (homedir, cmds['emerge'] + ("--sync", )),
            (homedir,
             lambda: self.assertTrue(os.path.exists(repo.location + "_back"))),
            (homedir, lambda: shutil.rmtree(repo.location + "_back")),
            (homedir, lambda: repos_set_conf("rsync")),
        )

        rsync_opts_repos_default = (
            (homedir, alter_ebuild),
            (homedir, lambda: repos_set_conf(
                "rsync", "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back"))),
            (homedir, cmds['emerge'] + ("--sync", )),
            (homedir,
             lambda: self.assertTrue(os.path.exists(repo.location + "_back"))),
            (homedir, lambda: shutil.rmtree(repo.location + "_back")),
            (homedir, lambda: repos_set_conf("rsync")),
        )

        rsync_opts_repos_default_ovr = (
            (homedir, alter_ebuild),
            (homedir, lambda: repos_set_conf(
                "rsync", "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back_nowhere"),
                "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back"))),
            (homedir, cmds['emerge'] + ("--sync", )),
            (homedir,
             lambda: self.assertTrue(os.path.exists(repo.location + "_back"))),
            (homedir, lambda: shutil.rmtree(repo.location + "_back")),
            (homedir, lambda: repos_set_conf("rsync")),
        )

        rsync_opts_repos_default_cancel = (
            (homedir, alter_ebuild),
            (homedir, lambda: repos_set_conf(
                "rsync", "sync-rsync-extra-opts = --backup --backup-dir=%s" %
                _shell_quote(repo.location + "_back_nowhere"
                             ), "sync-rsync-extra-opts = ")),
            (homedir, cmds['emerge'] + ("--sync", )),
            (homedir,
             lambda: self.assertFalse(os.path.exists(repo.location + "_back"))
             ),
            (homedir, lambda: repos_set_conf("rsync")),
        )

        delete_repo_location = (
            (homedir, lambda: shutil.rmtree(repo.user_location)),
            (homedir, lambda: os.mkdir(repo.user_location)),
        )

        delete_rcu_store_dir = ((homedir,
                                 lambda: shutil.rmtree(rcu_store_dir)), )

        revert_rcu_layout = (
            (homedir,
             lambda: os.rename(repo.user_location, repo.user_location + '.bak')
             ),
            (homedir,
             lambda: os.rename(os.path.realpath(repo.user_location + '.bak'),
                               repo.user_location)),
            (homedir, lambda: os.unlink(repo.user_location + '.bak')),
            (homedir,
             lambda: shutil.rmtree(repo.user_location + '_rcu_storedir')),
        )

        upstream_git_commit = (
            (
                repo.location + "_sync",
                git_cmd +
                ('commit', '--allow-empty', '-m', 'test empty commit'),
            ),
            (
                repo.location + "_sync",
                git_cmd +
                ('commit', '--allow-empty', '-m', 'test empty commit 2'),
            ),
        )

        delete_sync_repo = ((homedir,
                             lambda: shutil.rmtree(repo.location + "_sync")), )

        git_repo_create = (
            (repo.location, git_cmd + (
                "config",
                "--global",
                "user.name",
                committer_name,
            )),
            (repo.location, git_cmd + (
                "config",
                "--global",
                "user.email",
                committer_email,
            )),
            (repo.location, git_cmd + ("init-db", )),
            (repo.location, git_cmd + ("add", ".")),
            (repo.location,
             git_cmd + ("commit", "-a", "-m", "add whole repo")),
        )

        sync_type_git = ((homedir, lambda: repos_set_conf("git")), )

        sync_type_git_shallow = ((
            homedir, lambda: repos_set_conf("git", sync_depth=1)), )

        sync_rsync_rcu = ((homedir,
                           lambda: repos_set_conf("rsync", sync_rcu=True)), )

        delete_git_dir = (
            (homedir,
             lambda: shutil.rmtree(os.path.join(repo.location, ".git"))), )

        def hg_init_global_config():
            with open(os.path.join(homedir, ".hgrc"), "wt") as f:
                f.write("[ui]\nusername = {} <{}>\n".format(
                    committer_name, committer_email))

        hg_repo_create = (
            (repo.location, hg_init_global_config),
            (repo.location, hg_cmd + ("init", )),
            (repo.location, hg_cmd + ("add", ".")),
            (repo.location, hg_cmd + ("commit", "-A", "-m", "add whole repo")),
        )

        sync_type_mercurial = ((homedir,
                                lambda: repos_set_conf("mercurial")), )

        def append_newline(path):
            with open(path, "at") as f:
                f.write("\n")

        upstream_hg_commit = (
            (
                repo.location + "_sync",
                lambda: append_newline(
                    os.path.join(repo.location + "_sync",
                                 "metadata/layout.conf")),
            ),
            (
                repo.location + "_sync",
                hg_cmd +
                ("commit", "metadata/layout.conf", "-m", "test empty commit"),
            ),
            (
                repo.location + "_sync",
                lambda: append_newline(
                    os.path.join(repo.location + "_sync",
                                 "metadata/layout.conf")),
            ),
            (
                repo.location + "_sync",
                hg_cmd + ("commit", "metadata/layout.conf", "-m",
                          "test empty commit 2"),
            ),
        )

        if hg_binary is None:
            mercurial_tests = ()
        else:
            mercurial_tests = (delete_sync_repo + delete_git_dir +
                               hg_repo_create + sync_type_mercurial +
                               rename_repo + sync_cmds + upstream_hg_commit +
                               sync_cmds)

        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,
            "DISTDIR":
            distdir,
            "GENTOO_COMMITTER_NAME":
            committer_name,
            "GENTOO_COMMITTER_EMAIL":
            committer_email,
            "HOME":
            homedir,
            "PATH":
            os.environ["PATH"],
            "PORTAGE_GRPNAME":
            os.environ["PORTAGE_GRPNAME"],
            "PORTAGE_USERNAME":
            os.environ["PORTAGE_USERNAME"],
            "PYTHONDONTWRITEBYTECODE":
            os.environ.get("PYTHONDONTWRITEBYTECODE", ""),
            "PYTHONPATH":
            pythonpath,
        }
        repos_set_conf("rsync")

        if os.environ.get("SANDBOX_ON") == "1":
            # avoid problems from nested sandbox instances
            env["FEATURES"] = "-sandbox -usersandbox"

        dirs = [homedir, metadata_dir]
        try:
            for d in dirs:
                ensure_dirs(d)

            timestamp_path = os.path.join(metadata_dir, 'timestamp.chk')
            with open(timestamp_path, 'w') as f:
                f.write(
                    bump_timestamp.timestamp.strftime(
                        '%s\n' % TIMESTAMP_FORMAT, ))

            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 cwd, cmd in rename_repo + sync_cmds_auto_sync + sync_cmds + \
             rsync_opts_repos + rsync_opts_repos_default + \
             rsync_opts_repos_default_ovr + rsync_opts_repos_default_cancel + \
             bump_timestamp_cmds + sync_rsync_rcu + sync_cmds + delete_rcu_store_dir + \
             sync_cmds + revert_rcu_layout + \
             delete_repo_location + sync_cmds + sync_cmds + \
             bump_timestamp_cmds + sync_cmds + revert_rcu_layout + \
             delete_sync_repo + git_repo_create + sync_type_git + \
             rename_repo + sync_cmds + upstream_git_commit + sync_cmds + \
             sync_type_git_shallow + upstream_git_commit + sync_cmds + mercurial_tests:

                if hasattr(cmd, '__call__'):
                    cmd()
                    continue

                abs_cwd = os.path.join(repo.location, cwd)
                proc = subprocess.Popen(cmd,
                                        cwd=abs_cwd,
                                        env=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,
                                 "%s failed in %s" % (
                                     cmd,
                                     cwd,
                                 ))

        finally:
            playground.cleanup()
예제 #20
0
    def testResolverDepth(self):

        profile = {
            "package.mask": (
                # Mask an installed package (for which an update is
                # available) in order to test for bug 712298, where
                # --update caused --deep=<depth> to be violated for
                # such a package.
                "<dev-libs/B-2", ),
        }

        ebuilds = {
            "dev-libs/A-1": {
                "RDEPEND": "dev-libs/B"
            },
            "dev-libs/A-2": {
                "RDEPEND": "dev-libs/B"
            },
            "dev-libs/B-1": {
                "RDEPEND": "dev-libs/C"
            },
            "dev-libs/B-2": {
                "RDEPEND": "dev-libs/C"
            },
            "dev-libs/C-1": {},
            "dev-libs/C-2": {},
            "virtual/libusb-0": {
                "EAPI":
                "2",
                "SLOT":
                "0",
                "RDEPEND":
                "|| ( >=dev-libs/libusb-0.1.12-r1:0 dev-libs/libusb-compat >=sys-freebsd/freebsd-lib-8.0[usb] )"
            },
            "virtual/libusb-1": {
                "EAPI": "2",
                "SLOT": "1",
                "RDEPEND": ">=dev-libs/libusb-1.0.4:1"
            },
            "dev-libs/libusb-0.1.13": {},
            "dev-libs/libusb-1.0.5": {
                "SLOT": "1"
            },
            "dev-libs/libusb-compat-1": {},
            "sys-freebsd/freebsd-lib-8": {
                "IUSE": "+usb"
            },
            "sys-fs/udev-164": {
                "EAPI": "1",
                "RDEPEND": "virtual/libusb:0"
            },
            "virtual/jre-1.5.0": {
                "SLOT":
                "1.5",
                "RDEPEND":
                "|| ( =dev-java/sun-jre-bin-1.5.0* =virtual/jdk-1.5.0* )"
            },
            "virtual/jre-1.5.0-r1": {
                "SLOT":
                "1.5",
                "RDEPEND":
                "|| ( =dev-java/sun-jre-bin-1.5.0* =virtual/jdk-1.5.0* )"
            },
            "virtual/jre-1.6.0": {
                "SLOT":
                "1.6",
                "RDEPEND":
                "|| ( =dev-java/sun-jre-bin-1.6.0* =virtual/jdk-1.6.0* )"
            },
            "virtual/jre-1.6.0-r1": {
                "SLOT":
                "1.6",
                "RDEPEND":
                "|| ( =dev-java/sun-jre-bin-1.6.0* =virtual/jdk-1.6.0* )"
            },
            "virtual/jdk-1.5.0": {
                "SLOT": "1.5",
                "RDEPEND": "|| ( =dev-java/sun-jdk-1.5.0* dev-java/gcj-jdk )"
            },
            "virtual/jdk-1.5.0-r1": {
                "SLOT": "1.5",
                "RDEPEND": "|| ( =dev-java/sun-jdk-1.5.0* dev-java/gcj-jdk )"
            },
            "virtual/jdk-1.6.0": {
                "SLOT": "1.6",
                "RDEPEND":
                "|| ( =dev-java/icedtea-6* =dev-java/sun-jdk-1.6.0* )"
            },
            "virtual/jdk-1.6.0-r1": {
                "SLOT": "1.6",
                "RDEPEND":
                "|| ( =dev-java/icedtea-6* =dev-java/sun-jdk-1.6.0* )"
            },
            "dev-java/gcj-jdk-4.5": {},
            "dev-java/gcj-jdk-4.5-r1": {},
            "dev-java/icedtea-6.1": {},
            "dev-java/icedtea-6.1-r1": {},
            "dev-java/sun-jdk-1.5": {
                "SLOT": "1.5"
            },
            "dev-java/sun-jdk-1.6": {
                "SLOT": "1.6"
            },
            "dev-java/sun-jre-bin-1.5": {
                "SLOT": "1.5"
            },
            "dev-java/sun-jre-bin-1.6": {
                "SLOT": "1.6"
            },
            "dev-java/ant-core-1.8": {
                "DEPEND": ">=virtual/jdk-1.4"
            },
            "dev-db/hsqldb-1.8": {
                "RDEPEND": ">=virtual/jre-1.6"
            },
        }

        installed = {
            "dev-libs/A-1": {
                "RDEPEND": "dev-libs/B"
            },
            "dev-libs/B-1": {
                "RDEPEND": "dev-libs/C"
            },
            "dev-libs/C-1": {},
            "virtual/jre-1.5.0": {
                "SLOT":
                "1.5",
                "RDEPEND":
                "|| ( =virtual/jdk-1.5.0* =dev-java/sun-jre-bin-1.5.0* )"
            },
            "virtual/jre-1.6.0": {
                "SLOT":
                "1.6",
                "RDEPEND":
                "|| ( =virtual/jdk-1.6.0* =dev-java/sun-jre-bin-1.6.0* )"
            },
            "virtual/jdk-1.5.0": {
                "SLOT": "1.5",
                "RDEPEND": "|| ( =dev-java/sun-jdk-1.5.0* dev-java/gcj-jdk )"
            },
            "virtual/jdk-1.6.0": {
                "SLOT": "1.6",
                "RDEPEND":
                "|| ( =dev-java/icedtea-6* =dev-java/sun-jdk-1.6.0* )"
            },
            "dev-java/gcj-jdk-4.5": {},
            "dev-java/icedtea-6.1": {},
            "virtual/libusb-0": {
                "EAPI":
                "2",
                "SLOT":
                "0",
                "RDEPEND":
                "|| ( >=dev-libs/libusb-0.1.12-r1:0 dev-libs/libusb-compat >=sys-freebsd/freebsd-lib-8.0[usb] )"
            },
        }

        world = ["dev-libs/A"]

        test_cases = (
            # Test for bug 712298, where --update caused --deep=<depth>
            # to be violated for dependencies that were masked. In this
            # case, the installed dev-libs/B-1 dependency is masked.
            ResolverPlaygroundTestCase(["dev-libs/A"],
                                       options={
                                           "--update": True,
                                           "--deep": 0
                                       },
                                       success=True,
                                       mergelist=["dev-libs/A-2"]),
            ResolverPlaygroundTestCase(
                ["dev-libs/A"],
                options={
                    "--update": True,
                    "--deep": 1
                },
                success=True,
                mergelist=["dev-libs/B-2", "dev-libs/A-2"]),
            ResolverPlaygroundTestCase(
                ["dev-libs/A"],
                options={
                    "--update": True,
                    "--deep": 2
                },
                success=True,
                mergelist=["dev-libs/C-2", "dev-libs/B-2", "dev-libs/A-2"]),
            ResolverPlaygroundTestCase(
                ["@world"],
                options={
                    "--update": True,
                    "--deep": True
                },
                success=True,
                mergelist=["dev-libs/C-2", "dev-libs/B-2", "dev-libs/A-2"]),
            ResolverPlaygroundTestCase(
                ["@world"],
                options={"--emptytree": True},
                success=True,
                mergelist=["dev-libs/C-2", "dev-libs/B-2", "dev-libs/A-2"]),
            ResolverPlaygroundTestCase(["@world"],
                                       options={
                                           "--selective": True,
                                           "--deep": True
                                       },
                                       success=True,
                                       mergelist=[]),
            ResolverPlaygroundTestCase(["dev-libs/A"],
                                       options={"--deep": 2},
                                       success=True,
                                       mergelist=["dev-libs/A-2"]),
            ResolverPlaygroundTestCase(["virtual/jre"],
                                       options={},
                                       success=True,
                                       mergelist=['virtual/jre-1.6.0-r1']),
            ResolverPlaygroundTestCase(["virtual/jre"],
                                       options={"--deep": True},
                                       success=True,
                                       mergelist=['virtual/jre-1.6.0-r1']),

            # Test bug #141118, where we avoid pulling in
            # redundant deps, satisfying nested virtuals
            # as efficiently as possible.
            ResolverPlaygroundTestCase(["virtual/jre"],
                                       options={
                                           "--selective": True,
                                           "--deep": True
                                       },
                                       success=True,
                                       mergelist=[]),

            # Test bug #150361, where depgraph._greedy_slots()
            # is triggered by --update with AtomArg.
            ResolverPlaygroundTestCase(["virtual/jre"],
                                       options={"--update": True},
                                       success=True,
                                       ambiguous_merge_order=True,
                                       mergelist=[('virtual/jre-1.6.0-r1',
                                                   'virtual/jre-1.5.0-r1')]),

            # Recursively traversed virtual dependencies, and their
            # direct dependencies, are considered to have the same
            # depth as direct dependencies.
            ResolverPlaygroundTestCase(
                ["virtual/jre"],
                options={
                    "--update": True,
                    "--deep": 1
                },
                success=True,
                ambiguous_merge_order=True,
                merge_order_assertions=(('dev-java/icedtea-6.1-r1',
                                         'virtual/jdk-1.6.0-r1'),
                                        ('virtual/jdk-1.6.0-r1',
                                         'virtual/jre-1.6.0-r1'),
                                        ('dev-java/gcj-jdk-4.5-r1',
                                         'virtual/jdk-1.5.0-r1'),
                                        ('virtual/jdk-1.5.0-r1',
                                         'virtual/jre-1.5.0-r1')),
                mergelist=[
                    ('dev-java/icedtea-6.1-r1', 'dev-java/gcj-jdk-4.5-r1',
                     'virtual/jdk-1.6.0-r1', 'virtual/jdk-1.5.0-r1',
                     'virtual/jre-1.6.0-r1', 'virtual/jre-1.5.0-r1')
                ]),
            ResolverPlaygroundTestCase(["virtual/jre:1.5"],
                                       options={"--update": True},
                                       success=True,
                                       mergelist=['virtual/jre-1.5.0-r1']),
            ResolverPlaygroundTestCase(["virtual/jre:1.6"],
                                       options={"--update": True},
                                       success=True,
                                       mergelist=['virtual/jre-1.6.0-r1']),

            # Test that we don't pull in any unnecessary updates
            # when --update is not specified, even though we
            # specified --deep.
            ResolverPlaygroundTestCase(["dev-java/ant-core"],
                                       options={"--deep": True},
                                       success=True,
                                       mergelist=["dev-java/ant-core-1.8"]),
            ResolverPlaygroundTestCase(["dev-java/ant-core"],
                                       options={"--update": True},
                                       success=True,
                                       mergelist=["dev-java/ant-core-1.8"]),

            # Recursively traversed virtual dependencies, and their
            # direct dependencies, are considered to have the same
            # depth as direct dependencies.
            ResolverPlaygroundTestCase(["dev-java/ant-core"],
                                       options={
                                           "--update": True,
                                           "--deep": 1
                                       },
                                       success=True,
                                       mergelist=[
                                           'dev-java/icedtea-6.1-r1',
                                           'virtual/jdk-1.6.0-r1',
                                           'dev-java/ant-core-1.8'
                                       ]),
            ResolverPlaygroundTestCase(["dev-db/hsqldb"],
                                       options={"--deep": True},
                                       success=True,
                                       mergelist=["dev-db/hsqldb-1.8"]),

            # Don't traverse deps of an installed package with --deep=0,
            # even if it's a virtual.
            ResolverPlaygroundTestCase(["virtual/libusb:0"],
                                       options={
                                           "--selective": True,
                                           "--deep": 0
                                       },
                                       success=True,
                                       mergelist=[]),

            # Satisfy unsatisfied dep of installed package with --deep=1.
            ResolverPlaygroundTestCase(["virtual/libusb:0"],
                                       options={
                                           "--selective": True,
                                           "--deep": 1
                                       },
                                       success=True,
                                       mergelist=['dev-libs/libusb-0.1.13']),

            # Pull in direct dep of virtual, even with --deep=0.
            ResolverPlaygroundTestCase(
                ["sys-fs/udev"],
                options={"--deep": 0},
                success=True,
                mergelist=['dev-libs/libusb-0.1.13', 'sys-fs/udev-164']),

            # Test --nodeps with direct virtual deps.
            ResolverPlaygroundTestCase(["sys-fs/udev"],
                                       options={"--nodeps": True},
                                       success=True,
                                       mergelist=["sys-fs/udev-164"]),

            # Test that --nodeps overrides --deep.
            ResolverPlaygroundTestCase(["sys-fs/udev"],
                                       options={
                                           "--nodeps": True,
                                           "--deep": True
                                       },
                                       success=True,
                                       mergelist=["sys-fs/udev-164"]),

            # Test that --nodeps overrides --emptytree.
            ResolverPlaygroundTestCase(["sys-fs/udev"],
                                       options={
                                           "--nodeps": True,
                                           "--emptytree": True
                                       },
                                       success=True,
                                       mergelist=["sys-fs/udev-164"]),

            # Test --emptytree with virtuals.
            ResolverPlaygroundTestCase(["sys-fs/udev"],
                                       options={"--emptytree": True},
                                       success=True,
                                       mergelist=[
                                           'dev-libs/libusb-0.1.13',
                                           'virtual/libusb-0',
                                           'sys-fs/udev-164'
                                       ]),
        )

        playground = ResolverPlayground(ebuilds=ebuilds,
                                        installed=installed,
                                        profile=profile,
                                        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.cleanup()
예제 #21
0
    def testLicenseManager(self):

        user_config = {
            "package.license": (
                "dev-libs/* TEST",
                "dev-libs/A -TEST2",
                "=dev-libs/A-2 TEST3 @TEST",
                "*/* @EULA TEST2",
                "=dev-libs/C-1 *",
                "=dev-libs/C-2 -*",
            ),
        }

        playground = ResolverPlayground(user_config=user_config)
        try:
            portage.util.noiselimit = -2

            license_group_locations = (os.path.join(playground.portdir,
                                                    "profiles"), )
            pkg_license = os.path.join(playground.eroot, "etc", "portage")

            lic_man = LicenseManager(license_group_locations, pkg_license)

            self.assertEqual(lic_man._accept_license_str, None)
            self.assertEqual(lic_man._accept_license, None)
            self.assertEqual(lic_man._license_groups, {"EULA": ["TEST"]})
            self.assertEqual(lic_man._undef_lic_groups, set(["TEST"]))

            self.assertEqual(lic_man.extract_global_changes(), "TEST TEST2")
            self.assertEqual(lic_man.extract_global_changes(), "")

            lic_man.set_accept_license_str("TEST TEST2")
            self.assertEqual(lic_man._getPkgAcceptLicense("dev-libs/B-1", "0"),
                             ["TEST", "TEST2", "TEST"])
            self.assertEqual(lic_man._getPkgAcceptLicense("dev-libs/A-1", "0"),
                             ["TEST", "TEST2", "TEST", "-TEST2"])
            self.assertEqual(
                lic_man._getPkgAcceptLicense("dev-libs/A-2", "0"),
                ["TEST", "TEST2", "TEST", "-TEST2", "TEST3", "@TEST"])

            self.assertEqual(
                lic_man.get_prunned_accept_license("dev-libs/B-1", [], "TEST",
                                                   "0"), "TEST")
            self.assertEqual(
                lic_man.get_prunned_accept_license("dev-libs/A-1", [],
                                                   "-TEST2", "0"), "")
            self.assertEqual(
                lic_man.get_prunned_accept_license("dev-libs/A-2", [],
                                                   "|| ( TEST TEST2 )", "0"),
                "TEST")
            self.assertEqual(
                lic_man.get_prunned_accept_license("dev-libs/C-1", [], "TEST5",
                                                   "0"), "TEST5")
            self.assertEqual(
                lic_man.get_prunned_accept_license("dev-libs/C-2", [], "TEST2",
                                                   "0"), "")

            self.assertEqual(
                lic_man.getMissingLicenses("dev-libs/B-1", [], "TEST", "0"),
                [])
            self.assertEqual(
                lic_man.getMissingLicenses("dev-libs/A-1", [], "-TEST2", "0"),
                ["-TEST2"])
            self.assertEqual(
                lic_man.getMissingLicenses("dev-libs/A-2", [],
                                           "|| ( TEST TEST2 )", "0"), [])
            self.assertEqual(
                lic_man.getMissingLicenses("dev-libs/A-3", [],
                                           "|| ( TEST2 || ( TEST3 TEST4 ) )",
                                           "0"), ["TEST2", "TEST3", "TEST4"])
            self.assertEqual(
                lic_man.getMissingLicenses("dev-libs/C-1", [], "TEST5", "0"),
                [])
            self.assertEqual(
                lic_man.getMissingLicenses("dev-libs/C-2", [], "TEST2", "0"),
                ["TEST2"])
            self.assertEqual(
                lic_man.getMissingLicenses("dev-libs/D-1", [], "", "0"), [])
        finally:
            portage.util.noiselimit = 0
            playground.cleanup()
예제 #22
0
	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()
예제 #23
0
    def testSimple(self):

        debug = False

        install_something = """
S="${WORKDIR}"

pkg_pretend() {
	einfo "called pkg_pretend for $CATEGORY/$PF"
}

src_install() {
	einfo "installing something..."
	insinto /usr/lib/${P}
	echo "blah blah blah" > "${T}"/regular-file
	doins "${T}"/regular-file
	dosym regular-file /usr/lib/${P}/symlink || die

	# Test CONFIG_PROTECT
	insinto /etc
	newins "${T}"/regular-file ${PN}-${SLOT%/*}

	# Test code for bug #381629, using a copyright symbol encoded with latin-1.
	# We use $(printf "\\xa9") rather than $'\\xa9', since printf apparently
	# works in any case, while $'\\xa9' transforms to \\xef\\xbf\\xbd under
	# some conditions. TODO: Find out why it transforms to \\xef\\xbf\\xbd when
	# running tests for Python 3.2 (even though it's bash that is ultimately
	# responsible for performing the transformation).
	local latin_1_dir=/usr/lib/${P}/latin-1-$(printf "\\xa9")-directory
	insinto "${latin_1_dir}"
	echo "blah blah blah" > "${T}"/latin-1-$(printf "\\xa9")-regular-file || die
	doins "${T}"/latin-1-$(printf "\\xa9")-regular-file
	dosym latin-1-$(printf "\\xa9")-regular-file ${latin_1_dir}/latin-1-$(printf "\\xa9")-symlink || die
}

pkg_config() {
	einfo "called pkg_config for $CATEGORY/$PF"
}

pkg_info() {
	einfo "called pkg_info for $CATEGORY/$PF"
}

pkg_preinst() {
	einfo "called pkg_preinst for $CATEGORY/$PF"

	# Test that has_version and best_version work correctly with
	# prefix (involves internal ROOT -> EROOT calculation in order
	# to support ROOT override via the environment with EAPIs 3
	# and later which support prefix).
	if has_version $CATEGORY/$PN:$SLOT ; then
		einfo "has_version detects an installed instance of $CATEGORY/$PN:$SLOT"
		einfo "best_version reports that the installed instance is $(best_version $CATEGORY/$PN:$SLOT)"
	else
		einfo "has_version does not detect an installed instance of $CATEGORY/$PN:$SLOT"
	fi
	if [[ ${EPREFIX} != ${PORTAGE_OVERRIDE_EPREFIX} ]] ; then
		if has_version --host-root $CATEGORY/$PN:$SLOT ; then
			einfo "has_version --host-root detects an installed instance of $CATEGORY/$PN:$SLOT"
			einfo "best_version --host-root reports that the installed instance is $(best_version $CATEGORY/$PN:$SLOT)"
		else
			einfo "has_version --host-root does not detect an installed instance of $CATEGORY/$PN:$SLOT"
		fi
	fi
}

"""

        ebuilds = {
            "dev-libs/A-1": {
                "EAPI": "5",
                "IUSE": "+flag",
                "KEYWORDS": "x86",
                "LICENSE": "GPL-2",
                "MISC_CONTENT": install_something,
                "RDEPEND": "flag? ( dev-libs/B[flag] )",
            },
            "dev-libs/B-1": {
                "EAPI": "5",
                "IUSE": "+flag",
                "KEYWORDS": "x86",
                "LICENSE": "GPL-2",
                "MISC_CONTENT": install_something,
            },
            "dev-libs/C-1": {
                "EAPI": "6",
                "KEYWORDS": "~x86",
                "RDEPEND": "dev-libs/D[flag]",
            },
            "dev-libs/D-1": {
                "EAPI": "6",
                "KEYWORDS": "~x86",
                "IUSE": "flag",
            },
            "virtual/foo-0": {
                "EAPI": "5",
                "KEYWORDS": "x86",
                "LICENSE": "GPL-2",
            },
        }

        installed = {
            "dev-libs/A-1": {
                "EAPI": "5",
                "IUSE": "+flag",
                "KEYWORDS": "x86",
                "LICENSE": "GPL-2",
                "RDEPEND": "flag? ( dev-libs/B[flag] )",
                "USE": "flag",
            },
            "dev-libs/B-1": {
                "EAPI": "5",
                "IUSE": "+flag",
                "KEYWORDS": "x86",
                "LICENSE": "GPL-2",
                "USE": "flag",
            },
            "dev-libs/depclean-me-1": {
                "EAPI": "5",
                "IUSE": "",
                "KEYWORDS": "x86",
                "LICENSE": "GPL-2",
                "USE": "",
            },
            "app-misc/depclean-me-1": {
                "EAPI": "5",
                "IUSE": "",
                "KEYWORDS": "x86",
                "LICENSE": "GPL-2",
                "RDEPEND": "dev-libs/depclean-me",
                "USE": "",
            },
        }

        metadata_xml_files = (
            (
                "dev-libs/A",
                {
                    "flags":
                    "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
                },
            ),
            (
                "dev-libs/B",
                {
                    "flags":
                    "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
                },
            ),
        )

        playground = ResolverPlayground(ebuilds=ebuilds,
                                        installed=installed,
                                        debug=debug)
        settings = playground.settings
        eprefix = settings["EPREFIX"]
        eroot = settings["EROOT"]
        trees = playground.trees
        portdb = trees[eroot]["porttree"].dbapi
        test_repo_location = settings.repositories["test_repo"].location
        var_cache_edb = os.path.join(eprefix, "var", "cache", "edb")
        cachedir = os.path.join(var_cache_edb, "dep")
        cachedir_pregen = os.path.join(test_repo_location, "metadata",
                                       "md5-cache")

        portage_python = portage._python_interpreter
        dispatch_conf_cmd = (portage_python, "-b", "-Wd",
                             os.path.join(self.sbindir, "dispatch-conf"))
        ebuild_cmd = (portage_python, "-b", "-Wd",
                      os.path.join(self.bindir, "ebuild"))
        egencache_cmd = (portage_python, "-b", "-Wd",
                         os.path.join(self.bindir, "egencache"), "--repo",
                         "test_repo", "--repositories-configuration",
                         settings.repositories.config_string())
        emerge_cmd = (portage_python, "-b", "-Wd",
                      os.path.join(self.bindir, "emerge"))
        emaint_cmd = (portage_python, "-b", "-Wd",
                      os.path.join(self.sbindir, "emaint"))
        env_update_cmd = (portage_python, "-b", "-Wd",
                          os.path.join(self.sbindir, "env-update"))
        etc_update_cmd = (BASH_BINARY, os.path.join(self.sbindir,
                                                    "etc-update"))
        fixpackages_cmd = (portage_python, "-b", "-Wd",
                           os.path.join(self.sbindir, "fixpackages"))
        portageq_cmd = (portage_python, "-b", "-Wd",
                        os.path.join(self.bindir, "portageq"))
        quickpkg_cmd = (portage_python, "-b", "-Wd",
                        os.path.join(self.bindir, "quickpkg"))
        regenworld_cmd = (portage_python, "-b", "-Wd",
                          os.path.join(self.sbindir, "regenworld"))

        rm_binary = find_binary("rm")
        self.assertEqual(rm_binary is None, False, "rm command not found")
        rm_cmd = (rm_binary, )

        egencache_extra_args = []
        if self._have_python_xml():
            egencache_extra_args.append("--update-use-local-desc")

        test_ebuild = portdb.findname("dev-libs/A-1")
        self.assertFalse(test_ebuild is None)

        cross_prefix = os.path.join(eprefix, "cross_prefix")
        cross_root = os.path.join(eprefix, "cross_root")
        cross_eroot = os.path.join(cross_root, eprefix.lstrip(os.sep))

        test_commands = (
         env_update_cmd,
         portageq_cmd + ("envvar", "-v", "CONFIG_PROTECT", "EROOT",
          "PORTAGE_CONFIGROOT", "PORTAGE_TMPDIR", "USERLAND"),
         etc_update_cmd,
         dispatch_conf_cmd,
         emerge_cmd + ("--version",),
         emerge_cmd + ("--info",),
         emerge_cmd + ("--info", "--verbose"),
         emerge_cmd + ("--list-sets",),
         emerge_cmd + ("--check-news",),
         rm_cmd + ("-rf", cachedir),
         rm_cmd + ("-rf", cachedir_pregen),
         emerge_cmd + ("--regen",),
         rm_cmd + ("-rf", cachedir),
         ({"FEATURES" : "metadata-transfer"},) + \
          emerge_cmd + ("--regen",),
         rm_cmd + ("-rf", cachedir),
         ({"FEATURES" : "metadata-transfer"},) + \
          emerge_cmd + ("--regen",),
         rm_cmd + ("-rf", cachedir),
         egencache_cmd + ("--update",) + tuple(egencache_extra_args),
         ({"FEATURES" : "metadata-transfer"},) + \
          emerge_cmd + ("--metadata",),
         rm_cmd + ("-rf", cachedir),
         ({"FEATURES" : "metadata-transfer"},) + \
          emerge_cmd + ("--metadata",),
         emerge_cmd + ("--metadata",),
         rm_cmd + ("-rf", cachedir),
         emerge_cmd + ("--oneshot", "virtual/foo"),
         lambda: self.assertFalse(os.path.exists(
          os.path.join(pkgdir, "virtual", "foo-0.tbz2"))),
         ({"FEATURES" : "unmerge-backup"},) + \
          emerge_cmd + ("--unmerge", "virtual/foo"),
         lambda: self.assertTrue(os.path.exists(
          os.path.join(pkgdir, "virtual", "foo-0.tbz2"))),
         emerge_cmd + ("--pretend", "dev-libs/A"),
         ebuild_cmd + (test_ebuild, "manifest", "clean", "package", "merge"),
         emerge_cmd + ("--pretend", "--tree", "--complete-graph", "dev-libs/A"),
         emerge_cmd + ("-p", "dev-libs/B"),
         emerge_cmd + ("-p", "--newrepo", "dev-libs/B"),
         emerge_cmd + ("-B", "dev-libs/B",),
         emerge_cmd + ("--oneshot", "--usepkg", "dev-libs/B",),

         # trigger clean prior to pkg_pretend as in bug #390711
         ebuild_cmd + (test_ebuild, "unpack"),
         emerge_cmd + ("--oneshot", "dev-libs/A",),

         emerge_cmd + ("--noreplace", "dev-libs/A",),
         emerge_cmd + ("--config", "dev-libs/A",),
         emerge_cmd + ("--info", "dev-libs/A", "dev-libs/B"),
         emerge_cmd + ("--pretend", "--depclean", "--verbose", "dev-libs/B"),
         emerge_cmd + ("--pretend", "--depclean",),
         emerge_cmd + ("--depclean",),
         quickpkg_cmd + ("--include-config", "y", "dev-libs/A",),
         # Test bug #523684, where a file renamed or removed by the
         # admin forces replacement files to be merged with config
         # protection.
         lambda: self.assertEqual(0,
          len(list(find_updated_config_files(eroot,
          shlex_split(settings["CONFIG_PROTECT"]))))),
         lambda: os.unlink(os.path.join(eprefix, "etc", "A-0")),
         emerge_cmd + ("--usepkgonly", "dev-libs/A"),
         lambda: self.assertEqual(1,
          len(list(find_updated_config_files(eroot,
          shlex_split(settings["CONFIG_PROTECT"]))))),
         emaint_cmd + ("--check", "all"),
         emaint_cmd + ("--fix", "all"),
         fixpackages_cmd,
         regenworld_cmd,
         portageq_cmd + ("match", eroot, "dev-libs/A"),
         portageq_cmd + ("best_visible", eroot, "dev-libs/A"),
         portageq_cmd + ("best_visible", eroot, "binary", "dev-libs/A"),
         portageq_cmd + ("contents", eroot, "dev-libs/A-1"),
         portageq_cmd + ("metadata", eroot, "ebuild", "dev-libs/A-1", "EAPI", "IUSE", "RDEPEND"),
         portageq_cmd + ("metadata", eroot, "binary", "dev-libs/A-1", "EAPI", "USE", "RDEPEND"),
         portageq_cmd + ("metadata", eroot, "installed", "dev-libs/A-1", "EAPI", "USE", "RDEPEND"),
         portageq_cmd + ("owners", eroot, eroot + "usr"),
         emerge_cmd + ("-p", eroot + "usr"),
         emerge_cmd + ("-p", "--unmerge", "-q", eroot + "usr"),
         emerge_cmd + ("--unmerge", "--quiet", "dev-libs/A"),
         emerge_cmd + ("-C", "--quiet", "dev-libs/B"),

         emerge_cmd + ("--autounmask-continue", "dev-libs/C",),
         # Verify that the above --autounmask-continue command caused
         # USE=flag to be applied correctly to dev-libs/D.
         portageq_cmd + ("match", eroot, "dev-libs/D[flag]"),

         # Test cross-prefix usage, including chpathtool for binpkgs.
         ({"EPREFIX" : cross_prefix},) + \
          emerge_cmd + ("--usepkgonly", "dev-libs/A"),
         ({"EPREFIX" : cross_prefix},) + \
          portageq_cmd + ("has_version", cross_prefix, "dev-libs/A"),
         ({"EPREFIX" : cross_prefix},) + \
          portageq_cmd + ("has_version", cross_prefix, "dev-libs/B"),
         ({"EPREFIX" : cross_prefix},) + \
          emerge_cmd + ("-C", "--quiet", "dev-libs/B"),
         ({"EPREFIX" : cross_prefix},) + \
          emerge_cmd + ("-C", "--quiet", "dev-libs/A"),
         ({"EPREFIX" : cross_prefix},) + \
          emerge_cmd + ("dev-libs/A",),
         ({"EPREFIX" : cross_prefix},) + \
          portageq_cmd + ("has_version", cross_prefix, "dev-libs/A"),
         ({"EPREFIX" : cross_prefix},) + \
          portageq_cmd + ("has_version", cross_prefix, "dev-libs/B"),

         # Test ROOT support
         ({"ROOT": cross_root},) + emerge_cmd + ("dev-libs/B",),
         portageq_cmd + ("has_version", cross_eroot, "dev-libs/B"),
        )

        distdir = playground.distdir
        pkgdir = playground.pkgdir
        fake_bin = os.path.join(eprefix, "bin")
        portage_tmpdir = os.path.join(eprefix, "var", "tmp", "portage")
        profile_path = settings.profile_path
        user_config_dir = os.path.join(os.sep, eprefix, USER_CONFIG_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,
            "CLEAN_DELAY":
            "0",
            "DISTDIR":
            distdir,
            "EMERGE_WARNING_DELAY":
            "0",
            "INFODIR":
            "",
            "INFOPATH":
            "",
            "PATH":
            path,
            "PKGDIR":
            pkgdir,
            "PORTAGE_INST_GID":
            str(portage.data.portage_gid),
            "PORTAGE_INST_UID":
            str(portage.data.portage_uid),
            "PORTAGE_PYTHON":
            portage_python,
            "PORTAGE_REPOSITORIES":
            settings.repositories.config_string(),
            "PORTAGE_TMPDIR":
            portage_tmpdir,
            "PORT_LOGDIR":
            portage_tmpdir,
            "PYTHONDONTWRITEBYTECODE":
            os.environ.get("PYTHONDONTWRITEBYTECODE", ""),
            "PYTHONPATH":
            pythonpath,
            "__PORTAGE_TEST_PATH_OVERRIDE":
            fake_bin,
        }

        if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ:
            env["__PORTAGE_TEST_HARDLINK_LOCKS"] = \
             os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"]

        updates_dir = os.path.join(test_repo_location, "profiles", "updates")
        dirs = [
            cachedir, cachedir_pregen, cross_eroot, cross_prefix, distdir,
            fake_bin, portage_tmpdir, updates_dir, user_config_dir,
            var_cache_edb
        ]
        etc_symlinks = ("dispatch-conf.conf", "etc-update.conf")
        # Override things that may be unavailable, or may have portability
        # issues when running tests in exotic environments.
        #   prepstrip - bug #447810 (bash read builtin EINTR problem)
        true_symlinks = ["find", "prepstrip", "sed", "scanelf"]
        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))
            for x in etc_symlinks:
                os.symlink(os.path.join(self.cnf_etc_path, x),
                           os.path.join(eprefix, "etc", 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")
            for cp, xml_data in metadata_xml_files:
                with open(os.path.join(test_repo_location, cp, "metadata.xml"),
                          'w') as f:
                    f.write(playground.metadata_xml_template % xml_data)
            with open(os.path.join(updates_dir, "1Q-2010"), 'w') as f:
                f.write("""
slotmove =app-doc/pms-3 2 3
move dev-util/git dev-vcs/git
""")

            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 args in test_commands:

                if hasattr(args, '__call__'):
                    args()
                    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.cleanup()
예제 #24
0
    def testSubSlot(self):
        ebuilds = {
            "dev-libs/icu-4.8": {
                "EAPI": "4-slot-abi",
                "SLOT": "0/48"
            },
            "dev-libs/libxml2-2.7.8": {
                "EAPI": "4-slot-abi",
                "DEPEND": "dev-libs/icu:=",
                "RDEPEND": "dev-libs/icu:="
            },
        }
        binpkgs = {
            "dev-libs/icu-49": {
                "EAPI": "4-slot-abi",
                "SLOT": "0/49"
            },
            "dev-libs/icu-4.8": {
                "EAPI": "4-slot-abi",
                "SLOT": "0/48"
            },
            "dev-libs/libxml2-2.7.8": {
                "EAPI": "4-slot-abi",
                "DEPEND": "dev-libs/icu:0/49=",
                "RDEPEND": "dev-libs/icu:0/49="
            },
        }
        installed = {
            "dev-libs/icu-49": {
                "EAPI": "4-slot-abi",
                "SLOT": "0/49"
            },
            "dev-libs/libxml2-2.7.8": {
                "EAPI": "4-slot-abi",
                "DEPEND": "dev-libs/icu:0/49=",
                "RDEPEND": "dev-libs/icu:0/49="
            },
        }

        world = ["dev-libs/libxml2"]

        test_cases = (
            ResolverPlaygroundTestCase(
                ["dev-libs/icu"],
                options={"--oneshot": True},
                success=True,
                mergelist=["dev-libs/icu-4.8", "dev-libs/libxml2-2.7.8"]),
            ResolverPlaygroundTestCase(["dev-libs/icu"],
                                       options={
                                           "--oneshot": True,
                                           "--ignore-built-slot-operator-deps":
                                           "y"
                                       },
                                       success=True,
                                       mergelist=["dev-libs/icu-4.8"]),
            ResolverPlaygroundTestCase(["dev-libs/icu"],
                                       options={
                                           "--oneshot": True,
                                           "--usepkg": True
                                       },
                                       success=True,
                                       mergelist=[
                                           "[binary]dev-libs/icu-4.8",
                                           "dev-libs/libxml2-2.7.8"
                                       ]),
            ResolverPlaygroundTestCase(["dev-libs/icu"],
                                       options={
                                           "--oneshot": True,
                                           "--usepkgonly": True
                                       },
                                       success=True,
                                       mergelist=["[binary]dev-libs/icu-49"]),
            ResolverPlaygroundTestCase(
                ["@world"],
                options={
                    "--update": True,
                    "--deep": True
                },
                success=True,
                mergelist=["dev-libs/icu-4.8", "dev-libs/libxml2-2.7.8"]),
            ResolverPlaygroundTestCase(
                ["@world"],
                options={
                    "--update": True,
                    "--deep": True,
                    "--ignore-built-slot-operator-deps": "y"
                },
                success=True,
                mergelist=["dev-libs/icu-4.8"]),
            ResolverPlaygroundTestCase(["@world"],
                                       options={
                                           "--update": True,
                                           "--deep": True,
                                           "--usepkg": True
                                       },
                                       success=True,
                                       mergelist=[
                                           "[binary]dev-libs/icu-4.8",
                                           "dev-libs/libxml2-2.7.8"
                                       ]),
            ResolverPlaygroundTestCase(["@world"],
                                       options={
                                           "--update": True,
                                           "--deep": True,
                                           "--usepkgonly": True
                                       },
                                       success=True,
                                       mergelist=[]),
        )

        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.cleanup()
예제 #25
0
    def testSlotConflictUpdateVirt(self):

        ebuilds = {
            "dev-db/mysql-connector-c-6.1.11-r2": {
                "EAPI": "7",
                "SLOT": "0/18"
            },
            "dev-db/mysql-connector-c-8.0.17-r3": {
                "EAPI": "7",
                "SLOT": "0/21"
            },
            "virtual/libmysqlclient-18-r1": {
                "EAPI": "7",
                "SLOT": "0/18",
                "RDEPEND": "dev-db/mysql-connector-c:0/18",
            },
            "virtual/libmysqlclient-21": {
                "EAPI": "7",
                "SLOT": "0/21",
                "RDEPEND": "dev-db/mysql-connector-c:0/21",
            },
            "dev-perl/DBD-mysql-4.44.0": {
                "EAPI": "7",
                "RDEPEND": "virtual/libmysqlclient:=",
            },
        }

        installed = {
            "dev-db/mysql-connector-c-6.1.11-r2": {
                "EAPI": "7",
                "SLOT": "0/18"
            },
            "virtual/libmysqlclient-18-r1": {
                "EAPI": "7",
                "SLOT": "0/18",
                "RDEPEND": "dev-db/mysql-connector-c:0/18",
            },
            "dev-perl/DBD-mysql-4.44.0": {
                "EAPI": "7",
                "RDEPEND": "virtual/libmysqlclient:0/18=",
            },
        }

        world = ["dev-db/mysql-connector-c", "dev-perl/DBD-mysql"]

        test_cases = (
            # In order to avoid missed updates for bug 692746, consider
            # masking a package matched by all parent atoms.
            ResolverPlaygroundTestCase(
                ["@world"],
                options={
                    "--update": True,
                    "--deep": True
                },
                success=True,
                mergelist=[
                    "dev-db/mysql-connector-c-8.0.17-r3",
                    "virtual/libmysqlclient-21",
                    "dev-perl/DBD-mysql-4.44.0",
                ],
            ), )

        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()
예제 #26
0
    def testWholeSlotSubSlotMix(self):
        ebuilds = {
            "dev-libs/glib-1.2.10": {
                "SLOT": "1"
            },
            "dev-libs/glib-2.30.2": {
                "EAPI": "4-slot-abi",
                "SLOT": "2/2.30"
            },
            "dev-libs/dbus-glib-0.98": {
                "EAPI": "4-slot-abi",
                "DEPEND": "dev-libs/glib:2=",
                "RDEPEND": "dev-libs/glib:2="
            },
        }
        binpkgs = {
            "dev-libs/glib-1.2.10": {
                "SLOT": "1"
            },
            "dev-libs/glib-2.30.2": {
                "EAPI": "4-slot-abi",
                "SLOT": "2/2.30"
            },
            "dev-libs/glib-2.32.3": {
                "EAPI": "4-slot-abi",
                "SLOT": "2/2.32"
            },
            "dev-libs/dbus-glib-0.98": {
                "EAPI": "4-slot-abi",
                "DEPEND": "dev-libs/glib:2/2.32=",
                "RDEPEND": "dev-libs/glib:2/2.32="
            },
        }
        installed = {
            "dev-libs/glib-1.2.10": {
                "EAPI": "4-slot-abi",
                "SLOT": "1"
            },
            "dev-libs/glib-2.32.3": {
                "EAPI": "4-slot-abi",
                "SLOT": "2/2.32"
            },
            "dev-libs/dbus-glib-0.98": {
                "EAPI": "4-slot-abi",
                "DEPEND": "dev-libs/glib:2/2.32=",
                "RDEPEND": "dev-libs/glib:2/2.32="
            },
        }

        world = ["dev-libs/glib:1", "dev-libs/dbus-glib"]

        test_cases = (
            ResolverPlaygroundTestCase(
                ["dev-libs/glib"],
                options={"--oneshot": True},
                success=True,
                mergelist=["dev-libs/glib-2.30.2", "dev-libs/dbus-glib-0.98"]),
            ResolverPlaygroundTestCase(["dev-libs/glib"],
                                       options={
                                           "--oneshot": True,
                                           "--ignore-built-slot-operator-deps":
                                           "y"
                                       },
                                       success=True,
                                       mergelist=["dev-libs/glib-2.30.2"]),
            ResolverPlaygroundTestCase(["dev-libs/glib"],
                                       options={
                                           "--oneshot": True,
                                           "--usepkg": True
                                       },
                                       success=True,
                                       mergelist=[
                                           "[binary]dev-libs/glib-2.30.2",
                                           "dev-libs/dbus-glib-0.98"
                                       ]),
            ResolverPlaygroundTestCase(
                ["dev-libs/glib"],
                options={
                    "--oneshot": True,
                    "--usepkgonly": True
                },
                success=True,
                mergelist=["[binary]dev-libs/glib-2.32.3"]),
            ResolverPlaygroundTestCase(
                ["@world"],
                options={
                    "--update": True,
                    "--deep": True
                },
                success=True,
                mergelist=["dev-libs/glib-2.30.2", "dev-libs/dbus-glib-0.98"]),
            ResolverPlaygroundTestCase(
                ["@world"],
                options={
                    "--update": True,
                    "--deep": True,
                    "--ignore-built-slot-operator-deps": "y"
                },
                success=True,
                mergelist=["dev-libs/glib-2.30.2"]),
            ResolverPlaygroundTestCase(["@world"],
                                       options={
                                           "--update": True,
                                           "--deep": True,
                                           "--usepkg": True
                                       },
                                       success=True,
                                       mergelist=[
                                           "[binary]dev-libs/glib-2.30.2",
                                           "dev-libs/dbus-glib-0.98"
                                       ]),
            ResolverPlaygroundTestCase(["@world"],
                                       options={
                                           "--update": True,
                                           "--deep": True,
                                           "--usepkgonly": True
                                       },
                                       success=True,
                                       mergelist=[]),
        )

        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.cleanup()
예제 #27
0
    def testMoveSlotEnt(self):

        ebuilds = {
            "dev-libs/A-2::dont_apply_updates": {
                "EAPI": "5",
                "SLOT": "0/2.30",
            },
            "dev-libs/B-2::dont_apply_updates": {
                "SLOT": "0",
            },
            "dev-libs/C-2.1::dont_apply_updates": {
                "EAPI": "5",
                "SLOT": "0/2.1",
            },
        }

        installed = {
            "dev-libs/A-1::test_repo": {
                "EAPI": "5",
                "SLOT": "0/2.30",
            },
            "dev-libs/B-1::test_repo": {
                "SLOT": "0",
            },
            "dev-libs/C-1::test_repo": {
                "EAPI": "5",
                "SLOT": "0/1",
            },
        }

        binpkgs = {
            "dev-libs/A-1::test_repo": {
                "EAPI": "5",
                "SLOT": "0/2.30",
            },
            "dev-libs/A-2::dont_apply_updates": {
                "EAPI": "5",
                "SLOT": "0/2.30",
            },
            "dev-libs/B-1::test_repo": {
                "SLOT": "0",
            },
            "dev-libs/B-2::dont_apply_updates": {
                "SLOT": "0",
            },
            "dev-libs/C-1::test_repo": {
                "EAPI": "5",
                "SLOT": "0/1",
            },
            "dev-libs/C-2.1::dont_apply_updates": {
                "EAPI": "5",
                "SLOT": "0/2.1",
            },
        }

        updates = textwrap.dedent(
            """
			slotmove dev-libs/A 0 2
			slotmove dev-libs/B 0 1
			slotmove dev-libs/C 0 1
		"""
        )

        playground = ResolverPlayground(
            binpkgs=binpkgs, ebuilds=ebuilds, installed=installed
        )

        settings = playground.settings
        trees = playground.trees
        eroot = settings["EROOT"]
        test_repo_location = settings.repositories["test_repo"].location
        portdb = trees[eroot]["porttree"].dbapi
        vardb = trees[eroot]["vartree"].dbapi
        bindb = trees[eroot]["bintree"].dbapi

        updates_dir = os.path.join(test_repo_location, "profiles", "updates")

        try:
            ensure_dirs(updates_dir)
            with open(os.path.join(updates_dir, "1Q-2010"), "w") as f:
                f.write(updates)

            # Create an empty updates directory, so that this
            # repo doesn't inherit updates from the main repo.
            ensure_dirs(
                os.path.join(
                    portdb.getRepositoryPath("dont_apply_updates"),
                    "profiles",
                    "updates",
                )
            )

            global_noiselimit = portage.util.noiselimit
            portage.util.noiselimit = -2
            try:
                _do_global_updates(trees, {})
            finally:
                portage.util.noiselimit = global_noiselimit

            # Workaround for cache validation not working
            # correctly when filesystem has timestamp precision
            # of 1 second.
            vardb._clear_cache()

            # 0/2.30 -> 2/2.30
            self.assertEqual("2/2.30", vardb.aux_get("dev-libs/A-1", ["SLOT"])[0])
            self.assertEqual("2/2.30", bindb.aux_get("dev-libs/A-1", ["SLOT"])[0])

            # 0 -> 1
            self.assertEqual("1", vardb.aux_get("dev-libs/B-1", ["SLOT"])[0])
            self.assertEqual("1", bindb.aux_get("dev-libs/B-1", ["SLOT"])[0])

            # 0/1 -> 1 (equivalent to 1/1)
            self.assertEqual("1", vardb.aux_get("dev-libs/C-1", ["SLOT"])[0])
            self.assertEqual("1", bindb.aux_get("dev-libs/C-1", ["SLOT"])[0])

            # dont_apply_updates
            self.assertEqual("0/2.30", bindb.aux_get("dev-libs/A-2", ["SLOT"])[0])
            self.assertEqual("0", bindb.aux_get("dev-libs/B-2", ["SLOT"])[0])
            self.assertEqual("0/2.1", bindb.aux_get("dev-libs/C-2.1", ["SLOT"])[0])

        finally:
            playground.cleanup()
예제 #28
0
    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()
예제 #29
0
    def testManifest(self):

        distfiles = {
            "B-2.tar.bz2": b"binary\0content",
            "C-2.zip": b"binary\0content",
            "C-2.tar.bz2": b"binary\0content",
        }

        ebuilds = {
            "dev-libs/A-1::old_repo": {},
            "dev-libs/A-2::new_repo": {},
            "dev-libs/B-2::new_repo": {
                "SRC_URI": "B-2.tar.bz2"
            },
            "dev-libs/C-2::new_repo": {
                "SRC_URI": "C-2.zip C-2.tar.bz2"
            },
        }

        repo_configs = {
            "new_repo": {
                "layout.conf": (
                    "profile-formats = pms",
                    "thin-manifests = true",
                    "manifest-hashes = SHA256 SHA512 WHIRLPOOL",
                    "manifest-required-hashes = SHA512",
                    "# use implicit masters",
                ),
            }
        }

        test_cases = (
            ResolverPlaygroundTestCase(["=dev-libs/A-1"],
                                       mergelist=["dev-libs/A-1"],
                                       success=True),
            ResolverPlaygroundTestCase(["=dev-libs/A-2"],
                                       mergelist=["dev-libs/A-2"],
                                       success=True),
        )

        playground = ResolverPlayground(ebuilds=ebuilds,
                                        repo_configs=repo_configs,
                                        distfiles=distfiles)
        settings = playground.settings

        new_repo_config = settings.repositories["new_repo"]
        old_repo_config = settings.repositories["old_repo"]
        self.assertTrue(
            len(new_repo_config.masters) > 0, "new_repo has no default master")
        self.assertEqual(
            new_repo_config.masters[0].location,
            playground.settings.repositories["test_repo"].location,
            "new_repo default master is not test_repo",
        )
        self.assertEqual(new_repo_config.thin_manifest, True,
                         "new_repo_config.thin_manifest != True")

        new_manifest_file = os.path.join(new_repo_config.location, "dev-libs",
                                         "A", "Manifest")
        self.assertNotExists(new_manifest_file)

        new_manifest_file = os.path.join(new_repo_config.location, "dev-libs",
                                         "B", "Manifest")
        f = open(new_manifest_file)
        self.assertEqual(len(list(f)), 1)
        f.close()

        new_manifest_file = os.path.join(new_repo_config.location, "dev-libs",
                                         "C", "Manifest")
        f = open(new_manifest_file)
        self.assertEqual(len(list(f)), 2)
        f.close()

        old_manifest_file = os.path.join(old_repo_config.location, "dev-libs",
                                         "A", "Manifest")
        f = open(old_manifest_file)
        self.assertEqual(len(list(f)), 1)
        f.close()

        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.cleanup()
	def testSlotOperatorReverseDeps(self):

		ebuilds = {

			"media-libs/mesa-11.2.2" : {
				"EAPI": "6",
				"SLOT": "0",
				"RDEPEND": ">=sys-devel/llvm-3.6.0:="
			},

			"sys-devel/clang-3.7.1-r100" : {
				"EAPI": "6",
				"SLOT": "0/3.7",
				"RDEPEND": "~sys-devel/llvm-3.7.1"
			},

			"sys-devel/clang-3.8.0-r100" : {
				"EAPI": "6",
				"SLOT": "0/3.8",
				"RDEPEND": "~sys-devel/llvm-3.8.0"
			},

			"sys-devel/llvm-3.7.1-r2" : {
				"EAPI": "6",
				"SLOT": "0/3.7.1",
				"PDEPEND": "=sys-devel/clang-3.7.1-r100"
			},

			"sys-devel/llvm-3.8.0-r2" : {
				"EAPI": "6",
				"SLOT": "0/3.8.0",
				"PDEPEND": "=sys-devel/clang-3.8.0-r100"
			},

		}

		installed = {

			"media-libs/mesa-11.2.2" : {
				"EAPI": "6",
				"SLOT": "0",
				"RDEPEND": ">=sys-devel/llvm-3.6.0:0/3.7.1="
			},

			"sys-devel/clang-3.7.1-r100" : {
				"EAPI": "6",
				"SLOT": "0/3.7",
				"RDEPEND": "~sys-devel/llvm-3.7.1"
			},

			"sys-devel/llvm-3.7.1-r2" : {
				"EAPI": "6",
				"SLOT": "0/3.7.1",
				"PDEPEND": "=sys-devel/clang-3.7.1-r100"
			},

		}

		world = ["media-libs/mesa"]

		test_cases = (

			# Test bug #584626, where an llvm update is missed due to
			# the check_reverse_dependencies function seeing that
			# updating llvm will break a dependency of the installed
			# version of clang (though a clang update is available).
			ResolverPlaygroundTestCase(
				["@world"],
				options = {"--update": True, "--deep": True},
				success = True,
				mergelist = [
					'sys-devel/llvm-3.8.0-r2',
					'sys-devel/clang-3.8.0-r100',
					'media-libs/mesa-11.2.2',
				],
			),

			ResolverPlaygroundTestCase(
				["@world"],
				options = {
					"--update": True,
					"--deep": True,
					"--ignore-built-slot-operator-deps": "y",
				},
				success = True,
				mergelist = [
					'sys-devel/llvm-3.8.0-r2',
					'sys-devel/clang-3.8.0-r100',
				],
			),

		)

		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.cleanup()