generated from coulomb/repo-seed
Add guide-board pilot ingestion
This commit is contained in:
8
tests/fixtures/guide-board/logs/log-review-summary.json
vendored
Normal file
8
tests/fixtures/guide-board/logs/log-review-summary.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"reviewed_logs": [
|
||||
"raw/session/transcript.txt"
|
||||
],
|
||||
"warnings": [
|
||||
"Repository returned one optional capability warning."
|
||||
]
|
||||
}
|
||||
6
tests/fixtures/guide-board/raw/session/browser-response.json
vendored
Normal file
6
tests/fixtures/guide-board/raw/session/browser-response.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"repositoryId": "fixture-repo",
|
||||
"capabilities": {
|
||||
"capabilityQuery": "metadataonly"
|
||||
}
|
||||
}
|
||||
3
tests/fixtures/guide-board/raw/session/transcript.txt
vendored
Normal file
3
tests/fixtures/guide-board/raw/session/transcript.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
GET /cmis/browser
|
||||
200 OK
|
||||
Repository info collected for fixture.
|
||||
12
tests/fixtures/guide-board/reports/assessment-package.json
vendored
Normal file
12
tests/fixtures/guide-board/reports/assessment-package.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"package_version": 1,
|
||||
"files": [
|
||||
{ "path": "run.json", "kind": "run-metadata" },
|
||||
{ "path": "retention-summary.json", "kind": "retention-summary" },
|
||||
{ "path": "reports/report.md", "kind": "report" },
|
||||
{ "path": "scorecards/cmis-scorecard.json", "kind": "scorecard" },
|
||||
{ "path": "logs/log-review-summary.json", "kind": "log-review" },
|
||||
{ "path": "raw/session/transcript.txt", "kind": "raw-artifact" },
|
||||
{ "path": "raw/session/browser-response.json", "kind": "raw-artifact" }
|
||||
]
|
||||
}
|
||||
3
tests/fixtures/guide-board/reports/report.md
vendored
Normal file
3
tests/fixtures/guide-board/reports/report.md
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Guide-board CMIS Assessment
|
||||
|
||||
Fixture run `gb-fixture-001` completed with one warning and no failed checks.
|
||||
17
tests/fixtures/guide-board/retention-summary.json
vendored
Normal file
17
tests/fixtures/guide-board/retention-summary.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"retention_class": "release-evidence",
|
||||
"report_paths": [
|
||||
"reports/report.md",
|
||||
"scorecards/cmis-scorecard.json",
|
||||
"logs/log-review-summary.json"
|
||||
],
|
||||
"evidence_counts": {
|
||||
"raw_artifacts": 2,
|
||||
"reports": 3
|
||||
},
|
||||
"finding_counts": {
|
||||
"pass": 17,
|
||||
"warning": 1,
|
||||
"fail": 0
|
||||
}
|
||||
}
|
||||
10
tests/fixtures/guide-board/run.json
vendored
Normal file
10
tests/fixtures/guide-board/run.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"run_id": "gb-fixture-001",
|
||||
"target_profile_ref": "open-cmis-tck:browser-binding",
|
||||
"assessment_profile_ref": "guide-board:cmis-assessment:v1",
|
||||
"result_status": "passed-with-findings",
|
||||
"source_commits": {
|
||||
"guide-board": "1234567890abcdef",
|
||||
"open-cmis-tck": "abcdef1234567890"
|
||||
}
|
||||
}
|
||||
7
tests/fixtures/guide-board/scorecards/cmis-scorecard.json
vendored
Normal file
7
tests/fixtures/guide-board/scorecards/cmis-scorecard.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"scorecard": "cmis-browser-binding",
|
||||
"checks": 18,
|
||||
"passed": 17,
|
||||
"warnings": 1,
|
||||
"failed": 0
|
||||
}
|
||||
110
tests/integration/test_guide_board_pilot.py
Normal file
110
tests/integration/test_guide_board_pilot.py
Normal file
@@ -0,0 +1,110 @@
|
||||
"""Guide-board pilot ingestion tests (ARTIFACT-STORE-WP-0005)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from collections.abc import AsyncIterator
|
||||
from pathlib import Path
|
||||
from uuid import UUID
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from sqlalchemy import create_engine, insert
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from typer.testing import CliRunner
|
||||
|
||||
from artifactstore.cli import app as cli_app
|
||||
from artifactstore.dataplane import InProcessDataPlane
|
||||
from artifactstore.db.schema import metadata, retention_classes
|
||||
from artifactstore.db.seed import RETENTION_CLASS_SEEDS
|
||||
from artifactstore.events import RegistryViewWriter
|
||||
from artifactstore.manifest import decode as manifest_decode
|
||||
from artifactstore.pilots.guide_board import GUIDE_BOARD_SCHEMA_SLUG, ingest_run
|
||||
from artifactstore.registry import Registry
|
||||
from artifactstore.storage import LocalBackend
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
FIXTURE = REPO_ROOT / "tests" / "fixtures" / "guide-board"
|
||||
SCHEMA = REPO_ROOT / "schemas" / "guide-board.run.v1.json"
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def registry(tmp_path: Path) -> AsyncIterator[Registry]:
|
||||
db_path = tmp_path / "guide-board.db"
|
||||
engine = create_async_engine(f"sqlite+aiosqlite:///{db_path}")
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(metadata.create_all)
|
||||
for seed in RETENTION_CLASS_SEEDS:
|
||||
await conn.execute(insert(retention_classes).values(**seed))
|
||||
backend = LocalBackend(tmp_path / "storage", backend_id="local")
|
||||
reg = Registry(engine, InProcessDataPlane(backend), RegistryViewWriter())
|
||||
try:
|
||||
yield reg
|
||||
finally:
|
||||
await reg.dispose()
|
||||
|
||||
|
||||
async def _consume(stream: AsyncIterator[bytes]) -> bytes:
|
||||
out = bytearray()
|
||||
async for chunk in stream:
|
||||
out.extend(chunk)
|
||||
return bytes(out)
|
||||
|
||||
|
||||
async def test_guide_board_library_ingest_is_idempotent_and_downloadable(
|
||||
registry: Registry,
|
||||
) -> None:
|
||||
schema = json.loads(SCHEMA.read_text(encoding="utf-8"))
|
||||
await registry.register_metadata_schema(slug=GUIDE_BOARD_SCHEMA_SLUG, json_schema=schema)
|
||||
|
||||
first = await ingest_run(FIXTURE, registry=registry)
|
||||
second = await ingest_run(FIXTURE, registry=registry)
|
||||
|
||||
assert first.package_id
|
||||
assert first.manifest_digest.startswith("blake3:")
|
||||
assert first.manifest_digest == second.manifest_digest
|
||||
assert second.reused_existing is True
|
||||
|
||||
manifest = manifest_decode(
|
||||
await registry.get_manifest_bytes(UUID(first.package_id), format="cbor")
|
||||
)
|
||||
assert manifest.package.producer == "guide-board"
|
||||
assert manifest.package.metadata_schema_id is not None
|
||||
assert manifest.retention_summary.retention_class == "release-evidence"
|
||||
assert len(manifest.files) == 8
|
||||
|
||||
for file_entry in manifest.files:
|
||||
stream = await registry.get_file(UUID(file_entry.id))
|
||||
assert await _consume(stream) == (FIXTURE / file_entry.relative_path).read_bytes()
|
||||
|
||||
state = await registry.get_retention_state(UUID(first.package_id))
|
||||
assert state.effective_class == "release-evidence"
|
||||
|
||||
|
||||
def test_guide_board_cli_ingest_outputs_package_and_digest(
|
||||
tmp_path: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
db_path = tmp_path / "guide-board-cli.db"
|
||||
storage_root = tmp_path / "storage"
|
||||
storage_root.mkdir()
|
||||
sync_engine = create_engine(f"sqlite:///{db_path}", 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()
|
||||
|
||||
monkeypatch.setenv("ARTIFACTSTORE_DATABASE_URL", f"sqlite+aiosqlite:///{db_path}")
|
||||
monkeypatch.setenv("ARTIFACTSTORE_STORAGE_LOCAL_ROOT", str(storage_root))
|
||||
|
||||
result = CliRunner().invoke(
|
||||
cli_app,
|
||||
["guide-board", "ingest", str(FIXTURE), "--schema", str(SCHEMA)],
|
||||
)
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
payload = json.loads(result.output)
|
||||
assert payload["package_id"]
|
||||
assert payload["manifest_digest"].startswith("blake3:")
|
||||
assert payload["file_count"] == 8
|
||||
assert payload["reused_existing"] is False
|
||||
Reference in New Issue
Block a user