# Copyright 2012 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"] portdir = settings["PORTDIR"] user_config_dir = os.path.join(eprefix, USER_CONFIG_PATH) metadata_dir = os.path.join(portdir, "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, "-Wd", os.path.join(PORTAGE_BIN_PATH, "egencache")) python_cmd = (portage_python, "-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) """),), # Don't use python -Wd, since the pms format triggers deprecation warnings # 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, "-Wi", "-c") + (textwrap.dedent(""" import os, sys, portage if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb: sys.exit(1) """),), (portage_python, "-Wi", "-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, "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()