test_rule_publication_migration_upgrade.py 3.3 KB

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