98439629d1ec9cee93b1595134a8fbcefb896f03
[portage.git] / pym / portage / tests / dbapi / test_portdb_cache.py
1 # Copyright 2012-2013 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 import subprocess
5 import sys
6 import textwrap
7
8 import portage
9 from portage import os
10 from portage import _unicode_decode
11 from portage.const import (BASH_BINARY, PORTAGE_BIN_PATH,
12         PORTAGE_PYM_PATH, USER_CONFIG_PATH)
13 from portage.tests import TestCase
14 from portage.tests.resolver.ResolverPlayground import ResolverPlayground
15 from portage.util import ensure_dirs
16
17 class PortdbCacheTestCase(TestCase):
18
19         def testPortdbCache(self):
20                 debug = False
21
22                 ebuilds = {
23                         "dev-libs/A-1": {},
24                         "dev-libs/A-2": {},
25                         "sys-apps/B-1": {},
26                         "sys-apps/B-2": {},
27                 }
28
29                 playground = ResolverPlayground(ebuilds=ebuilds, debug=debug)
30                 settings = playground.settings
31                 eprefix = settings["EPREFIX"]
32                 test_repo_location = settings.repositories["test_repo"].location
33                 user_config_dir = os.path.join(eprefix, USER_CONFIG_PATH)
34                 metadata_dir = os.path.join(test_repo_location, "metadata")
35                 md5_cache_dir = os.path.join(metadata_dir, "md5-cache")
36                 pms_cache_dir = os.path.join(metadata_dir, "cache")
37                 layout_conf_path = os.path.join(metadata_dir, "layout.conf")
38
39                 portage_python = portage._python_interpreter
40                 egencache_cmd = (portage_python, "-Wd",
41                         os.path.join(PORTAGE_BIN_PATH, "egencache"),
42                         "--repo", "test_repo",
43                         "--repositories-configuration", settings.repositories.config_string())
44                 python_cmd = (portage_python, "-Wd", "-c")
45
46                 test_commands = (
47                         (lambda: not os.path.exists(pms_cache_dir),),
48                         (lambda: not os.path.exists(md5_cache_dir),),
49                         python_cmd + (textwrap.dedent("""
50                                 import os, sys, portage
51                                 if portage.portdb.porttree_root in portage.portdb._pregen_auxdb:
52                                         sys.exit(1)
53                         """),),
54
55                         egencache_cmd + ("--update",),
56                         (lambda: not os.path.exists(pms_cache_dir),),
57                         (lambda: os.path.exists(md5_cache_dir),),
58                         python_cmd + (textwrap.dedent("""
59                                 import os, sys, portage
60                                 if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb:
61                                         sys.exit(1)
62                         """),),
63                         python_cmd + (textwrap.dedent("""
64                                 import os, sys, portage
65                                 from portage.cache.flat_hash import md5_database
66                                 if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], md5_database):
67                                         sys.exit(1)
68                         """),),
69
70                         (BASH_BINARY, "-c", "echo %s > %s" %
71                                 tuple(map(portage._shell_quote,
72                                 ("cache-formats = md5-dict pms", layout_conf_path,)))),
73                         egencache_cmd + ("--update",),
74                         (lambda: os.path.exists(md5_cache_dir),),
75                         python_cmd + (textwrap.dedent("""
76                                 import os, sys, portage
77                                 if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb:
78                                         sys.exit(1)
79                         """),),
80                         python_cmd + (textwrap.dedent("""
81                                 import os, sys, portage
82                                 from portage.cache.flat_hash import md5_database
83                                 if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], md5_database):
84                                         sys.exit(1)
85                         """),),
86
87                         # Don't use python -Wd, since the pms format triggers deprecation warnings
88                         # in portdbapi._create_pregen_cache().
89                         (BASH_BINARY, "-c", "echo %s > %s" %
90                                 tuple(map(portage._shell_quote,
91                                 ("cache-formats = pms md5-dict", layout_conf_path,)))),
92                         (portage_python, "-Wi", "-c") + (textwrap.dedent("""
93                                 import os, sys, portage
94                                 if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb:
95                                         sys.exit(1)
96                         """),),
97                         (portage_python, "-Wi", "-c") + (textwrap.dedent("""
98                                 import os, sys, portage
99                                 from portage.cache.metadata import database as pms_database
100                                 if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], pms_database):
101                                         sys.exit(1)
102                         """),),
103
104                         # Test auto-detection and preference for md5-cache when both
105                         # cache formats are available but layout.conf is absent.
106                         (BASH_BINARY, "-c", "rm %s" % portage._shell_quote(layout_conf_path)),
107                         python_cmd + (textwrap.dedent("""
108                                 import os, sys, portage
109                                 if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb:
110                                         sys.exit(1)
111                         """),),
112                         python_cmd + (textwrap.dedent("""
113                                 import os, sys, portage
114                                 from portage.cache.flat_hash import md5_database
115                                 if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], md5_database):
116                                         sys.exit(1)
117                         """),),
118                 )
119
120                 pythonpath =  os.environ.get("PYTHONPATH")
121                 if pythonpath is not None and not pythonpath.strip():
122                         pythonpath = None
123                 if pythonpath is not None and \
124                         pythonpath.split(":")[0] == PORTAGE_PYM_PATH:
125                         pass
126                 else:
127                         if pythonpath is None:
128                                 pythonpath = ""
129                         else:
130                                 pythonpath = ":" + pythonpath
131                         pythonpath = PORTAGE_PYM_PATH + pythonpath
132
133                 env = {
134                         "PATH" : os.environ.get("PATH", ""),
135                         "PORTAGE_OVERRIDE_EPREFIX" : eprefix,
136                         "PORTAGE_PYTHON" : portage_python,
137                         "PORTAGE_REPOSITORIES" : settings.repositories.config_string(),
138                         "PYTHONPATH" : pythonpath,
139                 }
140
141                 if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ:
142                         env["__PORTAGE_TEST_HARDLINK_LOCKS"] = \
143                                 os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"]
144
145                 dirs = [user_config_dir]
146
147                 try:
148                         for d in dirs:
149                                 ensure_dirs(d)
150
151                         if debug:
152                                 # The subprocess inherits both stdout and stderr, for
153                                 # debugging purposes.
154                                 stdout = None
155                         else:
156                                 # The subprocess inherits stderr so that any warnings
157                                 # triggered by python -Wd will be visible.
158                                 stdout = subprocess.PIPE
159
160                         for i, args in enumerate(test_commands):
161
162                                 if hasattr(args[0], '__call__'):
163                                         self.assertTrue(args[0](),
164                                                 "callable at index %s failed" % (i,))
165                                         continue
166
167                                 proc = subprocess.Popen(args,
168                                         env=env, stdout=stdout)
169
170                                 if debug:
171                                         proc.wait()
172                                 else:
173                                         output = proc.stdout.readlines()
174                                         proc.wait()
175                                         proc.stdout.close()
176                                         if proc.returncode != os.EX_OK:
177                                                 for line in output:
178                                                         sys.stderr.write(_unicode_decode(line))
179
180                                 self.assertEqual(os.EX_OK, proc.returncode,
181                                         "command %d failed with args %s" % (i, args,))
182                 finally:
183                         playground.cleanup()