feat: 实现 CaseRun HWPOD 执行合同

This commit is contained in:
root
2026-07-16 16:08:05 +02:00
parent 324bb9d2e4
commit 814ea533f3
8 changed files with 147 additions and 49 deletions
+9 -3
View File
@@ -666,10 +666,16 @@ class NodeOpsExecutor:
data = status_body.get("data") if isinstance(status_body.get("data"), dict) else {}
active_port = str(data.get("port") or "")
active_baud = data.get("baudRate")
monitor_start = None
matches = status.get("ok") and status_body.get("success") is True and data.get("isMonitoring") is True and (not port or active_port.lower() == port.lower()) and (not baud or int(active_baud or 0) == int(baud))
if not matches:
ports = self._spawn_output([*command_base, "ports"], serial_dir, timeout_ms)
return {"ok": False, "blockerCode": "hwpod_uart_monitor_not_active", "summary": f"io.uart.read requires serial-monitor to be active on {port or 'the requested UART'}{('/' + str(baud)) if baud else ''}", "details": {"requestedPort": port or None, "baudRate": baud, "serialMonitor": {"dir": str(serial_dir), "command": command_base, "monitorStatus": status_body or status, "ports": self._parse_json(ports.get("stdout")) or ports}}}
start_args = ["monitor", "start", *(["-p", port] if port else []), *(["-b", str(baud)] if baud else [])]
start = self._spawn_output([*command_base, *start_args], serial_dir, timeout_ms)
start_body = self._parse_json(start.get("stdout"))
monitor_start = start_body or start
if not start.get("ok") or start_body.get("success") is not True:
ports = self._spawn_output([*command_base, "ports"], serial_dir, timeout_ms)
return {"ok": False, "blockerCode": "hwpod_uart_monitor_start_failed", "summary": f"serial-monitor could not start on {port or 'the requested UART'}{('/' + str(baud)) if baud else ''}", "details": {"requestedPort": port or None, "baudRate": baud, "serialMonitor": {"dir": str(serial_dir), "command": command_base, "monitorStatus": status_body or status, "start": start_body or start, "ports": self._parse_json(ports.get("stdout")) or ports}}}
limit = max(1, min(safe_int(args.get("limit"), max(1, safe_int(args.get("maxBytes"), 4096) // 80)), 200))
fetch_args = ["fetch", "-l", str(limit), "--session-only"]
if args.get("since"):
@@ -681,7 +687,7 @@ class NodeOpsExecutor:
rows = fetch_body.get("data") if isinstance(fetch_body.get("data"), list) else []
text = "\n".join(str(row.get("data")) for row in rows if isinstance(row, dict) and row.get("data"))
max_bytes = safe_int(args.get("maxBytes"), 16384)
return {"ok": True, "bindingSource": "serial-monitor-cli", "serialMonitorDir": str(serial_dir), "requestedPort": port or None, "resolvedPort": active_port or port or None, "baudRate": baud or active_baud, "command": [*command_base, *fetch_args], "data": rows, "count": fetch_body.get("count", len(rows)), "totalCount": fetch_body.get("totalCount"), "hasMore": fetch_body.get("hasMore", False), "text": text[:max_bytes], "truncated": len(text) > max_bytes or fetch_body.get("truncated") is True, "monitorStatus": status_body, "sourceFile": fetch_body.get("sourceFile")}
return {"ok": True, "bindingSource": "serial-monitor-cli", "serialMonitorDir": str(serial_dir), "requestedPort": port or None, "resolvedPort": active_port or port or None, "baudRate": baud or active_baud, "command": [*command_base, *fetch_args], "data": rows, "count": fetch_body.get("count", len(rows)), "totalCount": fetch_body.get("totalCount"), "hasMore": fetch_body.get("hasMore", False), "text": text[:max_bytes], "truncated": len(text) > max_bytes or fetch_body.get("truncated") is True, "monitorStatus": status_body, "monitorStarted": not matches, "monitorStart": monitor_start, "sourceFile": fetch_body.get("sourceFile")}
def _parse_json(self, text: object) -> dict:
try: