mirror of
https://github.com/TencentCloud/Octop.git
synced 2026-10-19 06:10:07 +08:00
Keep automatic update reminders on the latest stable release, pin upgrades to the confirmed version, and require --allow-prerelease for CLI beta installs. Co-authored-by: Cursor <cursoragent@cursor.com>
239 lines
8.1 KiB
Python
239 lines
8.1 KiB
Python
"""Tests for `octop update`."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from click.testing import CliRunner
|
|
|
|
from octop.cli.main import cli
|
|
from octop.infra.setup import self_update
|
|
|
|
|
|
def test_update_check_only_no_install(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
import octop.cli.commands.update as update_cmd
|
|
|
|
monkeypatch.setattr(
|
|
update_cmd,
|
|
"fetch_pypi_info",
|
|
lambda: self_update.PyPIInfo(version="9.9.9", latest_stable="9.9.9"),
|
|
)
|
|
monkeypatch.setattr(update_cmd, "get_local_version", lambda: "0.1.0")
|
|
monkeypatch.setattr(update_cmd, "get_editable_path", lambda: None)
|
|
|
|
called: dict[str, bool] = {}
|
|
|
|
def _fake_upgrade(**kw):
|
|
called["ran"] = True
|
|
return self_update.UpgradeResult(success=True)
|
|
|
|
monkeypatch.setattr(update_cmd, "run_upgrade", _fake_upgrade)
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["update", "--check"])
|
|
assert result.exit_code == 0
|
|
assert "9.9.9" in result.output
|
|
assert "ran" not in called
|
|
|
|
|
|
def test_update_yes_runs_upgrade(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
import octop.cli.commands.update as update_cmd
|
|
|
|
monkeypatch.setattr(
|
|
update_cmd,
|
|
"fetch_pypi_info",
|
|
lambda: self_update.PyPIInfo(version="9.9.9", latest_stable="9.9.9"),
|
|
)
|
|
monkeypatch.setattr(update_cmd, "get_local_version", lambda: "0.1.0")
|
|
monkeypatch.setattr(update_cmd, "get_editable_path", lambda: None)
|
|
monkeypatch.setattr(
|
|
update_cmd, "resolve_venv_python", lambda: "/home/user/.octop/venv/bin/python"
|
|
)
|
|
|
|
called: dict[str, bool] = {}
|
|
|
|
def _fake_upgrade(**kw):
|
|
called["ran"] = True
|
|
called["kwargs"] = kw
|
|
return self_update.UpgradeResult(success=True, installed_version="9.9.9")
|
|
|
|
monkeypatch.setattr(update_cmd, "run_upgrade", _fake_upgrade)
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["update", "--yes"])
|
|
assert result.exit_code == 0
|
|
assert called.get("ran") is True
|
|
assert called["kwargs"]["version"] == "9.9.9"
|
|
assert called["kwargs"]["allow_prerelease"] is False
|
|
assert "/home/user/.octop/venv/bin/python" in result.output
|
|
|
|
|
|
def test_update_already_latest(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
import octop.cli.commands.update as update_cmd
|
|
|
|
monkeypatch.setattr(
|
|
update_cmd,
|
|
"fetch_pypi_info",
|
|
lambda: self_update.PyPIInfo(version="0.1.0", latest_stable="0.1.0"),
|
|
)
|
|
monkeypatch.setattr(update_cmd, "get_local_version", lambda: "0.1.0")
|
|
monkeypatch.setattr(update_cmd, "get_editable_path", lambda: None)
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["update", "--check"])
|
|
assert result.exit_code == 0
|
|
assert "up to date" in result.output.lower()
|
|
|
|
|
|
def test_build_upgrade_command_uses_managed_venv_python() -> None:
|
|
python = "/home/user/.octop/venv/bin/python"
|
|
cmd = self_update.build_upgrade_command("uv", python, index_url="https://mirror.example/simple")
|
|
assert cmd is not None
|
|
assert "--python" in cmd
|
|
assert python in cmd
|
|
assert "--upgrade-package" in cmd
|
|
assert "octop" in cmd
|
|
assert "https://mirror.example/simple" in cmd
|
|
assert "--target" not in cmd
|
|
|
|
|
|
def test_build_upgrade_command_pins_version() -> None:
|
|
python = "/home/user/.octop/venv/bin/python"
|
|
cmd = self_update.build_upgrade_command("uv", python, version="0.9.33")
|
|
assert cmd is not None
|
|
assert "octop==0.9.33" in cmd
|
|
assert "--prerelease" not in cmd
|
|
|
|
|
|
def test_build_upgrade_command_green_packages_target(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
packages = tmp_path / "packages"
|
|
packages.mkdir()
|
|
monkeypatch.setenv("OCTOP_GREEN_PACKAGES", str(packages))
|
|
python = "/opt/octop/runtime/bin/python3"
|
|
cmd = self_update.build_upgrade_command("uv", python)
|
|
assert cmd is not None
|
|
assert "--target" in cmd
|
|
assert str(packages) in cmd
|
|
|
|
|
|
def test_resolve_venv_python_green_uses_current_interpreter(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
packages = tmp_path / "packages"
|
|
packages.mkdir()
|
|
venv_python = tmp_path / "venv" / "bin" / "python"
|
|
venv_python.parent.mkdir(parents=True)
|
|
venv_python.write_text("#!/bin/sh\n", encoding="utf-8")
|
|
monkeypatch.setenv("OCTOP_HOME", str(tmp_path))
|
|
monkeypatch.setenv("OCTOP_GREEN_PACKAGES", str(packages))
|
|
monkeypatch.setattr(self_update.sys, "executable", "/bundled/python3")
|
|
monkeypatch.setattr(self_update.sys, "prefix", "/usr")
|
|
monkeypatch.setattr(self_update.sys, "base_prefix", "/usr")
|
|
assert self_update.resolve_venv_python() == "/bundled/python3"
|
|
|
|
|
|
def test_resolve_venv_python_prefers_octop_home(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
venv_python = tmp_path / "venv" / "bin" / "python"
|
|
venv_python.parent.mkdir(parents=True)
|
|
venv_python.write_text("#!/bin/sh\n", encoding="utf-8")
|
|
|
|
monkeypatch.setenv("OCTOP_HOME", str(tmp_path))
|
|
monkeypatch.setattr(self_update.sys, "prefix", "/usr")
|
|
monkeypatch.setattr(self_update.sys, "base_prefix", "/usr")
|
|
monkeypatch.delenv("VIRTUAL_ENV", raising=False)
|
|
|
|
assert self_update.resolve_venv_python() == str(venv_python)
|
|
|
|
|
|
def test_update_check_skips_prerelease_by_default(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
import octop.cli.commands.update as update_cmd
|
|
|
|
monkeypatch.setattr(
|
|
update_cmd,
|
|
"fetch_pypi_info",
|
|
lambda: self_update.PyPIInfo(version="0.9.34b1", latest_stable="0.1.0"),
|
|
)
|
|
monkeypatch.setattr(update_cmd, "get_local_version", lambda: "0.1.0")
|
|
monkeypatch.setattr(update_cmd, "get_editable_path", lambda: None)
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["update", "--check"])
|
|
assert result.exit_code == 0
|
|
assert "0.1.0" in result.output
|
|
assert "0.9.34b1" not in result.output
|
|
assert "up to date" in result.output.lower()
|
|
|
|
|
|
def test_update_allow_prerelease_check_shows_prerelease(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
import octop.cli.commands.update as update_cmd
|
|
|
|
monkeypatch.setattr(
|
|
update_cmd,
|
|
"fetch_pypi_info",
|
|
lambda: self_update.PyPIInfo(version="0.9.34b1", latest_stable="0.1.0"),
|
|
)
|
|
monkeypatch.setattr(update_cmd, "get_local_version", lambda: "0.1.0")
|
|
monkeypatch.setattr(update_cmd, "get_editable_path", lambda: None)
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["update", "--check", "--allow-prerelease"])
|
|
assert result.exit_code == 0
|
|
assert "0.9.34b1" in result.output
|
|
|
|
|
|
def test_update_allow_prerelease_installs_prerelease(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
import octop.cli.commands.update as update_cmd
|
|
|
|
monkeypatch.setattr(
|
|
update_cmd,
|
|
"fetch_pypi_info",
|
|
lambda: self_update.PyPIInfo(version="0.9.34b1", latest_stable="0.1.0"),
|
|
)
|
|
monkeypatch.setattr(update_cmd, "get_local_version", lambda: "0.1.0")
|
|
monkeypatch.setattr(update_cmd, "get_editable_path", lambda: None)
|
|
monkeypatch.setattr(
|
|
update_cmd, "resolve_venv_python", lambda: "/home/user/.octop/venv/bin/python"
|
|
)
|
|
|
|
called: dict[str, object] = {}
|
|
|
|
def _fake_upgrade(**kw):
|
|
called["ran"] = True
|
|
called["kwargs"] = kw
|
|
return self_update.UpgradeResult(success=True, installed_version="0.9.34b1")
|
|
|
|
monkeypatch.setattr(update_cmd, "run_upgrade", _fake_upgrade)
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["update", "--allow-prerelease", "--yes"])
|
|
assert result.exit_code == 0
|
|
assert called.get("ran") is True
|
|
assert called["kwargs"]["version"] == "0.9.34b1"
|
|
assert called["kwargs"]["allow_prerelease"] is True
|
|
|
|
|
|
def test_update_editable_install_exits_nonzero(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
import octop.cli.commands.update as update_cmd
|
|
|
|
monkeypatch.setattr(
|
|
update_cmd,
|
|
"fetch_pypi_info",
|
|
lambda: self_update.PyPIInfo(version="9.9.9", latest_stable="9.9.9"),
|
|
)
|
|
monkeypatch.setattr(update_cmd, "get_local_version", lambda: "0.1.0")
|
|
monkeypatch.setattr(update_cmd, "get_editable_path", lambda: "/src/orca")
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["update", "--yes"])
|
|
assert result.exit_code == 1
|
|
assert "/src/orca" in result.output
|