ยปCore Development>Code coverage>Lib/distutils/tests/test_sdist.py

Python code coverage for Lib/distutils/tests/test_sdist.py

#countcontent
1n/a"""Tests for distutils.command.sdist."""
2n/aimport os
3n/aimport tarfile
4n/aimport unittest
5n/aimport warnings
6n/aimport zipfile
7n/afrom os.path import join
8n/afrom textwrap import dedent
9n/afrom test.support import captured_stdout, check_warnings, run_unittest
10n/a
11n/atry:
12n/a import zlib
13n/a ZLIB_SUPPORT = True
14n/aexcept ImportError:
15n/a ZLIB_SUPPORT = False
16n/a
17n/atry:
18n/a import grp
19n/a import pwd
20n/a UID_GID_SUPPORT = True
21n/aexcept ImportError:
22n/a UID_GID_SUPPORT = False
23n/a
24n/afrom distutils.command.sdist import sdist, show_formats
25n/afrom distutils.core import Distribution
26n/afrom distutils.tests.test_config import BasePyPIRCCommandTestCase
27n/afrom distutils.errors import DistutilsOptionError
28n/afrom distutils.spawn import find_executable
29n/afrom distutils.log import WARN
30n/afrom distutils.filelist import FileList
31n/afrom distutils.archive_util import ARCHIVE_FORMATS
32n/a
33n/aSETUP_PY = """
34n/afrom distutils.core import setup
35n/aimport somecode
36n/a
37n/asetup(name='fake')
38n/a"""
39n/a
40n/aMANIFEST = """\
41n/a# file GENERATED by distutils, do NOT edit
42n/aREADME
43n/abuildout.cfg
44n/ainroot.txt
45n/asetup.py
46n/adata%(sep)sdata.dt
47n/ascripts%(sep)sscript.py
48n/asome%(sep)sfile.txt
49n/asome%(sep)sother_file.txt
50n/asomecode%(sep)s__init__.py
51n/asomecode%(sep)sdoc.dat
52n/asomecode%(sep)sdoc.txt
53n/a"""
54n/a
55n/aclass SDistTestCase(BasePyPIRCCommandTestCase):
56n/a
57n/a def setUp(self):
58n/a # PyPIRCCommandTestCase creates a temp dir already
59n/a # and put it in self.tmp_dir
60n/a super(SDistTestCase, self).setUp()
61n/a # setting up an environment
62n/a self.old_path = os.getcwd()
63n/a os.mkdir(join(self.tmp_dir, 'somecode'))
64n/a os.mkdir(join(self.tmp_dir, 'dist'))
65n/a # a package, and a README
66n/a self.write_file((self.tmp_dir, 'README'), 'xxx')
67n/a self.write_file((self.tmp_dir, 'somecode', '__init__.py'), '#')
68n/a self.write_file((self.tmp_dir, 'setup.py'), SETUP_PY)
69n/a os.chdir(self.tmp_dir)
70n/a
71n/a def tearDown(self):
72n/a # back to normal
73n/a os.chdir(self.old_path)
74n/a super(SDistTestCase, self).tearDown()
75n/a
76n/a def get_cmd(self, metadata=None):
77n/a """Returns a cmd"""
78n/a if metadata is None:
79n/a metadata = {'name': 'fake', 'version': '1.0',
80n/a 'url': 'xxx', 'author': 'xxx',
81n/a 'author_email': 'xxx'}
82n/a dist = Distribution(metadata)
83n/a dist.script_name = 'setup.py'
84n/a dist.packages = ['somecode']
85n/a dist.include_package_data = True
86n/a cmd = sdist(dist)
87n/a cmd.dist_dir = 'dist'
88n/a return dist, cmd
89n/a
90n/a @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
91n/a def test_prune_file_list(self):
92n/a # this test creates a project with some VCS dirs and an NFS rename
93n/a # file, then launches sdist to check they get pruned on all systems
94n/a
95n/a # creating VCS directories with some files in them
96n/a os.mkdir(join(self.tmp_dir, 'somecode', '.svn'))
97n/a self.write_file((self.tmp_dir, 'somecode', '.svn', 'ok.py'), 'xxx')
98n/a
99n/a os.mkdir(join(self.tmp_dir, 'somecode', '.hg'))
100n/a self.write_file((self.tmp_dir, 'somecode', '.hg',
101n/a 'ok'), 'xxx')
102n/a
103n/a os.mkdir(join(self.tmp_dir, 'somecode', '.git'))
104n/a self.write_file((self.tmp_dir, 'somecode', '.git',
105n/a 'ok'), 'xxx')
106n/a
107n/a self.write_file((self.tmp_dir, 'somecode', '.nfs0001'), 'xxx')
108n/a
109n/a # now building a sdist
110n/a dist, cmd = self.get_cmd()
111n/a
112n/a # zip is available universally
113n/a # (tar might not be installed under win32)
114n/a cmd.formats = ['zip']
115n/a
116n/a cmd.ensure_finalized()
117n/a cmd.run()
118n/a
119n/a # now let's check what we have
120n/a dist_folder = join(self.tmp_dir, 'dist')
121n/a files = os.listdir(dist_folder)
122n/a self.assertEqual(files, ['fake-1.0.zip'])
123n/a
124n/a zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip'))
125n/a try:
126n/a content = zip_file.namelist()
127n/a finally:
128n/a zip_file.close()
129n/a
130n/a # making sure everything has been pruned correctly
131n/a self.assertEqual(len(content), 4)
132n/a
133n/a @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
134n/a @unittest.skipIf(find_executable('tar') is None,
135n/a "The tar command is not found")
136n/a @unittest.skipIf(find_executable('gzip') is None,
137n/a "The gzip command is not found")
138n/a def test_make_distribution(self):
139n/a # now building a sdist
140n/a dist, cmd = self.get_cmd()
141n/a
142n/a # creating a gztar then a tar
143n/a cmd.formats = ['gztar', 'tar']
144n/a cmd.ensure_finalized()
145n/a cmd.run()
146n/a
147n/a # making sure we have two files
148n/a dist_folder = join(self.tmp_dir, 'dist')
149n/a result = os.listdir(dist_folder)
150n/a result.sort()
151n/a self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz'])
152n/a
153n/a os.remove(join(dist_folder, 'fake-1.0.tar'))
154n/a os.remove(join(dist_folder, 'fake-1.0.tar.gz'))
155n/a
156n/a # now trying a tar then a gztar
157n/a cmd.formats = ['tar', 'gztar']
158n/a
159n/a cmd.ensure_finalized()
160n/a cmd.run()
161n/a
162n/a result = os.listdir(dist_folder)
163n/a result.sort()
164n/a self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz'])
165n/a
166n/a @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
167n/a def test_add_defaults(self):
168n/a
169n/a # http://bugs.python.org/issue2279
170n/a
171n/a # add_default should also include
172n/a # data_files and package_data
173n/a dist, cmd = self.get_cmd()
174n/a
175n/a # filling data_files by pointing files
176n/a # in package_data
177n/a dist.package_data = {'': ['*.cfg', '*.dat'],
178n/a 'somecode': ['*.txt']}
179n/a self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
180n/a self.write_file((self.tmp_dir, 'somecode', 'doc.dat'), '#')
181n/a
182n/a # adding some data in data_files
183n/a data_dir = join(self.tmp_dir, 'data')
184n/a os.mkdir(data_dir)
185n/a self.write_file((data_dir, 'data.dt'), '#')
186n/a some_dir = join(self.tmp_dir, 'some')
187n/a os.mkdir(some_dir)
188n/a # make sure VCS directories are pruned (#14004)
189n/a hg_dir = join(self.tmp_dir, '.hg')
190n/a os.mkdir(hg_dir)
191n/a self.write_file((hg_dir, 'last-message.txt'), '#')
192n/a # a buggy regex used to prevent this from working on windows (#6884)
193n/a self.write_file((self.tmp_dir, 'buildout.cfg'), '#')
194n/a self.write_file((self.tmp_dir, 'inroot.txt'), '#')
195n/a self.write_file((some_dir, 'file.txt'), '#')
196n/a self.write_file((some_dir, 'other_file.txt'), '#')
197n/a
198n/a dist.data_files = [('data', ['data/data.dt',
199n/a 'buildout.cfg',
200n/a 'inroot.txt',
201n/a 'notexisting']),
202n/a 'some/file.txt',
203n/a 'some/other_file.txt']
204n/a
205n/a # adding a script
206n/a script_dir = join(self.tmp_dir, 'scripts')
207n/a os.mkdir(script_dir)
208n/a self.write_file((script_dir, 'script.py'), '#')
209n/a dist.scripts = [join('scripts', 'script.py')]
210n/a
211n/a cmd.formats = ['zip']
212n/a cmd.use_defaults = True
213n/a
214n/a cmd.ensure_finalized()
215n/a cmd.run()
216n/a
217n/a # now let's check what we have
218n/a dist_folder = join(self.tmp_dir, 'dist')
219n/a files = os.listdir(dist_folder)
220n/a self.assertEqual(files, ['fake-1.0.zip'])
221n/a
222n/a zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip'))
223n/a try:
224n/a content = zip_file.namelist()
225n/a finally:
226n/a zip_file.close()
227n/a
228n/a # making sure everything was added
229n/a self.assertEqual(len(content), 12)
230n/a
231n/a # checking the MANIFEST
232n/a f = open(join(self.tmp_dir, 'MANIFEST'))
233n/a try:
234n/a manifest = f.read()
235n/a finally:
236n/a f.close()
237n/a self.assertEqual(manifest, MANIFEST % {'sep': os.sep})
238n/a
239n/a @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
240n/a def test_metadata_check_option(self):
241n/a # testing the `medata-check` option
242n/a dist, cmd = self.get_cmd(metadata={})
243n/a
244n/a # this should raise some warnings !
245n/a # with the `check` subcommand
246n/a cmd.ensure_finalized()
247n/a cmd.run()
248n/a warnings = [msg for msg in self.get_logs(WARN) if
249n/a msg.startswith('warning: check:')]
250n/a self.assertEqual(len(warnings), 2)
251n/a
252n/a # trying with a complete set of metadata
253n/a self.clear_logs()
254n/a dist, cmd = self.get_cmd()
255n/a cmd.ensure_finalized()
256n/a cmd.metadata_check = 0
257n/a cmd.run()
258n/a warnings = [msg for msg in self.get_logs(WARN) if
259n/a msg.startswith('warning: check:')]
260n/a self.assertEqual(len(warnings), 0)
261n/a
262n/a def test_check_metadata_deprecated(self):
263n/a # makes sure make_metadata is deprecated
264n/a dist, cmd = self.get_cmd()
265n/a with check_warnings() as w:
266n/a warnings.simplefilter("always")
267n/a cmd.check_metadata()
268n/a self.assertEqual(len(w.warnings), 1)
269n/a
270n/a def test_show_formats(self):
271n/a with captured_stdout() as stdout:
272n/a show_formats()
273n/a
274n/a # the output should be a header line + one line per format
275n/a num_formats = len(ARCHIVE_FORMATS.keys())
276n/a output = [line for line in stdout.getvalue().split('\n')
277n/a if line.strip().startswith('--formats=')]
278n/a self.assertEqual(len(output), num_formats)
279n/a
280n/a def test_finalize_options(self):
281n/a dist, cmd = self.get_cmd()
282n/a cmd.finalize_options()
283n/a
284n/a # default options set by finalize
285n/a self.assertEqual(cmd.manifest, 'MANIFEST')
286n/a self.assertEqual(cmd.template, 'MANIFEST.in')
287n/a self.assertEqual(cmd.dist_dir, 'dist')
288n/a
289n/a # formats has to be a string splitable on (' ', ',') or
290n/a # a stringlist
291n/a cmd.formats = 1
292n/a self.assertRaises(DistutilsOptionError, cmd.finalize_options)
293n/a cmd.formats = ['zip']
294n/a cmd.finalize_options()
295n/a
296n/a # formats has to be known
297n/a cmd.formats = 'supazipa'
298n/a self.assertRaises(DistutilsOptionError, cmd.finalize_options)
299n/a
300n/a # the following tests make sure there is a nice error message instead
301n/a # of a traceback when parsing an invalid manifest template
302n/a
303n/a def _check_template(self, content):
304n/a dist, cmd = self.get_cmd()
305n/a os.chdir(self.tmp_dir)
306n/a self.write_file('MANIFEST.in', content)
307n/a cmd.ensure_finalized()
308n/a cmd.filelist = FileList()
309n/a cmd.read_template()
310n/a warnings = self.get_logs(WARN)
311n/a self.assertEqual(len(warnings), 1)
312n/a
313n/a def test_invalid_template_unknown_command(self):
314n/a self._check_template('taunt knights *')
315n/a
316n/a def test_invalid_template_wrong_arguments(self):
317n/a # this manifest command takes one argument
318n/a self._check_template('prune')
319n/a
320n/a @unittest.skipIf(os.name != 'nt', 'test relevant for Windows only')
321n/a def test_invalid_template_wrong_path(self):
322n/a # on Windows, trailing slashes are not allowed
323n/a # this used to crash instead of raising a warning: #8286
324n/a self._check_template('include examples/')
325n/a
326n/a @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
327n/a def test_get_file_list(self):
328n/a # make sure MANIFEST is recalculated
329n/a dist, cmd = self.get_cmd()
330n/a
331n/a # filling data_files by pointing files in package_data
332n/a dist.package_data = {'somecode': ['*.txt']}
333n/a self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
334n/a cmd.formats = ['gztar']
335n/a cmd.ensure_finalized()
336n/a cmd.run()
337n/a
338n/a f = open(cmd.manifest)
339n/a try:
340n/a manifest = [line.strip() for line in f.read().split('\n')
341n/a if line.strip() != '']
342n/a finally:
343n/a f.close()
344n/a
345n/a self.assertEqual(len(manifest), 5)
346n/a
347n/a # adding a file
348n/a self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#')
349n/a
350n/a # make sure build_py is reinitialized, like a fresh run
351n/a build_py = dist.get_command_obj('build_py')
352n/a build_py.finalized = False
353n/a build_py.ensure_finalized()
354n/a
355n/a cmd.run()
356n/a
357n/a f = open(cmd.manifest)
358n/a try:
359n/a manifest2 = [line.strip() for line in f.read().split('\n')
360n/a if line.strip() != '']
361n/a finally:
362n/a f.close()
363n/a
364n/a # do we have the new file in MANIFEST ?
365n/a self.assertEqual(len(manifest2), 6)
366n/a self.assertIn('doc2.txt', manifest2[-1])
367n/a
368n/a @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
369n/a def test_manifest_marker(self):
370n/a # check that autogenerated MANIFESTs have a marker
371n/a dist, cmd = self.get_cmd()
372n/a cmd.ensure_finalized()
373n/a cmd.run()
374n/a
375n/a f = open(cmd.manifest)
376n/a try:
377n/a manifest = [line.strip() for line in f.read().split('\n')
378n/a if line.strip() != '']
379n/a finally:
380n/a f.close()
381n/a
382n/a self.assertEqual(manifest[0],
383n/a '# file GENERATED by distutils, do NOT edit')
384n/a
385n/a @unittest.skipUnless(ZLIB_SUPPORT, "Need zlib support to run")
386n/a def test_manifest_comments(self):
387n/a # make sure comments don't cause exceptions or wrong includes
388n/a contents = dedent("""\
389n/a # bad.py
390n/a #bad.py
391n/a good.py
392n/a """)
393n/a dist, cmd = self.get_cmd()
394n/a cmd.ensure_finalized()
395n/a self.write_file((self.tmp_dir, cmd.manifest), contents)
396n/a self.write_file((self.tmp_dir, 'good.py'), '# pick me!')
397n/a self.write_file((self.tmp_dir, 'bad.py'), "# don't pick me!")
398n/a self.write_file((self.tmp_dir, '#bad.py'), "# don't pick me!")
399n/a cmd.run()
400n/a self.assertEqual(cmd.filelist.files, ['good.py'])
401n/a
402n/a @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
403n/a def test_manual_manifest(self):
404n/a # check that a MANIFEST without a marker is left alone
405n/a dist, cmd = self.get_cmd()
406n/a cmd.formats = ['gztar']
407n/a cmd.ensure_finalized()
408n/a self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
409n/a self.write_file((self.tmp_dir, 'README.manual'),
410n/a 'This project maintains its MANIFEST file itself.')
411n/a cmd.run()
412n/a self.assertEqual(cmd.filelist.files, ['README.manual'])
413n/a
414n/a f = open(cmd.manifest)
415n/a try:
416n/a manifest = [line.strip() for line in f.read().split('\n')
417n/a if line.strip() != '']
418n/a finally:
419n/a f.close()
420n/a
421n/a self.assertEqual(manifest, ['README.manual'])
422n/a
423n/a archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz')
424n/a archive = tarfile.open(archive_name)
425n/a try:
426n/a filenames = [tarinfo.name for tarinfo in archive]
427n/a finally:
428n/a archive.close()
429n/a self.assertEqual(sorted(filenames), ['fake-1.0', 'fake-1.0/PKG-INFO',
430n/a 'fake-1.0/README.manual'])
431n/a
432n/a @unittest.skipUnless(ZLIB_SUPPORT, "requires zlib")
433n/a @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
434n/a @unittest.skipIf(find_executable('tar') is None,
435n/a "The tar command is not found")
436n/a @unittest.skipIf(find_executable('gzip') is None,
437n/a "The gzip command is not found")
438n/a def test_make_distribution_owner_group(self):
439n/a # now building a sdist
440n/a dist, cmd = self.get_cmd()
441n/a
442n/a # creating a gztar and specifying the owner+group
443n/a cmd.formats = ['gztar']
444n/a cmd.owner = pwd.getpwuid(0)[0]
445n/a cmd.group = grp.getgrgid(0)[0]
446n/a cmd.ensure_finalized()
447n/a cmd.run()
448n/a
449n/a # making sure we have the good rights
450n/a archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz')
451n/a archive = tarfile.open(archive_name)
452n/a try:
453n/a for member in archive.getmembers():
454n/a self.assertEqual(member.uid, 0)
455n/a self.assertEqual(member.gid, 0)
456n/a finally:
457n/a archive.close()
458n/a
459n/a # building a sdist again
460n/a dist, cmd = self.get_cmd()
461n/a
462n/a # creating a gztar
463n/a cmd.formats = ['gztar']
464n/a cmd.ensure_finalized()
465n/a cmd.run()
466n/a
467n/a # making sure we have the good rights
468n/a archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz')
469n/a archive = tarfile.open(archive_name)
470n/a
471n/a # note that we are not testing the group ownership here
472n/a # because, depending on the platforms and the container
473n/a # rights (see #7408)
474n/a try:
475n/a for member in archive.getmembers():
476n/a self.assertEqual(member.uid, os.getuid())
477n/a finally:
478n/a archive.close()
479n/a
480n/adef test_suite():
481n/a return unittest.makeSuite(SDistTestCase)
482n/a
483n/aif __name__ == "__main__":
484n/a run_unittest(test_suite())