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
192 lines
6.5 KiB
Python
192 lines
6.5 KiB
Python
from tamq.control import PaneDisplay
|
|
from tamq.service import Service
|
|
from tamq.store import Store
|
|
|
|
|
|
class FakeControl:
|
|
instances = []
|
|
|
|
def __init__(self, session):
|
|
self.session = session
|
|
self.injected = []
|
|
self.placed = []
|
|
self.submitted = []
|
|
self.__class__.instances.append(self)
|
|
|
|
def start(self):
|
|
return None
|
|
|
|
def session_exists(self, expected_pid=None):
|
|
return True
|
|
|
|
def inject(self, window, text):
|
|
self.injected.append((window, text))
|
|
|
|
def submit(self, window, text):
|
|
self.submitted.append((window, text))
|
|
|
|
def place(self, window, text):
|
|
self.placed.append((window, text))
|
|
|
|
def pane_display(self, window):
|
|
return PaneDisplay(
|
|
tty_path=f"/dev/pts/{window.rsplit(':', 1)[-1]}",
|
|
cursor_x=0,
|
|
cursor_y=0,
|
|
pane_height=24,
|
|
alternate_on=False,
|
|
)
|
|
|
|
def close(self):
|
|
return None
|
|
|
|
|
|
def test_service_delivery_injects_pending_messages(tmp_path, monkeypatch):
|
|
store = Store(tmp_path / "queue.sqlite3")
|
|
store.register_endpoint("tmux-amq-9-boot", 9, "tamq", ["repo-b"], "pane")
|
|
message_id = store.add("repo-a", "repo-b", "continue")
|
|
monkeypatch.setattr("tamq.service.ControlModeClient", FakeControl)
|
|
Service(store=store)._deliver_once()
|
|
assert FakeControl.instances[-1].injected == [("tamq:repo-b", "From:repo-a: continue")]
|
|
assert store.list()[0]["message_id"] == message_id
|
|
assert store.list()[0]["state"] == "injected"
|
|
|
|
|
|
def test_service_never_injects_manual_endpoint_messages(tmp_path, monkeypatch):
|
|
store = Store(tmp_path / "queue.sqlite3")
|
|
store.register_endpoint("tmux-amq-9-boot", 9, "tamq", ["repo-b"], "manual")
|
|
store.add("repo-a", "repo-b", "continue")
|
|
monkeypatch.setattr("tamq.service.ControlModeClient", FakeControl)
|
|
|
|
Service(store=store)._deliver_once()
|
|
|
|
assert FakeControl.instances[-1].injected == []
|
|
assert store.list()[0]["state"] == "pending"
|
|
|
|
|
|
def test_service_pushy_mode_places_once_without_enter(tmp_path, monkeypatch):
|
|
store = Store(tmp_path / "queue.sqlite3")
|
|
store.register_endpoint("tmux-amq-9-boot", 9, "tamq", ["repo-b"], "pushy")
|
|
message_id = store.add("repo-a", "repo-b", "first\nsecond")
|
|
monkeypatch.setattr("tamq.service.ControlModeClient", FakeControl)
|
|
service = Service(store=store, input_grace=0)
|
|
|
|
service._deliver_once()
|
|
control = FakeControl.instances[-1]
|
|
service._deliver_once()
|
|
|
|
assert control.placed == [
|
|
(
|
|
"tamq:repo-b",
|
|
"From:repo-a: first\nFrom:repo-a: second",
|
|
)
|
|
]
|
|
assert control.submitted == []
|
|
assert store.list()[0]["state"] == "injected"
|
|
|
|
|
|
def test_service_trigger_mode_submits_exactly_once(tmp_path, monkeypatch):
|
|
store = Store(tmp_path / "queue.sqlite3")
|
|
store.register_endpoint("ep", 9, "tamq", ["repo-b"], "trigger")
|
|
store.add("repo-a", "repo-b", "go", provenance="operator_input")
|
|
monkeypatch.setattr("tamq.service.ControlModeClient", FakeControl)
|
|
service = Service(store=store, input_grace=0)
|
|
service._deliver_once()
|
|
control = FakeControl.instances[-1]
|
|
service._deliver_once()
|
|
assert control.submitted == [("tamq:repo-b", "From:repo-a/o: go")]
|
|
assert control.placed == []
|
|
|
|
|
|
def test_failed_pushy_submission_remains_pending(tmp_path, monkeypatch):
|
|
store = Store(tmp_path / "queue.sqlite3")
|
|
store.register_endpoint("tmux-amq-9-boot", 9, "tamq", ["repo-b"], "pushy")
|
|
store.add("repo-a", "repo-b", "continue")
|
|
|
|
class FailingControl(FakeControl):
|
|
def place(self, window, text):
|
|
raise RuntimeError("tmux rejected input")
|
|
|
|
monkeypatch.setattr("tamq.service.ControlModeClient", FailingControl)
|
|
Service(store=store, input_grace=0)._deliver_once()
|
|
|
|
assert store.list()[0]["state"] == "pending"
|
|
|
|
|
|
def test_input_delivery_waits_for_new_endpoint_grace(tmp_path, monkeypatch):
|
|
store = Store(tmp_path / "queue.sqlite3")
|
|
store.register_endpoint("ep", 9, "tamq", ["repo-b"], "trigger")
|
|
store.add("repo-a", "repo-b", "first")
|
|
monkeypatch.setattr("tamq.service.ControlModeClient", FakeControl)
|
|
service = Service(store=store, input_grace=10)
|
|
|
|
service._deliver_once()
|
|
|
|
assert FakeControl.instances[-1].submitted == []
|
|
assert store.list()[0]["state"] == "pending"
|
|
|
|
|
|
def test_service_writes_output_once_and_retains_pending_ack(tmp_path, monkeypatch):
|
|
store = Store(tmp_path / "queue.sqlite3")
|
|
store.register_endpoint("tmux-amq-9-boot", 9, "tamq", ["repo-b"], "output")
|
|
message_id = store.add("repo-a", "repo-b", "continue")
|
|
writes = []
|
|
monkeypatch.setattr("tamq.service.ControlModeClient", FakeControl)
|
|
monkeypatch.setattr(
|
|
"tamq.service.write_terminal_output",
|
|
lambda path, text: writes.append((path, text)),
|
|
)
|
|
service = Service(store=store)
|
|
|
|
service._deliver_once()
|
|
service._deliver_once()
|
|
|
|
assert writes == [
|
|
(
|
|
"/dev/pts/repo-b",
|
|
"\r\nFrom:repo-a: continue\r\n",
|
|
)
|
|
]
|
|
row = store.list()[0]
|
|
assert row["state"] == "pending"
|
|
assert row["displayed_at"] is not None
|
|
assert store.db.execute("SELECT COUNT(*) FROM leases").fetchone()[0] == 0
|
|
|
|
|
|
def test_failed_terminal_output_remains_undisplayed_and_retryable(tmp_path, monkeypatch):
|
|
store = Store(tmp_path / "queue.sqlite3")
|
|
store.register_endpoint("tmux-amq-9-boot", 9, "tamq", ["repo-b"], "output")
|
|
store.add("repo-a", "repo-b", "continue")
|
|
attempts = []
|
|
monkeypatch.setattr("tamq.service.ControlModeClient", FakeControl)
|
|
|
|
def fail_once(path, text):
|
|
attempts.append((path, text))
|
|
if len(attempts) == 1:
|
|
raise OSError("temporary failure")
|
|
|
|
monkeypatch.setattr("tamq.service.write_terminal_output", fail_once)
|
|
service = Service(store=store)
|
|
|
|
service._deliver_once()
|
|
assert store.list()[0]["displayed_at"] is None
|
|
store.db.execute("UPDATE leases SET expires_at=0")
|
|
store.db.commit()
|
|
service._deliver_once()
|
|
|
|
assert len(attempts) == 2
|
|
assert store.list()[0]["displayed_at"] is not None
|
|
|
|
|
|
def test_service_disconnects_disappeared_tmux_endpoint(tmp_path, monkeypatch):
|
|
store = Store(tmp_path / "queue.sqlite3")
|
|
store.register_endpoint("tmux-amq-9-boot", 9, "tamq", ["repo-b"])
|
|
|
|
class MissingControl(FakeControl):
|
|
def session_exists(self, expected_pid=None):
|
|
assert expected_pid == 9
|
|
return False
|
|
|
|
monkeypatch.setattr("tamq.service.ControlModeClient", MissingControl)
|
|
Service(store=store)._deliver_once()
|
|
assert store.endpoints() == []
|