[ci skip] Fix contributors name in CHANGES.txt
[scons.git] / src / test_setup.py
blob5db21a1e9a5878b0dbc740ebe92f629788889a59
1 #!/usr/bin/env python
3 # __COPYRIGHT__
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
26 """
27 Test how the setup.py script installs SCons.
29 Note that this is an installation test, not a functional test, so the
30 name of this script doesn't end in *Tests.py.
31 """
33 import os
34 import os.path
35 import shutil
36 import sys
38 try: WindowsError
39 except NameError: WindowsError = OSError
41 import TestSCons
43 version = TestSCons.TestSCons.scons_version
45 scons_version = 'scons-%s' % version
47 python = TestSCons.python
49 class MyTestSCons(TestSCons.TestSCons):
51 _lib_modules = [
52 # A representative smattering of build engine modules.
53 '__init__.py',
54 'Action.py',
55 'Builder.py',
56 'Environment.py',
57 'Util.py',
60 _base_scripts = [
61 'scons',
62 'sconsign',
65 _version_scripts = [
66 'scons-%s' % version,
67 'sconsign-%s' % version,
70 _bat_scripts = [
71 'scons.bat',
74 _bat_version_scripts = [
75 'scons-%s.bat' % version,
78 _man_pages = [
79 'scons.1',
80 'sconsign.1',
83 def __init__(self):
84 super().__init__()
85 self.root = self.workpath('root')
86 self.prefix = self.root + os.path.splitdrive(sys.prefix)[1]
88 if sys.platform == 'win32':
89 self.bin_dir = os.path.join(self.prefix, 'Scripts')
90 self.bat_dir = self.prefix
91 self.standalone_lib = os.path.join(self.prefix, 'scons')
92 self.standard_lib = os.path.join(self.prefix,
93 'Lib',
94 'site-packages',
95 '')
96 self.version_lib = os.path.join(self.prefix, scons_version)
97 self.man_dir = os.path.join(self.prefix, 'Doc')
98 else:
99 self.bin_dir = os.path.join(self.prefix, 'bin')
100 self.bat_dir = self.bin_dir
101 self.lib_dir = os.path.join(self.prefix, 'lib')
102 self.standalone_lib = os.path.join(self.lib_dir, 'scons')
103 self.standard_lib = os.path.join(self.lib_dir,
104 'python%s' % sys.version[:3],
105 'site-packages',
107 self.version_lib = os.path.join(self.lib_dir, scons_version)
108 self.man_dir = os.path.join(self.prefix, 'man', 'man1')
110 self.prepend_bin_dir = lambda p: os.path.join(self.bin_dir, p)
111 self.prepend_bat_dir = lambda p: os.path.join(self.bat_dir, p)
112 self.prepend_man_dir = lambda p: os.path.join(self.man_dir, p)
114 def run(self, *args, **kw):
115 kw['chdir'] = scons_version
116 kw['program'] = python
117 kw['stderr'] = None
118 return TestSCons.TestSCons.run(self, *args, **kw)
120 def remove(self, dir):
121 try: shutil.rmtree(dir)
122 except (OSError, WindowsError): pass
124 def stdout_lines(self):
125 return self.stdout().split('\n')
128 def lib_line(self, lib):
129 return 'Installed SCons library modules into %s' % lib
131 def lib_paths(self, lib_dir):
132 return [os.path.join(lib_dir, 'SCons', p) for p in self._lib_modules]
134 def scripts_line(self):
135 return 'Installed SCons scripts into %s' % self.bin_dir
137 def base_script_paths(self):
138 scripts = self._base_scripts
139 return list(map(self.prepend_bin_dir, scripts))
141 def version_script_paths(self):
142 scripts = self._version_scripts
143 return list(map(self.prepend_bin_dir, scripts))
145 def bat_script_paths(self):
146 scripts = self._bat_scripts + self._bat_version_scripts
147 return list(map(self.prepend_bat_dir, scripts))
149 def man_page_line(self):
150 return 'Installed SCons man pages into %s' % self.man_dir
152 def man_page_paths(self):
153 return list(map(self.prepend_man_dir, self._man_pages))
156 def must_have_installed(self, paths):
157 for p in paths:
158 self.must_exist(p)
160 def must_not_have_installed(self, paths):
161 for p in paths:
162 self.must_not_exist(p)
164 try:
165 cwd = os.environ['SCONS_CWD']
166 except KeyError:
167 cwd = os.getcwd()
169 test = MyTestSCons()
171 test.subdir(test.root)
173 tar_gz = os.path.join(cwd, 'build', 'dist', '%s.tar.gz' % scons_version)
174 zip = os.path.join(cwd, 'build', 'dist', '%s.zip' % scons_version)
176 if os.path.isfile(zip):
177 try:
178 import zipfile
179 except ImportError:
180 pass
181 else:
182 with zipfile.ZipFile(zip, 'r') as zf:
184 for name in zf.namelist():
185 dname = os.path.dirname(name)
186 try:
187 os.makedirs(dname)
188 except FileExistsError:
189 pass
190 # if the file exists, then delete it before writing
191 # to it so that we don't end up trying to write to a symlink:
192 if os.path.isfile(name) or os.path.islink(name):
193 os.unlink(name)
194 if not os.path.isdir(name):
195 with open(name, 'w') as ofp:
196 ofp.write(zf.read(name))
198 if not os.path.isdir(scons_version) and os.path.isfile(tar_gz):
199 # Unpack the .tar.gz file. This should create the scons_version/
200 # subdirectory from which we execute the setup.py script therein.
201 os.system("gunzip -c %s | tar xf -" % tar_gz)
203 if not os.path.isdir(scons_version):
204 print("Cannot test package installation, found none of the following packages:")
205 print("\t" + tar_gz)
206 print("\t" + zip)
207 test.no_result(1)
209 # Verify that a virgin installation installs the version library,
210 # the scripts and (on UNIX/Linux systems) the man pages.
211 test.run(arguments = 'setup.py install --root=%s' % test.root)
212 test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines())
213 test.must_have_installed(test.lib_paths(test.version_lib))
215 # Verify that --standard-lib installs into the Python standard library.
216 test.run(arguments = 'setup.py install --root=%s --standard-lib' % test.root)
217 test.fail_test(not test.lib_line(test.standard_lib) in test.stdout_lines())
218 test.must_have_installed(test.lib_paths(test.standard_lib))
220 # Verify that --standalone-lib installs the standalone library.
221 test.run(arguments = 'setup.py install --root=%s --standalone-lib' % test.root)
222 test.fail_test(not test.lib_line(test.standalone_lib) in test.stdout_lines())
223 test.must_have_installed(test.lib_paths(test.standalone_lib))
225 # Verify that --version-lib installs into a version-specific library directory.
226 test.run(arguments = 'setup.py install --root=%s --version-lib' % test.root)
227 test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines())
229 # Now that all of the libraries are in place,
230 # verify that a default installation still installs the version library.
231 test.run(arguments = 'setup.py install --root=%s' % test.root)
232 test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines())
234 test.remove(test.version_lib)
236 # Now with only the standard and standalone libraries in place,
237 # verify that a default installation still installs the version library.
238 test.run(arguments = 'setup.py install --root=%s' % test.root)
239 test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines())
241 test.remove(test.version_lib)
242 test.remove(test.standalone_lib)
244 # Now with only the standard libraries in place,
245 # verify that a default installation still installs the version library.
246 test.run(arguments = 'setup.py install --root=%s' % test.root)
247 test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines())
252 test.run(arguments = 'setup.py install --root=%s' % test.root)
253 test.fail_test(not test.scripts_line() in test.stdout_lines())
254 if sys.platform == 'win32':
255 test.must_have_installed(test.base_script_paths())
256 test.must_have_installed(test.version_script_paths())
257 test.must_have_installed(test.bat_script_paths())
258 else:
259 test.must_have_installed(test.base_script_paths())
260 test.must_have_installed(test.version_script_paths())
261 test.must_not_have_installed(test.bat_script_paths())
263 test.remove(test.prefix)
265 test.run(arguments = 'setup.py install --root=%s --no-install-bat' % test.root)
266 test.fail_test(not test.scripts_line() in test.stdout_lines())
267 test.must_have_installed(test.base_script_paths())
268 test.must_have_installed(test.version_script_paths())
269 test.must_not_have_installed(test.bat_script_paths())
271 test.remove(test.prefix)
273 test.run(arguments = 'setup.py install --root=%s --install-bat' % test.root)
274 test.fail_test(not test.scripts_line() in test.stdout_lines())
275 test.must_have_installed(test.base_script_paths())
276 test.must_have_installed(test.version_script_paths())
277 test.must_have_installed(test.bat_script_paths())
279 test.remove(test.prefix)
281 test.run(arguments = 'setup.py install --root=%s --no-scons-script' % test.root)
282 test.fail_test(not test.scripts_line() in test.stdout_lines())
283 test.must_not_have_installed(test.base_script_paths())
284 test.must_have_installed(test.version_script_paths())
285 # Doesn't matter whether we installed the .bat scripts or not.
287 test.remove(test.prefix)
289 test.run(arguments = 'setup.py install --root=%s --no-version-script' % test.root)
290 test.fail_test(not test.scripts_line() in test.stdout_lines())
291 test.must_have_installed(test.base_script_paths())
292 test.must_not_have_installed(test.version_script_paths())
293 # Doesn't matter whether we installed the .bat scripts or not.
297 test.remove(test.man_dir)
299 test.run(arguments = 'setup.py install --root=%s' % test.root)
300 if sys.platform == 'win32':
301 test.fail_test(test.man_page_line() in test.stdout_lines())
302 test.must_not_have_installed(test.man_page_paths())
303 else:
304 test.fail_test(not test.man_page_line() in test.stdout_lines())
305 test.must_have_installed(test.man_page_paths())
307 test.remove(test.man_dir)
309 test.run(arguments = 'setup.py install --root=%s --no-install-man' % test.root)
310 test.fail_test(test.man_page_line() in test.stdout_lines())
311 test.must_not_have_installed(test.man_page_paths())
313 test.remove(test.man_dir)
315 test.run(arguments = 'setup.py install --root=%s --install-man' % test.root)
316 test.fail_test(not test.man_page_line() in test.stdout_lines())
317 test.must_have_installed(test.man_page_paths())
321 # Verify that we don't warn about the directory in which we've
322 # installed the modules when using a non-standard prefix.
323 other_prefix = test.workpath('other-prefix')
324 test.subdir(other_prefix)
325 test.run(arguments = 'setup.py install --prefix=%s' % other_prefix)
326 test.fail_test("you'll have to change the search path yourself" in test.stderr())
328 # All done.
329 test.pass_test()
331 # Local Variables:
332 # tab-width:4
333 # indent-tabs-mode:nil
334 # End:
335 # vim: set expandtab tabstop=4 shiftwidth=4: