#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" # shellcheck disable=SC1091 source "$ROOT_DIR/scripts/acceptance/route_acceptance_lib.sh" CRM_BASE="${CRM_BASE:-https://sub.tksea.top/portal-admin-api}" TS="${TS:-$(timestamp_token)}" ARTIFACT_DIR="${ARTIFACT_DIR:-$ROUTE_MATRIX_ROOT/${TS}_route_control_plane}" GROUP_ID="${GROUP_ID:-p2t4-cp-${TS}}" ROUTE_ID="${ROUTE_ID:-primary-${TS}}" PUBLIC_MODEL="${PUBLIC_MODEL:-gpt-5.4}" SHADOW_MODEL="${SHADOW_MODEL:-gpt-5.4}" SHADOW_HOST_ID="${SHADOW_HOST_ID:-shadow-host-${TS}}" SHADOW_GROUP_ID="${SHADOW_GROUP_ID:-shadow-group-${TS}}" crm_auth_init ensure_artifact_dir create_group_payload="$(python3 - "$GROUP_ID" <<'PY' import json, sys group_id = sys.argv[1] print(json.dumps({ "logical_group_id": group_id, "display_name": f"P2T4 Control Plane {group_id}", "status": "active", "description": "P2-T4 control plane verification group", "route_policy": "priority", "sticky_mode": "conversation_preferred", "conversation_ttl_seconds": 1200, "user_model_ttl_seconds": 600, "failover_threshold": 2, "cooldown_seconds": 300, }, ensure_ascii=False)) PY )" save_json 01-create-group "$(crm_curl_json POST "/api/logical-groups" "$create_group_payload")" add_model_payload="$(python3 - "$PUBLIC_MODEL" <<'PY' import json, sys print(json.dumps({"public_model": sys.argv[1], "status": "active"}, ensure_ascii=False)) PY )" save_json 02-add-group-model "$(crm_curl_json POST "/api/logical-groups/$GROUP_ID/models" "$add_model_payload")" create_route_payload="$(python3 - "$ROUTE_ID" "$SHADOW_GROUP_ID" "$SHADOW_HOST_ID" <<'PY' import json, sys route_id, shadow_group_id, shadow_host_id = sys.argv[1:4] print(json.dumps({ "route_id": route_id, "name": f"Primary {route_id}", "status": "active", "priority": 10, "weight": 100, "shadow_group_id": shadow_group_id, "shadow_host_id": shadow_host_id, "upstream_base_url_hint": "https://primary.example/v1", }, ensure_ascii=False)) PY )" save_json 03-create-route "$(crm_curl_json POST "/api/logical-groups/$GROUP_ID/routes" "$create_route_payload")" add_route_model_payload="$(python3 - "$PUBLIC_MODEL" "$SHADOW_MODEL" <<'PY' import json, sys public_model, shadow_model = sys.argv[1:3] print(json.dumps({ "public_model": public_model, "shadow_model": shadow_model, "status": "active", }, ensure_ascii=False)) PY )" save_json 04-add-route-model "$(crm_curl_json POST "/api/logical-groups/$GROUP_ID/routes/$ROUTE_ID/models" "$add_route_model_payload")" save_json 05-get-group "$(crm_curl_json GET "/api/logical-groups/$GROUP_ID")" update_group_payload="$(python3 - "$GROUP_ID" <<'PY' import json, sys group_id = sys.argv[1] print(json.dumps({ "display_name": f"P2T4 Control Plane Updated {group_id}", "status": "active", "description": "P2-T4 control plane verification group updated", "route_policy": "priority", "sticky_mode": "conversation_preferred", "conversation_ttl_seconds": 1500, "user_model_ttl_seconds": 900, "failover_threshold": 2, "cooldown_seconds": 360, }, ensure_ascii=False)) PY )" save_json 06-update-group "$(crm_curl_json PUT "/api/logical-groups/$GROUP_ID" "$update_group_payload")" update_route_payload="$(python3 - "$SHADOW_GROUP_ID" "$SHADOW_HOST_ID" <<'PY' import json, sys shadow_group_id, shadow_host_id = sys.argv[1:3] print(json.dumps({ "name": "Primary Route Updated", "status": "active", "priority": 12, "weight": 80, "shadow_group_id": shadow_group_id, "shadow_host_id": shadow_host_id, "upstream_base_url_hint": "https://primary-updated.example/v1", "cooldown_until": "", }, ensure_ascii=False)) PY )" save_json 07-update-route "$(crm_curl_json PUT "/api/logical-groups/$GROUP_ID/routes/$ROUTE_ID" "$update_route_payload")" save_json 08-list-routes "$(crm_curl_json GET "/api/logical-groups/$GROUP_ID/routes")" save_json 09-list-route-models "$(crm_curl_json GET "/api/logical-groups/$GROUP_ID/routes/$ROUTE_ID/models")" python3 - "$ARTIFACT_DIR" "$GROUP_ID" "$ROUTE_ID" "$PUBLIC_MODEL" "$SHADOW_MODEL" "$SHADOW_HOST_ID" "$SHADOW_GROUP_ID" >"$ARTIFACT_DIR/10-summary.json" <<'PY' import json import sys from pathlib import Path art_dir, group_id, route_id, public_model, shadow_model, shadow_host_id, shadow_group_id = sys.argv[1:8] art = Path(art_dir) create_group = json.loads((art / "01-create-group.json").read_text())["logical_group"] update_group = json.loads((art / "06-update-group.json").read_text())["logical_group"] update_route = json.loads((art / "07-update-route.json").read_text())["route"] list_routes = json.loads((art / "08-list-routes.json").read_text())["routes"] route_models = json.loads((art / "09-list-route-models.json").read_text())["route_models"] assert create_group["logical_group_id"] == group_id assert update_group["display_name"].startswith("P2T4 Control Plane Updated") assert update_route["route_id"] == route_id assert update_route["weight"] == 80 assert update_route["shadow_host_id"] == shadow_host_id assert update_route["shadow_group_id"] == shadow_group_id assert any(item["route_id"] == route_id for item in list_routes) assert any(item["public_model"] == public_model and item["shadow_model"] == shadow_model for item in route_models) summary = { "group_id": group_id, "route_id": route_id, "public_model": public_model, "shadow_model": shadow_model, "shadow_host_id": shadow_host_id, "shadow_group_id": shadow_group_id, "checks": { "group_created": True, "group_updated": True, "route_created": True, "route_updated": True, "route_model_created": True, "route_model_listed": True, }, } print(json.dumps(summary, ensure_ascii=False, indent=2)) PY cat "$ARTIFACT_DIR/10-summary.json"