ยปCore Development>Code coverage>Lib/packaging/tests/test_command_sdist.py

Python code coverage for Lib/packaging/tests/test_command_sdist.py

#countcontent
1n/a"""Tests for packaging.command.sdist."""
2n/aimport os
3n/aimport tarfile
4n/aimport zipfile
5n/a
6n/atry:
7n/a import grp
8n/a import pwd
9n/a UID_GID_SUPPORT = True
10n/aexcept ImportError:
11n/a UID_GID_SUPPORT = False
12n/a
13n/afrom shutil import get_archive_formats
14n/afrom os.path import join
15n/afrom packaging.dist import Distribution
16n/afrom packaging.util import find_executable
17n/afrom packaging.errors import PackagingOptionError
18n/afrom packaging.command.sdist import sdist, show_formats
19n/a
20n/afrom test.support import captured_stdout
21n/afrom packaging.tests import support, unittest
22n/afrom packaging.tests.support import requires_zlib
23n/a
24n/a
25n/aMANIFEST = """\
26n/a# file GENERATED by packaging, do NOT edit
27n/ainroot.txt
28n/asetup.cfg
29n/adata%(sep)sdata.dt
30n/ascripts%(sep)sscript.py
31n/asome%(sep)sfile.txt
32n/asome%(sep)sother_file.txt
33n/asomecode%(sep)s__init__.py
34n/asomecode%(sep)sdoc.dat
35n/asomecode%(sep)sdoc.txt
36n/a"""
37n/a
38n/a
39n/adef builder(dist, filelist):
40n/a filelist.append('bah')
41n/a
42n/a
43n/aclass SDistTestCase(support.TempdirManager,
44n/a support.LoggingCatcher,
45n/a support.EnvironRestorer,
46n/a unittest.TestCase):
47n/a
48n/a restore_environ = ['HOME']
49n/a
50n/a def setUp(self):
51n/a super(SDistTestCase, self).setUp()
52n/a self.tmp_dir = self.mkdtemp()
53n/a os.environ['HOME'] = self.tmp_dir
54n/a # setting up an environment
55n/a self.old_path = os.getcwd()
56n/a os.mkdir(join(self.tmp_dir, 'somecode'))
57n/a os.mkdir(join(self.tmp_dir, 'dist'))
58n/a # a package, and a README
59n/a self.write_file((self.tmp_dir, 'README'), 'xxx')
60n/a self.write_file((self.tmp_dir, 'somecode', '__init__.py'), '#')
61n/a os.chdir(self.tmp_dir)
62n/a
63n/a def tearDown(self):
64n/a # back to normal
65n/a os.chdir(self.old_path)
66n/a super(SDistTestCase, self).tearDown()
67n/a
68n/a def get_cmd(self, metadata=None):
69n/a """Returns a cmd"""
70n/a if metadata is None:
71n/a metadata = {'name': 'fake', 'version': '1.0',
72n/a 'home_page': 'xxx', 'author': 'xxx',
73n/a 'author_email': 'xxx'}
74n/a dist = Distribution(metadata)
75n/a dist.packages = ['somecode']
76n/a cmd = sdist(dist)
77n/a cmd.dist_dir = 'dist'
78n/a return dist, cmd
79n/a
80n/a @requires_zlib
81n/a def test_prune_file_list(self):
82n/a # this test creates a package with some vcs dirs in it
83n/a # and launch sdist to make sure they get pruned
84n/a # on all systems
85n/a
86n/a # creating VCS directories with some files in them
87n/a os.mkdir(join(self.tmp_dir, 'somecode', '.svn'))
88n/a self.write_file((self.tmp_dir, 'somecode', '.svn', 'ok.py'), 'xxx')
89n/a
90n/a os.mkdir(join(self.tmp_dir, 'somecode', '.hg'))
91n/a self.write_file((self.tmp_dir, 'somecode', '.hg',
92n/a 'ok'), 'xxx')
93n/a
94n/a os.mkdir(join(self.tmp_dir, 'somecode', '.git'))
95n/a self.write_file((self.tmp_dir, 'somecode', '.git',
96n/a 'ok'), 'xxx')
97n/a
98n/a # now building a sdist
99n/a dist, cmd = self.get_cmd()
100n/a
101n/a # zip is available universally
102n/a # (tar might not be installed under win32)
103n/a cmd.formats = ['zip']
104n/a
105n/a cmd.ensure_finalized()
106n/a cmd.run()
107n/a
108n/a # now let's check what we have
109n/a dist_folder = join(self.tmp_dir, 'dist')
110n/a files = os.listdir(dist_folder)
111n/a self.assertEqual(files, ['fake-1.0.zip'])
112n/a
113n/a with zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip')) as zip_file:
114n/a content = zip_file.namelist()
115n/a
116n/a # making sure everything has been pruned correctly
117n/a self.assertEqual(len(content), 2)
118n/a
119n/a @requires_zlib
120n/a @unittest.skipIf(find_executable('tar') is None or
121n/a find_executable('gzip') is None,
122n/a 'requires tar and gzip programs')
123n/a def test_make_distribution(self):
124n/a # building a sdist
125n/a dist, cmd = self.get_cmd()
126n/a
127n/a # creating a gztar then a tar
128n/a cmd.formats = ['gztar', 'tar']
129n/a cmd.ensure_finalized()
130n/a cmd.run()
131n/a
132n/a # making sure we have two files
133n/a dist_folder = join(self.tmp_dir, 'dist')
134n/a result = sorted(os.listdir(dist_folder))
135n/a self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz'])
136n/a
137n/a os.remove(join(dist_folder, 'fake-1.0.tar'))
138n/a os.remove(join(dist_folder, 'fake-1.0.tar.gz'))
139n/a
140n/a # now trying a tar then a gztar
141n/a cmd.formats = ['tar', 'gztar']
142n/a cmd.finalized = False
143n/a cmd.ensure_finalized()
144n/a cmd.run()
145n/a
146n/a result = sorted(os.listdir(dist_folder))
147n/a self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz'])
148n/a
149n/a @requires_zlib
150n/a def test_add_defaults(self):
151n/a
152n/a # http://bugs.python.org/issue2279
153n/a
154n/a # add_default should also include
155n/a # data_files and package_data
156n/a dist, cmd = self.get_cmd()
157n/a
158n/a # filling data_files by pointing files
159n/a # in package_data
160n/a dist.package_data = {'': ['*.cfg', '*.dat'],
161n/a 'somecode': ['*.txt']}
162n/a self.write_file((self.tmp_dir, 'setup.cfg'), '#')
163n/a self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
164n/a self.write_file((self.tmp_dir, 'somecode', 'doc.dat'), '#')
165n/a
166n/a # adding some data in data_files
167n/a data_dir = join(self.tmp_dir, 'data')
168n/a os.mkdir(data_dir)
169n/a self.write_file((data_dir, 'data.dt'), '#')
170n/a some_dir = join(self.tmp_dir, 'some')
171n/a os.mkdir(some_dir)
172n/a self.write_file((self.tmp_dir, 'inroot.txt'), '#')
173n/a self.write_file((some_dir, 'file.txt'), '#')
174n/a self.write_file((some_dir, 'other_file.txt'), '#')
175n/a
176n/a dist.data_files = {'data/data.dt': '{appdata}/data.dt',
177n/a 'inroot.txt': '{appdata}/inroot.txt',
178n/a 'some/file.txt': '{appdata}/file.txt',
179n/a 'some/other_file.txt': '{appdata}/other_file.txt'}
180n/a
181n/a # adding a script
182n/a script_dir = join(self.tmp_dir, 'scripts')
183n/a os.mkdir(script_dir)
184n/a self.write_file((script_dir, 'script.py'), '#')
185n/a dist.scripts = [join('scripts', 'script.py')]
186n/a
187n/a cmd.formats = ['zip']
188n/a cmd.use_defaults = True
189n/a
190n/a cmd.ensure_finalized()
191n/a cmd.run()
192n/a
193n/a # now let's check what we have
194n/a dist_folder = join(self.tmp_dir, 'dist')
195n/a files = os.listdir(dist_folder)
196n/a self.assertEqual(files, ['fake-1.0.zip'])
197n/a
198n/a with zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip')) as zip_file:
199n/a content = zip_file.namelist()
200n/a
201n/a # Making sure everything was added. This includes 8 code and data
202n/a # files in addition to PKG-INFO and setup.cfg
203n/a self.assertEqual(len(content), 10)
204n/a
205n/a # Checking the MANIFEST
206n/a with open(join(self.tmp_dir, 'MANIFEST')) as fp:
207n/a manifest = fp.read()
208n/a self.assertEqual(manifest, MANIFEST % {'sep': os.sep})
209n/a
210n/a @requires_zlib
211n/a def test_metadata_check_option(self):
212n/a # testing the `check-metadata` option
213n/a dist, cmd = self.get_cmd(metadata={'name': 'xxx', 'version': 'xxx'})
214n/a
215n/a # this should cause the check subcommand to log two warnings:
216n/a # version is invalid, home-page and author are missing
217n/a cmd.ensure_finalized()
218n/a cmd.run()
219n/a warnings = self.get_logs()
220n/a check_warnings = [msg for msg in warnings if
221n/a not msg.startswith('sdist:')]
222n/a self.assertEqual(len(check_warnings), 2, warnings)
223n/a
224n/a # trying with a complete set of metadata
225n/a self.loghandler.flush()
226n/a dist, cmd = self.get_cmd()
227n/a cmd.ensure_finalized()
228n/a cmd.metadata_check = False
229n/a cmd.run()
230n/a warnings = self.get_logs()
231n/a self.assertEqual(len(warnings), 2)
232n/a self.assertIn('using default file list', warnings[0])
233n/a self.assertIn("'setup.cfg' file not found", warnings[1])
234n/a
235n/a def test_show_formats(self):
236n/a with captured_stdout() as stdout:
237n/a show_formats()
238n/a stdout = stdout.getvalue()
239n/a
240n/a # the output should be a header line + one line per format
241n/a num_formats = len(get_archive_formats())
242n/a output = [line for line in stdout.split('\n')
243n/a if line.strip().startswith('--formats=')]
244n/a self.assertEqual(len(output), num_formats)
245n/a
246n/a def test_finalize_options(self):
247n/a dist, cmd = self.get_cmd()
248n/a cmd.finalize_options()
249n/a
250n/a # default options set by finalize
251n/a self.assertEqual(cmd.manifest, 'MANIFEST')
252n/a self.assertEqual(cmd.dist_dir, 'dist')
253n/a
254n/a # formats has to be a string splitable on (' ', ',') or
255n/a # a stringlist
256n/a cmd.formats = 1
257n/a self.assertRaises(PackagingOptionError, cmd.finalize_options)
258n/a cmd.formats = ['zip']
259n/a cmd.finalize_options()
260n/a
261n/a # formats has to be known
262n/a cmd.formats = 'supazipa'
263n/a self.assertRaises(PackagingOptionError, cmd.finalize_options)
264n/a
265n/a @requires_zlib
266n/a def test_template(self):
267n/a dist, cmd = self.get_cmd()
268n/a dist.extra_files = ['include yeah']
269n/a cmd.ensure_finalized()
270n/a self.write_file((self.tmp_dir, 'yeah'), 'xxx')
271n/a cmd.run()
272n/a with open(cmd.manifest) as f:
273n/a content = f.read()
274n/a
275n/a self.assertIn('yeah', content)
276n/a
277n/a @requires_zlib
278n/a @unittest.skipUnless(UID_GID_SUPPORT, "requires grp and pwd support")
279n/a @unittest.skipIf(find_executable('tar') is None or
280n/a find_executable('gzip') is None,
281n/a 'requires tar and gzip programs')
282n/a def test_make_distribution_owner_group(self):
283n/a # building a sdist
284n/a dist, cmd = self.get_cmd()
285n/a
286n/a # creating a gztar and specifying the owner+group
287n/a cmd.formats = ['gztar']
288n/a cmd.owner = pwd.getpwuid(0)[0]
289n/a cmd.group = grp.getgrgid(0)[0]
290n/a cmd.ensure_finalized()
291n/a cmd.run()
292n/a
293n/a # making sure we have the good rights
294n/a archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz')
295n/a with tarfile.open(archive_name) as archive:
296n/a for member in archive.getmembers():
297n/a self.assertEqual(member.uid, 0)
298n/a self.assertEqual(member.gid, 0)
299n/a
300n/a # building a sdist again
301n/a dist, cmd = self.get_cmd()
302n/a
303n/a # creating a gztar
304n/a cmd.formats = ['gztar']
305n/a cmd.ensure_finalized()
306n/a cmd.run()
307n/a
308n/a # making sure we have the good rights
309n/a archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz')
310n/a with tarfile.open(archive_name) as archive:
311n/a
312n/a # note that we are not testing the group ownership here
313n/a # because, depending on the platforms and the container
314n/a # rights (see #7408)
315n/a for member in archive.getmembers():
316n/a self.assertEqual(member.uid, os.getuid())
317n/a
318n/a @requires_zlib
319n/a def test_get_file_list(self):
320n/a # make sure MANIFEST is recalculated
321n/a dist, cmd = self.get_cmd()
322n/a # filling data_files by pointing files in package_data
323n/a dist.package_data = {'somecode': ['*.txt']}
324n/a self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
325n/a cmd.ensure_finalized()
326n/a cmd.run()
327n/a
328n/a # Should produce four lines. Those lines are one comment, one default
329n/a # (README) and two package files.
330n/a with open(cmd.manifest) as f:
331n/a manifest = [line.strip() for line in f.read().split('\n')
332n/a if line.strip() != '']
333n/a self.assertEqual(len(manifest), 3)
334n/a
335n/a # Adding a file
336n/a self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#')
337n/a
338n/a # make sure build_py is reinitialized, like a fresh run
339n/a build_py = dist.get_command_obj('build_py')
340n/a build_py.finalized = False
341n/a build_py.ensure_finalized()
342n/a
343n/a cmd.run()
344n/a
345n/a with open(cmd.manifest) as f:
346n/a manifest2 = [line.strip() for line in f.read().split('\n')
347n/a if line.strip() != '']
348n/a
349n/a # Do we have the new file in MANIFEST?
350n/a self.assertEqual(len(manifest2), 4)
351n/a self.assertIn('doc2.txt', manifest2[-1])
352n/a
353n/a @requires_zlib
354n/a def test_manifest_marker(self):
355n/a # check that autogenerated MANIFESTs have a marker
356n/a dist, cmd = self.get_cmd()
357n/a cmd.ensure_finalized()
358n/a cmd.run()
359n/a
360n/a with open(cmd.manifest) as f:
361n/a manifest = [line.strip() for line in f.read().split('\n')
362n/a if line.strip() != '']
363n/a
364n/a self.assertEqual(manifest[0],
365n/a '# file GENERATED by packaging, do NOT edit')
366n/a
367n/a @requires_zlib
368n/a def test_manual_manifest(self):
369n/a # check that a MANIFEST without a marker is left alone
370n/a dist, cmd = self.get_cmd()
371n/a cmd.ensure_finalized()
372n/a self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
373n/a cmd.run()
374n/a
375n/a with open(cmd.manifest) as f:
376n/a manifest = [line.strip() for line in f.read().split('\n')
377n/a if line.strip() != '']
378n/a
379n/a self.assertEqual(manifest, ['README.manual'])
380n/a
381n/a @requires_zlib
382n/a def test_manifest_builder(self):
383n/a dist, cmd = self.get_cmd()
384n/a cmd.manifest_builders = 'packaging.tests.test_command_sdist.builder'
385n/a cmd.ensure_finalized()
386n/a cmd.run()
387n/a self.assertIn('bah', cmd.filelist.files)
388n/a
389n/a
390n/adef test_suite():
391n/a return unittest.makeSuite(SDistTestCase)
392n/a
393n/aif __name__ == "__main__":
394n/a unittest.main(defaultTest="test_suite")