blob: 68dd3e2e1c3a4e7ca8222b73f822a22fc45c39be [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
39 os_patch = unittest.mock.patch("ensurepip.os")
40 patched_os = os_patch.start()
41 self.addCleanup(os_patch.stop)
42 patched_os.path = os.path
43 self.os_environ = patched_os.environ = os.environ.copy()
Nick Coghland0cf0632013-11-11 22:11:55 +100044
Nick Coghlanae2ee962013-12-23 23:07:07 +100045
Nick Coghlanf71cae02013-12-23 18:20:34 +100046class TestBootstrap(EnsurepipMixin, unittest.TestCase):
47
Nick Coghlanae2ee962013-12-23 23:07:07 +100048 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +100049 def test_basic_bootstrapping(self):
50 ensurepip.bootstrap()
51
52 self.run_pip.assert_called_once_with(
53 [
54 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -050055 unittest.mock.ANY, "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +100056 ],
57 unittest.mock.ANY,
58 )
59
60 additional_paths = self.run_pip.call_args[0][1]
61 self.assertEqual(len(additional_paths), 2)
62
Nick Coghlanae2ee962013-12-23 23:07:07 +100063 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +100064 def test_bootstrapping_with_root(self):
65 ensurepip.bootstrap(root="/foo/bar/")
66
67 self.run_pip.assert_called_once_with(
68 [
69 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -050070 unittest.mock.ANY, "--root", "/foo/bar/",
Nick Coghland0cf0632013-11-11 22:11:55 +100071 "setuptools", "pip",
72 ],
73 unittest.mock.ANY,
74 )
75
Nick Coghlanae2ee962013-12-23 23:07:07 +100076 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +100077 def test_bootstrapping_with_user(self):
78 ensurepip.bootstrap(user=True)
79
80 self.run_pip.assert_called_once_with(
81 [
82 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -050083 unittest.mock.ANY, "--user", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +100084 ],
85 unittest.mock.ANY,
86 )
87
Nick Coghlanae2ee962013-12-23 23:07:07 +100088 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +100089 def test_bootstrapping_with_upgrade(self):
90 ensurepip.bootstrap(upgrade=True)
91
92 self.run_pip.assert_called_once_with(
93 [
94 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -050095 unittest.mock.ANY, "--upgrade", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +100096 ],
97 unittest.mock.ANY,
98 )
99
Nick Coghlanae2ee962013-12-23 23:07:07 +1000100 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000101 def test_bootstrapping_with_verbosity_1(self):
102 ensurepip.bootstrap(verbosity=1)
103
104 self.run_pip.assert_called_once_with(
105 [
106 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -0500107 unittest.mock.ANY, "-v", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +1000108 ],
109 unittest.mock.ANY,
110 )
111
Nick Coghlanae2ee962013-12-23 23:07:07 +1000112 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000113 def test_bootstrapping_with_verbosity_2(self):
114 ensurepip.bootstrap(verbosity=2)
115
116 self.run_pip.assert_called_once_with(
117 [
118 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -0500119 unittest.mock.ANY, "-vv", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +1000120 ],
121 unittest.mock.ANY,
122 )
123
Nick Coghlanae2ee962013-12-23 23:07:07 +1000124 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000125 def test_bootstrapping_with_verbosity_3(self):
126 ensurepip.bootstrap(verbosity=3)
127
128 self.run_pip.assert_called_once_with(
129 [
130 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -0500131 unittest.mock.ANY, "-vvv", "setuptools", "pip",
Nick Coghland0cf0632013-11-11 22:11:55 +1000132 ],
133 unittest.mock.ANY,
134 )
135
Nick Coghlanae2ee962013-12-23 23:07:07 +1000136 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000137 def test_bootstrapping_with_regular_install(self):
138 ensurepip.bootstrap()
139 self.assertEqual(self.os_environ["ENSUREPIP_OPTIONS"], "install")
140
Nick Coghlanae2ee962013-12-23 23:07:07 +1000141 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000142 def test_bootstrapping_with_alt_install(self):
143 ensurepip.bootstrap(altinstall=True)
144 self.assertEqual(self.os_environ["ENSUREPIP_OPTIONS"], "altinstall")
145
Nick Coghlanae2ee962013-12-23 23:07:07 +1000146 @requires_usable_pip
Nick Coghland0cf0632013-11-11 22:11:55 +1000147 def test_bootstrapping_with_default_pip(self):
148 ensurepip.bootstrap(default_pip=True)
149 self.assertNotIn("ENSUREPIP_OPTIONS", self.os_environ)
150
151 def test_altinstall_default_pip_conflict(self):
152 with self.assertRaises(ValueError):
153 ensurepip.bootstrap(altinstall=True, default_pip=True)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000154 self.run_pip.assert_not_called()
155
Nick Coghlanae2ee962013-12-23 23:07:07 +1000156 @requires_usable_pip
Nick Coghlan6256fcb2013-12-23 16:16:07 +1000157 def test_pip_environment_variables_removed(self):
158 # ensurepip deliberately ignores all pip environment variables
159 # See http://bugs.python.org/issue19734 for details
160 self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder"
161 ensurepip.bootstrap()
162 self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ)
163
164
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000165@contextlib.contextmanager
166def fake_pip(version=ensurepip._PIP_VERSION):
167 if version is None:
168 pip = None
169 else:
170 class FakePip():
171 __version__ = version
172 pip = FakePip()
173 sentinel = object()
174 orig_pip = sys.modules.get("pip", sentinel)
175 sys.modules["pip"] = pip
176 try:
177 yield pip
178 finally:
179 if orig_pip is sentinel:
180 del sys.modules["pip"]
181 else:
182 sys.modules["pip"] = orig_pip
183
Nick Coghlanf71cae02013-12-23 18:20:34 +1000184class TestUninstall(EnsurepipMixin, unittest.TestCase):
Nick Coghlaned9af522013-12-23 17:39:12 +1000185
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000186 def test_uninstall_skipped_when_not_installed(self):
187 with fake_pip(None):
Nick Coghlanf71cae02013-12-23 18:20:34 +1000188 ensurepip._uninstall_helper()
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000189 self.run_pip.assert_not_called()
190
191 def test_uninstall_fails_with_wrong_version(self):
192 with fake_pip("not a valid version"):
193 with self.assertRaises(RuntimeError):
Nick Coghlanf71cae02013-12-23 18:20:34 +1000194 ensurepip._uninstall_helper()
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000195 self.run_pip.assert_not_called()
196
197
Nick Coghlanae2ee962013-12-23 23:07:07 +1000198 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000199 def test_uninstall(self):
200 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000201 ensurepip._uninstall_helper()
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000202
203 self.run_pip.assert_called_once_with(
204 ["uninstall", "-y", "pip", "setuptools"]
205 )
206
Nick Coghlanae2ee962013-12-23 23:07:07 +1000207 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000208 def test_uninstall_with_verbosity_1(self):
209 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000210 ensurepip._uninstall_helper(verbosity=1)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000211
212 self.run_pip.assert_called_once_with(
213 ["uninstall", "-y", "-v", "pip", "setuptools"]
214 )
215
Nick Coghlanae2ee962013-12-23 23:07:07 +1000216 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000217 def test_uninstall_with_verbosity_2(self):
218 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000219 ensurepip._uninstall_helper(verbosity=2)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000220
221 self.run_pip.assert_called_once_with(
222 ["uninstall", "-y", "-vv", "pip", "setuptools"]
223 )
224
Nick Coghlanae2ee962013-12-23 23:07:07 +1000225 @requires_usable_pip
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000226 def test_uninstall_with_verbosity_3(self):
227 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000228 ensurepip._uninstall_helper(verbosity=3)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000229
230 self.run_pip.assert_called_once_with(
231 ["uninstall", "-y", "-vvv", "pip", "setuptools"]
232 )
233
Nick Coghlanae2ee962013-12-23 23:07:07 +1000234 @requires_usable_pip
Nick Coghlaned9af522013-12-23 17:39:12 +1000235 def test_pip_environment_variables_removed(self):
236 # ensurepip deliberately ignores all pip environment variables
237 # See http://bugs.python.org/issue19734 for details
238 self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder"
239 with fake_pip():
Nick Coghlanf71cae02013-12-23 18:20:34 +1000240 ensurepip._uninstall_helper()
Nick Coghlaned9af522013-12-23 17:39:12 +1000241 self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ)
Nick Coghlanfdf3a622013-11-30 17:15:09 +1000242
Nick Coghland0cf0632013-11-11 22:11:55 +1000243
Nick Coghlanae2ee962013-12-23 23:07:07 +1000244class TestMissingSSL(EnsurepipMixin, unittest.TestCase):
245
246 def setUp(self):
247 sys.modules["ensurepip"] = ensurepip_no_ssl
248 @self.addCleanup
249 def restore_module():
250 sys.modules["ensurepip"] = ensurepip
251 super().setUp()
252
253 def test_bootstrap_requires_ssl(self):
254 self.os_environ["PIP_THIS_SHOULD_STAY"] = "test fodder"
255 with self.assertRaisesRegex(RuntimeError, "requires SSL/TLS"):
256 ensurepip_no_ssl.bootstrap()
257 self.run_pip.assert_not_called()
258 self.assertIn("PIP_THIS_SHOULD_STAY", self.os_environ)
259
260 def test_uninstall_requires_ssl(self):
261 self.os_environ["PIP_THIS_SHOULD_STAY"] = "test fodder"
262 with self.assertRaisesRegex(RuntimeError, "requires SSL/TLS"):
263 with fake_pip():
264 ensurepip_no_ssl._uninstall_helper()
265 self.run_pip.assert_not_called()
266 self.assertIn("PIP_THIS_SHOULD_STAY", self.os_environ)
267
Nick Coghlanf71cae02013-12-23 18:20:34 +1000268# Basic testing of the main functions and their argument parsing
269
270EXPECTED_VERSION_OUTPUT = "pip " + ensurepip._PIP_VERSION
271
272class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
273
274 def test_bootstrap_version(self):
275 with test.support.captured_stdout() as stdout:
276 with self.assertRaises(SystemExit):
277 ensurepip._main(["--version"])
278 result = stdout.getvalue().strip()
279 self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
280 self.run_pip.assert_not_called()
281
Nick Coghlanae2ee962013-12-23 23:07:07 +1000282 @requires_usable_pip
Nick Coghlanf71cae02013-12-23 18:20:34 +1000283 def test_basic_bootstrapping(self):
284 ensurepip._main([])
285
286 self.run_pip.assert_called_once_with(
287 [
288 "install", "--no-index", "--find-links",
Donald Stufftf7f58f82014-01-02 09:33:35 -0500289 unittest.mock.ANY, "setuptools", "pip",
Nick Coghlanf71cae02013-12-23 18:20:34 +1000290 ],
291 unittest.mock.ANY,
292 )
293
294 additional_paths = self.run_pip.call_args[0][1]
295 self.assertEqual(len(additional_paths), 2)
296
297class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
298
299 def test_uninstall_version(self):
300 with test.support.captured_stdout() as stdout:
301 with self.assertRaises(SystemExit):
302 ensurepip._uninstall._main(["--version"])
303 result = stdout.getvalue().strip()
304 self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
305 self.run_pip.assert_not_called()
306
Nick Coghlanae2ee962013-12-23 23:07:07 +1000307 @requires_usable_pip
Nick Coghlanf71cae02013-12-23 18:20:34 +1000308 def test_basic_uninstall(self):
309 with fake_pip():
310 ensurepip._uninstall._main([])
311
312 self.run_pip.assert_called_once_with(
313 ["uninstall", "-y", "pip", "setuptools"]
314 )
315
316
Nick Coghland0cf0632013-11-11 22:11:55 +1000317
318if __name__ == "__main__":
319 test.support.run_unittest(__name__)