blob: 31636fd9c3e774d90fb628cc92100212cc2a82d1 [file] [log] [blame]
Tarek Ziade1231a4e2011-05-19 13:07:25 +02001"""Tests for ``packaging.command.install_distinfo``. """
2
3import os
4import csv
5import hashlib
Éric Araujo0a733622011-08-20 09:31:25 +02006import sysconfig
Tarek Ziade1231a4e2011-05-19 13:07:25 +02007
8from packaging.command.install_distinfo import install_distinfo
9from packaging.command.cmd import Command
Éric Araujo0a733622011-08-20 09:31:25 +020010from packaging.compiler.extension import Extension
Tarek Ziade1231a4e2011-05-19 13:07:25 +020011from packaging.metadata import Metadata
12from packaging.tests import unittest, support
13
14
15class DummyInstallCmd(Command):
16
17 def __init__(self, dist=None):
18 self.outputs = []
19 self.distribution = dist
20
21 def __getattr__(self, name):
22 return None
23
24 def ensure_finalized(self):
25 pass
26
27 def get_outputs(self):
28 return (self.outputs +
29 self.get_finalized_command('install_distinfo').get_outputs())
30
31
32class InstallDistinfoTestCase(support.TempdirManager,
33 support.LoggingCatcher,
34 unittest.TestCase):
35
36 checkLists = lambda self, x, y: self.assertListEqual(sorted(x), sorted(y))
37
38 def test_empty_install(self):
39 pkg_dir, dist = self.create_dist(name='foo',
40 version='1.0')
41 install_dir = self.mkdtemp()
42
43 install = DummyInstallCmd(dist)
44 dist.command_obj['install_dist'] = install
45
46 cmd = install_distinfo(dist)
47 dist.command_obj['install_distinfo'] = cmd
48
Tarek Ziade1231a4e2011-05-19 13:07:25 +020049 cmd.distinfo_dir = install_dir
50 cmd.ensure_finalized()
51 cmd.run()
52
53 self.checkLists(os.listdir(install_dir), ['foo-1.0.dist-info'])
54
55 dist_info = os.path.join(install_dir, 'foo-1.0.dist-info')
56 self.checkLists(os.listdir(dist_info),
57 ['METADATA', 'RECORD', 'REQUESTED', 'INSTALLER'])
58 with open(os.path.join(dist_info, 'INSTALLER')) as fp:
59 self.assertEqual(fp.read(), 'distutils')
60 with open(os.path.join(dist_info, 'REQUESTED')) as fp:
61 self.assertEqual(fp.read(), '')
62 meta_path = os.path.join(dist_info, 'METADATA')
63 self.assertTrue(Metadata(path=meta_path).check())
64
65 def test_installer(self):
66 pkg_dir, dist = self.create_dist(name='foo',
67 version='1.0')
68 install_dir = self.mkdtemp()
69
70 install = DummyInstallCmd(dist)
71 dist.command_obj['install_dist'] = install
72
73 cmd = install_distinfo(dist)
74 dist.command_obj['install_distinfo'] = cmd
75
Tarek Ziade1231a4e2011-05-19 13:07:25 +020076 cmd.distinfo_dir = install_dir
77 cmd.installer = 'bacon-python'
78 cmd.ensure_finalized()
79 cmd.run()
80
81 dist_info = os.path.join(install_dir, 'foo-1.0.dist-info')
82 with open(os.path.join(dist_info, 'INSTALLER')) as fp:
83 self.assertEqual(fp.read(), 'bacon-python')
84
85 def test_requested(self):
86 pkg_dir, dist = self.create_dist(name='foo',
87 version='1.0')
88 install_dir = self.mkdtemp()
89
90 install = DummyInstallCmd(dist)
91 dist.command_obj['install_dist'] = install
92
93 cmd = install_distinfo(dist)
94 dist.command_obj['install_distinfo'] = cmd
95
Tarek Ziade1231a4e2011-05-19 13:07:25 +020096 cmd.distinfo_dir = install_dir
97 cmd.requested = False
98 cmd.ensure_finalized()
99 cmd.run()
100
101 dist_info = os.path.join(install_dir, 'foo-1.0.dist-info')
102 self.checkLists(os.listdir(dist_info),
103 ['METADATA', 'RECORD', 'INSTALLER'])
104
105 def test_no_record(self):
106 pkg_dir, dist = self.create_dist(name='foo',
107 version='1.0')
108 install_dir = self.mkdtemp()
109
110 install = DummyInstallCmd(dist)
111 dist.command_obj['install_dist'] = install
112
113 cmd = install_distinfo(dist)
114 dist.command_obj['install_distinfo'] = cmd
115
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200116 cmd.distinfo_dir = install_dir
117 cmd.no_record = True
118 cmd.ensure_finalized()
119 cmd.run()
120
121 dist_info = os.path.join(install_dir, 'foo-1.0.dist-info')
122 self.checkLists(os.listdir(dist_info),
123 ['METADATA', 'REQUESTED', 'INSTALLER'])
124
Éric Araujo0a733622011-08-20 09:31:25 +0200125 def test_record_basic(self):
126 install_dir = self.mkdtemp()
127 modules_dest = os.path.join(install_dir, 'lib')
128 scripts_dest = os.path.join(install_dir, 'bin')
129 project_dir, dist = self.create_dist(
130 name='Spamlib', version='0.1',
131 py_modules=['spam'], scripts=['spamd'],
132 ext_modules=[Extension('_speedspam', ['_speedspam.c'])])
133
134 # using a real install_dist command is too painful, so we use a mock
135 # class that's only a holder for options to be used by install_distinfo
136 # and we create placeholder files manually instead of using build_*.
137 # the install_* commands will still be consulted by install_distinfo.
138 os.chdir(project_dir)
139 self.write_file('spam', '# Python module')
140 self.write_file('spamd', '# Python script')
Éric Araujoced7eda2011-08-25 18:13:58 +0200141 extmod = '_speedspam' + sysconfig.get_config_var('SO')
Éric Araujo0a733622011-08-20 09:31:25 +0200142 self.write_file(extmod, '')
143
144 install = DummyInstallCmd(dist)
145 install.outputs = ['spam', 'spamd', extmod]
146 install.install_lib = modules_dest
147 install.install_scripts = scripts_dest
148 dist.command_obj['install_dist'] = install
149
150 cmd = install_distinfo(dist)
151 cmd.ensure_finalized()
152 dist.command_obj['install_distinfo'] = cmd
153 cmd.run()
154
Éric Araujoced7eda2011-08-25 18:13:58 +0200155 # checksum and size are not hard-coded for METADATA as it is
156 # platform-dependent (line endings)
157 metadata = os.path.join(modules_dest, 'Spamlib-0.1.dist-info',
158 'METADATA')
159 with open(metadata, 'rb') as fp:
160 content = fp.read()
161
162 metadata_size = str(len(content))
163 metadata_md5 = hashlib.md5(content).hexdigest()
164
Éric Araujo0a733622011-08-20 09:31:25 +0200165 record = os.path.join(modules_dest, 'Spamlib-0.1.dist-info', 'RECORD')
166 with open(record, encoding='utf-8') as fp:
167 content = fp.read()
168
169 found = []
170 for line in content.splitlines():
171 filename, checksum, size = line.split(',')
172 filename = os.path.basename(filename)
173 found.append((filename, checksum, size))
174
175 expected = [
176 ('spam', '6ab2f288ef2545868effe68757448b45', '15'),
Éric Araujoced7eda2011-08-25 18:13:58 +0200177 ('spamd', 'd13e6156ce78919a981e424b2fdcd974', '15'),
Éric Araujo0a733622011-08-20 09:31:25 +0200178 (extmod, 'd41d8cd98f00b204e9800998ecf8427e', '0'),
Éric Araujoced7eda2011-08-25 18:13:58 +0200179 ('METADATA', metadata_md5, metadata_size),
Éric Araujo0a733622011-08-20 09:31:25 +0200180 ('INSTALLER', '44e3fde05f3f537ed85831969acf396d', '9'),
181 ('REQUESTED', 'd41d8cd98f00b204e9800998ecf8427e', '0'),
182 ('RECORD', '', ''),
183 ]
184 self.assertEqual(found, expected)
185
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200186 def test_record(self):
187 pkg_dir, dist = self.create_dist(name='foo',
188 version='1.0')
189 install_dir = self.mkdtemp()
190
191 install = DummyInstallCmd(dist)
192 dist.command_obj['install_dist'] = install
193
194 fake_dists = os.path.join(os.path.dirname(__file__), 'fake_dists')
195 fake_dists = os.path.realpath(fake_dists)
196
197 # for testing, we simply add all files from _backport's fake_dists
198 dirs = []
199 for dir in os.listdir(fake_dists):
200 full_path = os.path.join(fake_dists, dir)
201 if (not dir.endswith('.egg') or dir.endswith('.egg-info') or
202 dir.endswith('.dist-info')) and os.path.isdir(full_path):
203 dirs.append(full_path)
204
205 for dir in dirs:
206 for path, subdirs, files in os.walk(dir):
207 install.outputs += [os.path.join(path, f) for f in files]
208 install.outputs += [os.path.join('path', f + 'c')
209 for f in files if f.endswith('.py')]
210
211 cmd = install_distinfo(dist)
212 dist.command_obj['install_distinfo'] = cmd
213
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200214 cmd.distinfo_dir = install_dir
215 cmd.ensure_finalized()
216 cmd.run()
217
218 dist_info = os.path.join(install_dir, 'foo-1.0.dist-info')
219
220 expected = []
221 for f in install.get_outputs():
Éric Araujof53cd892011-06-10 03:53:49 +0200222 if (f.endswith(('.pyc', '.pyo')) or f == os.path.join(
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200223 install_dir, 'foo-1.0.dist-info', 'RECORD')):
224 expected.append([f, '', ''])
225 else:
226 size = os.path.getsize(f)
227 md5 = hashlib.md5()
Victor Stinner35de5ac2011-05-19 15:09:57 +0200228 with open(f, 'rb') as fp:
229 md5.update(fp.read())
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200230 hash = md5.hexdigest()
231 expected.append([f, hash, str(size)])
232
233 parsed = []
234 with open(os.path.join(dist_info, 'RECORD'), 'r') as f:
235 reader = csv.reader(f, delimiter=',',
236 lineterminator=os.linesep,
237 quotechar='"')
238 parsed = list(reader)
239
240 self.maxDiff = None
241 self.checkLists(parsed, expected)
242
243
244def test_suite():
245 return unittest.makeSuite(InstallDistinfoTestCase)
246
247
248if __name__ == "__main__":
249 unittest.main(defaultTest="test_suite")