test_wp09_agent_runtime_postgres.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. from __future__ import annotations
  2. import os
  3. import uuid
  4. import pytest
  5. from sqlalchemy import create_engine, text
  6. from app.core.llm.runtime_governance import BudgetPolicy
  7. from app.core.llm.runtime_governance_repository import (
  8. SqlAlchemyRuntimeGovernanceRepository,
  9. )
  10. pytestmark = pytest.mark.integration
  11. def test_wp09_two_connections_allow_only_one_budget_lease_and_append_only_audit():
  12. database_url = os.getenv("TEST_DATABASE_URL")
  13. if not database_url:
  14. pytest.skip("TEST_DATABASE_URL is required")
  15. tenant_id = f"wp09_{uuid.uuid4().hex[:16]}"
  16. engine = create_engine(database_url)
  17. try:
  18. with engine.begin() as connection:
  19. repository = SqlAlchemyRuntimeGovernanceRepository(connection)
  20. repository.create_budget(tenant_id, BudgetPolicy(5, 10, 1, 100, 1, {"controlled-model-v1": 1}))
  21. first = engine.connect()
  22. second = engine.connect()
  23. transaction_one = first.begin()
  24. transaction_two = second.begin()
  25. try:
  26. repo_one = SqlAlchemyRuntimeGovernanceRepository(first)
  27. repo_two = SqlAlchemyRuntimeGovernanceRepository(second)
  28. assert repo_one.reserve_budget(tenant_id, "lease-a", "controlled-model-v1", 5, 10, 1, 50) > 0
  29. transaction_one.commit()
  30. with pytest.raises(ValueError, match="budget_exhausted"):
  31. repo_two.reserve_budget(tenant_id, "lease-b", "controlled-model-v1", 1, 1, 1, 1)
  32. transaction_two.rollback()
  33. with engine.begin() as connection:
  34. repository = SqlAlchemyRuntimeGovernanceRepository(connection)
  35. repository.append_audit({"invocation_id": str(uuid.uuid4()), "tenant_id": tenant_id, "idempotency_key": "audit-a", "route_id": "route-a", "generation": "generation-1", "lease_fence": 1, "input_hash": "a" * 64, "evidence_digests": ["b" * 64], "decision": "authorized"})
  36. with pytest.raises(ValueError, match="append_only_conflict"):
  37. repository.append_audit({"invocation_id": str(uuid.uuid4()), "tenant_id": tenant_id, "idempotency_key": "audit-a", "route_id": "route-a", "generation": "generation-1", "lease_fence": 1, "input_hash": "a" * 64, "evidence_digests": ["b" * 64], "decision": "authorized"})
  38. finally:
  39. if transaction_one.is_active:
  40. transaction_one.rollback()
  41. if transaction_two.is_active:
  42. transaction_two.rollback()
  43. first.close()
  44. second.close()
  45. finally:
  46. with engine.begin() as connection:
  47. connection.execute(text("DELETE FROM public.agent_invocation_audits WHERE tenant_id = :tenant_id"), {"tenant_id": tenant_id})
  48. connection.execute(text("DELETE FROM public.agent_runtime_reservations WHERE tenant_id = :tenant_id"), {"tenant_id": tenant_id})
  49. connection.execute(text("DELETE FROM public.agent_runtime_budgets WHERE tenant_id = :tenant_id"), {"tenant_id": tenant_id})
  50. engine.dispose()