from __future__ import annotations import hashlib import secrets from uuid import uuid4 from govoplan_core.core.operations import OperationalCheck from govoplan_files.backend.storage.backends import ( StorageBackendError, get_storage_backend, ) def managed_storage_roundtrip_check() -> OperationalCheck: """Exercise the configured managed store without retaining probe data.""" backend = get_storage_backend() key = f".govoplan-health/probes/{uuid4().hex}.bin" payload = secrets.token_bytes(64) expected_digest = hashlib.sha256(payload).hexdigest() delete_error: Exception | None = None try: backend.put_bytes(key, payload, content_type="application/octet-stream") stored = backend.get_bytes(key) info = backend.stat(key) if info.size_bytes != len(payload): raise StorageBackendError("Managed storage returned an unexpected object size") if hashlib.sha256(stored).hexdigest() != expected_digest: raise StorageBackendError("Managed storage returned different bytes than were written") except Exception as exc: # noqa: BLE001 - operational boundary reports provider failures. return OperationalCheck( id="files.managed_storage_roundtrip", label="Managed file storage", state="error", detail=( "The configured managed file store failed a bounded write/read/stat/delete " f"probe ({type(exc).__name__})." ), readiness_critical=True, metrics={"backend": backend.name, "probe_bytes": len(payload)}, ) finally: try: backend.delete(key) except Exception as exc: # noqa: BLE001 - reported below when the data probe passed. delete_error = exc if delete_error is not None: return OperationalCheck( id="files.managed_storage_roundtrip", label="Managed file storage", state="error", detail=( "Managed file bytes round-tripped, but probe cleanup failed " f"({type(delete_error).__name__})." ), readiness_critical=True, metrics={"backend": backend.name, "probe_bytes": len(payload)}, ) return OperationalCheck( id="files.managed_storage_roundtrip", label="Managed file storage", state="ok", detail="The configured managed file store passed write, read, stat, integrity, and delete checks.", metrics={"backend": backend.name, "probe_bytes": len(payload)}, )