Separated open-cmis-tck and guide-board repositories

This commit is contained in:
2026-05-07 21:52:08 +02:00
parent b0d3443dc0
commit e778dc2252
59 changed files with 489 additions and 5368 deletions

View File

@@ -0,0 +1,213 @@
"""CMIS Browser Binding preflight runner."""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen
def run(context: dict[str, Any]) -> dict[str, Any]:
target = context["target_profile"]
endpoint = _browser_endpoint(target)
if endpoint is None:
return {
"result": "fail",
"observations": [
"Target profile does not declare a CMIS Browser Binding endpoint."
],
"facts": {
"endpoint_found": False,
},
"artifact_refs": [],
}
timeout = _timeout_seconds(context)
artifact_refs: list[str] = []
request = Request(
endpoint["url"],
headers={
"Accept": "application/json, */*;q=0.1",
"User-Agent": "guide-board-open-cmis-tck-preflight/0.1.0",
},
)
try:
with urlopen(request, timeout=timeout) as response:
status_code = response.status
content_type = response.headers.get("Content-Type", "")
headers = dict(response.headers.items())
body = response.read(1024 * 1024)
artifact_refs = _write_response_artifacts(
context,
status_code,
content_type,
headers,
body,
)
except HTTPError as exc:
body = exc.read(1024 * 1024)
content_type = exc.headers.get("Content-Type", "")
artifact_refs = _write_response_artifacts(
context,
exc.code,
content_type,
dict(exc.headers.items()),
body,
)
return {
"result": "infrastructure_error",
"observations": [
f"CMIS Browser Binding endpoint returned HTTP {exc.code}."
],
"facts": {
"endpoint_found": True,
"url": endpoint["url"],
"http_status": exc.code,
"content_type": content_type,
},
"artifact_refs": artifact_refs,
}
except URLError as exc:
return {
"result": "infrastructure_error",
"observations": [
f"CMIS Browser Binding endpoint is not reachable: {exc.reason}."
],
"facts": {
"endpoint_found": True,
"url": endpoint["url"],
"error": str(exc.reason),
},
"artifact_refs": artifact_refs,
}
except TimeoutError:
return {
"result": "infrastructure_error",
"observations": [
f"CMIS Browser Binding endpoint did not respond within {timeout} seconds."
],
"facts": {
"endpoint_found": True,
"url": endpoint["url"],
"timeout_seconds": timeout,
},
"artifact_refs": artifact_refs,
}
facts: dict[str, Any] = {
"endpoint_found": True,
"url": endpoint["url"],
"binding": endpoint["binding"],
"http_status": status_code,
"content_type": content_type,
}
parsed = _parse_json(body)
if parsed is None:
facts["json_detected"] = False
return {
"result": "warning",
"observations": [
"CMIS Browser Binding endpoint is reachable but did not return parseable JSON."
],
"facts": facts,
"artifact_refs": artifact_refs,
}
facts["json_detected"] = True
facts.update(_repository_facts(parsed))
return {
"result": "pass",
"observations": [
"CMIS Browser Binding endpoint is reachable and returned parseable JSON."
],
"facts": facts,
"artifact_refs": artifact_refs,
}
def _browser_endpoint(target: dict[str, Any]) -> dict[str, Any] | None:
for endpoint in target.get("endpoints", []):
if endpoint.get("binding") == "cmis-browser":
return endpoint
return None
def _timeout_seconds(context: dict[str, Any]) -> float:
runtime_policy = context["assessment_profile"].get("runtime_policy", {})
configured = runtime_policy.get("timeout_seconds", 5)
if not isinstance(configured, (int, float)):
return 5.0
return max(1.0, min(float(configured), 10.0))
def _parse_json(body: bytes) -> Any:
try:
return json.loads(body.decode("utf-8"))
except (UnicodeDecodeError, json.JSONDecodeError):
return None
def _repository_facts(value: Any) -> dict[str, Any]:
if not isinstance(value, dict):
return {"repository_shape": "unknown"}
if "repositoryId" in value:
return {
"repository_shape": "single-repository-info",
"repository_ids": [value["repositoryId"]],
"cmis_version_supported": value.get("cmisVersionSupported"),
"capabilities_present": isinstance(value.get("capabilities"), dict),
}
repository_ids = []
for key, child in value.items():
if isinstance(child, dict) and (
"repositoryId" in child or "repositoryName" in child
):
repository_ids.append(str(child.get("repositoryId", key)))
if repository_ids:
return {
"repository_shape": "repository-map",
"repository_ids": repository_ids,
}
return {
"repository_shape": "object",
"top_level_keys": sorted(str(key) for key in value.keys())[:20],
}
def _write_response_artifacts(
context: dict[str, Any],
status_code: int,
content_type: str,
headers: dict[str, str],
body: bytes,
) -> list[str]:
run_dir = Path(context["run_dir"])
artifact_dir = run_dir / "artifacts" / "open-cmis-tck" / "preflight"
artifact_dir.mkdir(parents=True, exist_ok=True)
response_ref = "artifacts/open-cmis-tck/preflight/response-body.bin"
metadata_ref = "artifacts/open-cmis-tck/preflight/response-metadata.json"
(run_dir / response_ref).write_bytes(body)
(run_dir / metadata_ref).write_text(
json.dumps(
{
"status_code": status_code,
"content_type": content_type,
"headers": headers,
"byte_count": len(body),
},
indent=2,
sort_keys=True,
)
+ "\n",
encoding="utf-8",
)
return [metadata_ref, response_ref]