| # Copyright 2012-2014 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| import subprocess |
| import sys |
| import textwrap |
| |
| import portage |
| from portage import os |
| from portage import _unicode_decode |
| from portage.const import (BASH_BINARY, PORTAGE_BIN_PATH, |
| PORTAGE_PYM_PATH, USER_CONFIG_PATH) |
| from portage.tests import TestCase |
| from portage.tests.resolver.ResolverPlayground import ResolverPlayground |
| from portage.util import ensure_dirs |
| |
| class PortdbCacheTestCase(TestCase): |
| |
| def testPortdbCache(self): |
| debug = False |
| |
| ebuilds = { |
| "dev-libs/A-1": {}, |
| "dev-libs/A-2": {}, |
| "sys-apps/B-1": {}, |
| "sys-apps/B-2": {}, |
| } |
| |
| playground = ResolverPlayground(ebuilds=ebuilds, debug=debug) |
| settings = playground.settings |
| eprefix = settings["EPREFIX"] |
| test_repo_location = settings.repositories["test_repo"].location |
| user_config_dir = os.path.join(eprefix, USER_CONFIG_PATH) |
| metadata_dir = os.path.join(test_repo_location, "metadata") |
| md5_cache_dir = os.path.join(metadata_dir, "md5-cache") |
| pms_cache_dir = os.path.join(metadata_dir, "cache") |
| layout_conf_path = os.path.join(metadata_dir, "layout.conf") |
| |
| portage_python = portage._python_interpreter |
| egencache_cmd = (portage_python, "-b", "-Wd", |
| os.path.join(PORTAGE_BIN_PATH, "egencache"), |
| "--repo", "test_repo", |
| "--repositories-configuration", settings.repositories.config_string()) |
| python_cmd = (portage_python, "-b", "-Wd", "-c") |
| |
| test_commands = ( |
| (lambda: not os.path.exists(pms_cache_dir),), |
| (lambda: not os.path.exists(md5_cache_dir),), |
| python_cmd + (textwrap.dedent(""" |
| import os, sys, portage |
| if portage.portdb.porttree_root in portage.portdb._pregen_auxdb: |
| sys.exit(1) |
| """),), |
| |
| egencache_cmd + ("--update",), |
| (lambda: not os.path.exists(pms_cache_dir),), |
| (lambda: os.path.exists(md5_cache_dir),), |
| python_cmd + (textwrap.dedent(""" |
| import os, sys, portage |
| if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb: |
| sys.exit(1) |
| """),), |
| python_cmd + (textwrap.dedent(""" |
| import os, sys, portage |
| from portage.cache.flat_hash import md5_database |
| if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], md5_database): |
| sys.exit(1) |
| """),), |
| |
| (BASH_BINARY, "-c", "echo %s > %s" % |
| tuple(map(portage._shell_quote, |
| ("cache-formats = md5-dict pms", layout_conf_path,)))), |
| egencache_cmd + ("--update",), |
| (lambda: os.path.exists(md5_cache_dir),), |
| python_cmd + (textwrap.dedent(""" |
| import os, sys, portage |
| if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb: |
| sys.exit(1) |
| """),), |
| python_cmd + (textwrap.dedent(""" |
| import os, sys, portage |
| from portage.cache.flat_hash import md5_database |
| if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], md5_database): |
| sys.exit(1) |
| """),), |
| |
| # Disable DeprecationWarnings, since the pms format triggers them |
| # in portdbapi._create_pregen_cache(). |
| (BASH_BINARY, "-c", "echo %s > %s" % |
| tuple(map(portage._shell_quote, |
| ("cache-formats = pms md5-dict", layout_conf_path,)))), |
| (portage_python, "-b", "-Wd", "-Wi::DeprecationWarning", "-c") + (textwrap.dedent(""" |
| import os, sys, portage |
| if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb: |
| sys.exit(1) |
| """),), |
| (portage_python, "-b", "-Wd", "-Wi::DeprecationWarning", "-c") + (textwrap.dedent(""" |
| import os, sys, portage |
| from portage.cache.metadata import database as pms_database |
| if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], pms_database): |
| sys.exit(1) |
| """),), |
| |
| # Test auto-detection and preference for md5-cache when both |
| # cache formats are available but layout.conf is absent. |
| (BASH_BINARY, "-c", "rm %s" % portage._shell_quote(layout_conf_path)), |
| python_cmd + (textwrap.dedent(""" |
| import os, sys, portage |
| if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb: |
| sys.exit(1) |
| """),), |
| python_cmd + (textwrap.dedent(""" |
| import os, sys, portage |
| from portage.cache.flat_hash import md5_database |
| if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], md5_database): |
| sys.exit(1) |
| """),), |
| ) |
| |
| 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 = { |
| "PATH" : os.environ.get("PATH", ""), |
| "PORTAGE_OVERRIDE_EPREFIX" : eprefix, |
| "PORTAGE_PYTHON" : portage_python, |
| "PORTAGE_REPOSITORIES" : settings.repositories.config_string(), |
| "PYTHONPATH" : pythonpath, |
| } |
| |
| if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: |
| env["__PORTAGE_TEST_HARDLINK_LOCKS"] = \ |
| os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"] |
| |
| dirs = [user_config_dir] |
| |
| try: |
| for d in dirs: |
| ensure_dirs(d) |
| |
| 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, |
| "command %d failed with args %s" % (i, args,)) |
| finally: |
| playground.cleanup() |