summaryrefslogtreecommitdiff
path: root/tests/test_wheelfile.py
diff options
context:
space:
mode:
authorAlex Grönholm <alex.gronholm@nextday.fi>2018-05-26 20:51:16 +0300
committerAlex Grönholm <alex.gronholm@nextday.fi>2018-07-17 15:02:50 +0300
commit89492505b968f6bf9ae9cc35f88f8ecd6ce6cbf1 (patch)
tree3364662e4c077856db8d06fa3d57b4b544da21f8 /tests/test_wheelfile.py
parent353217fb496d61b3c5ce287b9c61a229e2ed27fe (diff)
downloadwheel-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.py180
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