Skip to content

Commit

Permalink
Add integration test for data-requires-python
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskuehl committed Oct 6, 2020
1 parent 4079e2d commit 74b34fb
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 32 deletions.
38 changes: 27 additions & 11 deletions testing.py
@@ -1,37 +1,53 @@
import json
import os.path
import shutil
import subprocess
import sys
import tempfile
from typing import NamedTuple
from typing import Optional
from typing import Tuple

from dumb_pypi import main


def make_package(path):
class FakePackage(NamedTuple):
filename: str
requires_python: Optional[str] = None

@property
def setup_py_contents(self):
return (
'from setuptools import setup\n'
'setup(name={!r}, version={!r})\n'
).format(*main.guess_name_version_from_filename(self.filename))

def as_json(self):
return json.dumps({
'filename': self.filename,
'requires_python': self.requires_python,
})


def make_package(package: FakePackage, path: str) -> None:
"""Make a fake package at path.
Even with --download, pip insists on extracting the downloaded packages (in
order to find dependencies), so we can't just make empty files.
"""
name, version = main.guess_name_version_from_filename(os.path.basename(path))

with tempfile.TemporaryDirectory() as td:
setup_py = os.path.join(td, 'setup.py')
with open(setup_py, 'w') as f:
f.write(
'from setuptools import setup\n'
'setup(name="{}", version="{}")\n'.format(name, version),
)
f.write(package.setup_py_contents)

args: Tuple[str, ...] = ('sdist', '--formats=zip')
if path.endswith(('.tgz', '.tar.gz')):
if package.filename.endswith(('.tgz', '.tar.gz')):
args = ('sdist', '--formats=gztar')
elif path.endswith('.tar'):
elif package.filename.endswith('.tar'):
args = ('sdist', '--formats=tar')
elif path.endswith('.whl'):
elif package.filename.endswith('.whl'):
args = ('bdist_wheel',)

subprocess.check_call((sys.executable, setup_py) + args, cwd=td)
created, = os.listdir(os.path.join(td, 'dist'))
shutil.move(os.path.join(td, 'dist', created), path)
shutil.move(os.path.join(td, 'dist', created), os.path.join(path, package.filename))
71 changes: 50 additions & 21 deletions tests/integration_test.py
@@ -1,22 +1,24 @@
import os
import subprocess

import pytest

from dumb_pypi import main
from testing import FakePackage
from testing import make_package


def install_packages(path, package_names):
def install_packages(path, fake_packages):
"""Deploy fake packages with the given names into path."""
pool = path.join('pool').mkdir()
for package in package_names:
make_package(pool.join(package).strpath)
for package in fake_packages:
make_package(package, pool.strpath)

package_list = path.join('package-list')
package_list.write('\n'.join(package_names) + '\n')
package_list = path.join('package-list.json')
package_list.write('\n'.join(package.as_json() for package in fake_packages) + '\n')

main.main((
'--package-list', package_list.strpath,
'--package-list-json', package_list.strpath,
'--output-dir', path.strpath,
'--packages-url', '../../pool/',
))
Expand All @@ -28,10 +30,10 @@ def pip_download(pip, index_url, path, *spec):
)


@pytest.mark.parametrize('package_names', (
('ocflib-2016.12.10.1.48-py2.py3-none-any.whl',),
('ocflib-2016.12.10.1.48.tar.gz',),
('ocflib-2016.12.10.1.48.zip',),
@pytest.mark.parametrize('packages', (
(FakePackage('ocflib-2016.12.10.1.48-py2.py3-none-any.whl'),),
(FakePackage('ocflib-2016.12.10.1.48.tar.gz'),),
(FakePackage('ocflib-2016.12.10.1.48.zip'),),
))
@pytest.mark.parametrize('requirement', (
'ocflib',
Expand All @@ -42,10 +44,10 @@ def test_simple_package(
tmpdir,
tmpweb,
all_pips,
package_names,
packages,
requirement,
):
install_packages(tmpweb.path, package_names)
install_packages(tmpweb.path, packages)
pip_download(
all_pips,
tmpweb.url + '/simple',
Expand All @@ -54,12 +56,12 @@ def test_simple_package(
)


@pytest.mark.parametrize('package_names', (
('aspy.yaml-0.2.1.zip',),
('aspy.yaml-0.2.1.tar',),
('aspy.yaml-0.2.1.tar.gz',),
('aspy.yaml-0.2.1.tgz',),
('aspy.yaml-0.2.1-py2.py3-none-any.whl',)
@pytest.mark.parametrize('packages', (
(FakePackage('aspy.yaml-0.2.1.zip'),),
(FakePackage('aspy.yaml-0.2.1.tar'),),
(FakePackage('aspy.yaml-0.2.1.tar.gz'),),
(FakePackage('aspy.yaml-0.2.1.tgz'),),
(FakePackage('aspy.yaml-0.2.1-py2.py3-none-any.whl'),)
))
@pytest.mark.parametrize('requirement', (
'aspy.yaml',
Expand All @@ -71,15 +73,15 @@ def test_normalized_packages_modern_pip(
tmpdir,
tmpweb,
modern_pips,
package_names,
packages,
requirement,
):
"""Only modern versions of pip fully normalize names before making requests
to PyPI, so old versions of pip cannot pass this test.
RATIONALE.md explains how we suggest adding support for old versions of pip.
"""
install_packages(tmpweb.path, package_names)
install_packages(tmpweb.path, packages)
pip_download(
modern_pips,
tmpweb.url + '/simple',
Expand All @@ -103,11 +105,38 @@ def test_normalized_packages_modern_pip_wheels(
normalized, so you can install with a wider varierty of names.
"""
install_packages(tmpweb.path, (
'aspy.yaml-0.2.1-py2.py3-none-any.whl',
FakePackage('aspy.yaml-0.2.1-py2.py3-none-any.whl'),
))
pip_download(
modern_pips,
tmpweb.url + '/simple',
tmpdir.strpath,
requirement,
)


def test_pip_9_respects_requires_python(
tmpdir,
tmpweb,
pip_versions,
):
pip = pip_versions['9.0.1']
install_packages(
tmpweb.path,
(
# This is a fallback that shouldn't be used.
FakePackage('foo-1.tar.gz'),
# This one should match all verisons we care about.
FakePackage('foo-2.tar.gz', requires_python='>=2'),
# Nonsensical requires_python value that will never match.
FakePackage('foo-3.tar.gz', requires_python='==1.2.3'),
)
)
pip_download(
pip,
tmpweb.url + '/simple',
tmpdir.strpath,
'foo',
)
downloaded_package, = tmpdir.listdir(fil=os.path.isfile)
assert downloaded_package.basename == 'foo-2.tar.gz'

0 comments on commit 74b34fb

Please sign in to comment.