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