1 # Copyright 2011-2014 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 (BASH_BINARY, PORTAGE_BASE_PATH,
11 PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, USER_CONFIG_PATH)
12 from portage.process import find_binary
13 from portage.tests import TestCase
14 from portage.tests.resolver.ResolverPlayground import ResolverPlayground
15 from portage.util import ensure_dirs
17 class SimpleEmergeTestCase(TestCase):
19 def _have_python_xml(self):
21 __import__("xml.etree.ElementTree")
22 __import__("xml.parsers.expat").parsers.expat.ExpatError
23 except (AttributeError, ImportError):
31 install_something = """
35 einfo "called pkg_pretend for $CATEGORY/$PF"
39 einfo "installing something..."
41 echo "blah blah blah" > "${T}"/regular-file
42 doins "${T}"/regular-file
43 dosym regular-file /usr/lib/${P}/symlink || die
45 # Test code for bug #381629, using a copyright symbol encoded with latin-1.
46 # We use $(printf "\\xa9") rather than $'\\xa9', since printf apparently
47 # works in any case, while $'\\xa9' transforms to \\xef\\xbf\\xbd under
48 # some conditions. TODO: Find out why it transforms to \\xef\\xbf\\xbd when
49 # running tests for Python 3.2 (even though it's bash that is ultimately
50 # responsible for performing the transformation).
51 local latin_1_dir=/usr/lib/${P}/latin-1-$(printf "\\xa9")-directory
52 insinto "${latin_1_dir}"
53 echo "blah blah blah" > "${T}"/latin-1-$(printf "\\xa9")-regular-file || die
54 doins "${T}"/latin-1-$(printf "\\xa9")-regular-file
55 dosym latin-1-$(printf "\\xa9")-regular-file ${latin_1_dir}/latin-1-$(printf "\\xa9")-symlink || die
59 einfo "called pkg_config for $CATEGORY/$PF"
63 einfo "called pkg_info for $CATEGORY/$PF"
67 einfo "called pkg_preinst for $CATEGORY/$PF"
69 # Test that has_version and best_version work correctly with
70 # prefix (involves internal ROOT -> EROOT calculation in order
71 # to support ROOT override via the environment with EAPIs 3
72 # and later which support prefix).
73 if has_version $CATEGORY/$PN:$SLOT ; then
74 einfo "has_version detects an installed instance of $CATEGORY/$PN:$SLOT"
75 einfo "best_version reports that the installed instance is $(best_version $CATEGORY/$PN:$SLOT)"
77 einfo "has_version does not detect an installed instance of $CATEGORY/$PN:$SLOT"
79 if [[ ${EPREFIX} != ${PORTAGE_OVERRIDE_EPREFIX} ]] ; then
80 if has_version --host-root $CATEGORY/$PN:$SLOT ; then
81 einfo "has_version --host-root detects an installed instance of $CATEGORY/$PN:$SLOT"
82 einfo "best_version --host-root reports that the installed instance is $(best_version $CATEGORY/$PN:$SLOT)"
84 einfo "has_version --host-root does not detect an installed instance of $CATEGORY/$PN:$SLOT"
97 "MISC_CONTENT": install_something,
98 "RDEPEND": "flag? ( dev-libs/B[flag] )",
105 "MISC_CONTENT": install_something,
120 "RDEPEND": "flag? ( dev-libs/B[flag] )",
130 "dev-libs/depclean-me-1": {
137 "app-misc/depclean-me-1": {
142 "RDEPEND": "dev-libs/depclean-me",
147 metadata_xml_files = (
151 "herd" : "base-system",
152 "flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
159 "flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
164 playground = ResolverPlayground(
165 ebuilds=ebuilds, installed=installed, debug=debug)
166 settings = playground.settings
167 eprefix = settings["EPREFIX"]
168 eroot = settings["EROOT"]
169 trees = playground.trees
170 portdb = trees[eroot]["porttree"].dbapi
171 test_repo_location = settings.repositories["test_repo"].location
172 var_cache_edb = os.path.join(eprefix, "var", "cache", "edb")
173 cachedir = os.path.join(var_cache_edb, "dep")
174 cachedir_pregen = os.path.join(test_repo_location, "metadata", "md5-cache")
176 portage_python = portage._python_interpreter
177 dispatch_conf_cmd = (portage_python, "-bb", "-Wd",
178 os.path.join(PORTAGE_BIN_PATH, "dispatch-conf"))
179 ebuild_cmd = (portage_python, "-bb", "-Wd",
180 os.path.join(PORTAGE_BIN_PATH, "ebuild"))
181 egencache_cmd = (portage_python, "-bb", "-Wd",
182 os.path.join(PORTAGE_BIN_PATH, "egencache"),
183 "--repo", "test_repo",
184 "--repositories-configuration", settings.repositories.config_string())
185 emerge_cmd = (portage_python, "-bb", "-Wd",
186 os.path.join(PORTAGE_BIN_PATH, "emerge"))
187 emaint_cmd = (portage_python, "-bb", "-Wd",
188 os.path.join(PORTAGE_BIN_PATH, "emaint"))
189 env_update_cmd = (portage_python, "-bb", "-Wd",
190 os.path.join(PORTAGE_BIN_PATH, "env-update"))
191 etc_update_cmd = (BASH_BINARY,
192 os.path.join(PORTAGE_BIN_PATH, "etc-update"))
193 fixpackages_cmd = (portage_python, "-bb", "-Wd",
194 os.path.join(PORTAGE_BIN_PATH, "fixpackages"))
195 portageq_cmd = (portage_python, "-bb", "-Wd",
196 os.path.join(PORTAGE_BIN_PATH, "portageq"))
197 quickpkg_cmd = (portage_python, "-bb", "-Wd",
198 os.path.join(PORTAGE_BIN_PATH, "quickpkg"))
199 regenworld_cmd = (portage_python, "-bb", "-Wd",
200 os.path.join(PORTAGE_BIN_PATH, "regenworld"))
202 rm_binary = find_binary("rm")
203 self.assertEqual(rm_binary is None, False,
204 "rm command not found")
205 rm_cmd = (rm_binary,)
207 egencache_extra_args = []
208 if self._have_python_xml():
209 egencache_extra_args.append("--update-use-local-desc")
211 test_ebuild = portdb.findname("dev-libs/A-1")
212 self.assertFalse(test_ebuild is None)
214 cross_prefix = os.path.join(eprefix, "cross_prefix")
218 portageq_cmd + ("envvar", "-v", "CONFIG_PROTECT", "EROOT",
219 "PORTAGE_CONFIGROOT", "PORTAGE_TMPDIR", "USERLAND"),
222 emerge_cmd + ("--version",),
223 emerge_cmd + ("--info",),
224 emerge_cmd + ("--info", "--verbose"),
225 emerge_cmd + ("--list-sets",),
226 emerge_cmd + ("--check-news",),
227 rm_cmd + ("-rf", cachedir),
228 rm_cmd + ("-rf", cachedir_pregen),
229 emerge_cmd + ("--regen",),
230 rm_cmd + ("-rf", cachedir),
231 ({"FEATURES" : "metadata-transfer"},) + \
232 emerge_cmd + ("--regen",),
233 rm_cmd + ("-rf", cachedir),
234 ({"FEATURES" : "metadata-transfer"},) + \
235 emerge_cmd + ("--regen",),
236 rm_cmd + ("-rf", cachedir),
237 egencache_cmd + ("--update",) + tuple(egencache_extra_args),
238 ({"FEATURES" : "metadata-transfer"},) + \
239 emerge_cmd + ("--metadata",),
240 rm_cmd + ("-rf", cachedir),
241 ({"FEATURES" : "metadata-transfer"},) + \
242 emerge_cmd + ("--metadata",),
243 emerge_cmd + ("--metadata",),
244 rm_cmd + ("-rf", cachedir),
245 emerge_cmd + ("--oneshot", "virtual/foo"),
246 emerge_cmd + ("--pretend", "dev-libs/A"),
247 ebuild_cmd + (test_ebuild, "manifest", "clean", "package", "merge"),
248 emerge_cmd + ("--pretend", "--tree", "--complete-graph", "dev-libs/A"),
249 emerge_cmd + ("-p", "dev-libs/B"),
250 emerge_cmd + ("-B", "dev-libs/B",),
251 emerge_cmd + ("--oneshot", "--usepkg", "dev-libs/B",),
253 # trigger clean prior to pkg_pretend as in bug #390711
254 ebuild_cmd + (test_ebuild, "unpack"),
255 emerge_cmd + ("--oneshot", "dev-libs/A",),
257 emerge_cmd + ("--noreplace", "dev-libs/A",),
258 emerge_cmd + ("--config", "dev-libs/A",),
259 emerge_cmd + ("--info", "dev-libs/A", "dev-libs/B"),
260 emerge_cmd + ("--pretend", "--depclean", "--verbose", "dev-libs/B"),
261 emerge_cmd + ("--pretend", "--depclean",),
262 emerge_cmd + ("--depclean",),
263 quickpkg_cmd + ("dev-libs/A",),
264 emerge_cmd + ("--usepkgonly", "dev-libs/A"),
265 emaint_cmd + ("--check", "all"),
266 emaint_cmd + ("--fix", "all"),
269 portageq_cmd + ("match", eroot, "dev-libs/A"),
270 portageq_cmd + ("best_visible", eroot, "dev-libs/A"),
271 portageq_cmd + ("best_visible", eroot, "binary", "dev-libs/A"),
272 portageq_cmd + ("contents", eroot, "dev-libs/A-1"),
273 portageq_cmd + ("metadata", eroot, "ebuild", "dev-libs/A-1", "EAPI", "IUSE", "RDEPEND"),
274 portageq_cmd + ("metadata", eroot, "binary", "dev-libs/A-1", "EAPI", "USE", "RDEPEND"),
275 portageq_cmd + ("metadata", eroot, "installed", "dev-libs/A-1", "EAPI", "USE", "RDEPEND"),
276 portageq_cmd + ("owners", eroot, eroot + "usr"),
277 emerge_cmd + ("-p", eroot + "usr"),
278 emerge_cmd + ("-p", "--unmerge", "-q", eroot + "usr"),
279 emerge_cmd + ("--unmerge", "--quiet", "dev-libs/A"),
280 emerge_cmd + ("-C", "--quiet", "dev-libs/B"),
282 # Test cross-prefix usage, including chpathtool for binpkgs.
283 ({"EPREFIX" : cross_prefix},) + \
284 emerge_cmd + ("--usepkgonly", "dev-libs/A"),
285 ({"EPREFIX" : cross_prefix},) + \
286 portageq_cmd + ("has_version", cross_prefix, "dev-libs/A"),
287 ({"EPREFIX" : cross_prefix},) + \
288 portageq_cmd + ("has_version", cross_prefix, "dev-libs/B"),
289 ({"EPREFIX" : cross_prefix},) + \
290 emerge_cmd + ("-C", "--quiet", "dev-libs/B"),
291 ({"EPREFIX" : cross_prefix},) + \
292 emerge_cmd + ("-C", "--quiet", "dev-libs/A"),
293 ({"EPREFIX" : cross_prefix},) + \
294 emerge_cmd + ("dev-libs/A",),
295 ({"EPREFIX" : cross_prefix},) + \
296 portageq_cmd + ("has_version", cross_prefix, "dev-libs/A"),
297 ({"EPREFIX" : cross_prefix},) + \
298 portageq_cmd + ("has_version", cross_prefix, "dev-libs/B"),
301 distdir = playground.distdir
302 pkgdir = playground.pkgdir
303 fake_bin = os.path.join(eprefix, "bin")
304 portage_tmpdir = os.path.join(eprefix, "var", "tmp", "portage")
305 profile_path = settings.profile_path
306 user_config_dir = os.path.join(os.sep, eprefix, USER_CONFIG_PATH)
308 path = os.environ.get("PATH")
309 if path is not None and not path.strip():
315 path = fake_bin + path
317 pythonpath = os.environ.get("PYTHONPATH")
318 if pythonpath is not None and not pythonpath.strip():
320 if pythonpath is not None and \
321 pythonpath.split(":")[0] == PORTAGE_PYM_PATH:
324 if pythonpath is None:
327 pythonpath = ":" + pythonpath
328 pythonpath = PORTAGE_PYM_PATH + pythonpath
331 "PORTAGE_OVERRIDE_EPREFIX" : eprefix,
334 "EMERGE_WARNING_DELAY" : "0",
339 "PORTAGE_INST_GID" : str(portage.data.portage_gid),
340 "PORTAGE_INST_UID" : str(portage.data.portage_uid),
341 "PORTAGE_PYTHON" : portage_python,
342 "PORTAGE_REPOSITORIES" : settings.repositories.config_string(),
343 "PORTAGE_TMPDIR" : portage_tmpdir,
344 "PYTHONPATH" : pythonpath,
345 "__PORTAGE_TEST_PATH_OVERRIDE" : fake_bin,
348 if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ:
349 env["__PORTAGE_TEST_HARDLINK_LOCKS"] = \
350 os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"]
352 updates_dir = os.path.join(test_repo_location, "profiles", "updates")
353 dirs = [cachedir, cachedir_pregen, distdir, fake_bin,
354 portage_tmpdir, updates_dir,
355 user_config_dir, var_cache_edb]
356 etc_symlinks = ("dispatch-conf.conf", "etc-update.conf")
357 # Override things that may be unavailable, or may have portability
358 # issues when running tests in exotic environments.
359 # prepstrip - bug #447810 (bash read builtin EINTR problem)
360 true_symlinks = ["find", "prepstrip", "sed", "scanelf"]
361 true_binary = find_binary("true")
362 self.assertEqual(true_binary is None, False,
363 "true command not found")
367 for x in true_symlinks:
368 os.symlink(true_binary, os.path.join(fake_bin, x))
369 for x in etc_symlinks:
370 os.symlink(os.path.join(PORTAGE_BASE_PATH, "cnf", x),
371 os.path.join(eprefix, "etc", x))
372 with open(os.path.join(var_cache_edb, "counter"), 'wb') as f:
374 # non-empty system set keeps --depclean quiet
375 with open(os.path.join(profile_path, "packages"), 'w') as f:
376 f.write("*dev-libs/token-system-pkg")
377 for cp, xml_data in metadata_xml_files:
378 with open(os.path.join(test_repo_location, cp, "metadata.xml"), 'w') as f:
379 f.write(playground.metadata_xml_template % xml_data)
380 with open(os.path.join(updates_dir, "1Q-2010"), 'w') as f:
382 slotmove =app-doc/pms-3 2 3
383 move dev-util/git dev-vcs/git
387 # The subprocess inherits both stdout and stderr, for
388 # debugging purposes.
391 # The subprocess inherits stderr so that any warnings
392 # triggered by python -Wd will be visible.
393 stdout = subprocess.PIPE
395 for args in test_commands:
397 if isinstance(args[0], dict):
398 local_env = env.copy()
399 local_env.update(args[0])
404 proc = subprocess.Popen(args,
405 env=local_env, stdout=stdout)
410 output = proc.stdout.readlines()
413 if proc.returncode != os.EX_OK:
415 sys.stderr.write(_unicode_decode(line))
417 self.assertEqual(os.EX_OK, proc.returncode,
418 "emerge failed with args %s" % (args,))