ResolverPlayground: support targetroot
authorZac Medico <zmedico@gentoo.org>
Wed, 26 Sep 2012 00:12:52 +0000 (17:12 -0700)
committerZac Medico <zmedico@gentoo.org>
Wed, 26 Sep 2012 00:12:52 +0000 (17:12 -0700)
In order to support targetroot, ResolverPlayground always writes
make.conf, since create_trees does not propagate all of the necessary
settings via the env parameter (because the env settings often need to
be isolated from eachother, especially for cross-compilation).

pym/portage/tests/dbapi/test_portdb_cache.py
pym/portage/tests/emerge/test_emerge_slot_abi.py
pym/portage/tests/emerge/test_simple.py
pym/portage/tests/resolver/ResolverPlayground.py
pym/portage/tests/resolver/test_targetroot.py [new file with mode: 0644]

index 4a0129b3ef2351910abd500321b1e10e44d69bed..6526246e11ad7407f1a1ccff5a27d65ac41a87a9 100644 (file)
@@ -113,18 +113,6 @@ class PortdbCacheTestCase(TestCase):
                        """),),
                )
 
-               features = []
-               if not portage.process.sandbox_capable or \
-                       os.environ.get("SANDBOX_ON") == "1":
-                       features.append("-sandbox")
-
-               make_conf = (
-                       "FEATURES=\"%s\"\n" % (" ".join(features),),
-                       "PORTDIR=\"%s\"\n" % (portdir,),
-                       "PORTAGE_GRPNAME=\"%s\"\n" % (os.environ["PORTAGE_GRPNAME"],),
-                       "PORTAGE_USERNAME=\"%s\"\n" % (os.environ["PORTAGE_USERNAME"],),
-               )
-
                pythonpath =  os.environ.get("PYTHONPATH")
                if pythonpath is not None and not pythonpath.strip():
                        pythonpath = None
@@ -154,9 +142,6 @@ class PortdbCacheTestCase(TestCase):
                try:
                        for d in dirs:
                                ensure_dirs(d)
-                       with open(os.path.join(user_config_dir, "make.conf"), 'w') as f:
-                               for line in make_conf:
-                                       f.write(line)
 
                        if debug:
                                # The subprocess inherits both stdout and stderr, for
index f18bd123b630a4f8691c6c76ac28de9c91687e9e..401c23bbf175c8dc44a646028d68f4a22bb34b2c 100644 (file)
@@ -94,25 +94,6 @@ class SlotAbiEmergeTestCase(TestCase):
                portage_tmpdir = os.path.join(eprefix, "var", "tmp", "portage")
                profile_path = settings.profile_path
 
-               features = []
-               if not portage.process.sandbox_capable or \
-                       os.environ.get("SANDBOX_ON") == "1":
-                       features.append("-sandbox")
-
-               make_conf = (
-                       "FEATURES=\"%s\"\n" % (" ".join(features),),
-                       "PORTDIR=\"%s\"\n" % (portdir,),
-                       "PORTAGE_GRPNAME=\"%s\"\n" % (os.environ["PORTAGE_GRPNAME"],),
-                       "PORTAGE_USERNAME=\"%s\"\n" % (os.environ["PORTAGE_USERNAME"],),
-                       "PKGDIR=\"%s\"\n" % (pkgdir,),
-                       "PORTAGE_INST_GID=%s\n" % (portage.data.portage_gid,),
-                       "PORTAGE_INST_UID=%s\n" % (portage.data.portage_uid,),
-                       "PORTAGE_TMPDIR=\"%s\"\n" % (portage_tmpdir,),
-                       "CLEAN_DELAY=0\n",
-                       "DISTDIR=\"%s\"\n" % (distdir,),
-                       "EMERGE_WARNING_DELAY=0\n",
-               )
-
                path =  os.environ.get("PATH")
                if path is not None and not path.strip():
                        path = None
@@ -155,9 +136,6 @@ class SlotAbiEmergeTestCase(TestCase):
                try:
                        for d in dirs:
                                ensure_dirs(d)
-                       with open(os.path.join(user_config_dir, "make.conf"), 'w') as f:
-                               for line in make_conf:
-                                       f.write(line)
                        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:
index 77a0554c0d3ac307eaab920176795187aa528c7f..56fbdb3bfa8bac00db8b79891967f5f8b71f4989 100644 (file)
@@ -266,20 +266,6 @@ pkg_preinst() {
                profile_path = settings.profile_path
                user_config_dir = os.path.join(os.sep, eprefix, USER_CONFIG_PATH)
 
-               features = []
-               if not portage.process.sandbox_capable or \
-                       os.environ.get("SANDBOX_ON") == "1":
-                       features.append("-sandbox")
-
-               # Since egencache ignores settings from the calling environment,
-               # configure it via make.conf.
-               make_conf = (
-                       "FEATURES=\"%s\"\n" % (" ".join(features),),
-                       "PORTDIR=\"%s\"\n" % (portdir,),
-                       "PORTAGE_GRPNAME=\"%s\"\n" % (os.environ["PORTAGE_GRPNAME"],),
-                       "PORTAGE_USERNAME=\"%s\"\n" % (os.environ["PORTAGE_USERNAME"],),
-               )
-
                path =  os.environ.get("PATH")
                if path is not None and not path.strip():
                        path = None
@@ -333,9 +319,6 @@ pkg_preinst() {
                try:
                        for d in dirs:
                                ensure_dirs(d)
-                       with open(os.path.join(user_config_dir, "make.conf"), 'w') as f:
-                               for line in make_conf:
-                                       f.write(line)
                        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:
index c7c9be9eadac893822464e9a568cb2ddf0dd54a6..a63d285a511b41ebb1e2b4c9b6f61271f8e73e4d 100644 (file)
@@ -55,7 +55,8 @@ class ResolverPlayground(object):
 """
 
        def __init__(self, ebuilds={}, binpkgs={}, installed={}, profile={}, repo_configs={}, \
-               user_config={}, sets={}, world=[], world_sets=[], distfiles={}, debug=False):
+               user_config={}, sets={}, world=[], world_sets=[], distfiles={},
+               targetroot=False, debug=False):
                """
                ebuilds: cpv -> metadata mapping simulating available ebuilds. 
                installed: cpv -> metadata mapping simulating installed packages.
@@ -65,6 +66,10 @@ class ResolverPlayground(object):
                self.debug = debug
                self.eprefix = normalize_path(tempfile.mkdtemp())
                self.eroot = self.eprefix + os.sep
+               if targetroot:
+                       self.target_root = os.path.join(self.eroot, 'target_root')
+               else:
+                       self.target_root = os.sep
                self.distdir = os.path.join(self.eroot, "var", "portage", "distfiles")
                self.pkgdir = os.path.join(self.eprefix, "pkgdir")
                self.portdir = os.path.join(self.eroot, "usr/portage")
@@ -363,7 +368,51 @@ class ResolverPlayground(object):
                        f.write("\n")
                f.close()
 
-               for config_file, lines in user_config.items():
+               portdir_overlay = []
+               for repo_name in sorted(self.repo_dirs):
+                       path = self.repo_dirs[repo_name]
+                       if path != self.portdir:
+                               portdir_overlay.append(path)
+
+               make_conf = {
+                       "ACCEPT_KEYWORDS": "x86",
+                       "CLEAN_DELAY": "0",
+                       "DISTDIR" : self.distdir,
+                       "EMERGE_WARNING_DELAY": "0",
+                       "PKGDIR": self.pkgdir,
+                       "PORTDIR": self.portdir,
+                       "PORTAGE_INST_GID": str(portage.data.portage_gid),
+                       "PORTAGE_INST_UID": str(portage.data.portage_uid),
+                       "PORTDIR_OVERLAY": " ".join("'%s'" % x for x in portdir_overlay),
+                       "PORTAGE_TMPDIR": os.path.join(self.eroot, 'var/tmp'),
+               }
+
+               if os.environ.get("NOCOLOR"):
+                       make_conf["NOCOLOR"] = os.environ["NOCOLOR"]
+
+               # Pass along PORTAGE_USERNAME and PORTAGE_GRPNAME since they
+               # need to be inherited by ebuild subprocesses.
+               if 'PORTAGE_USERNAME' in os.environ:
+                       make_conf['PORTAGE_USERNAME'] = os.environ['PORTAGE_USERNAME']
+               if 'PORTAGE_GRPNAME' in os.environ:
+                       make_conf['PORTAGE_GRPNAME'] = os.environ['PORTAGE_GRPNAME']
+
+               make_conf_lines = []
+               for k_v in make_conf.items():
+                       make_conf_lines.append('%s="%s"' % k_v)
+
+               if "make.conf" in user_config:
+                       make_conf_lines.extend(user_config["make.conf"])
+
+               if not portage.process.sandbox_capable or \
+                       os.environ.get("SANDBOX_ON") == "1":
+                       # avoid problems from nested sandbox instances
+                       make_conf_lines.append('FEATURES="${FEATURES} -sandbox"')
+
+               configs = user_config.copy()
+               configs["make.conf"] = make_conf_lines
+
+               for config_file, lines in configs.items():
                        if config_file not in self.config_files:
                                raise ValueError("Unknown config file: '%s'" % config_file)
 
@@ -406,23 +455,6 @@ class ResolverPlayground(object):
                                f.write("%s\n" % line)
                        f.close()
 
-               user_config_dir = os.path.join(self.eroot, "etc", "portage")
-
-               try:
-                       os.makedirs(user_config_dir)
-               except os.error:
-                       pass
-
-               for config_file, lines in user_config.items():
-                       if config_file not in self.config_files:
-                               raise ValueError("Unknown config file: '%s'" % config_file)
-
-                       file_name = os.path.join(user_config_dir, config_file)
-                       f = open(file_name, "w")
-                       for line in lines:
-                               f.write("%s\n" % line)
-                       f.close()
-
        def _create_world(self, world, world_sets):
                #Create /var/lib/portage/world
                var_lib_portage = os.path.join(self.eroot, "var", "lib", "portage")
@@ -442,43 +474,21 @@ class ResolverPlayground(object):
                f.close()
 
        def _load_config(self):
-               portdir_overlay = []
-               for repo_name in sorted(self.repo_dirs):
-                       path = self.repo_dirs[repo_name]
-                       if path != self.portdir:
-                               portdir_overlay.append(path)
 
-               env = {
-                       "ACCEPT_KEYWORDS": "x86",
-                       "DISTDIR" : self.distdir,
-                       "PKGDIR": self.pkgdir,
-                       "PORTDIR": self.portdir,
-                       "PORTDIR_OVERLAY": " ".join(portdir_overlay),
-                       'PORTAGE_TMPDIR'       : os.path.join(self.eroot, 'var/tmp'),
-               }
-
-               if os.environ.get("NOCOLOR"):
-                       env["NOCOLOR"] = os.environ["NOCOLOR"]
+               create_trees_kwargs = {}
+               if self.target_root != os.sep:
+                       create_trees_kwargs["target_root"] = self.target_root
 
-               if os.environ.get("SANDBOX_ON") == "1":
-                       # avoid problems from nested sandbox instances
-                       env["FEATURES"] = "-sandbox"
+               trees = portage.create_trees(env={}, eprefix=self.eprefix,
+                       **create_trees_kwargs)
 
-               # Pass along PORTAGE_USERNAME and PORTAGE_GRPNAME since they
-               # need to be inherited by ebuild subprocesses.
-               if 'PORTAGE_USERNAME' in os.environ:
-                       env['PORTAGE_USERNAME'] = os.environ['PORTAGE_USERNAME']
-               if 'PORTAGE_GRPNAME' in os.environ:
-                       env['PORTAGE_GRPNAME'] = os.environ['PORTAGE_GRPNAME']
-
-               trees = portage.create_trees(env=env, eprefix=self.eprefix)
                for root, root_trees in trees.items():
                        settings = root_trees["vartree"].settings
                        settings._init_dirs()
                        setconfig = load_default_config(settings, root_trees)
                        root_trees["root_config"] = RootConfig(settings, root_trees, setconfig)
-               
-               return settings, trees
+
+               return trees[trees._target_eroot]["vartree"].settings, trees
 
        def run(self, atoms, options={}, action=None):
                options = options.copy()
@@ -531,9 +541,10 @@ class ResolverPlayground(object):
                                return
 
        def cleanup(self):
-               portdb = self.trees[self.eroot]["porttree"].dbapi
-               portdb.close_caches()
-               portage.dbapi.porttree.portdbapi.portdbapi_instances.remove(portdb)
+               for eroot in self.trees:
+                       portdb = self.trees[eroot]["porttree"].dbapi
+                       portdb.close_caches()
+                       portage.dbapi.porttree.portdbapi.portdbapi_instances.remove(portdb)
                if self.debug:
                        print("\nEROOT=%s" % self.eroot)
                else:
diff --git a/pym/portage/tests/resolver/test_targetroot.py b/pym/portage/tests/resolver/test_targetroot.py
new file mode 100644 (file)
index 0000000..ef07a76
--- /dev/null
@@ -0,0 +1,50 @@
+# Copyright 2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from portage.tests import TestCase
+from portage.tests.resolver.ResolverPlayground import ResolverPlayground, ResolverPlaygroundTestCase
+
+class TargetRootTestCase(TestCase):
+
+       def testTargetRoot(self):
+               ebuilds = {
+                       "dev-lang/python-3.2": {
+                               "EAPI": "5-hdepend",
+                               "IUSE": "targetroot",
+                               "HDEPEND": "targetroot? ( ~dev-lang/python-3.2 )",
+                       }, 
+               }
+
+               test_cases = (
+                       ResolverPlaygroundTestCase(
+                               ["dev-lang/python"],
+                               options = {},
+                               success = True,
+                               mergelist = ["dev-lang/python-3.2", "dev-lang/python-3.2"]),
+               )
+
+               playground = ResolverPlayground(ebuilds=ebuilds, targetroot=True,
+                       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()
+
+               test_cases = (
+                       ResolverPlaygroundTestCase(
+                               ["dev-lang/python"],
+                               options = {},
+                               success = True,
+                               mergelist = ["dev-lang/python-3.2"]),
+               )
+
+               playground = ResolverPlayground(ebuilds=ebuilds, targetroot=False,
+                       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()