|
11 | 11 |
|
12 | 12 | from poetry.config.config import Config
|
13 | 13 | from poetry.core.packages.package import Package
|
| 14 | +from poetry.core.packages.utils.link import Link |
| 15 | +from poetry.installation.chef import Chef |
14 | 16 | from poetry.installation.executor import Executor
|
15 | 17 | from poetry.installation.operations import Install
|
16 | 18 | from poetry.installation.operations import Uninstall
|
@@ -52,7 +54,9 @@ def callback(request, uri, headers):
|
52 | 54 | return [200, headers, f.read()]
|
53 | 55 |
|
54 | 56 | http.register_uri(
|
55 |
| - http.GET, re.compile("^https://files.pythonhosted.org/.*$"), body=callback, |
| 57 | + http.GET, |
| 58 | + re.compile("^https://files.pythonhosted.org/.*$"), |
| 59 | + body=callback, |
56 | 60 | )
|
57 | 61 |
|
58 | 62 |
|
@@ -251,3 +255,81 @@ def test_executor_should_delete_incomplete_downloads(
|
251 | 255 | executor._download(Install(Package("tomlkit", "0.5.3")))
|
252 | 256 |
|
253 | 257 | assert not destination_fixture.exists()
|
| 258 | + |
| 259 | + |
| 260 | +def test_executor_should_check_every_possible_hash_types( |
| 261 | + config, io, pool, mocker, fixture_dir, tmp_dir |
| 262 | +): |
| 263 | + mocker.patch.object( |
| 264 | + Chef, |
| 265 | + "get_cached_archive_for_link", |
| 266 | + side_effect=lambda link: link, |
| 267 | + ) |
| 268 | + mocker.patch.object( |
| 269 | + Executor, |
| 270 | + "_download_archive", |
| 271 | + return_value=fixture_dir("distributions").joinpath( |
| 272 | + "demo-0.1.0-py2.py3-none-any.whl" |
| 273 | + ), |
| 274 | + ) |
| 275 | + |
| 276 | + env = MockEnv(path=Path(tmp_dir)) |
| 277 | + executor = Executor(env, pool, config, io) |
| 278 | + |
| 279 | + package = Package("demo", "0.1.0") |
| 280 | + package.files = [ |
| 281 | + { |
| 282 | + "file": "demo-0.1.0-py2.py3-none-any.whl", |
| 283 | + "hash": "md5:15507846fd4299596661d0197bfb4f90", |
| 284 | + } |
| 285 | + ] |
| 286 | + |
| 287 | + archive = executor._download_link( |
| 288 | + Install(package), Link("https://example.com/demo-0.1.0-py2.py3-none-any.whl") |
| 289 | + ) |
| 290 | + |
| 291 | + assert archive == fixture_dir("distributions").joinpath( |
| 292 | + "demo-0.1.0-py2.py3-none-any.whl" |
| 293 | + ) |
| 294 | + |
| 295 | + |
| 296 | +def test_executor_should_check_every_possible_hash_types_before_failing( |
| 297 | + config, io, pool, mocker, fixture_dir, tmp_dir |
| 298 | +): |
| 299 | + mocker.patch.object( |
| 300 | + Chef, |
| 301 | + "get_cached_archive_for_link", |
| 302 | + side_effect=lambda link: link, |
| 303 | + ) |
| 304 | + mocker.patch.object( |
| 305 | + Executor, |
| 306 | + "_download_archive", |
| 307 | + return_value=fixture_dir("distributions").joinpath( |
| 308 | + "demo-0.1.0-py2.py3-none-any.whl" |
| 309 | + ), |
| 310 | + ) |
| 311 | + |
| 312 | + env = MockEnv(path=Path(tmp_dir)) |
| 313 | + executor = Executor(env, pool, config, io) |
| 314 | + |
| 315 | + package = Package("demo", "0.1.0") |
| 316 | + package.files = [ |
| 317 | + {"file": "demo-0.1.0-py2.py3-none-any.whl", "hash": "md5:123456"}, |
| 318 | + {"file": "demo-0.1.0-py2.py3-none-any.whl", "hash": "sha256:123456"}, |
| 319 | + ] |
| 320 | + |
| 321 | + expected_message = ( |
| 322 | + "Invalid hashes " |
| 323 | + "(" |
| 324 | + "md5:15507846fd4299596661d0197bfb4f90, " |
| 325 | + "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a" |
| 326 | + ") " |
| 327 | + "for demo (0.1.0) using archive demo-0.1.0-py2.py3-none-any.whl. " |
| 328 | + "Expected one of md5:123456, sha256:123456." |
| 329 | + ) |
| 330 | + |
| 331 | + with pytest.raises(RuntimeError, match=re.escape(expected_message)): |
| 332 | + executor._download_link( |
| 333 | + Install(package), |
| 334 | + Link("https://example.com/demo-0.1.0-py2.py3-none-any.whl"), |
| 335 | + ) |
0 commit comments