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
257 lines
8.8 KiB
Python
257 lines
8.8 KiB
Python
import json
|
|
|
|
from tamq.cli import build_parser, main, normalize_argv
|
|
import pytest
|
|
|
|
|
|
def test_help_and_version(capsys):
|
|
with pytest.raises(SystemExit) as exc:
|
|
main(["--version"])
|
|
assert exc.value.code == 0
|
|
assert "0.1.0" in capsys.readouterr().out
|
|
assert main([]) == 0
|
|
assert "usage:" in capsys.readouterr().out
|
|
|
|
|
|
def test_root_help_exposes_repository_shorthand_and_command(capsys):
|
|
with pytest.raises(SystemExit) as exc:
|
|
main(["--help"])
|
|
assert exc.value.code == 0
|
|
output = capsys.readouterr().out
|
|
assert "tamq [--detach] [--command COMMAND] [--mode MODE] REPO" in output
|
|
assert "With no --command" in output
|
|
assert "@TARGET: MESSAGE" in output
|
|
|
|
|
|
def test_attach_delegates_to_tmux(monkeypatch):
|
|
calls = []
|
|
monkeypatch.delenv("TMUX", raising=False)
|
|
monkeypatch.setattr("tamq.cli.subprocess.run", lambda args, check=False: calls.append((args, check)) or type("R", (), {"returncode": 0})())
|
|
assert main(["attach", "--session", "demo"]) == 0
|
|
assert calls == [(["tmux", "attach-session", "-t", "demo"], False)]
|
|
|
|
|
|
def test_attach_switches_client_when_already_in_tmux(monkeypatch):
|
|
calls = []
|
|
monkeypatch.setenv("TMUX", "/tmp/tmux,1,0")
|
|
monkeypatch.setattr("tamq.cli.subprocess.run", lambda args, check=False: calls.append(args) or type("R", (), {"returncode": 0})())
|
|
assert main(["attach"]) == 0
|
|
assert calls == [["tmux", "switch-client", "-t", "tamq"]]
|
|
|
|
|
|
def test_start_parser_supports_command_and_cmd_alias():
|
|
parser = build_parser()
|
|
canonical = parser.parse_args(["start", "--command", "codex --quiet", "a", "b"])
|
|
compatibility = parser.parse_args(["start", "--cmd", "claude", "a"])
|
|
neutral = parser.parse_args(["start", "a", "b"])
|
|
inbox_only = parser.parse_args(["start", "--no-display", "a"])
|
|
pushy = parser.parse_args(["start", "--mode", "pushy", "a"])
|
|
assert canonical.initial_command == "codex --quiet"
|
|
assert canonical.repos == ["a", "b"]
|
|
assert compatibility.initial_command == "claude"
|
|
assert neutral.initial_command is None
|
|
assert inbox_only.no_display is True
|
|
assert pushy.mode == "pushy"
|
|
|
|
|
|
def test_repository_first_and_command_first_start_shorthand():
|
|
assert normalize_argv(["flex-auth", "audit-core"]) == [
|
|
"start",
|
|
"flex-auth",
|
|
"audit-core",
|
|
]
|
|
assert normalize_argv(["--command", "codex", "flex-auth"]) == [
|
|
"start",
|
|
"--command",
|
|
"codex",
|
|
"flex-auth",
|
|
]
|
|
assert normalize_argv(["--no-display", "flex-auth"]) == [
|
|
"start",
|
|
"--no-display",
|
|
"flex-auth",
|
|
]
|
|
assert normalize_argv(["--mode", "pushy", "flex-auth"]) == [
|
|
"start",
|
|
"--mode",
|
|
"pushy",
|
|
"flex-auth",
|
|
]
|
|
assert normalize_argv(["--mode=pushy", "flex-auth"]) == [
|
|
"start",
|
|
"--mode=pushy",
|
|
"flex-auth",
|
|
]
|
|
assert normalize_argv(["status"]) == ["status"]
|
|
assert normalize_argv(["--verbose", "flex-auth", "audit-core"]) == [
|
|
"--verbose",
|
|
"start",
|
|
"flex-auth",
|
|
"audit-core",
|
|
]
|
|
|
|
|
|
def test_detached_no_service_start_skips_socket_registration(monkeypatch, capsys):
|
|
endpoint = type(
|
|
"Endpoint",
|
|
(),
|
|
{
|
|
"endpoint_id": "tmux-amq-42",
|
|
"instance_key": "tmux-amq-42-boot",
|
|
"pid": 42,
|
|
"session": "tamq",
|
|
"repos": ["a", "b"],
|
|
},
|
|
)()
|
|
|
|
class Manager:
|
|
def preflight(self, repos, command):
|
|
assert repos == ["a", "b"]
|
|
assert command is None
|
|
return "plan"
|
|
|
|
def ensure_plan(self, plan, *, tap=True):
|
|
assert plan == "plan"
|
|
assert tap is False
|
|
return endpoint
|
|
|
|
monkeypatch.setattr("tamq.cli.TmuxManager", Manager)
|
|
monkeypatch.setattr("tamq.cli.preflight_runtime_paths", lambda: None)
|
|
monkeypatch.setattr("tamq.cli.request", lambda payload: pytest.fail("socket request must not run"))
|
|
monkeypatch.setattr("tamq.cli.attach_session", lambda session: pytest.fail("detached start must not attach"))
|
|
assert main(["start", "--detach", "--no-service", "a", "b"]) == 0
|
|
summary = json.loads(capsys.readouterr().out)
|
|
assert summary["service"] is False
|
|
assert summary["messaging"] is False
|
|
assert summary["repos"] == ["a", "b"]
|
|
|
|
|
|
def test_interactive_no_service_start_attaches(monkeypatch, capsys):
|
|
endpoint = type(
|
|
"Endpoint",
|
|
(),
|
|
{
|
|
"endpoint_id": "tmux-amq-42",
|
|
"instance_key": "tmux-amq-42-boot",
|
|
"session": "tamq",
|
|
"repos": ["a"],
|
|
},
|
|
)()
|
|
|
|
class Manager:
|
|
def preflight(self, repos, command):
|
|
return "plan"
|
|
|
|
def ensure_plan(self, plan, *, tap=True):
|
|
assert tap is False
|
|
return endpoint
|
|
|
|
attached = []
|
|
monkeypatch.setattr("tamq.cli.TmuxManager", Manager)
|
|
monkeypatch.setattr("tamq.cli.preflight_runtime_paths", lambda: None)
|
|
monkeypatch.setattr("tamq.cli.attach_session", lambda session: attached.append(session) or 0)
|
|
assert main(["start", "--no-service", "a"]) == 0
|
|
assert attached == ["tamq"]
|
|
assert json.loads(capsys.readouterr().out)["repos"] == ["a"]
|
|
|
|
|
|
def test_registration_failure_rolls_back_created_windows(monkeypatch, capsys):
|
|
endpoint = type(
|
|
"Endpoint",
|
|
(),
|
|
{
|
|
"endpoint_id": "tmux-amq-42",
|
|
"instance_key": "tmux-amq-42-boot",
|
|
"pid": 42,
|
|
"session": "tamq",
|
|
"repos": ["a"],
|
|
},
|
|
)()
|
|
rolled_back = []
|
|
|
|
class Manager:
|
|
def preflight(self, repos, command):
|
|
return "plan"
|
|
|
|
def ensure_plan(self, plan, *, tap=True):
|
|
assert tap is False
|
|
return endpoint
|
|
|
|
def rollback(self, value):
|
|
rolled_back.append(value)
|
|
|
|
async def failed_registration(payload):
|
|
return {"ok": False, "error": "denied"}
|
|
|
|
monkeypatch.setattr("tamq.cli.TmuxManager", Manager)
|
|
monkeypatch.setattr("tamq.cli.preflight_runtime_paths", lambda: None)
|
|
monkeypatch.setattr("tamq.cli.ensure_output_service", lambda: True)
|
|
monkeypatch.setattr("tamq.cli.request", failed_registration)
|
|
assert main(["start", "--detach", "a"]) == 1
|
|
assert rolled_back == [endpoint]
|
|
assert "endpoint registration failed: denied" in capsys.readouterr().err
|
|
|
|
|
|
def test_pushy_mode_registers_explicit_delivery_mode(monkeypatch, capsys):
|
|
endpoint = type(
|
|
"Endpoint",
|
|
(),
|
|
{
|
|
"endpoint_id": "tmux-amq-42",
|
|
"instance_key": "tmux-amq-42-boot",
|
|
"pid": 42,
|
|
"session": "tamq",
|
|
"repos": ["a", "b"],
|
|
},
|
|
)()
|
|
requests = []
|
|
|
|
class Manager:
|
|
def preflight(self, repos, command):
|
|
assert repos == ["a", "b"]
|
|
assert command == "codex"
|
|
return "plan"
|
|
|
|
def ensure_plan(self, plan, *, tap=True):
|
|
assert tap is True
|
|
return endpoint
|
|
|
|
def rollback(self, value):
|
|
pytest.fail("successful registration must not roll back")
|
|
|
|
async def register(payload):
|
|
requests.append(payload)
|
|
return {"ok": True}
|
|
|
|
monkeypatch.setattr("tamq.cli.TmuxManager", Manager)
|
|
monkeypatch.setattr("tamq.cli.preflight_runtime_paths", lambda: None)
|
|
monkeypatch.setattr("tamq.cli.ensure_pushy_service", lambda: True)
|
|
monkeypatch.setattr(
|
|
"tamq.cli.ensure_output_service",
|
|
lambda: pytest.fail("output capability must not select pushy mode"),
|
|
)
|
|
monkeypatch.setattr("tamq.cli.request", register)
|
|
|
|
assert main([
|
|
"start", "--detach", "--mode", "pushy", "--command", "codex", "a", "b"
|
|
]) == 0
|
|
summary = json.loads(capsys.readouterr().out)
|
|
assert summary["mode"] == "pushy"
|
|
assert summary["delivery_mode"] == "pushy"
|
|
assert summary["input_observation_requested"] is True
|
|
assert requests[0]["delivery_mode"] == "pushy"
|
|
|
|
|
|
def test_tap_requires_explicit_command_and_service(capsys):
|
|
assert main(["start", "--tap", "a"]) == 2
|
|
assert "--tap requires an explicit --command" in capsys.readouterr().err
|
|
assert main(["start", "--tap", "--no-service", "--command", "sh", "a"]) == 2
|
|
assert "--tap cannot be combined with --no-service" in capsys.readouterr().err
|
|
assert main(["start", "--tap", "--no-display", "--command", "sh", "a"]) == 2
|
|
assert "--tap cannot be combined with --no-display" in capsys.readouterr().err
|
|
assert main(["start", "--no-display", "--mode", "pushy", "a"]) == 2
|
|
assert "conflicts with the selected --mode" in capsys.readouterr().err
|
|
assert main(["start", "--tap", "--mode", "pushy", "--command", "sh", "a"]) == 2
|
|
assert "--tap cannot be combined with --mode" in capsys.readouterr().err
|
|
assert main(["start", "--no-service", "--mode", "pushy", "a"]) == 2
|
|
assert "--mode cannot be combined with --no-service" in capsys.readouterr().err
|