blob: a78ca14886b8893915b512b527ebd7640befc2f4 [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)
Benjamin Petersonc844b002014-04-16 16:06:39 -0400156 self.assertFalse(self.run_pip.called)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000157
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()
Benjamin Petersonc844b002014-04-16 16:06:39 -0400197 self.assertFalse(self.run_pip.called)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000198
Nick Coghlana46cf122014-02-28 23:35:05 +1000199 def test_uninstall_skipped_with_warning_for_wrong_version(self):
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000200 with fake_pip("not a valid version"):
Nick Coghlana46cf122014-02-28 23:35:05 +1000201 with test.support.captured_stderr() as stderr:
Nick Coghlanf71cae02013-12-23 18:20:34 +1000202 ensurepip._uninstall_helper()
Nick Coghlana46cf122014-02-28 23:35:05 +1000203 warning = stderr.getvalue().strip()
204 self.assertIn("only uninstall a matching version", warning)
Benjamin Petersonc844b002014-04-16 16:06:39 -0400205 self.assertFalse(self.run_pip.called)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000206
207
Nick Coghlanae2ee962013-12-23 23:07:07 +1000208 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000209 def test_uninstall(self):
210 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000211 ensurepip._uninstall_helper()
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000212
213 self.run_pip.assert_called_once_with(
Donald Stufft71a85892015-06-02 10:37:08 -0400214 [
215 "uninstall", "-y", "--disable-pip-version-check", "pip",
216 "setuptools",
217 ]
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000218 )
219
Nick Coghlanae2ee962013-12-23 23:07:07 +1000220 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000221 def test_uninstall_with_verbosity_1(self):
222 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000223 ensurepip._uninstall_helper(verbosity=1)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000224
225 self.run_pip.assert_called_once_with(
Donald Stufft71a85892015-06-02 10:37:08 -0400226 [
227 "uninstall", "-y", "--disable-pip-version-check", "-v", "pip",
228 "setuptools",
229 ]
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000230 )
231
Nick Coghlanae2ee962013-12-23 23:07:07 +1000232 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000233 def test_uninstall_with_verbosity_2(self):
234 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000235 ensurepip._uninstall_helper(verbosity=2)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000236
237 self.run_pip.assert_called_once_with(
Donald Stufft71a85892015-06-02 10:37:08 -0400238 [
239 "uninstall", "-y", "--disable-pip-version-check", "-vv", "pip",
240 "setuptools",
241 ]
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000242 )
243
Nick Coghlanae2ee962013-12-23 23:07:07 +1000244 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000245 def test_uninstall_with_verbosity_3(self):
246 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000247 ensurepip._uninstall_helper(verbosity=3)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000248
249 self.run_pip.assert_called_once_with(
Donald Stufft71a85892015-06-02 10:37:08 -0400250 [
251 "uninstall", "-y", "--disable-pip-version-check", "-vvv",
252 "pip", "setuptools",
253 ]
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000254 )
255
Nick Coghlanae2ee962013-12-23 23:07:07 +1000256 @requires_usable_pip
Nick Coghlaned9af522013-12-23 17:39:12 +1000257 def test_pip_environment_variables_removed(self):
258 # ensurepip deliberately ignores all pip environment variables
259 # See http://bugs.python.org/issue19734 for details
260 self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder"
261 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000262 ensurepip._uninstall_helper()
Nick Coghlaned9af522013-12-23 17:39:12 +1000263 self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000264
Nick Coghlan6edd82a2014-02-04 23:02:36 +1000265 @requires_usable_pip
266 def test_pip_config_file_disabled(self):
267 # ensurepip deliberately ignores the pip config file
268 # See http://bugs.python.org/issue20053 for details
269 with fake_pip():
270 ensurepip._uninstall_helper()
271 self.assertEqual(self.os_environ["PIP_CONFIG_FILE"], os.devnull)
272
Nick Coghland0cf0632013-11-11 22:11:55 +1000273
Nick Coghlanae2ee962013-12-23 23:07:07 +1000274class TestMissingSSL(EnsurepipMixin, unittest.TestCase):
275
276 def setUp(self):
277 sys.modules["ensurepip"] = ensurepip_no_ssl
278 @self.addCleanup
279 def restore_module():
280 sys.modules["ensurepip"] = ensurepip
281 super().setUp()
282
283 def test_bootstrap_requires_ssl(self):
284 self.os_environ["PIP_THIS_SHOULD_STAY"] = "test fodder"
285 with self.assertRaisesRegex(RuntimeError, "requires SSL/TLS"):
286 ensurepip_no_ssl.bootstrap()
Benjamin Petersonc844b002014-04-16 16:06:39 -0400287 self.assertFalse(self.run_pip.called)
Nick Coghlanae2ee962013-12-23 23:07:07 +1000288 self.assertIn("PIP_THIS_SHOULD_STAY", self.os_environ)
289
290 def test_uninstall_requires_ssl(self):
291 self.os_environ["PIP_THIS_SHOULD_STAY"] = "test fodder"
292 with self.assertRaisesRegex(RuntimeError, "requires SSL/TLS"):
293 with fake_pip():
294 ensurepip_no_ssl._uninstall_helper()
Benjamin Petersonc844b002014-04-16 16:06:39 -0400295 self.assertFalse(self.run_pip.called)
Nick Coghlanae2ee962013-12-23 23:07:07 +1000296 self.assertIn("PIP_THIS_SHOULD_STAY", self.os_environ)
297
Nick Coghlanc00fa632014-02-15 09:14:54 +1000298 def test_main_exits_early_with_warning(self):
299 with test.support.captured_stderr() as stderr:
300 ensurepip_no_ssl._main(["--version"])
301 warning = stderr.getvalue().strip()
302 self.assertTrue(warning.endswith("requires SSL/TLS"), warning)
Benjamin Petersonc844b002014-04-16 16:06:39 -0400303 self.assertFalse(self.run_pip.called)
Nick Coghlanc00fa632014-02-15 09:14:54 +1000304
Nick Coghlanf71cae02013-12-23 18:20:34 +1000305# Basic testing of the main functions and their argument parsing
306
307EXPECTED_VERSION_OUTPUT = "pip " + ensurepip._PIP_VERSION
308
309class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
310
Nick Coghlanc00fa632014-02-15 09:14:54 +1000311 @requires_usable_pip
Nick Coghlanf71cae02013-12-23 18:20:34 +1000312 def test_bootstrap_version(self):
313 with test.support.captured_stdout() as stdout:
314 with self.assertRaises(SystemExit):
315 ensurepip._main(["--version"])
316 result = stdout.getvalue().strip()
317 self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
Benjamin Petersonc844b002014-04-16 16:06:39 -0400318 self.assertFalse(self.run_pip.called)
Nick Coghlanf71cae02013-12-23 18:20:34 +1000319
Nick Coghlanae2ee962013-12-23 23:07:07 +1000320 @requires_usable_pip
Nick Coghlanf71cae02013-12-23 18:20:34 +1000321 def test_basic_bootstrapping(self):
322 ensurepip._main([])
323
324 self.run_pip.assert_called_once_with(
325 [
326 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -0500327 unittest.mock.ANY, "setuptools", "pip",
Nick Coghlanf71cae02013-12-23 18:20:34 +1000328 ],
329 unittest.mock.ANY,
330 )
331
332 additional_paths = self.run_pip.call_args[0][1]
333 self.assertEqual(len(additional_paths), 2)
334
335class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
336
337 def test_uninstall_version(self):
338 with test.support.captured_stdout() as stdout:
339 with self.assertRaises(SystemExit):
340 ensurepip._uninstall._main(["--version"])
341 result = stdout.getvalue().strip()
342 self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
Benjamin Petersonc844b002014-04-16 16:06:39 -0400343 self.assertFalse(self.run_pip.called)
Nick Coghlanf71cae02013-12-23 18:20:34 +1000344
Nick Coghlanae2ee962013-12-23 23:07:07 +1000345 @requires_usable_pip
Nick Coghlanf71cae02013-12-23 18:20:34 +1000346 def test_basic_uninstall(self):
347 with fake_pip():
348 ensurepip._uninstall._main([])
349
350 self.run_pip.assert_called_once_with(
Donald Stufft71a85892015-06-02 10:37:08 -0400351 [
352 "uninstall", "-y", "--disable-pip-version-check", "pip",
353 "setuptools",
354 ]
Nick Coghlanf71cae02013-12-23 18:20:34 +1000355 )
356
357
Nick Coghland0cf0632013-11-11 22:11:55 +1000358
359if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500360 unittest.main()