Files

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")