105 lines
3.4 KiB
Python
105 lines
3.4 KiB
Python
"""Tests for EvoScientist.updater deployment detection and plan building."""
|
|
|
|
import json
|
|
|
|
import pytest
|
|
|
|
from pathlib import Path
|
|
|
|
from EvoScientist.updater import (
|
|
DEPLOY_DOCKER,
|
|
DEPLOY_PIPX,
|
|
DEPLOY_SYSTEMD,
|
|
DEPLOY_UVTOOL,
|
|
DEPLOY_VENV,
|
|
SystemProbe,
|
|
UpdateInProgressError,
|
|
build_install_command,
|
|
build_plan,
|
|
copy_updater,
|
|
detect_deployment,
|
|
release_plan_lock,
|
|
write_plan_locked,
|
|
)
|
|
|
|
|
|
def _probe(**kw):
|
|
base = dict(in_container=False, invocation_id=None, uv_tool_pkg=False, pipx_pkg=False)
|
|
return SystemProbe(**{**base, **kw})
|
|
|
|
|
|
def test_docker_wins_over_systemd_marker():
|
|
assert detect_deployment(_probe(in_container=True, invocation_id="abc")) == DEPLOY_DOCKER
|
|
|
|
|
|
def test_systemd_before_cli():
|
|
assert detect_deployment(_probe(invocation_id="abc", uv_tool_pkg=True)) == DEPLOY_SYSTEMD
|
|
|
|
|
|
def test_uvtool_pipx_venv_order():
|
|
assert detect_deployment(_probe(uv_tool_pkg=True, pipx_pkg=True)) == DEPLOY_UVTOOL
|
|
assert detect_deployment(_probe(pipx_pkg=True)) == DEPLOY_PIPX
|
|
assert detect_deployment(_probe()) == DEPLOY_VENV
|
|
|
|
|
|
def test_install_commands():
|
|
artifact = Path("/tmp/updates/v1/EvoScientist-1-py3-none-any.whl")
|
|
assert build_install_command(DEPLOY_UVTOOL, artifact, "/usr/bin/python3") == [
|
|
"uv", "tool", "install", "--force", str(artifact),
|
|
]
|
|
assert build_install_command(DEPLOY_PIPX, artifact, "/usr/bin/python3") == [
|
|
"pipx", "install", "--force", str(artifact),
|
|
]
|
|
assert build_install_command(DEPLOY_VENV, artifact, "/usr/bin/python3") == [
|
|
"/usr/bin/python3", "-m", "pip", "install", "--force-reinstall", str(artifact),
|
|
]
|
|
systemd_cmd = build_install_command(DEPLOY_SYSTEMD, artifact, "/usr/bin/python3")
|
|
assert systemd_cmd[0:2] == ["uv", "tool"] or systemd_cmd[0] == "/usr/bin/python3"
|
|
|
|
|
|
def _plan(tmp_path):
|
|
artifact = tmp_path / "v0.2.3" / "EvoScientist-0.2.3-py3-none-any.whl"
|
|
artifact.parent.mkdir(parents=True)
|
|
artifact.write_bytes(b"x")
|
|
return build_plan(
|
|
version="0.2.3",
|
|
artifact=artifact,
|
|
kind=DEPLOY_UVTOOL,
|
|
python="/usr/bin/python3",
|
|
argv=["EvoSci", "deploy", "--port", "6174"],
|
|
cwd=tmp_path,
|
|
deploy_mode="full",
|
|
staging=tmp_path,
|
|
systemd_unit=None,
|
|
)
|
|
|
|
|
|
def test_build_plan_fields(tmp_path):
|
|
plan = _plan(tmp_path)
|
|
assert plan["version"] == "0.2.3"
|
|
assert plan["install_command"][0:3] == ["uv", "tool", "install"]
|
|
assert plan["respawn_command"] == ["EvoSci", "deploy", "--port", "6174"]
|
|
assert plan["cwd"] == str(tmp_path)
|
|
assert plan["deploy_mode"] == "full"
|
|
assert plan["restart"] == {"strategy": "cli", "unit": None}
|
|
assert plan["result_path"].endswith("update-result.json")
|
|
assert plan["previous_version"]
|
|
|
|
|
|
def test_write_plan_locked_rejects_second_writer(tmp_path):
|
|
plan = _plan(tmp_path)
|
|
plan_path = tmp_path / "v0.2.3" / "plan.json"
|
|
write_plan_locked(plan, plan_path)
|
|
assert json.loads(plan_path.read_text())["version"] == "0.2.3"
|
|
with pytest.raises(UpdateInProgressError):
|
|
write_plan_locked(plan, plan_path)
|
|
release_plan_lock(plan_path)
|
|
write_plan_locked(plan, plan_path) # releasable and writable again
|
|
release_plan_lock(plan_path)
|
|
|
|
|
|
def test_copy_updater_produces_standalone_copy(tmp_path):
|
|
copied = copy_updater(tmp_path)
|
|
assert copied == tmp_path / "updater.py"
|
|
assert "detect_deployment" in copied.read_text(encoding="utf-8")
|