sdlc-hub/tests/test_agents.py
Andrey Epifancev 43c43ade81 Миграция v7: токены и статус по агентам модулей (#91)
tokens -> {client, agents: {модуль: токен}}, agent_status по агентам
(ключ agent, last_call_at), настройки агента и маршруты agent-scope по
модулю токена, min_agent_version переехал в модуль jira.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 00:45:44 +04:00

94 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Агенты модулей: токен определяет модуль, миграция v7 сохраняет агента jira (wiki-module, решения 1–3, 6, 15)."""
import pytest
from jira_hub.core import cli, db, queue, settings
from jira_hub.core.client import HubError
from v6db import make_v6_db
def test_v6_upgrade_keeps_jira_agent(tmp_path):
make_v6_db(tmp_path / "hub.sqlite")
conn = db.connect(tmp_path / "hub.sqlite")
try:
assert db._schema_version(conn) == 7
tok = settings.tokens(conn)
assert tok["client"] == "T-client" and tok["agents"]["jira"] == "T-agent" and "agent" not in tok
row = conn.execute("SELECT * FROM agent_status WHERE agent = 'jira'").fetchone()
assert row["agent_version"] == "14"
assert conn.execute("SELECT COUNT(*) AS n FROM agent_status").fetchone()["n"] == 1
assert list((tmp_path / "backups").glob("*schema-v6*")) # копия перед миграцией
finally:
conn.close()
def test_v6_upgrade_keeps_settings_and_projects(tmp_path):
make_v6_db(tmp_path / "hub.sqlite")
conn = db.connect(tmp_path / "hub.sqlite")
try:
assert settings.get(conn, "min_agent_version") == 1
rows = conn.execute("SELECT label, board_id, board_type FROM project ORDER BY label").fetchall()
assert [tuple(r) for r in rows] == [("AWPCA", 4216, "scrum"), ("sfm_kedr", None, None)]
finally:
conn.close()
def test_migrate_adds_status_row_for_new_agent_module(conn_two_modules):
"""R-1: строки agent_status для модулей реестра вставляются при каждом migrate, а не только в шаге 6 → 7."""
names = {r["agent"] for r in conn_two_modules.execute("SELECT agent FROM agent_status")}
assert names == {"jira", "stub"}
def test_ensure_defaults_adds_missing_agent_token(conn_two_modules):
tok = settings.tokens(conn_two_modules)
assert set(tok["agents"]) == {"jira", "stub"} and tok["agents"]["jira"] != tok["agents"]["stub"]
def test_agent_token_routes(hub_server):
assert hub_server["agent"].post("/agent/claim", {})["command"] is None
assert hub_server["agent"].get("/agent/settings")["settings_version"] >= 1
with pytest.raises(HubError) as e:
hub_server["client"].post("/agent/claim", {})
assert e.value.status == 401
def test_module_agent_route_requires_own_module(hub_server_two_modules):
jira, stub = hub_server_two_modules["agents"]["jira"], hub_server_two_modules["agents"]["stub"]
with pytest.raises(HubError) as e:
stub.post("/agent/state", {})
assert e.value.status == 401
with pytest.raises(HubError) as e:
jira.post("/agent/stub", {})
assert e.value.status == 401
assert stub.post("/agent/stub", {}) == {"agent": "stub"}
assert jira.post("/agent/claim", {})["command"] is None # маршруты ядра открыты обоим агентам
assert stub.post("/agent/claim", {})["command"] is None
def test_agent_settings_per_module(hub_server_two_modules):
jira = hub_server_two_modules["agents"]["jira"].get("/agent/settings")
stub = hub_server_two_modules["agents"]["stub"].get("/agent/settings")
assert "project_key" in jira and "transitions_map" in jira and "settings_version" in jira
assert "stub_key" not in jira and "board_id" not in jira
assert set(stub) == {"stub_key", "settings_version"}
def test_agent_query_cannot_be_forged(hub_server_two_modules):
"""Служебный ключ запроса приходит только от диспетчера: _agent в адресе перезаписывается."""
stub = hub_server_two_modules["agents"]["stub"]
assert stub.call("POST", "/agent/stub", {}, params={"_agent": "jira"}) == {"agent": "stub"}
def test_tokens_cli_lists_agents(tmp_path, monkeypatch, capsys):
monkeypatch.setenv("JIRA_HUB_HOME", str(tmp_path))
assert cli.main(["tokens"]) == 0
lines = capsys.readouterr().out.splitlines()
assert lines[0].startswith("клиентский токен: ") and lines[1].startswith("агент jira: ")
assert lines[2].startswith("база: ")
def test_agent_view_min_version_from_module_key(conn_two_modules):
conn_two_modules.execute("UPDATE agent_status SET agent_version = '3' WHERE agent = 'jira'")
settings.set_(conn_two_modules, "min_agent_version", 5)
assert queue.agent_view(conn_two_modules, "jira")["warning"] == "обновите агента"
assert queue.agent_view(conn_two_modules, "stub")["warning"] is None