feat: deliver installable local alpha sessions
Some checks failed
tamq-ci / test (push) Failing after 6s
Some checks failed
tamq-ci / test (push) Failing after 6s
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a03397-4d51-7fd1-8ff2-946eb22ea2bc
This commit is contained in:
parent
d56bd3c79f
commit
5774fbd548
18 changed files with 890 additions and 94 deletions
180
tests/test_install_target.py
Normal file
180
tests/test_install_target.py
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_make_install_uses_isolated_uv_tool_install():
|
||||
makefile = Path("Makefile").read_text(encoding="utf-8")
|
||||
assert "install:" in makefile
|
||||
assert "uv tool install --force --reinstall --refresh ." in makefile
|
||||
assert "tamq --version" in makefile
|
||||
assert "uninstall:" in makefile
|
||||
assert "uv tool uninstall tmux-amq" in makefile
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
shutil.which("uv") is None or shutil.which("tmux") is None,
|
||||
reason="installed-package smoke requires uv and tmux",
|
||||
)
|
||||
def test_isolated_installed_tool_session_smoke(tmp_path):
|
||||
project = Path(__file__).resolve().parents[1]
|
||||
tool_dir = tmp_path / "tools"
|
||||
bin_dir = tmp_path / "bin"
|
||||
runtime_dir = tmp_path / "runtime"
|
||||
state_dir = tmp_path / "state"
|
||||
repo_a = tmp_path / "railiance-platform"
|
||||
repo_b = tmp_path / "activity-core"
|
||||
for path in (bin_dir, runtime_dir, repo_a, repo_b):
|
||||
path.mkdir(parents=True)
|
||||
|
||||
gita = bin_dir / "gita"
|
||||
gita.write_text(
|
||||
"#!/usr/bin/env python3\n"
|
||||
"import sys\n"
|
||||
f"paths = {{'railiance-platform': {str(repo_a)!r}, 'activity-core': {str(repo_b)!r}}}\n"
|
||||
"if sys.argv[1:] == ['ls']:\n"
|
||||
" print('railiance-platform activity-core')\n"
|
||||
"elif sys.argv[1:] == ['freeze']:\n"
|
||||
" for slug, path in paths.items(): print(f'local,{slug},{path}')\n"
|
||||
"else:\n"
|
||||
" raise SystemExit(2)\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
agent = bin_dir / "alpha-agent"
|
||||
agent.write_text(
|
||||
"#!/bin/sh\nprintf 'installed-alpha-ready\\n'\nexec sleep 30\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
gita.chmod(0o755)
|
||||
agent.chmod(0o755)
|
||||
|
||||
socket_name = f"tamq-installed-{os.getpid()}"
|
||||
env = os.environ.copy()
|
||||
env.update(
|
||||
{
|
||||
"PATH": f"{bin_dir}:{env['PATH']}",
|
||||
"UV_TOOL_DIR": str(tool_dir),
|
||||
"UV_TOOL_BIN_DIR": str(bin_dir),
|
||||
"UV_CACHE_DIR": str(tmp_path / "uv-cache"),
|
||||
"XDG_RUNTIME_DIR": str(runtime_dir),
|
||||
"TAMQ_STATE_DIR": str(state_dir),
|
||||
"TAMQ_TMUX_SOCKET": socket_name,
|
||||
}
|
||||
)
|
||||
tamq = bin_dir / "tamq"
|
||||
tmux = ["tmux", "-L", socket_name]
|
||||
|
||||
def run(*args: str) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(
|
||||
args,
|
||||
cwd=tmp_path,
|
||||
env=env,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
timeout=30,
|
||||
)
|
||||
|
||||
try:
|
||||
subprocess.run(
|
||||
["uv", "tool", "install", "--force", "--reinstall", "--refresh", str(project)],
|
||||
cwd=project,
|
||||
env=env,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
timeout=60,
|
||||
)
|
||||
assert run(str(tamq), "--version").stdout.strip() == "0.1.0"
|
||||
started = json.loads(
|
||||
run(
|
||||
str(tamq),
|
||||
"start",
|
||||
"--detach",
|
||||
"--command",
|
||||
"alpha-agent",
|
||||
"railiance-platform",
|
||||
"activity-core",
|
||||
).stdout
|
||||
)
|
||||
assert started["repos"] == ["railiance-platform", "activity-core"]
|
||||
rows = run(
|
||||
*tmux,
|
||||
"list-windows",
|
||||
"-t",
|
||||
"tamq",
|
||||
"-F",
|
||||
"#{window_name}|#{pane_current_path}|#{pane_pid}",
|
||||
).stdout.splitlines()
|
||||
parsed = {name: (path, pid) for name, path, pid in (row.split("|", 2) for row in rows)}
|
||||
assert parsed["railiance-platform"][0] == str(repo_a)
|
||||
assert parsed["activity-core"][0] == str(repo_b)
|
||||
|
||||
repeated = json.loads(
|
||||
run(
|
||||
str(tamq),
|
||||
"start",
|
||||
"--detach",
|
||||
"--command",
|
||||
"alpha-agent",
|
||||
"railiance-platform",
|
||||
"activity-core",
|
||||
).stdout
|
||||
)
|
||||
assert repeated["instance_id"] == started["instance_id"]
|
||||
repeated_rows = run(
|
||||
*tmux,
|
||||
"list-windows",
|
||||
"-t",
|
||||
"tamq",
|
||||
"-F",
|
||||
"#{window_name}|#{pane_current_path}|#{pane_pid}",
|
||||
).stdout.splitlines()
|
||||
assert repeated_rows == rows
|
||||
pre_delivery_status = json.loads(run(str(tamq), "status").stdout)
|
||||
assert pre_delivery_status["service"] is True
|
||||
assert [item["endpoint_id"] for item in pre_delivery_status["endpoints"]] == [
|
||||
started["instance_id"]
|
||||
]
|
||||
|
||||
message_id = run(
|
||||
str(tamq), "send", "@activity-core:", "installed-message"
|
||||
).stdout.strip()
|
||||
deadline = time.monotonic() + 5
|
||||
history = []
|
||||
while time.monotonic() < deadline:
|
||||
history = [
|
||||
json.loads(line)
|
||||
for line in run(str(tamq), "history", "--repo", "activity-core").stdout.splitlines()
|
||||
]
|
||||
if history and history[-1]["state"] == "injected":
|
||||
break
|
||||
time.sleep(0.05)
|
||||
assert history[-1]["message_id"] == message_id
|
||||
assert history[-1]["state"] == "injected"
|
||||
status = json.loads(run(str(tamq), "status").stdout)
|
||||
assert status["service"] is True
|
||||
assert [item["endpoint_id"] for item in status["endpoints"]] == [started["instance_id"]]
|
||||
assert run(str(tamq), "stop").returncode == 0
|
||||
finally:
|
||||
subprocess.run(
|
||||
[str(tamq), "stop"],
|
||||
cwd=tmp_path,
|
||||
env=env,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
timeout=5,
|
||||
)
|
||||
subprocess.run(
|
||||
[*tmux, "kill-server"],
|
||||
env=env,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue