1 # Copyright 2011 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
9 from portage import _unicode_decode
10 from portage.const import PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, USER_CONFIG_PATH
11 from portage.process import find_binary
12 from portage.tests import TestCase
13 from portage.tests.resolver.ResolverPlayground import ResolverPlayground
14 from portage.util import ensure_dirs
16 class SimpleEmergeTestCase(TestCase):
18 def _have_python_xml(self):
20 __import__("xml.etree.ElementTree")
21 __import__("xml.parsers.expat").parsers.expat.ExpatError
22 except (AttributeError, ImportError):
30 install_something = """
34 einfo "called pkg_pretend for $CATEGORY/$PF"
38 einfo "installing something..."
40 echo "blah blah blah" > "${T}"/regular-file
41 doins "${T}"/regular-file
42 dosym regular-file /usr/lib/${P}/symlink || die
44 # Test code for bug #381629, using a copyright symbol encoded with latin-1.
45 # We use $(printf "\\xa9") rather than $'\\xa9', since printf apparently
46 # works in any case, while $'\\xa9' transforms to \\xef\\xbf\\xbd under
47 # some conditions. TODO: Find out why it transforms to \\xef\\xbf\\xbd when
48 # running tests for Python 3.2 (even though it's bash that is ultimately
49 # responsible for performing the transformation).
50 local latin_1_dir=/usr/lib/${P}/latin-1-$(printf "\\xa9")-directory
51 insinto "${latin_1_dir}"
52 echo "blah blah blah" > "${T}"/latin-1-$(printf "\\xa9")-regular-file || die
53 doins "${T}"/latin-1-$(printf "\\xa9")-regular-file
54 dosym latin-1-$(printf "\\xa9")-regular-file ${latin_1_dir}/latin-1-$(printf "\\xa9")-symlink || die
58 einfo "called pkg_config for $CATEGORY/$PF"
62 einfo "called pkg_info for $CATEGORY/$PF"
73 "MISC_CONTENT": install_something,
74 "RDEPEND": "flag? ( dev-libs/B[flag] )",
81 "MISC_CONTENT": install_something,
96 "RDEPEND": "flag? ( dev-libs/B[flag] )",
106 "dev-libs/depclean-me-1": {
113 "app-misc/depclean-me-1": {
118 "RDEPEND": "dev-libs/depclean-me",
123 metadata_xml_files = (
127 "herd" : "base-system",
128 "flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
135 "flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
140 playground = ResolverPlayground(
141 ebuilds=ebuilds, installed=installed, debug=debug)
142 settings = playground.settings
143 eprefix = settings["EPREFIX"]
144 eroot = settings["EROOT"]
145 trees = playground.trees
146 portdb = trees[eroot]["porttree"].dbapi
147 portdir = settings["PORTDIR"]
148 var_cache_edb = os.path.join(eprefix, "var", "cache", "edb")
149 cachedir = os.path.join(var_cache_edb, "dep")
150 cachedir_pregen = os.path.join(portdir, "metadata", "cache")
152 portage_python = portage._python_interpreter
153 ebuild_cmd = (portage_python, "-Wd",
154 os.path.join(PORTAGE_BIN_PATH, "ebuild"))
155 egencache_cmd = (portage_python, "-Wd",
156 os.path.join(PORTAGE_BIN_PATH, "egencache"))
157 emerge_cmd = (portage_python, "-Wd",
158 os.path.join(PORTAGE_BIN_PATH, "emerge"))
159 emaint_cmd = (portage_python, "-Wd",
160 os.path.join(PORTAGE_BIN_PATH, "emaint"))
161 env_update_cmd = (portage_python, "-Wd",
162 os.path.join(PORTAGE_BIN_PATH, "env-update"))
163 fixpackages_cmd = (portage_python, "-Wd",
164 os.path.join(PORTAGE_BIN_PATH, "fixpackages"))
165 portageq_cmd = (portage_python, "-Wd",
166 os.path.join(PORTAGE_BIN_PATH, "portageq"))
167 quickpkg_cmd = (portage_python, "-Wd",
168 os.path.join(PORTAGE_BIN_PATH, "quickpkg"))
169 regenworld_cmd = (portage_python, "-Wd",
170 os.path.join(PORTAGE_BIN_PATH, "regenworld"))
172 rm_binary = find_binary("rm")
173 self.assertEqual(rm_binary is None, False,
174 "rm command not found")
175 rm_cmd = (rm_binary,)
177 egencache_extra_args = []
178 if self._have_python_xml():
179 egencache_extra_args.append("--update-use-local-desc")
181 test_ebuild = portdb.findname("dev-libs/A-1")
182 self.assertFalse(test_ebuild is None)
186 emerge_cmd + ("--version",),
187 emerge_cmd + ("--info",),
188 emerge_cmd + ("--info", "--verbose"),
189 emerge_cmd + ("--list-sets",),
190 emerge_cmd + ("--check-news",),
191 rm_cmd + ("-rf", cachedir),
192 rm_cmd + ("-rf", cachedir_pregen),
193 emerge_cmd + ("--regen",),
194 rm_cmd + ("-rf", cachedir),
195 ({"FEATURES" : "metadata-transfer"},) + \
196 emerge_cmd + ("--regen",),
197 rm_cmd + ("-rf", cachedir),
198 ({"FEATURES" : "metadata-transfer parse-eapi-ebuild-head"},) + \
199 emerge_cmd + ("--regen",),
200 rm_cmd + ("-rf", cachedir),
201 egencache_cmd + ("--update",) + tuple(egencache_extra_args),
202 ({"FEATURES" : "metadata-transfer"},) + \
203 emerge_cmd + ("--metadata",),
204 rm_cmd + ("-rf", cachedir),
205 ({"FEATURES" : "metadata-transfer"},) + \
206 emerge_cmd + ("--metadata",),
207 emerge_cmd + ("--metadata",),
208 rm_cmd + ("-rf", cachedir),
209 emerge_cmd + ("--oneshot", "virtual/foo"),
210 emerge_cmd + ("--pretend", "dev-libs/A"),
211 ebuild_cmd + (test_ebuild, "manifest", "clean", "package", "merge"),
212 emerge_cmd + ("--pretend", "--tree", "--complete-graph", "dev-libs/A"),
213 emerge_cmd + ("-p", "dev-libs/B"),
214 emerge_cmd + ("-B", "dev-libs/B",),
215 emerge_cmd + ("--oneshot", "--usepkg", "dev-libs/B",),
216 emerge_cmd + ("--oneshot", "dev-libs/A",),
217 emerge_cmd + ("--noreplace", "dev-libs/A",),
218 emerge_cmd + ("--config", "dev-libs/A",),
219 emerge_cmd + ("--info", "dev-libs/A", "dev-libs/B"),
220 emerge_cmd + ("--pretend", "--depclean", "--verbose", "dev-libs/B"),
221 emerge_cmd + ("--pretend", "--depclean",),
222 emerge_cmd + ("--depclean",),
223 quickpkg_cmd + ("dev-libs/A",),
224 emerge_cmd + ("--usepkgonly", "dev-libs/A"),
225 emaint_cmd + ("--check", "all"),
226 emaint_cmd + ("--fix", "all"),
229 portageq_cmd + ("match", eroot, "dev-libs/A"),
230 portageq_cmd + ("best_visible", eroot, "dev-libs/A"),
231 portageq_cmd + ("best_visible", eroot, "binary", "dev-libs/A"),
232 portageq_cmd + ("contents", eroot, "dev-libs/A-1"),
233 portageq_cmd + ("metadata", eroot, "ebuild", "dev-libs/A-1", "EAPI", "IUSE", "RDEPEND"),
234 portageq_cmd + ("metadata", eroot, "binary", "dev-libs/A-1", "EAPI", "USE", "RDEPEND"),
235 portageq_cmd + ("metadata", eroot, "installed", "dev-libs/A-1", "EAPI", "USE", "RDEPEND"),
236 portageq_cmd + ("owners", eroot, eroot + "usr"),
237 emerge_cmd + ("-p", eroot + "usr"),
238 emerge_cmd + ("-p", "--unmerge", "-q", eroot + "usr"),
239 emerge_cmd + ("--unmerge", "--quiet", "dev-libs/A"),
240 emerge_cmd + ("-C", "--quiet", "dev-libs/B"),
243 distdir = os.path.join(eprefix, "distdir")
244 pkgdir = os.path.join(eprefix, "pkgdir")
245 fake_bin = os.path.join(eprefix, "bin")
246 portage_tmpdir = os.path.join(eprefix, "var", "tmp", "portage")
247 profile_path = settings.profile_path
248 user_config_dir = os.path.join(os.sep, eprefix, USER_CONFIG_PATH)
251 if not portage.process.sandbox_capable:
252 features.append("-sandbox")
254 # Since egencache ignores settings from the calling environment,
255 # configure it via make.conf.
257 "FEATURES=\"%s\"\n" % (" ".join(features),),
258 "PORTDIR=\"%s\"\n" % (portdir,),
261 path = os.environ.get("PATH")
262 if path is not None and not path.strip():
268 path = fake_bin + path
270 pythonpath = os.environ.get("PYTHONPATH")
271 if pythonpath is not None and not pythonpath.strip():
273 if pythonpath is not None and \
274 pythonpath.split(":")[0] == PORTAGE_PYM_PATH:
277 if pythonpath is None:
280 pythonpath = ":" + pythonpath
281 pythonpath = PORTAGE_PYM_PATH + pythonpath
284 "__PORTAGE_TEST_EPREFIX" : eprefix,
287 "EMERGE_WARNING_DELAY" : "0",
292 "PORTAGE_GRPNAME" : os.environ["PORTAGE_GRPNAME"],
293 "PORTAGE_INST_GID" : str(portage.data.portage_gid),
294 "PORTAGE_INST_UID" : str(portage.data.portage_uid),
295 "PORTAGE_PYTHON" : portage_python,
296 "PORTAGE_TMPDIR" : portage_tmpdir,
297 "PORTAGE_USERNAME" : os.environ["PORTAGE_USERNAME"],
298 "PYTHONPATH" : pythonpath,
301 updates_dir = os.path.join(portdir, "profiles", "updates")
302 dirs = [cachedir, cachedir_pregen, distdir, fake_bin,
303 portage_tmpdir, updates_dir,
304 user_config_dir, var_cache_edb]
305 true_symlinks = ["chown", "chgrp"]
306 true_binary = find_binary("true")
307 self.assertEqual(true_binary is None, False,
308 "true command not found")
312 with open(os.path.join(user_config_dir, "make.conf"), 'w') as f:
313 for line in make_conf:
315 for x in true_symlinks:
316 os.symlink(true_binary, os.path.join(fake_bin, x))
317 with open(os.path.join(var_cache_edb, "counter"), 'wb') as f:
319 # non-empty system set keeps --depclean quiet
320 with open(os.path.join(profile_path, "packages"), 'w') as f:
321 f.write("*dev-libs/token-system-pkg")
322 for cp, xml_data in metadata_xml_files:
323 with open(os.path.join(portdir, cp, "metadata.xml"), 'w') as f:
324 f.write(playground.metadata_xml_template % xml_data)
325 with open(os.path.join(updates_dir, "1Q-2010"), 'w') as f:
327 slotmove =app-doc/pms-3 2 3
328 move dev-util/git dev-vcs/git
332 # The subprocess inherits both stdout and stderr, for
333 # debugging purposes.
336 # The subprocess inherits stderr so that any warnings
337 # triggered by python -Wd will be visible.
338 stdout = subprocess.PIPE
340 for args in test_commands:
342 if isinstance(args[0], dict):
343 local_env = env.copy()
344 local_env.update(args[0])
349 proc = subprocess.Popen(args,
350 env=local_env, stdout=stdout)
355 output = proc.stdout.readlines()
358 if proc.returncode != os.EX_OK:
360 sys.stderr.write(_unicode_decode(line))
362 self.assertEqual(os.EX_OK, proc.returncode,
363 "emerge failed with args %s" % (args,))