test_integration.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. # Licensed under the Apache License, Version 2.0 (the "License");
  2. # you may not use this file except in compliance with the License.
  3. # You may obtain a copy of the License at
  4. #
  5. # http://www.apache.org/licenses/LICENSE-2.0
  6. #
  7. # Unless required by applicable law or agreed to in writing, software
  8. # distributed under the License is distributed on an "AS IS" BASIS,
  9. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  10. # implied.
  11. # See the License for the specific language governing permissions and
  12. # limitations under the License.
  13. import os.path
  14. import shlex
  15. import sys
  16. import fixtures
  17. import testtools
  18. import textwrap
  19. from pbr.tests import base
  20. from pbr.tests import test_packaging
  21. PIPFLAGS = shlex.split(os.environ.get('PIPFLAGS', ''))
  22. PIPVERSION = os.environ.get('PIPVERSION', 'pip')
  23. PBRVERSION = os.environ.get('PBRVERSION', 'pbr')
  24. REPODIR = os.environ.get('REPODIR', '')
  25. WHEELHOUSE = os.environ.get('WHEELHOUSE', '')
  26. PIP_CMD = ['-m', 'pip'] + PIPFLAGS + ['install', '-f', WHEELHOUSE]
  27. PROJECTS = shlex.split(os.environ.get('PROJECTS', ''))
  28. PBR_ROOT = os.path.abspath(os.path.join(__file__, '..', '..', '..'))
  29. def all_projects():
  30. if not REPODIR:
  31. return
  32. # Future: make this path parameterisable.
  33. excludes = set(['tempest', 'requirements'])
  34. for name in PROJECTS:
  35. name = name.strip()
  36. short_name = name.split('/')[-1]
  37. try:
  38. with open(os.path.join(
  39. REPODIR, short_name, 'setup.py'), 'rt') as f:
  40. if 'pbr' not in f.read():
  41. continue
  42. except IOError:
  43. continue
  44. if short_name in excludes:
  45. continue
  46. yield (short_name, dict(name=name, short_name=short_name))
  47. class TestIntegration(base.BaseTestCase):
  48. scenarios = list(all_projects())
  49. def setUp(self):
  50. # Integration tests need a higher default - big repos can be slow to
  51. # clone, particularly under guest load.
  52. env = fixtures.EnvironmentVariable(
  53. 'OS_TEST_TIMEOUT', os.environ.get('OS_TEST_TIMEOUT', '600'))
  54. with env:
  55. super(TestIntegration, self).setUp()
  56. base._config_git()
  57. @testtools.skipUnless(
  58. os.environ.get('PBR_INTEGRATION', None) == '1',
  59. 'integration tests not enabled')
  60. def test_integration(self):
  61. # Test that we can:
  62. # - run sdist from the repo in a venv
  63. # - install the resulting tarball in a new venv
  64. # - pip install the repo
  65. # - pip install -e the repo
  66. # We don't break these into separate tests because we'd need separate
  67. # source dirs to isolate from side effects of running pip, and the
  68. # overheads of setup would start to beat the benefits of parallelism.
  69. self.useFixture(base.CapturedSubprocess(
  70. 'sync-req',
  71. ['python', 'update.py', os.path.join(REPODIR, self.short_name)],
  72. cwd=os.path.join(REPODIR, 'requirements')))
  73. self.useFixture(base.CapturedSubprocess(
  74. 'commit-requirements',
  75. 'git diff --quiet || git commit -amrequirements',
  76. cwd=os.path.join(REPODIR, self.short_name), shell=True))
  77. path = os.path.join(
  78. self.useFixture(fixtures.TempDir()).path, 'project')
  79. self.useFixture(base.CapturedSubprocess(
  80. 'clone',
  81. ['git', 'clone', os.path.join(REPODIR, self.short_name), path]))
  82. venv = self.useFixture(
  83. test_packaging.Venv('sdist',
  84. modules=['pip', 'wheel', PBRVERSION],
  85. pip_cmd=PIP_CMD))
  86. python = venv.python
  87. self.useFixture(base.CapturedSubprocess(
  88. 'sdist', [python, 'setup.py', 'sdist'], cwd=path))
  89. venv = self.useFixture(
  90. test_packaging.Venv('tarball',
  91. modules=['pip', 'wheel', PBRVERSION],
  92. pip_cmd=PIP_CMD))
  93. python = venv.python
  94. filename = os.path.join(
  95. path, 'dist', os.listdir(os.path.join(path, 'dist'))[0])
  96. self.useFixture(base.CapturedSubprocess(
  97. 'tarball', [python] + PIP_CMD + [filename]))
  98. venv = self.useFixture(
  99. test_packaging.Venv('install-git',
  100. modules=['pip', 'wheel', PBRVERSION],
  101. pip_cmd=PIP_CMD))
  102. root = venv.path
  103. python = venv.python
  104. self.useFixture(base.CapturedSubprocess(
  105. 'install-git', [python] + PIP_CMD + ['git+file://' + path]))
  106. if self.short_name == 'nova':
  107. found = False
  108. for _, _, filenames in os.walk(root):
  109. if 'migrate.cfg' in filenames:
  110. found = True
  111. self.assertTrue(found)
  112. venv = self.useFixture(
  113. test_packaging.Venv('install-e',
  114. modules=['pip', 'wheel', PBRVERSION],
  115. pip_cmd=PIP_CMD))
  116. root = venv.path
  117. python = venv.python
  118. self.useFixture(base.CapturedSubprocess(
  119. 'install-e', [python] + PIP_CMD + ['-e', path]))
  120. class TestInstallWithoutPbr(base.BaseTestCase):
  121. @testtools.skipUnless(
  122. os.environ.get('PBR_INTEGRATION', None) == '1',
  123. 'integration tests not enabled')
  124. def test_install_without_pbr(self):
  125. # Test easy-install of a thing that depends on a thing using pbr
  126. tempdir = self.useFixture(fixtures.TempDir()).path
  127. # A directory containing sdists of the things we're going to depend on
  128. # in using-package.
  129. dist_dir = os.path.join(tempdir, 'distdir')
  130. os.mkdir(dist_dir)
  131. self._run_cmd(sys.executable, ('setup.py', 'sdist', '-d', dist_dir),
  132. allow_fail=False, cwd=PBR_ROOT)
  133. # testpkg - this requires a pbr-using package
  134. test_pkg_dir = os.path.join(tempdir, 'testpkg')
  135. os.mkdir(test_pkg_dir)
  136. pkgs = {
  137. 'pkgTest': {
  138. 'setup.py': textwrap.dedent("""\
  139. #!/usr/bin/env python
  140. import setuptools
  141. setuptools.setup(
  142. name = 'pkgTest',
  143. tests_require = ['pkgReq'],
  144. test_suite='pkgReq'
  145. )
  146. """),
  147. 'setup.cfg': textwrap.dedent("""\
  148. [easy_install]
  149. find_links = %s
  150. """ % dist_dir)},
  151. 'pkgReq': {
  152. 'requirements.txt': textwrap.dedent("""\
  153. pbr
  154. """),
  155. 'pkgReq/__init__.py': textwrap.dedent("""\
  156. print("FakeTest loaded and ran")
  157. """)},
  158. }
  159. pkg_dirs = self.useFixture(
  160. test_packaging.CreatePackages(pkgs)).package_dirs
  161. test_pkg_dir = pkg_dirs['pkgTest']
  162. req_pkg_dir = pkg_dirs['pkgReq']
  163. self._run_cmd(sys.executable, ('setup.py', 'sdist', '-d', dist_dir),
  164. allow_fail=False, cwd=req_pkg_dir)
  165. # A venv to test within
  166. venv = self.useFixture(test_packaging.Venv('nopbr', ['pip', 'wheel']))
  167. python = venv.python
  168. # Run the depending script
  169. self.useFixture(base.CapturedSubprocess(
  170. 'nopbr', [python] + ['setup.py', 'test'], cwd=test_pkg_dir))
  171. class TestMarkersPip(base.BaseTestCase):
  172. scenarios = [
  173. ('pip-1.5', {'modules': ['pip>=1.5,<1.6']}),
  174. ('pip-6.0', {'modules': ['pip>=6.0,<6.1']}),
  175. ('pip-latest', {'modules': ['pip']}),
  176. ('setuptools-EL7', {'modules': ['pip==1.4.1', 'setuptools==0.9.8']}),
  177. ('setuptools-Trusty', {'modules': ['pip==1.5', 'setuptools==2.2']}),
  178. ('setuptools-minimum', {'modules': ['pip==1.5', 'setuptools==0.7.2']}),
  179. ]
  180. @testtools.skipUnless(
  181. os.environ.get('PBR_INTEGRATION', None) == '1',
  182. 'integration tests not enabled')
  183. def test_pip_versions(self):
  184. pkgs = {
  185. 'test_markers':
  186. {'requirements.txt': textwrap.dedent("""\
  187. pkg_a; python_version=='1.2'
  188. pkg_b; python_version!='1.2'
  189. """)},
  190. 'pkg_a': {},
  191. 'pkg_b': {},
  192. }
  193. pkg_dirs = self.useFixture(
  194. test_packaging.CreatePackages(pkgs)).package_dirs
  195. temp_dir = self.useFixture(fixtures.TempDir()).path
  196. repo_dir = os.path.join(temp_dir, 'repo')
  197. venv = self.useFixture(test_packaging.Venv('markers'))
  198. bin_python = venv.python
  199. os.mkdir(repo_dir)
  200. for module in self.modules:
  201. self._run_cmd(
  202. bin_python,
  203. ['-m', 'pip', 'install', '--upgrade', module],
  204. cwd=venv.path, allow_fail=False)
  205. for pkg in pkg_dirs:
  206. self._run_cmd(
  207. bin_python, ['setup.py', 'sdist', '-d', repo_dir],
  208. cwd=pkg_dirs[pkg], allow_fail=False)
  209. self._run_cmd(
  210. bin_python,
  211. ['-m', 'pip', 'install', '--no-index', '-f', repo_dir,
  212. 'test_markers'],
  213. cwd=venv.path, allow_fail=False)
  214. self.assertIn('pkg-b', self._run_cmd(
  215. bin_python, ['-m', 'pip', 'freeze'], cwd=venv.path,
  216. allow_fail=False)[0])
  217. class TestLTSSupport(base.BaseTestCase):
  218. # These versions come from the versions installed from the 'virtualenv'
  219. # command from the 'python-virtualenv' package.
  220. scenarios = [
  221. ('EL7', {'modules': ['pip==1.4.1', 'setuptools==0.9.8'],
  222. 'py3support': True}), # And EPEL6
  223. ('Trusty', {'modules': ['pip==1.5', 'setuptools==2.2'],
  224. 'py3support': True}),
  225. ('Jessie', {'modules': ['pip==1.5.6', 'setuptools==5.5.1'],
  226. 'py3support': True}),
  227. # Wheezy has pip1.1, which cannot be called with '-m pip'
  228. # So we'll use a different version of pip here.
  229. ('WheezyPrecise', {'modules': ['pip==1.4.1', 'setuptools==0.6c11'],
  230. 'py3support': False})
  231. ]
  232. @testtools.skipUnless(
  233. os.environ.get('PBR_INTEGRATION', None) == '1',
  234. 'integration tests not enabled')
  235. def test_lts_venv_default_versions(self):
  236. if (sys.version_info[0] == 3 and not self.py3support):
  237. self.skipTest('This combination will not install with py3, '
  238. 'skipping test')
  239. venv = self.useFixture(
  240. test_packaging.Venv('setuptools', modules=self.modules))
  241. bin_python = venv.python
  242. pbr = 'file://%s#egg=pbr' % PBR_ROOT
  243. # Installing PBR is a reasonable indication that we are not broken on
  244. # this particular combination of setuptools and pip.
  245. self._run_cmd(bin_python, ['-m', 'pip', 'install', pbr],
  246. cwd=venv.path, allow_fail=False)