Esempio n. 1
0
    def test_success(self, tmpdir):
        """Make sure no error is raised when at least one hash matches.

        Test check_against_path because it calls everything else.

        """
        file = tmpdir / 'to_hash'
        file.write('hello')
        hashes = Hashes({
            'sha256': ['2cf24dba5fb0a30e26e83b2ac5b9e29e'
                       '1b161e5c1fa7425e73043362938b9824'],
            'sha224': ['wrongwrong'],
            'md5': ['5d41402abc4b2a76b9719d911017c592']})
        hashes.check_against_path(file)
Esempio n. 2
0
 def test_unknown_hash(self):
     """Hashes should raise InstallationError when it encounters an unknown
     hash."""
     hashes = Hashes({'badbad': ['dummy']})
     with pytest.raises(InstallationError):
         hashes.check_against_file(BytesIO(b'hello'))
Esempio n. 3
0
 def test_failure(self):
     """Hashes should raise HashMismatch when no hashes match."""
     hashes = Hashes({'sha256': ['wrongwrong']})
     with pytest.raises(HashMismatch):
         hashes.check_against_file(BytesIO(b'hello'))
Esempio n. 4
0
 def test_non_zero(self) -> None:
     """Test that truthiness tests tell whether any known-good hashes
     exist."""
     assert Hashes({"sha256": ["dummy"]})
     assert not Hashes()
     assert not Hashes({})
Esempio n. 5
0
 def test_equality(self) -> None:
     assert Hashes() == Hashes()
     assert Hashes({"sha256": ["abcd"]}) == Hashes({"sha256": ["abcd"]})
     assert Hashes({"sha256": ["ab",
                               "cd"]}) == Hashes({"sha256": ["cd", "ab"]})
Esempio n. 6
0
 def test_failure(self) -> None:
     """Hashes should raise HashMismatch when no hashes match."""
     hashes = Hashes({"sha256": ["wrongwrong"]})
     with pytest.raises(HashMismatch):
         hashes.check_against_file(BytesIO(b"hello"))
Esempio n. 7
0
 def test_unknown_hash(self) -> None:
     """Hashes should raise InstallationError when it encounters an unknown
     hash."""
     hashes = Hashes({"badbad": ["dummy"]})
     with pytest.raises(InstallationError):
         hashes.check_against_file(BytesIO(b"hello"))
Esempio n. 8
0
 def test_equality(self):
     assert Hashes() == Hashes()
     assert Hashes({'sha256': ['abcd']}) == Hashes({'sha256': ['abcd']})
     assert Hashes({'sha256': ['ab',
                               'cd']}) == Hashes({'sha256': ['cd', 'ab']})
Esempio n. 9
0
 def test_hash(self):
     cache = {}
     cache[Hashes({'sha256': ['ab', 'cd']})] = 42
     assert cache[Hashes({'sha256': ['ab', 'cd']})] == 42
Esempio n. 10
0
 def test_unknown_hash(self):
     """Hashes should raise InstallationError when it encounters an unknown
     hash."""
     hashes = Hashes({'badbad': ['dummy']})
     with pytest.raises(InstallationError):
         hashes.check_against_file(BytesIO(b'hello'))
Esempio n. 11
0
 def test_non_zero(self):
     """Test that truthiness tests tell whether any known-good hashes
     exist."""
     assert Hashes({'sha256': 'dummy'})
     assert not Hashes()
     assert not Hashes({})
Esempio n. 12
0
 def test_failure(self):
     """Hashes should raise HashMismatch when no hashes match."""
     hashes = Hashes({'sha256': ['wrongwrong']})
     with pytest.raises(HashMismatch):
         hashes.check_against_file(BytesIO(b'hello'))
Esempio n. 13
0
 def test_is_hash_allowed(self, hash_name, hex_digest, expected):
     hashes_data = {
         'sha512': [128 * 'a', 128 * 'b'],
     }
     hashes = Hashes(hashes_data)
     assert hashes.is_hash_allowed(hash_name, hex_digest) == expected
Esempio n. 14
0
class TestLink:

    @pytest.mark.parametrize('url, expected', [
        (
            'https://*****:*****@example.com/path/page.html',
            '<Link https://user:****@example.com/path/page.html>',
        ),
    ])
    def test_repr(self, url, expected):
        link = Link(url)
        assert repr(link) == expected

    @pytest.mark.parametrize('url, expected', [
        ('http://yo/wheel.whl', 'wheel.whl'),
        ('http://yo/wheel', 'wheel'),
        ('https://example.com/path/page.html', 'page.html'),
        # Test a quoted character.
        ('https://example.com/path/page%231.html', 'page#1.html'),
        (
            'http://yo/myproject-1.0%2Bfoobar.0-py2.py3-none-any.whl',
            'myproject-1.0+foobar.0-py2.py3-none-any.whl',
        ),
        # Test a path that ends in a slash.
        ('https://example.com/path/', 'path'),
        ('https://example.com/path//', 'path'),
        # Test a url with no filename.
        ('https://example.com/', 'example.com'),
        # Test a url with no filename and with auth information.
        (
            'https://*****:*****@example.com/',
            'example.com',
        ),
    ])
    def test_filename(self, url, expected):
        link = Link(url)
        assert link.filename == expected

    def test_splitext(self):
        assert ('wheel', '.whl') == Link('http://yo/wheel.whl').splitext()

    def test_no_ext(self):
        assert '' == Link('http://yo/wheel').ext

    def test_ext(self):
        assert '.whl' == Link('http://yo/wheel.whl').ext

    def test_ext_fragment(self):
        assert '.whl' == Link('http://yo/wheel.whl#frag').ext

    def test_ext_query(self):
        assert '.whl' == Link('http://yo/wheel.whl?a=b').ext

    def test_is_wheel(self):
        assert Link('http://yo/wheel.whl').is_wheel

    def test_is_wheel_false(self):
        assert not Link('http://yo/not_a_wheel').is_wheel

    def test_fragments(self):
        url = 'git+https://example.com/package#egg=eggname'
        assert 'eggname' == Link(url).egg_fragment
        assert None is Link(url).subdirectory_fragment
        url = 'git+https://example.com/package#egg=eggname&subdirectory=subdir'
        assert 'eggname' == Link(url).egg_fragment
        assert 'subdir' == Link(url).subdirectory_fragment
        url = 'git+https://example.com/package#subdirectory=subdir&egg=eggname'
        assert 'eggname' == Link(url).egg_fragment
        assert 'subdir' == Link(url).subdirectory_fragment

    @pytest.mark.parametrize('yanked_reason, expected', [
        (None, False),
        ('', True),
        ('there was a mistake', True),
    ])
    def test_is_yanked(self, yanked_reason, expected):
        link = Link(
            'https://example.com/wheel.whl',
            yanked_reason=yanked_reason,
        )
        assert link.is_yanked == expected

    @pytest.mark.parametrize('hash_name, hex_digest, expected', [
        # Test a value that matches but with the wrong hash_name.
        ('sha384', 128 * 'a', False),
        # Test matching values, including values other than the first.
        ('sha512', 128 * 'a', True),
        ('sha512', 128 * 'b', True),
        # Test a matching hash_name with a value that doesn't match.
        ('sha512', 128 * 'c', False),
        # Test a link without a hash value.
        ('sha512', '', False),
    ])
    def test_is_hash_allowed(self, hash_name, hex_digest, expected):
        url = (
            'https://example.com/wheel.whl#{hash_name}={hex_digest}'.format(
                hash_name=hash_name,
                hex_digest=hex_digest,
            )
        )
        link = Link(url)
        hashes_data = {
            'sha512': [128 * 'a', 128 * 'b'],
        }
        hashes = Hashes(hashes_data)
        assert link.is_hash_allowed(hashes) == expected

    def test_is_hash_allowed__no_hash(self):
        link = Link('https://example.com/wheel.whl')
        hashes_data = {
            'sha512': [128 * 'a'],
        }
        hashes = Hashes(hashes_data)
        assert not link.is_hash_allowed(hashes)

    @pytest.mark.parametrize('hashes, expected', [
        (None, False),
        # Also test a success case to show the test is correct.
        (Hashes({'sha512': [128 * 'a']}), True),
    ])
    def test_is_hash_allowed__none_hashes(self, hashes, expected):
        url = 'https://example.com/wheel.whl#sha512={}'.format(128 * 'a')
        link = Link(url)
        assert link.is_hash_allowed(hashes) == expected
Esempio n. 15
0
    def _iter_found_candidates(
            self,
            ireqs,  # type: Sequence[InstallRequirement]
            specifier,  # type: SpecifierSet
    ):
        # type: (...) -> Iterable[Candidate]
        if not ireqs:
            return ()

        # The InstallRequirement implementation requires us to give it a
        # "template". Here we just choose the first requirement to represent
        # all of them.
        # Hopefully the Project model can correct this mismatch in the future.
        template = ireqs[0]
        name = canonicalize_name(template.req.name)

        hashes = Hashes()
        extras = frozenset()  # type: FrozenSet[str]
        for ireq in ireqs:
            specifier &= ireq.req.specifier
            hashes |= ireq.hashes(trust_internet=False)
            extras |= frozenset(ireq.extras)

        # We use this to ensure that we only yield a single candidate for
        # each version (the finder's preferred one for that version). The
        # requirement needs to return only one candidate per version, so we
        # implement that logic here so that requirements using this helper
        # don't all have to do the same thing later.
        candidates = collections.OrderedDict()  # type: VersionCandidates

        # Get the installed version, if it matches, unless the user
        # specified `--force-reinstall`, when we want the version from
        # the index instead.
        installed_version = None
        installed_candidate = None
        if not self._force_reinstall and name in self._installed_dists:
            installed_dist = self._installed_dists[name]
            installed_version = installed_dist.parsed_version
            if specifier.contains(installed_version, prereleases=True):
                installed_candidate = self._make_candidate_from_dist(
                    dist=installed_dist,
                    extras=extras,
                    template=template,
                )

        found = self._finder.find_best_candidate(
            project_name=name,
            specifier=specifier,
            hashes=hashes,
        )
        for ican in found.iter_applicable():
            if ican.version == installed_version and installed_candidate:
                candidate = installed_candidate
            else:
                candidate = self._make_candidate_from_link(
                    link=ican.link,
                    extras=extras,
                    template=template,
                    name=name,
                    version=ican.version,
                )
            candidates[ican.version] = candidate

        # Yield the installed version even if it is not found on the index.
        if installed_version and installed_candidate:
            candidates[installed_version] = installed_candidate

        return six.itervalues(candidates)
Esempio n. 16
0
 def empty(cls):
     # type: () -> Constraint
     return Constraint(SpecifierSet(), Hashes(), frozenset())