85 lines
3.6 KiB
Python
85 lines
3.6 KiB
Python
"""Ядро очереди на модуле-заглушке: механика не знает типов команд jira (hub-modules, решение 4)."""
|
|
import os
|
|
import time
|
|
from dataclasses import replace
|
|
|
|
import pytest
|
|
|
|
from sdlc_hub.core import files, queue, registry
|
|
from sdlc_hub.core.errors import CommandError
|
|
from sdlc_hub.core.modules import CommandHooks, Module
|
|
from sdlc_hub.modules import jira
|
|
|
|
SHA = "a" * 64
|
|
|
|
|
|
def _validate(cmds):
|
|
return [{"type": c["type"], "params": c.get("params") or {}} for c in cmds]
|
|
|
|
|
|
def make_stub(events, refs=()):
|
|
hooks = CommandHooks(
|
|
types=frozenset({"w", "r"}), read_types=frozenset({"r"}), validate=_validate,
|
|
check_batch=lambda conn, cmds, project, files_dir: cmds,
|
|
tail=lambda conn, cmds, project: {"type": "r", "params": {}} if any(c["type"] == "w" for c in cmds) else None,
|
|
pause=lambda conn, ctype: 7, deliver_params=lambda conn, cmd, files_dir: cmd["params"],
|
|
temp_definer=None, temp_keys_used=lambda cmd: [], substitute=lambda t, p, m: p,
|
|
drop_unresolved=lambda cmd, unresolved: unresolved, retry_params=lambda cmd: cmd["params"],
|
|
check_confirmed=lambda conn, cmd: (False, None), on_claim=lambda *a: None, on_failed=lambda *a: None,
|
|
check_result=lambda conn, cmd, status, result, files_dir: (status, None),
|
|
on_result=lambda conn, cmd, status, *a: events.append(("on_result", cmd["type"], status)),
|
|
after_result=lambda conn, cmd, status: events.append(("after_result", cmd["type"], status)),
|
|
on_late_result=lambda *a: False)
|
|
return Module(name="t", commands=hooks, file_refs=lambda conn: set(refs))
|
|
|
|
|
|
@pytest.fixture
|
|
def stub(monkeypatch):
|
|
events = []
|
|
monkeypatch.setattr(registry, "_cache", [jira.MODULE, make_stub(events)])
|
|
return events
|
|
|
|
|
|
def test_tail_and_estimate(open_db, stub):
|
|
conn = open_db()
|
|
b = queue.create_batch(conn, "x", "claude", [{"type": "w", "params": {}}])
|
|
assert [c["type"] for c in queue.batch_view(conn, b["id"])["commands"]] == ["w", "r"]
|
|
assert b["estimate_seconds"] == 14 and queue.estimate(conn, ["w", "r"]) == 14
|
|
|
|
|
|
def test_mixed_modules(open_db, stub):
|
|
conn = open_db()
|
|
with pytest.raises(CommandError, match="команды разных модулей в одном пакете"):
|
|
queue.create_batch(conn, "x", "claude", [{"type": "w"}, {"type": "refresh", "params": {"jql": "x"}}])
|
|
|
|
|
|
def test_on_result_called(tmp_path, open_db, stub):
|
|
path = tmp_path / "hub.sqlite"
|
|
conn = open_db(path)
|
|
queue.create_batch(conn, "x", "claude", [{"type": "w", "params": {}}])
|
|
cmd = queue.claim(conn, "t")
|
|
seen = {}
|
|
real = stub.append
|
|
|
|
def after(conn_, cmd_, status):
|
|
other = open_db(path) # новое соединение видит зафиксированное
|
|
seen["status"] = other.execute("SELECT status FROM command WHERE id = ?", (cmd_["id"],)).fetchone()["status"]
|
|
real(("after_result", cmd_["type"], status))
|
|
|
|
hooks = replace(registry.module("t").commands, after_result=after)
|
|
registry._cache[1] = replace(registry.module("t"), commands=hooks)
|
|
queue.report_result(conn, cmd["id"], "done", {})
|
|
assert ("on_result", "w", "done") in stub and ("after_result", "w", "done") in stub
|
|
assert seen["status"] == "done"
|
|
|
|
|
|
def test_sweep_uses_file_refs(tmp_path, open_db, monkeypatch):
|
|
monkeypatch.setattr(registry, "_cache", [jira.MODULE, make_stub([], refs={SHA})])
|
|
root = tmp_path / "files"
|
|
root.mkdir()
|
|
(root / SHA).write_bytes(b"x")
|
|
old = time.time() - 40 * 86400
|
|
os.utime(root / SHA, (old, old))
|
|
assert files.sweep(open_db(), root) == []
|
|
assert (root / SHA).exists()
|