1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00
pip/tests/unit/test_self_check_outdated.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

186 lines
5.6 KiB
Python
Raw Permalink Normal View History

import datetime
import json
import logging
import os
2017-05-16 12:16:30 +02:00
import sys
from optparse import Values
from pathlib import Path
from typing import Optional
from unittest.mock import ANY, Mock, patch
2017-05-16 12:16:30 +02:00
import pytest
from freezegun import freeze_time
from pip._vendor.packaging.version import Version
from pip._internal import self_outdated_check
@pytest.mark.parametrize(
["key", "expected"],
[
(
"/hello/world/venv",
"fcd2d5175dd33d5df759ee7b045264230205ef837bf9f582f7c3ada7",
),
(
"C:\\Users\\User\\Desktop\\venv",
"902cecc0745b8ecf2509ba473f3556f0ba222fedc6df433acda24aa5",
),
],
)
def test_get_statefile_name_known_values(key: str, expected: str) -> None:
assert expected == self_outdated_check._get_statefile_name(key)
2020-04-23 06:01:05 +02:00
@freeze_time("1970-01-02T11:00:00Z")
@patch("pip._internal.self_outdated_check._self_version_check_logic")
@patch("pip._internal.self_outdated_check.SelfCheckState")
def test_pip_self_version_check_calls_underlying_implementation(
mocked_state: Mock, mocked_function: Mock, tmpdir: Path
) -> None:
# GIVEN
mock_session = Mock()
2023-08-26 10:20:40 +02:00
fake_options = Values({"cache_dir": str(tmpdir)})
# WHEN
self_outdated_check.pip_self_version_check(mock_session, fake_options)
# THEN
mocked_state.assert_called_once_with(cache_dir=str(tmpdir))
mocked_function.assert_called_once_with(
state=mocked_state(cache_dir=str(tmpdir)),
current_time=datetime.datetime(
1970, 1, 2, 11, 0, 0, tzinfo=datetime.timezone.utc
),
local_version=ANY,
get_remote_version=ANY,
)
@pytest.mark.parametrize(
[
"installed_version",
"remote_version",
"stored_version",
"installed_by_pip",
"should_show_prompt",
],
[
# A newer version available!
("1.0", "2.0", None, True, True),
# A newer version available, and cached value is new too!
("1.0", "2.0", "2.0", True, True),
# A newer version available, but was not installed by pip.
("1.0", "2.0", None, False, False),
# On the latest version already.
("2.0", "2.0", None, True, False),
# On the latest version already, and cached value matches.
("2.0", "2.0", "2.0", True, False),
# A newer version available, but cached value is older.
("1.0", "2.0", "1.0", True, False),
],
)
def test_core_logic(
installed_version: str,
remote_version: str,
stored_version: Optional[str],
installed_by_pip: bool,
should_show_prompt: bool,
caplog: pytest.LogCaptureFixture,
monkeypatch: pytest.MonkeyPatch,
) -> None:
# GIVEN
monkeypatch.setattr(
self_outdated_check, "was_installed_by_pip", lambda _: installed_by_pip
)
mock_state = Mock()
mock_state.get.return_value = stored_version
fake_time = datetime.datetime(2000, 1, 1, 0, 0, 0)
version_that_should_be_checked = stored_version or remote_version
# WHEN
with caplog.at_level(logging.DEBUG):
return_value = self_outdated_check._self_version_check_logic(
state=mock_state,
current_time=fake_time,
local_version=Version(installed_version),
get_remote_version=lambda: remote_version,
)
# THEN
mock_state.get.assert_called_once_with(fake_time)
assert caplog.messages == [
f"Remote version of pip: {version_that_should_be_checked}",
f"Local version of pip: {installed_version}",
f"Was pip installed by pip? {installed_by_pip}",
]
if stored_version:
mock_state.set.assert_not_called()
else:
mock_state.set.assert_called_once_with(
version_that_should_be_checked, fake_time
)
if not should_show_prompt:
assert return_value is None
return # the remaining assertions are for the other case.
assert return_value is not None
assert return_value.old == installed_version
assert return_value.new == remote_version
class TestSelfCheckState:
def test_no_cache(self) -> None:
# GIVEN / WHEN
state = self_outdated_check.SelfCheckState(cache_dir="")
assert state._statefile_path is None
def test_reads_expected_statefile(self, tmpdir: Path) -> None:
# GIVEN
cache_dir = tmpdir / "cache_dir"
expected_path = (
cache_dir
/ "selfcheck"
/ self_outdated_check._get_statefile_name(sys.prefix)
)
cache_dir.mkdir()
(cache_dir / "selfcheck").mkdir()
expected_path.write_text('{"foo": "bar"}')
# WHEN
state = self_outdated_check.SelfCheckState(cache_dir=str(cache_dir))
# THEN
assert state._statefile_path == os.fspath(expected_path)
assert state._state == {"foo": "bar"}
def test_writes_expected_statefile(self, tmpdir: Path) -> None:
# GIVEN
cache_dir = tmpdir / "cache_dir"
cache_dir.mkdir()
expected_path = (
cache_dir
/ "selfcheck"
/ self_outdated_check._get_statefile_name(sys.prefix)
)
# WHEN
state = self_outdated_check.SelfCheckState(cache_dir=str(cache_dir))
state.set(
"1.0.0",
datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc),
)
# THEN
assert state._statefile_path == os.fspath(expected_path)
contents = expected_path.read_text()
assert json.loads(contents) == {
"key": sys.prefix,
"last_check": "2000-01-01T00:00:00+00:00",
"pypi_version": "1.0.0",
}