Add S3 backend and storage verification

This commit is contained in:
2026-05-16 23:26:03 +02:00
parent b7ceaf7682
commit 864f7f203c
18 changed files with 1085 additions and 40 deletions

View File

@@ -8,11 +8,11 @@ from pathlib import Path
from typing import Any
import pytest
from sqlalchemy import create_engine, insert, inspect
from sqlalchemy import create_engine, insert, inspect, select
from typer.testing import CliRunner
from artifactstore.cli import app as cli_app
from artifactstore.db.schema import metadata, retention_classes
from artifactstore.db.schema import metadata, retention_classes, storage_locations
from artifactstore.db.seed import RETENTION_CLASS_SEEDS
REPO_ROOT = Path(__file__).resolve().parents[2]
@@ -252,3 +252,57 @@ def test_cli_retention_sweep_marks_expired_package(
assert result.exit_code == 0, result.output
payload = json.loads(result.output)
assert payload == {"marked_package_ids": [package_id], "marked_count": 1}
def test_cli_storage_verify_marks_local_location_verified(
runner: CliRunner,
env_db: Path,
) -> None:
sync_engine = create_engine(f"sqlite:///{env_db}", future=True)
metadata.create_all(sync_engine)
with sync_engine.begin() as conn:
conn.execute(insert(retention_classes), [dict(s) for s in RETENTION_CLASS_SEEDS])
sync_engine.dispose()
async def create_stored_file() -> None:
from collections.abc import AsyncIterator
from artifactstore.app import build_registry
from artifactstore.config import get_settings
async def stream() -> AsyncIterator[bytes]:
yield b"verify-me"
registry = build_registry(get_settings())
try:
package_id = await registry.create_package(
name="verify",
producer="tests",
subject="storage",
retention_class="raw-evidence",
actor="ops",
)
await registry.ingest_file(
package_id,
relative_path="verify.txt",
media_type="text/plain",
stream=stream(),
actor="ops",
)
finally:
await registry.dispose()
asyncio.run(create_stored_file())
result = runner.invoke(cli_app, ["storage", "verify", "--backend", "local"])
assert result.exit_code == 0, result.output
payload = json.loads(result.output)
assert payload["verified_count"] == 1
assert payload["failed_count"] == 0
assert payload["results"][0]["verified"] is True
sync_engine = create_engine(f"sqlite:///{env_db}", future=True)
with sync_engine.connect() as conn:
status = conn.execute(select(storage_locations.c.status)).scalar_one()
sync_engine.dispose()
assert status == "verified"