Complete name-first 1C adapter saved-state support
This commit is contained in:
@@ -12,6 +12,17 @@ from urllib.error import HTTPError, URLError
|
||||
DEFAULT_BASE_URL = "http://docker-gpu.cin.su:8011"
|
||||
DEFAULT_MCP_URL = "http://docker.cin.su:8021"
|
||||
EXPECTED_CONTRACT_VERSION = "onec-selector-contract.v1"
|
||||
PREFLIGHT_CLASSIFICATION_STATUSES = {
|
||||
"ready",
|
||||
"needs_prepare",
|
||||
"needs_resolution",
|
||||
"needs_repository_lock",
|
||||
"blocked",
|
||||
"blocked_by_support",
|
||||
"blocked_by_support_live_sql",
|
||||
"blocked_by_support_rule",
|
||||
"blocked_support_unknown",
|
||||
}
|
||||
|
||||
|
||||
def post_json(url: str, payload: dict[str, Any], *, timeout: float, headers: dict[str, str] | None = None) -> tuple[dict[str, str], dict[str, Any]]:
|
||||
@@ -106,6 +117,10 @@ def require(condition: bool, message: str, failures: list[str]) -> None:
|
||||
failures.append(message)
|
||||
|
||||
|
||||
def classified_preflight_status(value: Any) -> bool:
|
||||
return str(value or "") in PREFLIGHT_CLASSIFICATION_STATUSES
|
||||
|
||||
|
||||
def method_names(help_result: dict[str, Any]) -> set[str]:
|
||||
return {str(item.get("name") or "") for item in help_result.get("methods") or [] if isinstance(item, dict)}
|
||||
|
||||
@@ -120,13 +135,24 @@ def first_saved_module_target(endpoint_url: str, base_id: str, timeout: float, *
|
||||
session_id=session_id,
|
||||
)
|
||||
modules = result.get("modules") if isinstance(result.get("modules"), list) else []
|
||||
targets: list[dict[str, Any]] = []
|
||||
for module in modules:
|
||||
if not isinstance(module, dict):
|
||||
continue
|
||||
for stream in module.get("streams") or []:
|
||||
if isinstance(stream, dict) and isinstance(stream.get("write_plan_target"), dict):
|
||||
return stream["write_plan_target"]
|
||||
return None
|
||||
targets.append(stream["write_plan_target"])
|
||||
# A concrete stream target can be freshness-checked without decoding and
|
||||
# structurally diffing a whole saved form descriptor. Prefer it so this
|
||||
# deployment smoke remains bounded on large ConfigCASSave forms.
|
||||
return next(
|
||||
(
|
||||
target
|
||||
for target in targets
|
||||
if target.get("stream_index") is not None or "#stream:" in str(target.get("module_ref") or "")
|
||||
),
|
||||
targets[0] if targets else None,
|
||||
)
|
||||
|
||||
|
||||
def run_smoke(endpoint_url: str, base_id: str, timeout: float, *, transport: str) -> dict[str, Any]:
|
||||
@@ -173,7 +199,7 @@ def run_smoke(endpoint_url: str, base_id: str, timeout: float, *, transport: str
|
||||
"plan_allowed": (blocked.get("plan") or {}).get("allowed") if isinstance(blocked.get("plan"), dict) else None,
|
||||
}
|
||||
require(blocked.get("schema") == "onec_metadata_write_preflight.v1", "preflight must return expected schema", failures)
|
||||
require(blocked.get("status") in {"blocked", "needs_resolution"}, "effective path preflight must be blocked or need resolution", failures)
|
||||
require(classified_preflight_status(blocked.get("status")), "effective path preflight must classify readiness or a safety gate", failures)
|
||||
require(blocked.get("allowed") is False, "effective path preflight must not be allowed", failures)
|
||||
|
||||
target = first_saved_module_target(endpoint_url, base_id, timeout, transport=transport, session_id=session_id)
|
||||
@@ -201,7 +227,7 @@ def run_smoke(endpoint_url: str, base_id: str, timeout: float, *, transport: str
|
||||
"writer": (concrete.get("route") or {}).get("writer") if isinstance(concrete.get("route"), dict) else None,
|
||||
}
|
||||
require(concrete.get("schema") == "onec_metadata_write_preflight.v1", "concrete preflight must return expected schema", failures)
|
||||
require(concrete.get("status") in {"ready", "needs_prepare", "blocked"}, "concrete preflight must classify readiness", failures)
|
||||
require(classified_preflight_status(concrete.get("status")), "concrete preflight must classify readiness or a safety gate", failures)
|
||||
if concrete.get("status") == "ready":
|
||||
require(freshness.get("status") == "live_sql_verified", "ready concrete preflight must be live SQL verified", failures)
|
||||
else:
|
||||
@@ -230,7 +256,18 @@ def main() -> int:
|
||||
args = parser.parse_args()
|
||||
|
||||
endpoint_url = args.mcp_url if args.transport == "mcp" else args.base_url
|
||||
report = run_smoke(endpoint_url, args.base_id, args.timeout, transport=args.transport)
|
||||
try:
|
||||
report = run_smoke(endpoint_url, args.base_id, args.timeout, transport=args.transport)
|
||||
except (TimeoutError, URLError, OSError) as exc:
|
||||
report = {
|
||||
"schema": "onec_write_preflight_smoke.v1",
|
||||
"status": "failed",
|
||||
"endpoint_url": endpoint_url,
|
||||
"transport": args.transport,
|
||||
"base_id": args.base_id,
|
||||
"checks": {},
|
||||
"failures": [f"transport timeout/error: {type(exc).__name__}: {str(exc)[:300]}"],
|
||||
}
|
||||
if args.report:
|
||||
args.report.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.report.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
Reference in New Issue
Block a user