"""lasuite-drive — Q3.2 recipe-specific functional test (plan §4.3: "upload a file to a workspace, list/download it; MinIO bucket present"). Drive stores all uploaded documents in MinIO (S3) — the `minio` service, bucket `drive-media-storage` (created by the `minio-createbuckets` one-shot, versioning enabled). This exercises that storage backend end-to-end at the S3 layer: it (1) confirms the bucket exists, and (2) does a real upload → list → download round-trip and asserts the bytes survive. It runs `mc` (bundled in the minio/minio image) INSIDE the `minio` service container, authenticating with the in-container root creds (`/run/secrets/minio_{ru,rp}`) — the same path the recipe's own createbuckets job uses. No dep on keycloak, so it runs on the base deploy regardless of SSO state. NOT health-only: a drive whose object store is missing the bucket, or that can't persist/serve an object, fails here even though the SPA at `/` returns 200. """ from __future__ import annotations import os import sys import uuid sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "..", "runner")) from harness import lifecycle # noqa: E402 BUCKET = "drive-media-storage" def _mc(domain: str, script: str) -> str: """Run an `mc` shell script inside the minio container (root creds from /run/secrets).""" prelude = ( 'set -e; ' 'U=$(cat /run/secrets/minio_ru); P=$(cat /run/secrets/minio_rp); ' 'mc alias set ccci http://localhost:9000 "$U" "$P" >/dev/null 2>&1; ' ) return lifecycle.exec_in_app(domain, ["sh", "-c", prelude + script], service="minio") def test_minio_bucket_present_and_object_roundtrip(live_app): domain = live_app # per-run drive app domain # 1) The drive media bucket exists (mc ls returns 0; set -e raises otherwise). _mc(domain, f"mc ls ccci/{BUCKET} >/dev/null") # 2) Real upload -> list -> download round-trip with a unique marker. marker = f"ccci-drive-probe-{uuid.uuid4().hex}" key = f"ccci-probe/{marker}.txt" out = _mc( domain, # upload via stdin; list the object; read it back (tagged); then delete. f'printf %s "{marker}" | mc pipe ccci/{BUCKET}/{key} >/dev/null 2>&1; ' f'mc ls ccci/{BUCKET}/{key}; ' f'echo "READBACK:$(mc cat ccci/{BUCKET}/{key})"; ' f'mc rm ccci/{BUCKET}/{key} >/dev/null 2>&1', ) # The object was listed (its key appears) and its content round-tripped intact. assert f"{marker}.txt" in out, f"uploaded object not listed in bucket: {out!r}" assert f"READBACK:{marker}" in out, ( f"object content did not round-trip through MinIO; got: {out!r}" )