mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 05:50:44 +08:00
Block CLI/inventory until ume_alarm_xlsx_report (or aggregate) succeeds, and return job_id for big NE batches via get_ne_exec_job. Co-authored-by: Cursor <cursoragent@cursor.com>
110 lines
3.4 KiB
Python
110 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
import time
|
|
from pathlib import Path
|
|
|
|
from runtime.chat.ops_report_first_guard import (
|
|
maybe_block_cli_before_report,
|
|
report_first_block_payload,
|
|
)
|
|
from svc.jobs.ne_exec_jobs import (
|
|
count_exec_ne_targets,
|
|
get_ne_exec_job,
|
|
should_run_exec_managed_ne_async,
|
|
start_ne_exec_job,
|
|
strip_async_flag,
|
|
)
|
|
|
|
|
|
def test_report_first_blocks_cli_before_report() -> None:
|
|
blocked = maybe_block_cli_before_report(
|
|
tool_name="mcp__netx__execManagedNe",
|
|
intent="fiber_cut",
|
|
store=None,
|
|
session_id="",
|
|
turn_uuid="",
|
|
lang="en",
|
|
local_report_ok=False,
|
|
)
|
|
assert blocked is not None
|
|
assert blocked["error_code"] == "report_first_required"
|
|
assert blocked["next_tool"] == "ume_alarm_xlsx_report"
|
|
|
|
|
|
def test_report_first_allows_after_local_ok() -> None:
|
|
assert (
|
|
maybe_block_cli_before_report(
|
|
tool_name="mcp__netx__listCliTargets",
|
|
intent="offline",
|
|
store=None,
|
|
session_id="s",
|
|
turn_uuid="t",
|
|
local_report_ok=True,
|
|
)
|
|
is None
|
|
)
|
|
|
|
|
|
def test_report_first_ignores_non_report_intents() -> None:
|
|
assert (
|
|
maybe_block_cli_before_report(
|
|
tool_name="mcp__netx__execManagedNe",
|
|
intent="continue",
|
|
store=None,
|
|
session_id="",
|
|
turn_uuid="",
|
|
local_report_ok=False,
|
|
)
|
|
is None
|
|
)
|
|
|
|
|
|
def test_report_first_payload_zh() -> None:
|
|
out = report_first_block_payload(intent="fiber_cut", lang="zh")
|
|
assert "ume_alarm_xlsx_report" in out["hint"]
|
|
assert out["example"].get("mode") == "fiber_cut"
|
|
|
|
|
|
def test_should_async_by_ne_count(monkeypatch) -> None:
|
|
monkeypatch.setenv("AIA_EXEC_MANAGED_NE_ASYNC_MIN_NES", "4")
|
|
assert not should_run_exec_managed_ne_async({"ume_ne_ids": ["a", "b", "c"], "commands": ["show"]})
|
|
assert should_run_exec_managed_ne_async({"ume_ne_ids": ["a", "b", "c", "d"], "commands": ["show"]})
|
|
assert should_run_exec_managed_ne_async({"async": True, "ume_ne_id": "x", "commands": ["show"]})
|
|
assert not should_run_exec_managed_ne_async(
|
|
{"async": False, "ume_ne_ids": ["a", "b", "c", "d", "e"], "commands": ["show"]}
|
|
)
|
|
|
|
|
|
def test_count_and_strip_async() -> None:
|
|
assert count_exec_ne_targets({"targets": [{"ume_ne_id": "1", "commands": ["a"]}, {"ne_id": "2", "commands": ["b"]}]}) == 2
|
|
assert "async" not in strip_async_flag({"async": True, "commands": ["x"]})
|
|
|
|
|
|
def test_ne_exec_job_roundtrip(tmp_path: Path, monkeypatch) -> None:
|
|
monkeypatch.setenv("AIA_NE_EXEC_JOB_DIR", str(tmp_path))
|
|
|
|
def _runner() -> dict:
|
|
time.sleep(0.05)
|
|
return {"ok": True, "data": {"results": [1]}}
|
|
|
|
ack = start_ne_exec_job(
|
|
tool_name="mcp__netx__execManagedNe",
|
|
arguments={"ume_ne_ids": ["a", "b", "c", "d"], "commands": ["show version"]},
|
|
runner=_runner,
|
|
session_id="sess",
|
|
)
|
|
assert ack["ok"] is True
|
|
assert ack["async"] is True
|
|
jid = ack["job_id"]
|
|
deadline = time.time() + 2.0
|
|
status = ""
|
|
while time.time() < deadline:
|
|
polled = get_ne_exec_job(jid)
|
|
status = str(polled.get("status") or "")
|
|
if status in {"succeeded", "failed", "timeout"}:
|
|
break
|
|
time.sleep(0.05)
|
|
assert status == "succeeded"
|
|
done = get_ne_exec_job(jid)
|
|
assert done["terminal"] is True
|
|
assert done["result"]["ok"] is True
|