7d8426b9b991eb0f1390d3a4805c7f100e1292af
[portage.git] / pym / portage / tests / emerge / test_emerge_slot_abi.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
7 import portage
8 from portage import os
9 from portage import _unicode_decode
10 from portage.const import (BASH_BINARY, PORTAGE_BIN_PATH,
11         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
16
17 class SlotAbiEmergeTestCase(TestCase):
18
19         def testSlotAbiEmerge(self):
20
21                 debug = False
22
23                 ebuilds = {
24                         "dev-libs/glib-1.2.10" : {
25                                 "SLOT": "1"
26                         },
27                         "dev-libs/glib-2.30.2" : {
28                                 "EAPI": "4-slot-abi",
29                                 "SLOT": "2/2.30"
30                         },
31                         "dev-libs/glib-2.32.3" : {
32                                 "EAPI": "4-slot-abi",
33                                 "SLOT": "2/2.32"
34                         },
35                         "dev-libs/dbus-glib-0.98" : {
36                                 "EAPI": "4-slot-abi",
37                                 "DEPEND":  "dev-libs/glib:2=",
38                                 "RDEPEND": "dev-libs/glib:2="
39                         },
40                 }
41                 installed = {
42                         "dev-libs/glib-1.2.10" : {
43                                 "EAPI": "4-slot-abi",
44                                 "SLOT": "1"
45                         },
46                         "dev-libs/glib-2.30.2" : {
47                                 "EAPI": "4-slot-abi",
48                                 "SLOT": "2/2.30"
49                         },
50                         "dev-libs/dbus-glib-0.98" : {
51                                 "EAPI": "4-slot-abi",
52                                 "DEPEND":  "dev-libs/glib:2/2.30=",
53                                 "RDEPEND": "dev-libs/glib:2/2.30="
54                         },
55                 }
56
57                 world = ["dev-libs/glib:1", "dev-libs/dbus-glib"]
58
59                 playground = ResolverPlayground(ebuilds=ebuilds,
60                         installed=installed, world=world, debug=debug)
61                 settings = playground.settings
62                 eprefix = settings["EPREFIX"]
63                 eroot = settings["EROOT"]
64                 trees = playground.trees
65                 portdb = trees[eroot]["porttree"].dbapi
66                 vardb = trees[eroot]["vartree"].dbapi
67                 var_cache_edb = os.path.join(eprefix, "var", "cache", "edb")
68                 user_config_dir = os.path.join(eprefix, USER_CONFIG_PATH)
69                 package_mask_path = os.path.join(user_config_dir, "package.mask")
70
71                 portage_python = portage._python_interpreter
72                 ebuild_cmd = (portage_python, "-Wd",
73                         os.path.join(PORTAGE_BIN_PATH, "ebuild"))
74                 emerge_cmd = (portage_python, "-Wd",
75                         os.path.join(PORTAGE_BIN_PATH, "emerge"))
76
77                 test_ebuild = portdb.findname("dev-libs/dbus-glib-0.98")
78                 self.assertFalse(test_ebuild is None)
79
80                 test_commands = (
81                         emerge_cmd + ("--oneshot", "dev-libs/glib",),
82                         (lambda: "dev-libs/glib:2/2.32=" in vardb.aux_get("dev-libs/dbus-glib-0.98", ["RDEPEND"])[0],),
83                         (BASH_BINARY, "-c", "echo %s >> %s" %
84                                 tuple(map(portage._shell_quote,
85                                 (">=dev-libs/glib-2.32", package_mask_path,)))),
86                         emerge_cmd + ("--oneshot", "dev-libs/glib",),
87                         (lambda: "dev-libs/glib:2/2.30=" in vardb.aux_get("dev-libs/dbus-glib-0.98", ["RDEPEND"])[0],),
88                 )
89
90                 distdir = playground.distdir
91                 pkgdir = playground.pkgdir
92                 fake_bin = os.path.join(eprefix, "bin")
93                 portage_tmpdir = os.path.join(eprefix, "var", "tmp", "portage")
94                 profile_path = settings.profile_path
95
96                 path =  os.environ.get("PATH")
97                 if path is not None and not path.strip():
98                         path = None
99                 if path is None:
100                         path = ""
101                 else:
102                         path = ":" + path
103                 path = fake_bin + path
104
105                 pythonpath =  os.environ.get("PYTHONPATH")
106                 if pythonpath is not None and not pythonpath.strip():
107                         pythonpath = None
108                 if pythonpath is not None and \
109                         pythonpath.split(":")[0] == PORTAGE_PYM_PATH:
110                         pass
111                 else:
112                         if pythonpath is None:
113                                 pythonpath = ""
114                         else:
115                                 pythonpath = ":" + pythonpath
116                         pythonpath = PORTAGE_PYM_PATH + pythonpath
117
118                 env = {
119                         "PORTAGE_OVERRIDE_EPREFIX" : eprefix,
120                         "PATH" : path,
121                         "PORTAGE_PYTHON" : portage_python,
122                         "PORTAGE_REPOSITORIES" : settings.repositories.config_string(),
123                         "PYTHONPATH" : pythonpath,
124                 }
125
126                 if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ:
127                         env["__PORTAGE_TEST_HARDLINK_LOCKS"] = \
128                                 os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"]
129
130                 dirs = [distdir, fake_bin, portage_tmpdir,
131                         user_config_dir, var_cache_edb]
132                 true_symlinks = ["chown", "chgrp"]
133                 true_binary = find_binary("true")
134                 self.assertEqual(true_binary is None, False,
135                         "true command not found")
136                 try:
137                         for d in dirs:
138                                 ensure_dirs(d)
139                         for x in true_symlinks:
140                                 os.symlink(true_binary, os.path.join(fake_bin, x))
141                         with open(os.path.join(var_cache_edb, "counter"), 'wb') as f:
142                                 f.write(b"100")
143                         # non-empty system set keeps --depclean quiet
144                         with open(os.path.join(profile_path, "packages"), 'w') as f:
145                                 f.write("*dev-libs/token-system-pkg")
146
147                         if debug:
148                                 # The subprocess inherits both stdout and stderr, for
149                                 # debugging purposes.
150                                 stdout = None
151                         else:
152                                 # The subprocess inherits stderr so that any warnings
153                                 # triggered by python -Wd will be visible.
154                                 stdout = subprocess.PIPE
155
156                         for i, args in enumerate(test_commands):
157
158                                 if hasattr(args[0], '__call__'):
159                                         self.assertTrue(args[0](),
160                                                 "callable at index %s failed" % (i,))
161                                         continue
162
163                                 proc = subprocess.Popen(args,
164                                         env=env, stdout=stdout)
165
166                                 if debug:
167                                         proc.wait()
168                                 else:
169                                         output = proc.stdout.readlines()
170                                         proc.wait()
171                                         proc.stdout.close()
172                                         if proc.returncode != os.EX_OK:
173                                                 for line in output:
174                                                         sys.stderr.write(_unicode_decode(line))
175
176                                 self.assertEqual(os.EX_OK, proc.returncode,
177                                         "emerge failed with args %s" % (args,))
178                 finally:
179                         playground.cleanup()