test_fresh_output_storage.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. from __future__ import annotations
  2. from pathlib import Path
  3. from sqlalchemy import insert
  4. from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
  5. from script_build_host.application.legacy_api import LegacyScriptBuildApiService
  6. from script_build_host.application.legacy_projection import LegacyDetailProjectionService
  7. from script_build_host.domain.records import Principal
  8. from script_build_host.infrastructure.legacy_tables import (
  9. legacy_metadata,
  10. script_build_element,
  11. script_build_paragraph,
  12. script_build_paragraph_element,
  13. script_build_record,
  14. script_build_task_plan_step,
  15. )
  16. from script_build_host.infrastructure.raw_artifacts import FileRawArtifactStore
  17. from script_build_host.infrastructure.tables import metadata
  18. class _Authorizer:
  19. async def require_access(self, _principal: Principal, _script_build_id: int) -> None:
  20. return None
  21. async def test_ten_table_fresh_database_supports_detail_and_log_without_history_tables() -> None:
  22. engine = create_async_engine("sqlite+aiosqlite:///:memory:")
  23. legacy_tables = (
  24. script_build_record,
  25. script_build_paragraph,
  26. script_build_element,
  27. script_build_paragraph_element,
  28. script_build_task_plan_step,
  29. )
  30. async with engine.begin() as connection:
  31. await connection.run_sync(metadata.create_all)
  32. await connection.run_sync(
  33. lambda sync_connection: legacy_metadata.create_all(
  34. sync_connection,
  35. tables=legacy_tables,
  36. )
  37. )
  38. sessions = async_sessionmaker(engine, expire_on_commit=False)
  39. async with sessions() as session, session.begin():
  40. await session.execute(
  41. insert(script_build_record).values(
  42. id=1,
  43. execution_id=11,
  44. topic_build_id=12,
  45. topic_id=13,
  46. status="success",
  47. reson_trace_id="root-1",
  48. is_deleted=False,
  49. is_favorited=False,
  50. summary="fresh output",
  51. )
  52. )
  53. authorizer = _Authorizer()
  54. projection = LegacyDetailProjectionService(
  55. sessions,
  56. authorizer, # type: ignore[arg-type]
  57. include_legacy_decision_traces=False,
  58. )
  59. detail = await projection.project_authorized(1, principal=Principal("owner"))
  60. assert detail["build"]["id"] == 1
  61. assert detail["decision_traces"] == []
  62. legacy_api = LegacyScriptBuildApiService(
  63. sessions,
  64. sessions,
  65. authorizer, # type: ignore[arg-type]
  66. include_legacy_logs=False,
  67. )
  68. log = await legacy_api.log(1, Principal("owner"))
  69. assert log["log_content"] == "fresh output"
  70. await engine.dispose()
  71. async def test_raw_artifact_store_persists_and_revalidates_content(tmp_path: Path) -> None:
  72. store = FileRawArtifactStore(tmp_path)
  73. reference = await store.freeze_bytes(b"fresh raw output", media_type="text/plain")
  74. assert await store.read_bytes(reference) == b"fresh raw output"