test_virtualenv.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import glob
  2. import os
  3. import sys
  4. import pathlib
  5. import pytest
  6. from pytest_fixture_config import yield_requires_config
  7. import pytest_virtualenv
  8. from .textwrap import DALS
  9. from .test_easy_install import make_nspkg_sdist
  10. @pytest.fixture(autouse=True)
  11. def pytest_virtualenv_works(virtualenv):
  12. """
  13. pytest_virtualenv may not work. if it doesn't, skip these
  14. tests. See #1284.
  15. """
  16. venv_prefix = virtualenv.run(
  17. 'python -c "import sys; print(sys.prefix)"',
  18. capture=True,
  19. ).strip()
  20. if venv_prefix == sys.prefix:
  21. pytest.skip("virtualenv is broken (see pypa/setuptools#1284)")
  22. @yield_requires_config(pytest_virtualenv.CONFIG, ['virtualenv_executable'])
  23. @pytest.fixture(scope='function')
  24. def bare_virtualenv():
  25. """ Bare virtualenv (no pip/setuptools/wheel).
  26. """
  27. with pytest_virtualenv.VirtualEnv(args=(
  28. '--no-wheel',
  29. '--no-pip',
  30. '--no-setuptools',
  31. )) as venv:
  32. yield venv
  33. SOURCE_DIR = os.path.join(os.path.dirname(__file__), '../..')
  34. def test_clean_env_install(bare_virtualenv):
  35. """
  36. Check setuptools can be installed in a clean environment.
  37. """
  38. bare_virtualenv.run(['python', 'setup.py', 'install'], cd=SOURCE_DIR)
  39. def _get_pip_versions():
  40. # This fixture will attempt to detect if tests are being run without
  41. # network connectivity and if so skip some tests
  42. network = True
  43. if not os.environ.get('NETWORK_REQUIRED', False): # pragma: nocover
  44. try:
  45. from urllib.request import urlopen
  46. from urllib.error import URLError
  47. except ImportError:
  48. from urllib2 import urlopen, URLError # Python 2.7 compat
  49. try:
  50. urlopen('https://pypi.org', timeout=1)
  51. except URLError:
  52. # No network, disable most of these tests
  53. network = False
  54. network_versions = [
  55. 'pip==9.0.3',
  56. 'pip==10.0.1',
  57. 'pip==18.1',
  58. 'pip==19.0.1',
  59. 'https://github.com/pypa/pip/archive/master.zip',
  60. ]
  61. versions = [None] + [
  62. pytest.param(v, **({} if network else {'marks': pytest.mark.skip}))
  63. for v in network_versions
  64. ]
  65. return versions
  66. @pytest.mark.parametrize('pip_version', _get_pip_versions())
  67. def test_pip_upgrade_from_source(pip_version, virtualenv):
  68. """
  69. Check pip can upgrade setuptools from source.
  70. """
  71. # Install pip/wheel, and remove setuptools (as it
  72. # should not be needed for bootstraping from source)
  73. if pip_version is None:
  74. upgrade_pip = ()
  75. else:
  76. upgrade_pip = ('python -m pip install -U {pip_version} --retries=1',)
  77. virtualenv.run(' && '.join((
  78. 'pip uninstall -y setuptools',
  79. 'pip install -U wheel',
  80. ) + upgrade_pip).format(pip_version=pip_version))
  81. dist_dir = virtualenv.workspace
  82. # Generate source distribution / wheel.
  83. virtualenv.run(' && '.join((
  84. 'python setup.py -q sdist -d {dist}',
  85. 'python setup.py -q bdist_wheel -d {dist}',
  86. )).format(dist=dist_dir), cd=SOURCE_DIR)
  87. sdist = glob.glob(os.path.join(dist_dir, '*.zip'))[0]
  88. wheel = glob.glob(os.path.join(dist_dir, '*.whl'))[0]
  89. # Then update from wheel.
  90. virtualenv.run('pip install ' + wheel)
  91. # And finally try to upgrade from source.
  92. virtualenv.run('pip install --no-cache-dir --upgrade ' + sdist)
  93. def _check_test_command_install_requirements(virtualenv, tmpdir):
  94. """
  95. Check the test command will install all required dependencies.
  96. """
  97. # Install setuptools.
  98. virtualenv.run('python setup.py develop', cd=SOURCE_DIR)
  99. def sdist(distname, version):
  100. dist_path = tmpdir.join('%s-%s.tar.gz' % (distname, version))
  101. make_nspkg_sdist(str(dist_path), distname, version)
  102. return dist_path
  103. dependency_links = [
  104. pathlib.Path(str(dist_path)).as_uri()
  105. for dist_path in (
  106. sdist('foobar', '2.4'),
  107. sdist('bits', '4.2'),
  108. sdist('bobs', '6.0'),
  109. sdist('pieces', '0.6'),
  110. )
  111. ]
  112. with tmpdir.join('setup.py').open('w') as fp:
  113. fp.write(DALS(
  114. '''
  115. from setuptools import setup
  116. setup(
  117. dependency_links={dependency_links!r},
  118. install_requires=[
  119. 'barbazquux1; sys_platform in ""',
  120. 'foobar==2.4',
  121. ],
  122. setup_requires='bits==4.2',
  123. tests_require="""
  124. bobs==6.0
  125. """,
  126. extras_require={{
  127. 'test': ['barbazquux2'],
  128. ':"" in sys_platform': 'pieces==0.6',
  129. ':python_version > "1"': """
  130. pieces
  131. foobar
  132. """,
  133. }}
  134. )
  135. '''.format(dependency_links=dependency_links)))
  136. with tmpdir.join('test.py').open('w') as fp:
  137. fp.write(DALS(
  138. '''
  139. import foobar
  140. import bits
  141. import bobs
  142. import pieces
  143. open('success', 'w').close()
  144. '''))
  145. # Run test command for test package.
  146. # use 'virtualenv.python' as workaround for man-group/pytest-plugins#166
  147. cmd = [virtualenv.python, 'setup.py', 'test', '-s', 'test']
  148. virtualenv.run(cmd, cd=str(tmpdir))
  149. assert tmpdir.join('success').check()
  150. def test_test_command_install_requirements(virtualenv, tmpdir):
  151. # Ensure pip/wheel packages are installed.
  152. virtualenv.run(
  153. "python -c \"__import__('pkg_resources').require(['pip', 'wheel'])\"")
  154. _check_test_command_install_requirements(virtualenv, tmpdir)
  155. def test_test_command_install_requirements_when_using_easy_install(
  156. bare_virtualenv, tmpdir):
  157. _check_test_command_install_requirements(bare_virtualenv, tmpdir)
  158. def test_no_missing_dependencies(bare_virtualenv):
  159. """
  160. Quick and dirty test to ensure all external dependencies are vendored.
  161. """
  162. for command in ('upload',): # sorted(distutils.command.__all__):
  163. bare_virtualenv.run(
  164. ['python', 'setup.py', command, '-h'], cd=SOURCE_DIR)