Harden V1 demo workflow smoke
This commit is contained in:
+5
-3
@@ -17,9 +17,11 @@ Verify the explicit demo workflow plus export artifact path:
|
||||
bash scripts/verify_demo_export_workflow.sh http://192.168.10.150:1202
|
||||
```
|
||||
|
||||
The demo/export smoke seeds the offline fixture demo, verifies persisted QA/QC
|
||||
results, creates metadata/report/vector GeoJSON exports, lists exports and
|
||||
downloads the JSON/GeoJSON/HTML artifacts through the frontend proxy.
|
||||
The demo/export smoke is intentionally mutating and idempotent: it seeds the
|
||||
offline fixture demo if needed, verifies the project area GeoJSON, fixture
|
||||
datasets, vector FeatureCollection content, vector feature summary, persisted
|
||||
QA/QC metrics, creates metadata/report/vector GeoJSON exports, lists exports
|
||||
and downloads the JSON/GeoJSON/HTML artifacts through the frontend proxy.
|
||||
|
||||
## Tower deployment
|
||||
|
||||
|
||||
@@ -72,6 +72,72 @@ curl -fsS -X POST "${BASE_URL%/}/api/v1/demo/workflow" > "${TMP_DIR}/demo.json"
|
||||
require_json_data "${TMP_DIR}/demo.json"
|
||||
project_id="$(json_field "${TMP_DIR}/demo.json" "data.project_id")"
|
||||
candidate_dataset_id="$(json_field "${TMP_DIR}/demo.json" "data.candidate_dataset_id")"
|
||||
reference_dataset_id="$(json_field "${TMP_DIR}/demo.json" "data.reference_dataset_id")"
|
||||
area_id="$(json_field "${TMP_DIR}/demo.json" "data.area_id")"
|
||||
quality_check_id="$(json_field "${TMP_DIR}/demo.json" "data.quality_check_id")"
|
||||
|
||||
curl -fsS "${BASE_URL%/}/api/v1/projects/${project_id}" > "${TMP_DIR}/project.json"
|
||||
require_json_data "${TMP_DIR}/project.json"
|
||||
|
||||
curl -fsS "${BASE_URL%/}/api/v1/projects/${project_id}/areas" > "${TMP_DIR}/areas.json"
|
||||
require_json_data "${TMP_DIR}/areas.json"
|
||||
"${PYTHON_BIN}" - "${TMP_DIR}/areas.json" "${area_id}" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
||||
path, area_id = sys.argv[1], sys.argv[2]
|
||||
with open(path, "r", encoding="utf-8") as handle:
|
||||
payload = json.load(handle)
|
||||
items = payload["data"]["items"]
|
||||
if not items:
|
||||
raise SystemExit("Demo workflow did not expose any project areas")
|
||||
matches = [item for item in items if item["id"] == area_id]
|
||||
if not matches:
|
||||
raise SystemExit(f"Demo area {area_id} was not returned by the area list")
|
||||
geometry = matches[0].get("geometry")
|
||||
if not geometry or geometry.get("type") not in {"Polygon", "MultiPolygon"}:
|
||||
raise SystemExit("Demo area response does not include GeoJSON Polygon/MultiPolygon geometry")
|
||||
PY
|
||||
|
||||
curl -fsS "${BASE_URL%/}/api/v1/projects/${project_id}/datasets" > "${TMP_DIR}/datasets.json"
|
||||
require_json_data "${TMP_DIR}/datasets.json"
|
||||
"${PYTHON_BIN}" - "${TMP_DIR}/datasets.json" "${candidate_dataset_id}" "${reference_dataset_id}" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
||||
path, candidate_id, reference_id = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||
with open(path, "r", encoding="utf-8") as handle:
|
||||
payload = json.load(handle)
|
||||
items = payload["data"]["items"]
|
||||
ids = {item["id"]: item for item in items}
|
||||
if candidate_id not in ids:
|
||||
raise SystemExit("Candidate fixture dataset is missing from project dataset list")
|
||||
if reference_id not in ids:
|
||||
raise SystemExit("Reference fixture dataset is missing from project dataset list")
|
||||
if ids[candidate_id]["dataset_type"] not in {"vector", "geojson"}:
|
||||
raise SystemExit("Candidate fixture dataset is not vector-like")
|
||||
if ids[reference_id].get("dataset_role") != "reference":
|
||||
raise SystemExit("Reference fixture dataset is not marked as reference")
|
||||
PY
|
||||
|
||||
curl -fsS "${BASE_URL%/}/api/v1/projects/${project_id}/datasets/${candidate_dataset_id}/content" > "${TMP_DIR}/candidate_content.json"
|
||||
if ! grep -q '"FeatureCollection"' "${TMP_DIR}/candidate_content.json"; then
|
||||
echo "Candidate dataset content is not a FeatureCollection" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
curl -fsS "${BASE_URL%/}/api/v1/projects/${project_id}/datasets/${candidate_dataset_id}/vector/summary" > "${TMP_DIR}/candidate_summary.json"
|
||||
require_json_data "${TMP_DIR}/candidate_summary.json"
|
||||
"${PYTHON_BIN}" - "${TMP_DIR}/candidate_summary.json" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
||||
with open(sys.argv[1], "r", encoding="utf-8") as handle:
|
||||
payload = json.load(handle)
|
||||
feature_count = payload["data"].get("feature_count") or 0
|
||||
if feature_count < 1:
|
||||
raise SystemExit("Candidate vector summary does not report persisted features")
|
||||
PY
|
||||
|
||||
curl -fsS "${BASE_URL%/}/api/v1/projects/${project_id}/quality-checks" > "${TMP_DIR}/quality_checks.json"
|
||||
require_json_data "${TMP_DIR}/quality_checks.json"
|
||||
@@ -80,6 +146,23 @@ if [ "${quality_count}" -lt 1 ]; then
|
||||
echo "Expected at least one persisted QA/QC result after demo workflow" >&2
|
||||
exit 1
|
||||
fi
|
||||
"${PYTHON_BIN}" - "${TMP_DIR}/quality_checks.json" "${quality_check_id}" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
||||
path, quality_check_id = sys.argv[1], sys.argv[2]
|
||||
with open(path, "r", encoding="utf-8") as handle:
|
||||
payload = json.load(handle)
|
||||
items = payload["data"]["items"]
|
||||
matches = [item for item in items if item["id"] == quality_check_id]
|
||||
if not matches:
|
||||
raise SystemExit("Seeded quality_check_id is not listed in project QA/QC results")
|
||||
metric_keys = {metric["metric_key"] for metric in matches[0].get("metrics", [])}
|
||||
required = {"precision", "recall", "f1", "mean_iou", "false_positive_count", "false_negative_count"}
|
||||
missing = required - metric_keys
|
||||
if missing:
|
||||
raise SystemExit(f"QA/QC result is missing metrics: {sorted(missing)}")
|
||||
PY
|
||||
|
||||
curl -fsS -X POST "${BASE_URL%/}/api/v1/exports/metadata" \
|
||||
-H "Content-Type: application/json" \
|
||||
@@ -128,4 +211,6 @@ fi
|
||||
|
||||
echo "Demo/export workflow verification passed"
|
||||
echo "Project: ${project_id}"
|
||||
echo "Area: ${area_id}"
|
||||
echo "Datasets: candidate=${candidate_dataset_id}, reference=${reference_dataset_id}"
|
||||
echo "Exports created: metadata=${metadata_export_id}, report=${report_export_id}, dataset=${dataset_export_id}"
|
||||
|
||||
Reference in New Issue
Block a user