diff options
Diffstat (limited to 'tests/testutils/python_repo.py')
-rw-r--r-- | tests/testutils/python_repo.py | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/tests/testutils/python_repo.py b/tests/testutils/python_repo.py new file mode 100644 index 000000000..9cda5e910 --- /dev/null +++ b/tests/testutils/python_repo.py @@ -0,0 +1,128 @@ +from setuptools.sandbox import run_setup +import os +import pytest +import re +import shutil + + +SETUP_TEMPLATE = '''\ +from setuptools import setup + +setup( + name='{name}', + version='{version}', + description='{name}', + packages=['{pkgdirname}'], + entry_points={{ + 'console_scripts': [ + '{pkgdirname}={pkgdirname}:main' + ] + }} +) +''' + +# All packages generated via generate_pip_package will have the functions below +INIT_TEMPLATE = '''\ +def main(): + print('This is {name}') + +def hello(actor='world'): + print('Hello {{}}! This is {name}'.format(actor)) +''' + +HTML_TEMPLATE = '''\ +<html> + <head> + <title>Links for {name}</title> + </head> + <body> + <a href='{name}-{version}.tar.gz'>{name}-{version}.tar.gz</a><br /> + </body> +</html> +''' + + +# Creates a simple python source distribution and copies this into a specified +# directory which is to serve as a mock python repository +# +# Args: +# tmpdir (str): Directory in which the source files will be created +# pypi (str): Directory serving as a mock python repository +# name (str): The name of the package to be created +# version (str): The version of the package to be created +# +# Returns: +# None +# +def generate_pip_package(tmpdir, pypi, name, version='0.1'): + # check if package already exists in pypi + pypi_package = os.path.join(pypi, re.sub('[^0-9a-zA-Z]+', '-', name)) + if os.path.exists(pypi_package): + return + + # create the package source files in tmpdir resulting in a directory + # tree resembling the following structure: + # + # tmpdir + # |-- setup.py + # `-- package + # `-- __init__.py + # + setup_file = os.path.join(tmpdir, 'setup.py') + pkgdirname = re.sub('[^0-9a-zA-Z]+', '', name) + with open(setup_file, 'w') as f: + f.write( + SETUP_TEMPLATE.format( + name=name, + version=version, + pkgdirname=pkgdirname + ) + ) + os.chmod(setup_file, 0o755) + + package = os.path.join(tmpdir, pkgdirname) + os.makedirs(package) + + main_file = os.path.join(package, '__init__.py') + with open(main_file, 'w') as f: + f.write(INIT_TEMPLATE.format(name=name)) + os.chmod(main_file, 0o644) + + run_setup(setup_file, ['sdist']) + + # create directory for this package in pypi resulting in a directory + # tree resembling the following structure: + # + # pypi + # `-- pypi_package + # |-- index.html + # `-- foo-0.1.tar.gz + # + os.makedirs(pypi_package) + + # add an index html page + index_html = os.path.join(pypi_package, 'index.html') + with open(index_html, 'w') as f: + f.write(HTML_TEMPLATE.format(name=name, version=version)) + + # copy generated tarfile to pypi package + dist_dir = os.path.join(tmpdir, 'dist') + for tar in os.listdir(dist_dir): + tarpath = os.path.join(dist_dir, tar) + shutil.copy(tarpath, pypi_package) + + +@pytest.fixture +def setup_pypi_repo(tmpdir): + def create_pkgdir(package): + pkgdirname = re.sub('[^0-9a-zA-Z]+', '', package) + pkgdir = os.path.join(str(tmpdir), pkgdirname) + os.makedirs(pkgdir) + return pkgdir + + def add_packages(packages, pypi_repo): + for package in packages: + pkgdir = create_pkgdir(package) + generate_pip_package(pkgdir, pypi_repo, package) + + return add_packages |