• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import os
2import subprocess
3
4import virtualenv
5from setuptools.extern.six.moves import http_client
6from setuptools.extern.six.moves import xmlrpc_client
7
8TOP = 200
9PYPI_HOSTNAME = 'pypi.python.org'
10
11
12def rpc_pypi(method, *args):
13    """Call an XML-RPC method on the Pypi server."""
14    conn = http_client.HTTPSConnection(PYPI_HOSTNAME)
15    headers = {'Content-Type': 'text/xml'}
16    payload = xmlrpc_client.dumps(args, method)
17
18    conn.request("POST", "/pypi", payload, headers)
19    response = conn.getresponse()
20    if response.status == 200:
21        result = xmlrpc_client.loads(response.read())[0][0]
22        return result
23    else:
24        raise RuntimeError("Unable to download the list of top "
25                           "packages from Pypi.")
26
27
28def get_top_packages(limit):
29    """Collect the name of the top packages on Pypi."""
30    packages = rpc_pypi('top_packages')
31    return packages[:limit]
32
33
34def _package_install(package_name, tmp_dir=None, local_setuptools=True):
35    """Try to install a package and return the exit status.
36
37    This function creates a virtual environment, install setuptools using pip
38    and then install the required package. If local_setuptools is True, it
39    will install the local version of setuptools.
40    """
41    package_dir = os.path.join(tmp_dir, "test_%s" % package_name)
42    if not local_setuptools:
43        package_dir = package_dir + "_baseline"
44
45    virtualenv.create_environment(package_dir)
46
47    pip_path = os.path.join(package_dir, "bin", "pip")
48    if local_setuptools:
49        subprocess.check_call([pip_path, "install", "."])
50    returncode = subprocess.call([pip_path, "install", package_name])
51    return returncode
52
53
54def test_package_install(package_name, tmpdir):
55    """Test to verify the outcome of installing a package.
56
57    This test compare that the return code when installing a package is the
58    same as with the current stable version of setuptools.
59    """
60    new_exit_status = _package_install(package_name, tmp_dir=str(tmpdir))
61    if new_exit_status:
62        print("Installation failed, testing against stable setuptools",
63              package_name)
64        old_exit_status = _package_install(package_name, tmp_dir=str(tmpdir),
65                                           local_setuptools=False)
66        assert new_exit_status == old_exit_status
67
68
69def pytest_generate_tests(metafunc):
70    """Generator function for test_package_install.
71
72    This function will generate calls to test_package_install. If a package
73    list has been specified on the command line, it will be used. Otherwise,
74    Pypi will be queried to get the current list of top packages.
75    """
76    if "package_name" in metafunc.fixturenames:
77        if not metafunc.config.option.package_name:
78            packages = get_top_packages(TOP)
79            packages = [name for name, downloads in packages]
80        else:
81            packages = metafunc.config.option.package_name
82        metafunc.parametrize("package_name", packages)
83