PageRenderTime 48ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/integration/modules/pip.py

https://gitlab.com/ricardo.hernandez/salt
Python | 428 lines | 336 code | 70 blank | 22 comment | 53 complexity | 0311cc9828f2f5994bdf900df990343a MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. '''
  3. :codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
  4. tests.integration.modules.pip
  5. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  6. '''
  7. # Import python libs
  8. from __future__ import absolute_import
  9. import os
  10. import pwd
  11. import shutil
  12. import re
  13. import tempfile
  14. # Import Salt Testing libs
  15. from salttesting import skipIf
  16. from salttesting.helpers import ensure_in_syspath
  17. ensure_in_syspath('../../')
  18. # Import salt libs
  19. import integration
  20. import salt.utils
  21. from salt.modules.virtualenv_mod import KNOWN_BINARY_NAMES
  22. @skipIf(salt.utils.which_bin(KNOWN_BINARY_NAMES) is None, 'virtualenv not installed')
  23. class PipModuleTest(integration.ModuleCase):
  24. def setUp(self):
  25. super(PipModuleTest, self).setUp()
  26. self.venv_test_dir = tempfile.mkdtemp(dir=integration.SYS_TMP_DIR)
  27. self.venv_dir = os.path.join(self.venv_test_dir, 'venv')
  28. for key in os.environ.copy():
  29. if key.startswith('PIP_'):
  30. os.environ.pop(key)
  31. self.pip_temp = os.path.join(self.venv_test_dir, '.pip-temp')
  32. if not os.path.isdir(self.pip_temp):
  33. os.makedirs(self.pip_temp)
  34. os.environ['PIP_SOURCE_DIR'] = os.environ['PIP_BUILD_DIR'] = ''
  35. def pip_successful_install(self, target, expect=('flake8', 'pep8',)):
  36. '''
  37. isolate regex for extracting `successful install` message from pip
  38. '''
  39. expect = set(expect)
  40. expect_str = '|'.join(expect)
  41. success = re.search(
  42. r'^.*Successfully installed\s([^\n]+)(?:Clean.*)?',
  43. target,
  44. re.M | re.S)
  45. success_for = re.findall(
  46. r'({0})(?:-(?:[\d\.-]))?'.format(expect_str),
  47. success.groups()[0]
  48. ) if success else []
  49. return expect.issubset(set(success_for))
  50. def test_issue_2087_missing_pip(self):
  51. # Let's create the testing virtualenv
  52. self.run_function('virtualenv.create', [self.venv_dir])
  53. # Let's remove the pip binary
  54. pip_bin = os.path.join(self.venv_dir, 'bin', 'pip')
  55. if not os.path.isfile(pip_bin):
  56. self.skipTest(
  57. 'Failed to find the pip binary to the test virtualenv'
  58. )
  59. os.remove(pip_bin)
  60. # Let's run a pip depending functions
  61. for func in ('pip.freeze', 'pip.list'):
  62. ret = self.run_function(func, bin_env=self.venv_dir)
  63. self.assertIn(
  64. 'Command required for \'{0}\' not found: '
  65. 'Could not find a `pip` binary in virtualenv'.format(func),
  66. ret
  67. )
  68. @skipIf(os.geteuid() != 0, 'you must be root to run this test')
  69. def test_requirements_as_list_of_chains__sans_no_chown__cwd_set__absolute_file_path(self):
  70. self.run_function('virtualenv.create', [self.venv_dir])
  71. # Create a requirements file that depends on another one.
  72. req1_filename = os.path.join(self.venv_dir, 'requirements1.txt')
  73. req1b_filename = os.path.join(self.venv_dir, 'requirements1b.txt')
  74. req2_filename = os.path.join(self.venv_dir, 'requirements2.txt')
  75. req2b_filename = os.path.join(self.venv_dir, 'requirements2b.txt')
  76. with salt.utils.fopen(req1_filename, 'wb') as f:
  77. f.write('-r requirements1b.txt\n')
  78. with salt.utils.fopen(req1b_filename, 'wb') as f:
  79. f.write('flake8\n')
  80. with salt.utils.fopen(req2_filename, 'wb') as f:
  81. f.write('-r requirements2b.txt\n')
  82. with salt.utils.fopen(req2b_filename, 'wb') as f:
  83. f.write('pep8\n')
  84. this_user = pwd.getpwuid(os.getuid())[0]
  85. requirements_list = [req1_filename, req2_filename]
  86. ret = self.run_function(
  87. 'pip.install', requirements=requirements_list, user=this_user,
  88. bin_env=self.venv_dir, cwd=self.venv_dir
  89. )
  90. try:
  91. self.assertEqual(ret['retcode'], 0)
  92. found = self.pip_successful_install(ret['stdout'])
  93. self.assertTrue(found)
  94. except (AssertionError, TypeError):
  95. import pprint
  96. pprint.pprint(ret)
  97. raise
  98. @skipIf(os.geteuid() != 0, 'you must be root to run this test')
  99. def test_requirements_as_list_of_chains__sans_no_chown__cwd_not_set__absolute_file_path(self):
  100. self.run_function('virtualenv.create', [self.venv_dir])
  101. # Create a requirements file that depends on another one.
  102. req1_filename = os.path.join(self.venv_dir, 'requirements1.txt')
  103. req1b_filename = os.path.join(self.venv_dir, 'requirements1b.txt')
  104. req2_filename = os.path.join(self.venv_dir, 'requirements2.txt')
  105. req2b_filename = os.path.join(self.venv_dir, 'requirements2b.txt')
  106. with salt.utils.fopen(req1_filename, 'wb') as f:
  107. f.write('-r requirements1b.txt\n')
  108. with salt.utils.fopen(req1b_filename, 'wb') as f:
  109. f.write('flake8\n')
  110. with salt.utils.fopen(req2_filename, 'wb') as f:
  111. f.write('-r requirements2b.txt\n')
  112. with salt.utils.fopen(req2b_filename, 'wb') as f:
  113. f.write('pep8\n')
  114. this_user = pwd.getpwuid(os.getuid())[0]
  115. requirements_list = [req1_filename, req2_filename]
  116. ret = self.run_function(
  117. 'pip.install', requirements=requirements_list, user=this_user,
  118. bin_env=self.venv_dir
  119. )
  120. try:
  121. self.assertEqual(ret['retcode'], 0)
  122. found = self.pip_successful_install(ret['stdout'])
  123. self.assertTrue(found)
  124. except (AssertionError, TypeError):
  125. import pprint
  126. pprint.pprint(ret)
  127. raise
  128. @skipIf(os.geteuid() != 0, 'you must be root to run this test')
  129. def test_requirements_as_list__sans_no_chown__absolute_file_path(self):
  130. self.run_function('virtualenv.create', [self.venv_dir])
  131. req1_filename = os.path.join(self.venv_dir, 'requirements.txt')
  132. req2_filename = os.path.join(self.venv_dir, 'requirements2.txt')
  133. with salt.utils.fopen(req1_filename, 'wb') as f:
  134. f.write('flake8\n')
  135. with salt.utils.fopen(req2_filename, 'wb') as f:
  136. f.write('pep8\n')
  137. this_user = pwd.getpwuid(os.getuid())[0]
  138. requirements_list = [req1_filename, req2_filename]
  139. ret = self.run_function(
  140. 'pip.install', requirements=requirements_list, user=this_user,
  141. bin_env=self.venv_dir
  142. )
  143. found = self.pip_successful_install(ret['stdout'])
  144. try:
  145. self.assertEqual(ret['retcode'], 0)
  146. self.assertTrue(found)
  147. except (AssertionError, TypeError):
  148. import pprint
  149. pprint.pprint(ret)
  150. raise
  151. @skipIf(os.geteuid() != 0, 'you must be root to run this test')
  152. def test_requirements_as_list__sans_no_chown__non_absolute_file_path(self):
  153. self.run_function('virtualenv.create', [self.venv_dir])
  154. # Create a requirements file that depends on another one.
  155. req1_filename = 'requirements.txt'
  156. req2_filename = 'requirements2.txt'
  157. req_cwd = self.venv_dir
  158. req1_filepath = os.path.join(req_cwd, req1_filename)
  159. req2_filepath = os.path.join(req_cwd, req2_filename)
  160. with salt.utils.fopen(req1_filepath, 'wb') as f:
  161. f.write('flake8\n')
  162. with salt.utils.fopen(req2_filepath, 'wb') as f:
  163. f.write('pep8\n')
  164. this_user = pwd.getpwuid(os.getuid())[0]
  165. requirements_list = [req1_filename, req2_filename]
  166. ret = self.run_function(
  167. 'pip.install', requirements=requirements_list, user=this_user,
  168. bin_env=self.venv_dir, cwd=req_cwd
  169. )
  170. try:
  171. self.assertEqual(ret['retcode'], 0)
  172. found = self.pip_successful_install(ret['stdout'])
  173. self.assertTrue(found)
  174. except (AssertionError, TypeError):
  175. import pprint
  176. pprint.pprint(ret)
  177. raise
  178. @skipIf(os.geteuid() != 0, 'you must be root to run this test')
  179. def test_chained_requirements__sans_no_chown__absolute_file_path(self):
  180. self.run_function('virtualenv.create', [self.venv_dir])
  181. # Create a requirements file that depends on another one.
  182. req1_filename = os.path.join(self.venv_dir, 'requirements.txt')
  183. req2_filename = os.path.join(self.venv_dir, 'requirements2.txt')
  184. with salt.utils.fopen(req1_filename, 'wb') as f:
  185. f.write('-r requirements2.txt')
  186. with salt.utils.fopen(req2_filename, 'wb') as f:
  187. f.write('pep8')
  188. this_user = pwd.getpwuid(os.getuid())[0]
  189. ret = self.run_function(
  190. 'pip.install', requirements=req1_filename, user=this_user,
  191. bin_env=self.venv_dir
  192. )
  193. try:
  194. self.assertEqual(ret['retcode'], 0)
  195. self.assertIn('installed pep8', ret['stdout'])
  196. except (AssertionError, TypeError):
  197. import pprint
  198. pprint.pprint(ret)
  199. raise
  200. @skipIf(os.geteuid() != 0, 'you must be root to run this test')
  201. def test_chained_requirements__sans_no_chown__non_absolute_file_path(self):
  202. self.run_function('virtualenv.create', [self.venv_dir])
  203. # Create a requirements file that depends on another one.
  204. req_basepath = (self.venv_dir)
  205. req1_filename = 'requirements.txt'
  206. req2_filename = 'requirements2.txt'
  207. req1_file = os.path.join(self.venv_dir, req1_filename)
  208. req2_file = os.path.join(self.venv_dir, req2_filename)
  209. with salt.utils.fopen(req1_file, 'wb') as f:
  210. f.write('-r requirements2.txt')
  211. with salt.utils.fopen(req2_file, 'wb') as f:
  212. f.write('pep8')
  213. this_user = pwd.getpwuid(os.getuid())[0]
  214. ret = self.run_function(
  215. 'pip.install', requirements=req1_filename, user=this_user,
  216. no_chown=False, cwd=req_basepath, bin_env=self.venv_dir
  217. )
  218. try:
  219. self.assertEqual(ret['retcode'], 0)
  220. self.assertIn('installed pep8', ret['stdout'])
  221. except (AssertionError, TypeError):
  222. import pprint
  223. pprint.pprint(ret)
  224. raise
  225. @skipIf(os.geteuid() != 0, 'you must be root to run this test')
  226. def test_issue_4805_nested_requirements_user_no_chown(self):
  227. self.run_function('virtualenv.create', [self.venv_dir])
  228. # Create a requirements file that depends on another one.
  229. req1_filename = os.path.join(self.venv_dir, 'requirements.txt')
  230. req2_filename = os.path.join(self.venv_dir, 'requirements2.txt')
  231. with salt.utils.fopen(req1_filename, 'wb') as f:
  232. f.write('-r requirements2.txt')
  233. with salt.utils.fopen(req2_filename, 'wb') as f:
  234. f.write('pep8')
  235. this_user = pwd.getpwuid(os.getuid())[0]
  236. ret = self.run_function(
  237. 'pip.install', requirements=req1_filename, user=this_user,
  238. no_chown=True, bin_env=self.venv_dir
  239. )
  240. try:
  241. self.assertEqual(ret['retcode'], 0)
  242. self.assertIn('installed pep8', ret['stdout'])
  243. except (AssertionError, TypeError):
  244. import pprint
  245. pprint.pprint(ret)
  246. raise
  247. def test_pip_uninstall(self):
  248. # Let's create the testing virtualenv
  249. self.run_function('virtualenv.create', [self.venv_dir])
  250. ret = self.run_function('pip.install', ['pep8'], bin_env=self.venv_dir)
  251. self.assertEqual(ret['retcode'], 0)
  252. self.assertIn('installed pep8', ret['stdout'])
  253. ret = self.run_function(
  254. 'pip.uninstall', ['pep8'], bin_env=self.venv_dir
  255. )
  256. try:
  257. self.assertEqual(ret['retcode'], 0)
  258. self.assertIn('uninstalled pep8', ret['stdout'])
  259. except AssertionError:
  260. import pprint
  261. pprint.pprint(ret)
  262. raise
  263. def test_pip_install_upgrade(self):
  264. # Create the testing virtualenv
  265. self.run_function('virtualenv.create', [self.venv_dir])
  266. ret = self.run_function(
  267. 'pip.install', ['pep8==1.3.4'], bin_env=self.venv_dir
  268. )
  269. try:
  270. self.assertEqual(ret['retcode'], 0)
  271. self.assertIn('installed pep8', ret['stdout'])
  272. except AssertionError:
  273. import pprint
  274. pprint.pprint(ret)
  275. raise
  276. ret = self.run_function(
  277. 'pip.install',
  278. ['pep8'],
  279. bin_env=self.venv_dir,
  280. upgrade=True
  281. )
  282. try:
  283. self.assertEqual(ret['retcode'], 0)
  284. self.assertIn('installed pep8', ret['stdout'])
  285. except AssertionError:
  286. import pprint
  287. pprint.pprint(ret)
  288. raise
  289. ret = self.run_function(
  290. 'pip.uninstall', ['pep8'], bin_env=self.venv_dir
  291. )
  292. try:
  293. self.assertEqual(ret['retcode'], 0)
  294. self.assertIn('uninstalled pep8', ret['stdout'])
  295. except AssertionError:
  296. import pprint
  297. pprint.pprint(ret)
  298. raise
  299. def test_pip_install_multiple_editables(self):
  300. editables = [
  301. 'git+https://github.com/jek/blinker.git#egg=Blinker',
  302. 'git+https://github.com/saltstack/salt-testing.git#egg=SaltTesting'
  303. ]
  304. # Create the testing virtualenv
  305. self.run_function('virtualenv.create', [self.venv_dir])
  306. ret = self.run_function(
  307. 'pip.install', [],
  308. editable='{0}'.format(','.join(editables)),
  309. bin_env=self.venv_dir
  310. )
  311. try:
  312. self.assertEqual(ret['retcode'], 0)
  313. self.assertIn(
  314. 'Successfully installed Blinker SaltTesting', ret['stdout']
  315. )
  316. except AssertionError:
  317. import pprint
  318. pprint.pprint(ret)
  319. raise
  320. def test_pip_install_multiple_editables_and_pkgs(self):
  321. editables = [
  322. 'git+https://github.com/jek/blinker.git#egg=Blinker',
  323. 'git+https://github.com/saltstack/salt-testing.git#egg=SaltTesting'
  324. ]
  325. # Create the testing virtualenv
  326. self.run_function('virtualenv.create', [self.venv_dir])
  327. ret = self.run_function(
  328. 'pip.install', ['pep8'],
  329. editable='{0}'.format(','.join(editables)),
  330. bin_env=self.venv_dir
  331. )
  332. try:
  333. self.assertEqual(ret['retcode'], 0)
  334. for package in ('Blinker', 'SaltTesting', 'pep8'):
  335. self.assertRegexpMatches(
  336. ret['stdout'],
  337. r'(?:.*)(Successfully installed)(?:.*)({0})(?:.*)'.format(package)
  338. )
  339. except AssertionError:
  340. import pprint
  341. pprint.pprint(ret)
  342. raise
  343. def tearDown(self):
  344. super(PipModuleTest, self).tearDown()
  345. if os.path.isdir(self.venv_test_dir):
  346. shutil.rmtree(self.venv_test_dir)
  347. if os.path.isdir(self.pip_temp):
  348. shutil.rmtree(self.pip_temp)
  349. if __name__ == '__main__':
  350. from integration import run_tests
  351. run_tests(PipModuleTest)