test_rule_publication_migration_upgrade.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from __future__ import annotations
  2. from contextlib import suppress
  3. import pytest
  4. from sqlalchemy import create_engine, text
  5. from app.core.common.identifiers import new_governance_uid
  6. from tests.integration.test_rule_artifact_migration_upgrade import (
  7. _compose_value,
  8. _upgrade,
  9. )
  10. @pytest.mark.parametrize("legacy_status", ["draft", "validated", "published"])
  11. def test_any_legacy_rule_blocks_real_190_to_200_upgrade(legacy_status):
  12. platform_user = _compose_value(
  13. r"\n postgres:.*?POSTGRES_USER:\s*([^\s]+)"
  14. )
  15. platform_password = _compose_value(
  16. r"\n postgres:.*?POSTGRES_PASSWORD:\s*([^\s]+)"
  17. )
  18. platform_port = _compose_value(r'"(15432):5432"')
  19. admin_url = (
  20. f"postgresql+psycopg2://{platform_user}:{platform_password}"
  21. f"@127.0.0.1:{platform_port}/postgres"
  22. )
  23. database_name = (
  24. f"task7_legacy_{new_governance_uid().replace('-', '')}"
  25. )
  26. database_url = (
  27. f"postgresql+psycopg2://{platform_user}:{platform_password}"
  28. f"@127.0.0.1:{platform_port}/{database_name}"
  29. )
  30. admin = create_engine(admin_url, isolation_level="AUTOCOMMIT")
  31. engine = None
  32. try:
  33. with admin.connect() as connection:
  34. connection.execute(text(f'CREATE DATABASE "{database_name}"'))
  35. _upgrade(database_url, "20260723_190")
  36. engine = create_engine(database_url, pool_pre_ping=True)
  37. rule_uid = new_governance_uid()
  38. with engine.begin() as connection:
  39. connection.execute(
  40. text(
  41. "INSERT INTO public.data_rules "
  42. "(id, rule_uid, name, category, status) VALUES "
  43. "(CAST(:id AS uuid), CAST(:rule_uid AS uuid), "
  44. "'legacy rule', 'legacy', 'active')"
  45. ),
  46. {"id": new_governance_uid(), "rule_uid": rule_uid},
  47. )
  48. connection.execute(
  49. text(
  50. "INSERT INTO public.data_rule_versions "
  51. "(id, rule_uid, version_no, source_text, rule_spec, "
  52. "spec_hash, status) VALUES "
  53. "(CAST(:id AS uuid), CAST(:rule_uid AS uuid), 1, "
  54. "'legacy', '{}'::jsonb, :spec_hash, :legacy_status)"
  55. ),
  56. {
  57. "id": new_governance_uid(),
  58. "rule_uid": rule_uid,
  59. "spec_hash": "a" * 64,
  60. "legacy_status": legacy_status,
  61. },
  62. )
  63. engine.dispose()
  64. engine = None
  65. with pytest.raises(Exception, match="pre-Task7"):
  66. _upgrade(database_url, "20260723_200")
  67. engine = create_engine(database_url, pool_pre_ping=True)
  68. with engine.connect() as connection:
  69. assert connection.execute(
  70. text("SELECT version_num FROM alembic_version")
  71. ).scalar_one() == "20260723_190"
  72. finally:
  73. if engine is not None:
  74. engine.dispose()
  75. with suppress(Exception), admin.connect() as connection:
  76. connection.execute(
  77. text(
  78. "SELECT pg_terminate_backend(pid) "
  79. "FROM pg_stat_activity "
  80. "WHERE datname = :database_name "
  81. "AND pid <> pg_backend_pid()"
  82. ),
  83. {"database_name": database_name},
  84. )
  85. connection.execute(
  86. text(f'DROP DATABASE IF EXISTS "{database_name}"')
  87. )
  88. admin.dispose()