diff options
| author | Alex Grönholm <alex.gronholm@nextday.fi> | 2018-05-26 20:51:16 +0300 |
|---|---|---|
| committer | Alex Grönholm <alex.gronholm@nextday.fi> | 2018-07-17 15:02:50 +0300 |
| commit | 89492505b968f6bf9ae9cc35f88f8ecd6ce6cbf1 (patch) | |
| tree | 3364662e4c077856db8d06fa3d57b4b544da21f8 /tests/test_wheelfile.py | |
| parent | 353217fb496d61b3c5ce287b9c61a229e2ed27fe (diff) | |
| download | wheel-git-89492505b968f6bf9ae9cc35f88f8ecd6ce6cbf1.tar.gz | |
Renamed the wheel.tool package to wheel.cli and migrated CLI stuff there
The VerifyingZipFile class was also merged to the WheelFile class.
Diffstat (limited to 'tests/test_wheelfile.py')
| -rw-r--r-- | tests/test_wheelfile.py | 180 |
1 files changed, 127 insertions, 53 deletions
diff --git a/tests/test_wheelfile.py b/tests/test_wheelfile.py index 16ca83e..03eeac7 100644 --- a/tests/test_wheelfile.py +++ b/tests/test_wheelfile.py @@ -1,89 +1,163 @@ -import hashlib -import zipfile -from io import BytesIO +# coding: utf-8 +from __future__ import unicode_literals + +from zipfile import ZipFile, ZIP_DEFLATED import pytest -import wheel.archive -import wheel.install +from wheel.cli import WheelError +from wheel.util import native, as_bytes +from wheel.wheelfile import WheelFile + + +@pytest.fixture +def wheel_path(tmpdir): + return str(tmpdir.join('test-1.0-py2.py3-none-any.whl')) + + +def test_wheelfile_re(tmpdir): + # Regression test for #208 + path = tmpdir.join('foo-2-py3-none-any.whl') + with WheelFile(str(path), 'w') as wf: + assert wf.parsed_filename.group('namever') == 'foo-2' + + +@pytest.mark.parametrize('filename', [ + 'test.whl', + 'test-1.0.whl', + 'test-1.0-py2.whl', + 'test-1.0-py2-none.whl', + 'test-1.0-py2-none-any' +]) +def test_bad_wheel_filename(filename): + exc = pytest.raises(WheelError, WheelFile, filename) + exc.match('^Bad wheel filename {!r}$'.format(filename)) + + +def test_missing_record(wheel_path): + with ZipFile(wheel_path, 'w') as zf: + zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, w0rld!")\n')) + exc = pytest.raises(WheelError, WheelFile, wheel_path) + exc.match("^Missing test-1.0.dist-info/RECORD file$") -def test_verifying_zipfile(): - if not hasattr(zipfile.ZipExtFile, '_update_crc'): - pytest.skip('No ZIP verification. Missing ZipExtFile._update_crc.') - bio = BytesIO() - zf = zipfile.ZipFile(bio, 'w') - zf.writestr("one", b"first file") - zf.writestr("two", b"second file") - zf.writestr("three", b"third file") - zf.close() +def test_unsupported_hash_algorithm(wheel_path): + with ZipFile(wheel_path, 'w') as zf: + zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, w0rld!")\n')) + zf.writestr( + 'test-1.0.dist-info/RECORD', + as_bytes('hello/héllö.py,sha000=bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo,25')) - # In default mode, VerifyingZipFile checks the hash of any read file - # mentioned with set_expected_hash(). Files not mentioned with - # set_expected_hash() are not checked. - vzf = wheel.install.VerifyingZipFile(bio, 'r') - vzf.set_expected_hash("one", hashlib.sha256(b"first file").digest()) - vzf.set_expected_hash("three", "blurble") - vzf.open("one").read() - vzf.open("two").read() - pytest.raises(wheel.install.BadWheelFile, vzf.open("three").read) + exc = pytest.raises(WheelError, WheelFile, wheel_path) + exc.match("^Unsupported hash algorithm: sha000$") - # In strict mode, VerifyingZipFile requires every read file to be - # mentioned with set_expected_hash(). - vzf.strict = True - pytest.raises(wheel.install.BadWheelFile, vzf.open, "two") - vzf.set_expected_hash("two", None) - vzf.open("two").read() +@pytest.mark.parametrize('algorithm, digest', [ + ('md5', '4J-scNa2qvSgy07rS4at-Q'), + ('sha1', 'QjCnGu5Qucb6-vir1a6BVptvOA4') +], ids=['md5', 'sha1']) +def test_weak_hash_algorithm(wheel_path, algorithm, digest): + hash_string = '{}={}'.format(algorithm, digest) + with ZipFile(wheel_path, 'w') as zf: + zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, w0rld!")\n')) + zf.writestr('test-1.0.dist-info/RECORD', + as_bytes('hello/héllö.py,{},25'.format(hash_string))) + exc = pytest.raises(WheelError, WheelFile, wheel_path) + exc.match(r"^Weak hash algorithm \({}\) is not permitted by PEP 427$".format(algorithm)) -def test_pop_zipfile(): - bio = BytesIO() - zf = wheel.install.VerifyingZipFile(bio, 'w') - zf.writestr("one", b"first file") - zf.writestr("two", b"second file") - zf.close() - pytest.raises(RuntimeError, zf.pop) +@pytest.mark.parametrize('algorithm, digest', [ + ('sha256', 'bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo'), + ('sha384', 'cDXriAy_7i02kBeDkN0m2RIDz85w6pwuHkt2PZ4VmT2PQc1TZs8Ebvf6eKDFcD_S'), + ('sha512', 'kdX9CQlwNt4FfOpOKO_X0pn_v1opQuksE40SrWtMyP1NqooWVWpzCE3myZTfpy8g2azZON_' + 'iLNpWVxTwuDWqBQ') +], ids=['sha256', 'sha384', 'sha512']) +def test_testzip(wheel_path, algorithm, digest): + hash_string = '{}={}'.format(algorithm, digest) + with ZipFile(wheel_path, 'w') as zf: + zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, world!")\n')) + zf.writestr('test-1.0.dist-info/RECORD', + as_bytes('hello/héllö.py,{},25'.format(hash_string))) - zf = wheel.install.VerifyingZipFile(bio, 'a') - zf.pop() - zf.close() + with WheelFile(wheel_path) as wf: + wf.testzip() - zf = wheel.install.VerifyingZipFile(bio, 'r') - assert len(zf.infolist()) == 1 +def test_testzip_missing_hash(wheel_path): + with ZipFile(wheel_path, 'w') as zf: + zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, world!")\n')) + zf.writestr('test-1.0.dist-info/RECORD', '') -def test_zipfile_timestamp(tmpdir, monkeypatch): + with WheelFile(wheel_path) as wf: + exc = pytest.raises(WheelError, wf.testzip) + exc.match(native("^No hash found for file 'hello/héllö.py'$")) + + +def test_testzip_bad_hash(wheel_path): + with ZipFile(wheel_path, 'w') as zf: + zf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, w0rld!")\n')) + zf.writestr( + 'test-1.0.dist-info/RECORD', + as_bytes('hello/héllö.py,sha256=bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo,25')) + + with WheelFile(wheel_path) as wf: + exc = pytest.raises(WheelError, wf.testzip) + exc.match(native("^Hash mismatch for file 'hello/héllö.py'$")) + + +def test_write_str(wheel_path): + with WheelFile(wheel_path, 'w') as wf: + wf.writestr(native('hello/héllö.py'), as_bytes('print("Héllö, world!")\n')) + + with ZipFile(wheel_path, 'r') as zf: + infolist = zf.infolist() + assert len(infolist) == 2 + assert infolist[0].filename == native('hello/héllö.py') + assert infolist[0].file_size == 25 + assert infolist[1].filename == 'test-1.0.dist-info/RECORD' + + record = zf.read('test-1.0.dist-info/RECORD') + assert record == as_bytes( + 'hello/héllö.py,sha256=bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo,25\n' + 'test-1.0.dist-info/RECORD,,\n') + + +def test_timestamp(tmpdir_factory, wheel_path, monkeypatch): # An environment variable can be used to influence the timestamp on # TarInfo objects inside the zip. See issue #143. + build_dir = tmpdir_factory.mktemp('build') for filename in ('one', 'two', 'three'): - tmpdir.join(filename).write(filename + '\n') + build_dir.join(filename).write(filename + '\n') # The earliest date representable in TarInfos, 1980-01-01 monkeypatch.setenv('SOURCE_DATE_EPOCH', '315576060') - zip_base_name = str(tmpdir.join('dummy')) - zip_filename = wheel.archive.make_wheelfile_inner(zip_base_name, str(tmpdir)) - with zipfile.ZipFile(zip_filename, 'r') as zf: + with WheelFile(wheel_path, 'w') as wf: + wf.write_files(str(build_dir)) + + with ZipFile(wheel_path, 'r') as zf: for info in zf.infolist(): assert info.date_time[:3] == (1980, 1, 1) + assert info.compress_type == ZIP_DEFLATED -def test_zipfile_attributes(tmpdir): +def test_attributes(tmpdir_factory, wheel_path): # With the change from ZipFile.write() to .writestr(), we need to manually # set member attributes. + build_dir = tmpdir_factory.mktemp('build') files = (('foo', 0o644), ('bar', 0o755)) for filename, mode in files: - path = tmpdir.join(filename) + path = build_dir.join(filename) path.write(filename + '\n') path.chmod(mode) - zip_base_name = str(tmpdir.join('dummy')) - zip_filename = wheel.archive.make_wheelfile_inner(zip_base_name, str(tmpdir)) - with zipfile.ZipFile(zip_filename, 'r') as zf: + with WheelFile(wheel_path, 'w') as wf: + wf.write_files(str(build_dir)) + + with ZipFile(wheel_path, 'r') as zf: for filename, mode in files: - info = zf.getinfo(str(tmpdir.join(filename))) + info = zf.getinfo(filename) assert info.external_attr == (mode | 0o100000) << 16 - assert info.compress_type == zipfile.ZIP_DEFLATED + assert info.compress_type == ZIP_DEFLATED |
