Skip to content

Commit

Permalink
Add unit tests for cache origin.json... and fix a bug
Browse files Browse the repository at this point in the history
  • Loading branch information
sbidoul committed May 30, 2022
1 parent 6b18cba commit 05d2b85
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 11 deletions.
11 changes: 6 additions & 5 deletions src/pip/_internal/operations/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,21 +505,22 @@ def _prepare_linked_requirement(
# prepare_editable_requirement).
assert not req.editable
req.download_info = direct_url_from_link(link, req.source_dir)

# For use in later processing,
# preserve the file path on the requirement.
if local_file:
req.local_file_path = local_file.path
# Make sure we have a hash in download_info. If we got it as part of the
# URL, it will have been verified and we can rely on it. Otherwise we
# compute it from the downloaded file.
if (
isinstance(req.download_info.info, ArchiveInfo)
and not req.download_info.info.hash
and local_file
):
hash = hash_file(local_file.path)[0].hexdigest()
req.download_info.info.hash = f"sha256={hash}"

# For use in later processing,
# preserve the file path on the requirement.
if local_file:
req.local_file_path = local_file.path

dist = _get_prepared_distribution(
req,
self.build_tracker,
Expand Down
64 changes: 58 additions & 6 deletions tests/unit/test_req.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import sys
import tempfile
from functools import partial
from typing import Iterator, Tuple, cast
from typing import Iterator, Optional, Tuple, cast
from unittest import mock

import pytest
from pip._vendor.packaging.markers import Marker
from pip._vendor.packaging.requirements import Requirement

from pip._internal.cache import WheelCache
from pip._internal.commands import create_command
from pip._internal.commands.install import InstallCommand
from pip._internal.exceptions import (
Expand All @@ -22,7 +23,9 @@
)
from pip._internal.index.package_finder import PackageFinder
from pip._internal.metadata import select_backend
from pip._internal.models.direct_url import ArchiveInfo, DirInfo, VcsInfo
from pip._internal.models.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo
from pip._internal.models.format_control import FormatControl
from pip._internal.models.link import Link
from pip._internal.network.session import PipSession
from pip._internal.operations.build.build_tracker import get_build_tracker
from pip._internal.operations.prepare import RequirementPreparer
Expand All @@ -43,7 +46,7 @@
)
from pip._internal.resolution.legacy.resolver import Resolver
from pip._internal.utils.urls import path_to_url
from tests.lib import TestData, make_test_finder, requirements_file
from tests.lib import TestData, make_test_finder, requirements_file, wheel
from tests.lib.path import Path


Expand Down Expand Up @@ -77,7 +80,10 @@ def teardown(self) -> None:

@contextlib.contextmanager
def _basic_resolver(
self, finder: PackageFinder, require_hashes: bool = False
self,
finder: PackageFinder,
require_hashes: bool = False,
wheel_cache: Optional[WheelCache] = None,
) -> Iterator[Resolver]:
make_install_req = partial(
install_req_from_req_string,
Expand Down Expand Up @@ -106,7 +112,7 @@ def _basic_resolver(
preparer=preparer,
make_install_req=make_install_req,
finder=finder,
wheel_cache=None,
wheel_cache=wheel_cache,
use_user_site=False,
upgrade_strategy="to-satisfy-only",
ignore_dependencies=False,
Expand Down Expand Up @@ -366,7 +372,6 @@ def test_download_info_index_url(self) -> None:
req = reqset.all_requirements[0]
assert req.download_info
assert isinstance(req.download_info.info, ArchiveInfo)
assert req.download_info.info.hash

@pytest.mark.network
def test_download_info_web_archive(self) -> None:
Expand All @@ -391,6 +396,53 @@ def test_download_info_web_archive(self) -> None:
"ad977496000576e1b6c41f6449a9897087ce9da6db4f15b603fe8372af4bf3c6"
)

def test_download_info_archive_legacy_cache(
self, tmp_path: Path, shared_data: TestData
) -> None:
"""Test download_info hash is not set for an archive with legacy cache entry."""
url = path_to_url(shared_data.packages / "simple-1.0.tar.gz")
finder = make_test_finder()
wheel_cache = WheelCache(str(tmp_path / "cache"), FormatControl())
cache_entry_dir = wheel_cache.get_path_for_link(Link(url))
Path(cache_entry_dir).mkdir(parents=True)
wheel.make_wheel(name="simple", version="1.0").save_to_dir(cache_entry_dir)
with self._basic_resolver(finder, wheel_cache=wheel_cache) as resolver:
ireq = get_processed_req_from_line(f"simple @ {url}")
reqset = resolver.resolve([ireq], True)
assert len(reqset.all_requirements) == 1
req = reqset.all_requirements[0]
assert req.original_link_is_in_wheel_cache
assert req.download_info
assert req.download_info.url == url
assert isinstance(req.download_info.info, ArchiveInfo)
assert not req.download_info.info.hash

def test_download_info_archive_cache_with_origin(
self, tmp_path: Path, shared_data: TestData
) -> None:
"""Test download_info hash is set for a web archive with cache entry
that has origin.json."""
url = path_to_url(shared_data.packages / "simple-1.0.tar.gz")
hash = "sha256=ad977496000576e1b6c41f6449a9897087ce9da6db4f15b603fe8372af4bf3c6"
finder = make_test_finder()
wheel_cache = WheelCache(str(tmp_path / "cache"), FormatControl())
cache_entry_dir = wheel_cache.get_path_for_link(Link(url))
Path(cache_entry_dir).mkdir(parents=True)
Path(cache_entry_dir).joinpath("origin.json").write_text(
DirectUrl(url, ArchiveInfo(hash=hash)).to_json()
)
wheel.make_wheel(name="simple", version="1.0").save_to_dir(cache_entry_dir)
with self._basic_resolver(finder, wheel_cache=wheel_cache) as resolver:
ireq = get_processed_req_from_line(f"simple @ {url}")
reqset = resolver.resolve([ireq], True)
assert len(reqset.all_requirements) == 1
req = reqset.all_requirements[0]
assert req.original_link_is_in_wheel_cache
assert req.download_info
assert req.download_info.url == url
assert isinstance(req.download_info.info, ArchiveInfo)
assert req.download_info.info.hash == hash

def test_download_info_local_wheel(self, data: TestData) -> None:
"""Test that download_info is set for requirements from a local wheel."""
finder = make_test_finder()
Expand Down

0 comments on commit 05d2b85

Please sign in to comment.