Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: recipe_engine/third_party/setuptools/tests/test_sdist.py

Issue 1344583003: Recipe package system. (Closed) Base URL: git@github.com:luci/recipes-py.git@master
Patch Set: Recompiled proto Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # -*- coding: utf-8 -*-
2 """sdist tests"""
3
4 import locale
5 import os
6 import shutil
7 import sys
8 import tempfile
9 import unittest
10 import unicodedata
11 import re
12 import contextlib
13 from setuptools.tests import environment, test_svn
14 from setuptools.tests.py26compat import skipIf
15
16 from setuptools.compat import StringIO, unicode, PY3, PY2
17 from setuptools.command.sdist import sdist, walk_revctrl
18 from setuptools.command.egg_info import manifest_maker
19 from setuptools.dist import Distribution
20 from setuptools import svn_utils
21
22 SETUP_ATTRS = {
23 'name': 'sdist_test',
24 'version': '0.0',
25 'packages': ['sdist_test'],
26 'package_data': {'sdist_test': ['*.txt']}
27 }
28
29
30 SETUP_PY = """\
31 from setuptools import setup
32
33 setup(**%r)
34 """ % SETUP_ATTRS
35
36
37 if PY3:
38 LATIN1_FILENAME = 'smörbröd.py'.encode('latin-1')
39 else:
40 LATIN1_FILENAME = 'sm\xf6rbr\xf6d.py'
41
42
43 # Cannot use context manager because of Python 2.4
44 @contextlib.contextmanager
45 def quiet():
46 old_stdout, old_stderr = sys.stdout, sys.stderr
47 sys.stdout, sys.stderr = StringIO(), StringIO()
48 try:
49 yield
50 finally:
51 sys.stdout, sys.stderr = old_stdout, old_stderr
52
53
54 # Fake byte literals for Python <= 2.5
55 def b(s, encoding='utf-8'):
56 if PY3:
57 return s.encode(encoding)
58 return s
59
60
61 # Convert to POSIX path
62 def posix(path):
63 if PY3 and not isinstance(path, str):
64 return path.replace(os.sep.encode('ascii'), b('/'))
65 else:
66 return path.replace(os.sep, '/')
67
68
69 # HFS Plus uses decomposed UTF-8
70 def decompose(path):
71 if isinstance(path, unicode):
72 return unicodedata.normalize('NFD', path)
73 try:
74 path = path.decode('utf-8')
75 path = unicodedata.normalize('NFD', path)
76 path = path.encode('utf-8')
77 except UnicodeError:
78 pass # Not UTF-8
79 return path
80
81
82 class TestSdistTest(unittest.TestCase):
83
84 def setUp(self):
85 self.temp_dir = tempfile.mkdtemp()
86 f = open(os.path.join(self.temp_dir, 'setup.py'), 'w')
87 f.write(SETUP_PY)
88 f.close()
89
90 # Set up the rest of the test package
91 test_pkg = os.path.join(self.temp_dir, 'sdist_test')
92 os.mkdir(test_pkg)
93 # *.rst was not included in package_data, so c.rst should not be
94 # automatically added to the manifest when not under version control
95 for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst']:
96 # Just touch the files; their contents are irrelevant
97 open(os.path.join(test_pkg, fname), 'w').close()
98
99 self.old_cwd = os.getcwd()
100 os.chdir(self.temp_dir)
101
102 def tearDown(self):
103 os.chdir(self.old_cwd)
104 shutil.rmtree(self.temp_dir)
105
106 def test_package_data_in_sdist(self):
107 """Regression test for pull request #4: ensures that files listed in
108 package_data are included in the manifest even if they're not added to
109 version control.
110 """
111
112 dist = Distribution(SETUP_ATTRS)
113 dist.script_name = 'setup.py'
114 cmd = sdist(dist)
115 cmd.ensure_finalized()
116
117 with quiet():
118 cmd.run()
119
120 manifest = cmd.filelist.files
121 self.assertTrue(os.path.join('sdist_test', 'a.txt') in manifest)
122 self.assertTrue(os.path.join('sdist_test', 'b.txt') in manifest)
123 self.assertTrue(os.path.join('sdist_test', 'c.rst') not in manifest)
124
125
126 def test_defaults_case_sensitivity(self):
127 """
128 Make sure default files (README.*, etc.) are added in a case-sensiti ve
129 way to avoid problems with packages built on Windows.
130 """
131
132 open(os.path.join(self.temp_dir, 'readme.rst'), 'w').close()
133 open(os.path.join(self.temp_dir, 'SETUP.cfg'), 'w').close()
134
135 dist = Distribution(SETUP_ATTRS)
136 # the extension deliberately capitalized for this test
137 # to make sure the actual filename (not capitalized) gets added
138 # to the manifest
139 dist.script_name = 'setup.PY'
140 cmd = sdist(dist)
141 cmd.ensure_finalized()
142
143 with quiet():
144 cmd.run()
145
146 # lowercase all names so we can test in a case-insensitive way to make s ure the files are not included
147 manifest = map(lambda x: x.lower(), cmd.filelist.files)
148 self.assertFalse('readme.rst' in manifest, manifest)
149 self.assertFalse('setup.py' in manifest, manifest)
150 self.assertFalse('setup.cfg' in manifest, manifest)
151
152 def test_manifest_is_written_with_utf8_encoding(self):
153 # Test for #303.
154 dist = Distribution(SETUP_ATTRS)
155 dist.script_name = 'setup.py'
156 mm = manifest_maker(dist)
157 mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
158 os.mkdir('sdist_test.egg-info')
159
160 # UTF-8 filename
161 filename = os.path.join('sdist_test', 'smörbröd.py')
162
163 # Must create the file or it will get stripped.
164 open(filename, 'w').close()
165
166 # Add UTF-8 filename and write manifest
167 with quiet():
168 mm.run()
169 mm.filelist.append(filename)
170 mm.write_manifest()
171
172 manifest = open(mm.manifest, 'rbU')
173 contents = manifest.read()
174 manifest.close()
175
176 # The manifest should be UTF-8 encoded
177 try:
178 u_contents = contents.decode('UTF-8')
179 except UnicodeDecodeError:
180 e = sys.exc_info()[1]
181 self.fail(e)
182
183 # The manifest should contain the UTF-8 filename
184 if PY2:
185 fs_enc = sys.getfilesystemencoding()
186 filename = filename.decode(fs_enc)
187
188 self.assertTrue(posix(filename) in u_contents)
189
190 # Python 3 only
191 if PY3:
192
193 def test_write_manifest_allows_utf8_filenames(self):
194 # Test for #303.
195 dist = Distribution(SETUP_ATTRS)
196 dist.script_name = 'setup.py'
197 mm = manifest_maker(dist)
198 mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
199 os.mkdir('sdist_test.egg-info')
200
201 # UTF-8 filename
202 filename = os.path.join(b('sdist_test'), b('smörbröd.py'))
203
204 # Must touch the file or risk removal
205 open(filename, "w").close()
206
207 # Add filename and write manifest
208 with quiet():
209 mm.run()
210 u_filename = filename.decode('utf-8')
211 mm.filelist.files.append(u_filename)
212 # Re-write manifest
213 mm.write_manifest()
214
215 manifest = open(mm.manifest, 'rbU')
216 contents = manifest.read()
217 manifest.close()
218
219 # The manifest should be UTF-8 encoded
220 try:
221 contents.decode('UTF-8')
222 except UnicodeDecodeError:
223 e = sys.exc_info()[1]
224 self.fail(e)
225
226 # The manifest should contain the UTF-8 filename
227 self.assertTrue(posix(filename) in contents)
228
229 # The filelist should have been updated as well
230 self.assertTrue(u_filename in mm.filelist.files)
231
232 def test_write_manifest_skips_non_utf8_filenames(self):
233 """
234 Files that cannot be encoded to UTF-8 (specifically, those that
235 weren't originally successfully decoded and have surrogate
236 escapes) should be omitted from the manifest.
237 See https://bitbucket.org/tarek/distribute/issue/303 for history.
238 """
239 dist = Distribution(SETUP_ATTRS)
240 dist.script_name = 'setup.py'
241 mm = manifest_maker(dist)
242 mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
243 os.mkdir('sdist_test.egg-info')
244
245 # Latin-1 filename
246 filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
247
248 # Add filename with surrogates and write manifest
249 with quiet():
250 mm.run()
251 u_filename = filename.decode('utf-8', 'surrogateescape')
252 mm.filelist.append(u_filename)
253 # Re-write manifest
254 mm.write_manifest()
255
256 manifest = open(mm.manifest, 'rbU')
257 contents = manifest.read()
258 manifest.close()
259
260 # The manifest should be UTF-8 encoded
261 try:
262 contents.decode('UTF-8')
263 except UnicodeDecodeError:
264 e = sys.exc_info()[1]
265 self.fail(e)
266
267 # The Latin-1 filename should have been skipped
268 self.assertFalse(posix(filename) in contents)
269
270 # The filelist should have been updated as well
271 self.assertFalse(u_filename in mm.filelist.files)
272
273 def test_manifest_is_read_with_utf8_encoding(self):
274 # Test for #303.
275 dist = Distribution(SETUP_ATTRS)
276 dist.script_name = 'setup.py'
277 cmd = sdist(dist)
278 cmd.ensure_finalized()
279
280 # Create manifest
281 with quiet():
282 cmd.run()
283
284 # Add UTF-8 filename to manifest
285 filename = os.path.join(b('sdist_test'), b('smörbröd.py'))
286 cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
287 manifest = open(cmd.manifest, 'ab')
288 manifest.write(b('\n') + filename)
289 manifest.close()
290
291 # The file must exist to be included in the filelist
292 open(filename, 'w').close()
293
294 # Re-read manifest
295 cmd.filelist.files = []
296 with quiet():
297 cmd.read_manifest()
298
299 # The filelist should contain the UTF-8 filename
300 if PY3:
301 filename = filename.decode('utf-8')
302 self.assertTrue(filename in cmd.filelist.files)
303
304 # Python 3 only
305 if PY3:
306
307 def test_read_manifest_skips_non_utf8_filenames(self):
308 # Test for #303.
309 dist = Distribution(SETUP_ATTRS)
310 dist.script_name = 'setup.py'
311 cmd = sdist(dist)
312 cmd.ensure_finalized()
313
314 # Create manifest
315 with quiet():
316 cmd.run()
317
318 # Add Latin-1 filename to manifest
319 filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
320 cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
321 manifest = open(cmd.manifest, 'ab')
322 manifest.write(b('\n') + filename)
323 manifest.close()
324
325 # The file must exist to be included in the filelist
326 open(filename, 'w').close()
327
328 # Re-read manifest
329 cmd.filelist.files = []
330 with quiet():
331 try:
332 cmd.read_manifest()
333 except UnicodeDecodeError:
334 e = sys.exc_info()[1]
335 self.fail(e)
336
337 # The Latin-1 filename should have been skipped
338 filename = filename.decode('latin-1')
339 self.assertFalse(filename in cmd.filelist.files)
340
341 @skipIf(PY3 and locale.getpreferredencoding() != 'UTF-8',
342 'Unittest fails if locale is not utf-8 but the manifests is recorded correctly')
343 def test_sdist_with_utf8_encoded_filename(self):
344 # Test for #303.
345 dist = Distribution(SETUP_ATTRS)
346 dist.script_name = 'setup.py'
347 cmd = sdist(dist)
348 cmd.ensure_finalized()
349
350 # UTF-8 filename
351 filename = os.path.join(b('sdist_test'), b('smörbröd.py'))
352 open(filename, 'w').close()
353
354 with quiet():
355 cmd.run()
356
357 if sys.platform == 'darwin':
358 filename = decompose(filename)
359
360 if PY3:
361 fs_enc = sys.getfilesystemencoding()
362
363 if sys.platform == 'win32':
364 if fs_enc == 'cp1252':
365 # Python 3 mangles the UTF-8 filename
366 filename = filename.decode('cp1252')
367 self.assertTrue(filename in cmd.filelist.files)
368 else:
369 filename = filename.decode('mbcs')
370 self.assertTrue(filename in cmd.filelist.files)
371 else:
372 filename = filename.decode('utf-8')
373 self.assertTrue(filename in cmd.filelist.files)
374 else:
375 self.assertTrue(filename in cmd.filelist.files)
376
377 def test_sdist_with_latin1_encoded_filename(self):
378 # Test for #303.
379 dist = Distribution(SETUP_ATTRS)
380 dist.script_name = 'setup.py'
381 cmd = sdist(dist)
382 cmd.ensure_finalized()
383
384 # Latin-1 filename
385 filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
386 open(filename, 'w').close()
387 self.assertTrue(os.path.isfile(filename))
388
389 with quiet():
390 cmd.run()
391
392 if PY3:
393 # not all windows systems have a default FS encoding of cp1252
394 if sys.platform == 'win32':
395 # Latin-1 is similar to Windows-1252 however
396 # on mbcs filesys it is not in latin-1 encoding
397 fs_enc = sys.getfilesystemencoding()
398 if fs_enc == 'mbcs':
399 filename = filename.decode('mbcs')
400 else:
401 filename = filename.decode('latin-1')
402
403 self.assertTrue(filename in cmd.filelist.files)
404 else:
405 # The Latin-1 filename should have been skipped
406 filename = filename.decode('latin-1')
407 self.assertFalse(filename in cmd.filelist.files)
408 else:
409 # Under Python 2 there seems to be no decoded string in the
410 # filelist. However, due to decode and encoding of the
411 # file name to get utf-8 Manifest the latin1 maybe excluded
412 try:
413 # fs_enc should match how one is expect the decoding to
414 # be proformed for the manifest output.
415 fs_enc = sys.getfilesystemencoding()
416 filename.decode(fs_enc)
417 self.assertTrue(filename in cmd.filelist.files)
418 except UnicodeDecodeError:
419 self.assertFalse(filename in cmd.filelist.files)
420
421 class TestDummyOutput(environment.ZippedEnvironment):
422
423 def setUp(self):
424 self.datafile = os.path.join('setuptools', 'tests',
425 'svn_data', "dummy.zip")
426 self.dataname = "dummy"
427 super(TestDummyOutput, self).setUp()
428
429 def _run(self):
430 code, data = environment.run_setup_py(["sdist"],
431 pypath=self.old_cwd,
432 data_stream=0)
433 if code:
434 info = "DIR: " + os.path.abspath('.')
435 info += "\n SDIST RETURNED: %i\n\n" % code
436 info += data
437 raise AssertionError(info)
438
439 datalines = data.splitlines()
440
441 possible = (
442 "running sdist",
443 "running egg_info",
444 "creating dummy\.egg-info",
445 "writing dummy\.egg-info",
446 "writing top-level names to dummy\.egg-info",
447 "writing dependency_links to dummy\.egg-info",
448 "writing manifest file 'dummy\.egg-info",
449 "reading manifest file 'dummy\.egg-info",
450 "reading manifest template 'MANIFEST\.in'",
451 "writing manifest file 'dummy\.egg-info",
452 "creating dummy-0.1.1",
453 "making hard links in dummy-0\.1\.1",
454 "copying files to dummy-0\.1\.1",
455 "copying \S+ -> dummy-0\.1\.1",
456 "copying dummy",
457 "copying dummy\.egg-info",
458 "hard linking \S+ -> dummy-0\.1\.1",
459 "hard linking dummy",
460 "hard linking dummy\.egg-info",
461 "Writing dummy-0\.1\.1",
462 "creating dist",
463 "creating 'dist",
464 "Creating tar archive",
465 "running check",
466 "adding 'dummy-0\.1\.1",
467 "tar .+ dist/dummy-0\.1\.1\.tar dummy-0\.1\.1",
468 "gzip .+ dist/dummy-0\.1\.1\.tar",
469 "removing 'dummy-0\.1\.1' \\(and everything under it\\)",
470 )
471
472 print(" DIR: " + os.path.abspath('.'))
473 for line in datalines:
474 found = False
475 for pattern in possible:
476 if re.match(pattern, line):
477 print(" READ: " + line)
478 found = True
479 break
480 if not found:
481 raise AssertionError("Unexpexected: %s\n-in-\n%s"
482 % (line, data))
483
484 return data
485
486 def test_sources(self):
487 self._run()
488
489
490 class TestSvn(environment.ZippedEnvironment):
491
492 def setUp(self):
493 version = svn_utils.SvnInfo.get_svn_version()
494 if not version: # None or Empty
495 return
496
497 self.base_version = tuple([int(x) for x in version.split('.')][:2])
498
499 if not self.base_version:
500 raise ValueError('No SVN tools installed')
501 elif self.base_version < (1, 3):
502 raise ValueError('Insufficient SVN Version %s' % version)
503 elif self.base_version >= (1, 9):
504 # trying the latest version
505 self.base_version = (1, 8)
506
507 self.dataname = "svn%i%i_example" % self.base_version
508 self.datafile = os.path.join('setuptools', 'tests',
509 'svn_data', self.dataname + ".zip")
510 super(TestSvn, self).setUp()
511
512 @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
513 def test_walksvn(self):
514 if self.base_version >= (1, 6):
515 folder2 = 'third party2'
516 folder3 = 'third party3'
517 else:
518 folder2 = 'third_party2'
519 folder3 = 'third_party3'
520
521 # TODO is this right
522 expected = set([
523 os.path.join('a file'),
524 os.path.join(folder2, 'Changes.txt'),
525 os.path.join(folder2, 'MD5SUMS'),
526 os.path.join(folder2, 'README.txt'),
527 os.path.join(folder3, 'Changes.txt'),
528 os.path.join(folder3, 'MD5SUMS'),
529 os.path.join(folder3, 'README.txt'),
530 os.path.join(folder3, 'TODO.txt'),
531 os.path.join(folder3, 'fin'),
532 os.path.join('third_party', 'README.txt'),
533 os.path.join('folder', folder2, 'Changes.txt'),
534 os.path.join('folder', folder2, 'MD5SUMS'),
535 os.path.join('folder', folder2, 'WatashiNiYomimasu.txt'),
536 os.path.join('folder', folder3, 'Changes.txt'),
537 os.path.join('folder', folder3, 'fin'),
538 os.path.join('folder', folder3, 'MD5SUMS'),
539 os.path.join('folder', folder3, 'oops'),
540 os.path.join('folder', folder3, 'WatashiNiYomimasu.txt'),
541 os.path.join('folder', folder3, 'ZuMachen.txt'),
542 os.path.join('folder', 'third_party', 'WatashiNiYomimasu.txt'),
543 os.path.join('folder', 'lalala.txt'),
544 os.path.join('folder', 'quest.txt'),
545 # The example will have a deleted file
546 # (or should) but shouldn't return it
547 ])
548 self.assertEqual(set(x for x in walk_revctrl()), expected)
549
550
551 def test_suite():
552 return unittest.defaultTestLoader.loadTestsFromName(__name__)
OLDNEW
« no previous file with comments | « recipe_engine/third_party/setuptools/tests/test_sandbox.py ('k') | recipe_engine/third_party/setuptools/tests/test_svn.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698