blob: 8644a651bb11dc7d801bcd6df59ec4f6df9f7569 [file] [log] [blame]
Nick Coghland0cf0632013-11-11 22:11:55 +10001import unittest
2import unittest.mock
Nick Coghland0cf0632013-11-11 22:11:55 +10003import test.support
Nick Coghland3e83e22013-11-13 22:24:58 +10004import os
5import os.path
Nick Coghlanfdf3a622013-11-30 17:15:09 +10006import contextlib
7import sys
Nick Coghland0cf0632013-11-11 22:11:55 +10008
Nick Coghlanf71cae02013-12-23 18:20:34 +10009import ensurepip
10import ensurepip._uninstall
Nick Coghland0cf0632013-11-11 22:11:55 +100011
Nick Coghlanae2ee962013-12-23 23:07:07 +100012# pip currently requires ssl support, so we ensure we handle
13# it being missing (http://bugs.python.org/issue19744)
14ensurepip_no_ssl = test.support.import_fresh_module("ensurepip",
15 blocked=["ssl"])
16try:
17 import ssl
18except ImportError:
19 def requires_usable_pip(f):
20 deco = unittest.skip(ensurepip._MISSING_SSL_MESSAGE)
21 return deco(f)
22else:
23 def requires_usable_pip(f):
24 return f
25
Nick Coghland0cf0632013-11-11 22:11:55 +100026class TestEnsurePipVersion(unittest.TestCase):
27
28 def test_returns_version(self):
29 self.assertEqual(ensurepip._PIP_VERSION, ensurepip.version())
30
Nick Coghlanf71cae02013-12-23 18:20:34 +100031class EnsurepipMixin:
Nick Coghland0cf0632013-11-11 22:11:55 +100032
33 def setUp(self):
34 run_pip_patch = unittest.mock.patch("ensurepip._run_pip")
35 self.run_pip = run_pip_patch.start()
36 self.addCleanup(run_pip_patch.stop)
37
Nick Coghland3e83e22013-11-13 22:24:58 +100038 # Avoid side effects on the actual os module
Nick Coghlan6edd82a2014-02-04 23:02:36 +100039 real_devnull = os.devnull
Nick Coghland3e83e22013-11-13 22:24:58 +100040 os_patch = unittest.mock.patch("ensurepip.os")
41 patched_os = os_patch.start()
42 self.addCleanup(os_patch.stop)
Nick Coghlan6edd82a2014-02-04 23:02:36 +100043 patched_os.devnull = real_devnull
Nick Coghland3e83e22013-11-13 22:24:58 +100044 patched_os.path = os.path
45 self.os_environ = patched_os.environ = os.environ.copy()
Nick Coghland0cf0632013-11-11 22:11:55 +100046
Nick Coghlanae2ee962013-12-23 23:07:07 +100047
Nick Coghlanf71cae02013-12-23 18:20:34 +100048class TestBootstrap(EnsurepipMixin, unittest.TestCase):
49
Nick Coghlanae2ee962013-12-23 23:07:07 +100050 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +100051 def test_basic_bootstrapping(self):
52 ensurepip.bootstrap()
53
54 self.run_pip.assert_called_once_with(
55 [
56 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -050057 unittest.mock.ANY, "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +100058 ],
59 unittest.mock.ANY,
60 )
61
62 additional_paths = self.run_pip.call_args[0][1]
63 self.assertEqual(len(additional_paths), 2)
64
Nick Coghlanae2ee962013-12-23 23:07:07 +100065 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +100066 def test_bootstrapping_with_root(self):
67 ensurepip.bootstrap(root="/foo/bar/")
68
69 self.run_pip.assert_called_once_with(
70 [
71 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -050072 unittest.mock.ANY, "--root", "/foo/bar/",
Nick Coghland0cf0632013-11-11 22:11:55 +100073 "setuptools", "pip",
74 ],
75 unittest.mock.ANY,
76 )
77
Nick Coghlanae2ee962013-12-23 23:07:07 +100078 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +100079 def test_bootstrapping_with_user(self):
80 ensurepip.bootstrap(user=True)
81
82 self.run_pip.assert_called_once_with(
83 [
84 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -050085 unittest.mock.ANY, "--user", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +100086 ],
87 unittest.mock.ANY,
88 )
89
Nick Coghlanae2ee962013-12-23 23:07:07 +100090 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +100091 def test_bootstrapping_with_upgrade(self):
92 ensurepip.bootstrap(upgrade=True)
93
94 self.run_pip.assert_called_once_with(
95 [
96 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -050097 unittest.mock.ANY, "--upgrade", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +100098 ],
99 unittest.mock.ANY,
100 )
101
Nick Coghlanae2ee962013-12-23 23:07:07 +1000102 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000103 def test_bootstrapping_with_verbosity_1(self):
104 ensurepip.bootstrap(verbosity=1)
105
106 self.run_pip.assert_called_once_with(
107 [
108 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -0500109 unittest.mock.ANY, "-v", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +1000110 ],
111 unittest.mock.ANY,
112 )
113
Nick Coghlanae2ee962013-12-23 23:07:07 +1000114 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000115 def test_bootstrapping_with_verbosity_2(self):
116 ensurepip.bootstrap(verbosity=2)
117
118 self.run_pip.assert_called_once_with(
119 [
120 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -0500121 unittest.mock.ANY, "-vv", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +1000122 ],
123 unittest.mock.ANY,
124 )
125
Nick Coghlanae2ee962013-12-23 23:07:07 +1000126 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000127 def test_bootstrapping_with_verbosity_3(self):
128 ensurepip.bootstrap(verbosity=3)
129
130 self.run_pip.assert_called_once_with(
131 [
132 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -0500133 unittest.mock.ANY, "-vvv", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +1000134 ],
135 unittest.mock.ANY,
136 )
137
Nick Coghlanae2ee962013-12-23 23:07:07 +1000138 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000139 def test_bootstrapping_with_regular_install(self):
140 ensurepip.bootstrap()
141 self.assertEqual(self.os_environ["ENSUREPIP_OPTIONS"], "install")
142
Nick Coghlanae2ee962013-12-23 23:07:07 +1000143 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000144 def test_bootstrapping_with_alt_install(self):
145 ensurepip.bootstrap(altinstall=True)
146 self.assertEqual(self.os_environ["ENSUREPIP_OPTIONS"], "altinstall")
147
Nick Coghlanae2ee962013-12-23 23:07:07 +1000148 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000149 def test_bootstrapping_with_default_pip(self):
150 ensurepip.bootstrap(default_pip=True)
151 self.assertNotIn("ENSUREPIP_OPTIONS", self.os_environ)
152
153 def test_altinstall_default_pip_conflict(self):
154 with self.assertRaises(ValueError):
155 ensurepip.bootstrap(altinstall=True, default_pip=True)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000156 self.run_pip.assert_not_called()
157
Nick Coghlanae2ee962013-12-23 23:07:07 +1000158 @requires_usable_pip
Nick Coghlan6256fcb2013-12-23 16:16:07 +1000159 def test_pip_environment_variables_removed(self):
160 # ensurepip deliberately ignores all pip environment variables
161 # See http://bugs.python.org/issue19734 for details
162 self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder"
163 ensurepip.bootstrap()
164 self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ)
165
Nick Coghlan6edd82a2014-02-04 23:02:36 +1000166 @requires_usable_pip
167 def test_pip_config_file_disabled(self):
168 # ensurepip deliberately ignores the pip config file
169 # See http://bugs.python.org/issue20053 for details
170 ensurepip.bootstrap()
171 self.assertEqual(self.os_environ["PIP_CONFIG_FILE"], os.devnull)
Nick Coghlan6256fcb2013-12-23 16:16:07 +1000172
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000173@contextlib.contextmanager
174def fake_pip(version=ensurepip._PIP_VERSION):
175 if version is None:
176 pip = None
177 else:
178 class FakePip():
179 __version__ = version
180 pip = FakePip()
181 sentinel = object()
182 orig_pip = sys.modules.get("pip", sentinel)
183 sys.modules["pip"] = pip
184 try:
185 yield pip
186 finally:
187 if orig_pip is sentinel:
188 del sys.modules["pip"]
189 else:
190 sys.modules["pip"] = orig_pip
191
Nick Coghlanf71cae02013-12-23 18:20:34 +1000192class TestUninstall(EnsurepipMixin, unittest.TestCase):
Nick Coghlaned9af522013-12-23 17:39:12 +1000193
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000194 def test_uninstall_skipped_when_not_installed(self):
195 with fake_pip(None):
Nick Coghlanf71cae02013-12-23 18:20:34 +1000196 ensurepip._uninstall_helper()
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000197 self.run_pip.assert_not_called()
198
199 def test_uninstall_fails_with_wrong_version(self):
200 with fake_pip("not a valid version"):
201 with self.assertRaises(RuntimeError):
Nick Coghlanf71cae02013-12-23 18:20:34 +1000202 ensurepip._uninstall_helper()
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000203 self.run_pip.assert_not_called()
204
205
Nick Coghlanae2ee962013-12-23 23:07:07 +1000206 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000207 def test_uninstall(self):
208 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000209 ensurepip._uninstall_helper()
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000210
211 self.run_pip.assert_called_once_with(
212 ["uninstall", "-y", "pip", "setuptools"]
213 )
214
Nick Coghlanae2ee962013-12-23 23:07:07 +1000215 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000216 def test_uninstall_with_verbosity_1(self):
217 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000218 ensurepip._uninstall_helper(verbosity=1)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000219
220 self.run_pip.assert_called_once_with(
221 ["uninstall", "-y", "-v", "pip", "setuptools"]
222 )
223
Nick Coghlanae2ee962013-12-23 23:07:07 +1000224 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000225 def test_uninstall_with_verbosity_2(self):
226 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000227 ensurepip._uninstall_helper(verbosity=2)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000228
229 self.run_pip.assert_called_once_with(
230 ["uninstall", "-y", "-vv", "pip", "setuptools"]
231 )
232
Nick Coghlanae2ee962013-12-23 23:07:07 +1000233 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000234 def test_uninstall_with_verbosity_3(self):
235 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000236 ensurepip._uninstall_helper(verbosity=3)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000237
238 self.run_pip.assert_called_once_with(
239 ["uninstall", "-y", "-vvv", "pip", "setuptools"]
240 )
241
Nick Coghlanae2ee962013-12-23 23:07:07 +1000242 @requires_usable_pip
Nick Coghlaned9af522013-12-23 17:39:12 +1000243 def test_pip_environment_variables_removed(self):
244 # ensurepip deliberately ignores all pip environment variables
245 # See http://bugs.python.org/issue19734 for details
246 self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder"
247 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000248 ensurepip._uninstall_helper()
Nick Coghlaned9af522013-12-23 17:39:12 +1000249 self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000250
Nick Coghlan6edd82a2014-02-04 23:02:36 +1000251 @requires_usable_pip
252 def test_pip_config_file_disabled(self):
253 # ensurepip deliberately ignores the pip config file
254 # See http://bugs.python.org/issue20053 for details
255 with fake_pip():
256 ensurepip._uninstall_helper()
257 self.assertEqual(self.os_environ["PIP_CONFIG_FILE"], os.devnull)
258
Nick Coghland0cf0632013-11-11 22:11:55 +1000259
Nick Coghlanae2ee962013-12-23 23:07:07 +1000260class TestMissingSSL(EnsurepipMixin, unittest.TestCase):
261
262 def setUp(self):
263 sys.modules["ensurepip"] = ensurepip_no_ssl
264 @self.addCleanup
265 def restore_module():
266 sys.modules["ensurepip"] = ensurepip
267 super().setUp()
268
269 def test_bootstrap_requires_ssl(self):
270 self.os_environ["PIP_THIS_SHOULD_STAY"] = "test fodder"
271 with self.assertRaisesRegex(RuntimeError, "requires SSL/TLS"):
272 ensurepip_no_ssl.bootstrap()
273 self.run_pip.assert_not_called()
274 self.assertIn("PIP_THIS_SHOULD_STAY", self.os_environ)
275
276 def test_uninstall_requires_ssl(self):
277 self.os_environ["PIP_THIS_SHOULD_STAY"] = "test fodder"
278 with self.assertRaisesRegex(RuntimeError, "requires SSL/TLS"):
279 with fake_pip():
280 ensurepip_no_ssl._uninstall_helper()
281 self.run_pip.assert_not_called()
282 self.assertIn("PIP_THIS_SHOULD_STAY", self.os_environ)
283
Nick Coghlanc00fa632014-02-15 09:14:54 +1000284 def test_main_exits_early_with_warning(self):
285 with test.support.captured_stderr() as stderr:
286 ensurepip_no_ssl._main(["--version"])
287 warning = stderr.getvalue().strip()
288 self.assertTrue(warning.endswith("requires SSL/TLS"), warning)
289 self.run_pip.assert_not_called()
290
Nick Coghlanf71cae02013-12-23 18:20:34 +1000291# Basic testing of the main functions and their argument parsing
292
293EXPECTED_VERSION_OUTPUT = "pip " + ensurepip._PIP_VERSION
294
295class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
296
Nick Coghlanc00fa632014-02-15 09:14:54 +1000297 @requires_usable_pip
Nick Coghlanf71cae02013-12-23 18:20:34 +1000298 def test_bootstrap_version(self):
299 with test.support.captured_stdout() as stdout:
300 with self.assertRaises(SystemExit):
301 ensurepip._main(["--version"])
302 result = stdout.getvalue().strip()
303 self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
304 self.run_pip.assert_not_called()
305
Nick Coghlanae2ee962013-12-23 23:07:07 +1000306 @requires_usable_pip
Nick Coghlanf71cae02013-12-23 18:20:34 +1000307 def test_basic_bootstrapping(self):
308 ensurepip._main([])
309
310 self.run_pip.assert_called_once_with(
311 [
312 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -0500313 unittest.mock.ANY, "setuptools", "pip",
Nick Coghlanf71cae02013-12-23 18:20:34 +1000314 ],
315 unittest.mock.ANY,
316 )
317
318 additional_paths = self.run_pip.call_args[0][1]
319 self.assertEqual(len(additional_paths), 2)
320
321class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
322
323 def test_uninstall_version(self):
324 with test.support.captured_stdout() as stdout:
325 with self.assertRaises(SystemExit):
326 ensurepip._uninstall._main(["--version"])
327 result = stdout.getvalue().strip()
328 self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
329 self.run_pip.assert_not_called()
330
Nick Coghlanae2ee962013-12-23 23:07:07 +1000331 @requires_usable_pip
Nick Coghlanf71cae02013-12-23 18:20:34 +1000332 def test_basic_uninstall(self):
333 with fake_pip():
334 ensurepip._uninstall._main([])
335
336 self.run_pip.assert_called_once_with(
337 ["uninstall", "-y", "pip", "setuptools"]
338 )
339
340
Nick Coghland0cf0632013-11-11 22:11:55 +1000341
342if __name__ == "__main__":
343 test.support.run_unittest(__name__)