2025-03-27 07:22:56 +08:00
import pytest
import os
import subprocess
from pathlib import Path
from pytest_postgresql import factories
2025-03-27 07:59:50 +08:00
import shutil
import tempfile
2025-03-27 07:22:56 +08:00
# Create postgresql fixture
postgresql_my_proc = factories . postgresql_proc ( port = None )
postgresql_my = factories . postgresql ( " postgresql_my_proc " )
@pytest.fixture ( scope = " function " )
def schema_setup ( postgresql_my ) :
""" Fixture to provide a test postgres database """
return postgresql_my
2025-03-28 05:50:41 +08:00
def test_aaaasschema_migration_check ( schema_setup , monkeypatch ) :
2025-03-27 07:22:56 +08:00
""" Test to check if schema requires migration """
# Set test database URL
test_db_url = f " postgresql:// { schema_setup . info . user } :@ { schema_setup . info . host } : { schema_setup . info . port } / { schema_setup . info . dbname } "
2025-12-23 09:03:53 +08:00
# test_db_url = "postgresql://test-user:test-password@test-host.example.com/test-db?sslmode=require"
2025-03-28 05:50:41 +08:00
monkeypatch . setenv ( " DATABASE_URL " , test_db_url )
2025-03-27 07:22:56 +08:00
2025-03-30 06:27:09 +08:00
deploy_dir = Path ( " ./litellm-proxy-extras/litellm_proxy_extras " )
2025-03-27 07:59:50 +08:00
source_migrations_dir = deploy_dir / " migrations "
2025-03-27 08:12:09 +08:00
schema_path = Path ( " ./schema.prisma " )
2025-03-27 07:22:56 +08:00
2025-03-27 07:59:50 +08:00
# Create temporary migrations directory next to schema.prisma
temp_migrations_dir = schema_path . parent / " migrations "
2025-03-27 07:22:56 +08:00
2025-03-27 07:59:50 +08:00
try :
# Copy migrations to correct location
if temp_migrations_dir . exists ( ) :
shutil . rmtree ( temp_migrations_dir )
shutil . copytree ( source_migrations_dir , temp_migrations_dir )
2025-03-27 07:22:56 +08:00
2025-03-27 07:59:50 +08:00
if not temp_migrations_dir . exists ( ) or not any ( temp_migrations_dir . iterdir ( ) ) :
print ( " No existing migrations found - first migration needed " )
2025-03-29 23:23:18 +08:00
pytest . fail (
" No existing migrations found - first migration needed. Run `litellm/ci_cd/baseline_db.py` to create new migration -E.g. `python litellm/ci_cd/baseline_db_migration.py`. "
)
2025-03-27 07:22:56 +08:00
2025-03-27 07:59:50 +08:00
# Apply all existing migrations
subprocess . run (
[ " prisma " , " migrate " , " deploy " , " --schema " , str ( schema_path ) ] , check = True
)
# Compare current database state against schema
2025-03-27 07:22:56 +08:00
diff_result = subprocess . run (
[
" prisma " ,
" migrate " ,
" diff " ,
2025-03-27 07:59:50 +08:00
" --from-url " ,
test_db_url ,
2025-03-27 07:22:56 +08:00
" --to-schema-datamodel " ,
2025-03-27 07:59:50 +08:00
str ( schema_path ) ,
" --script " , # Show the SQL diff
" --exit-code " , # Return exit code 2 if there are differences
2025-03-27 07:22:56 +08:00
] ,
capture_output = True ,
text = True ,
)
2025-03-27 07:59:50 +08:00
print ( " Exit code: " , diff_result . returncode )
print ( " Stdout: " , diff_result . stdout )
print ( " Stderr: " , diff_result . stderr )
if diff_result . returncode == 2 :
print ( " Schema changes detected. New migration needed. " )
print ( " Schema differences: " )
print ( diff_result . stdout )
pytest . fail (
2025-03-29 23:23:18 +08:00
" Schema changes detected - new migration required. Run `litellm/ci_cd/run_migration.py` to create new migration -E.g. `python litellm/ci_cd/run_migration.py <migration_name>`. "
2025-03-27 07:59:50 +08:00
)
else :
print ( " No schema changes detected. Migration not needed. " )
finally :
# Clean up: remove temporary migrations directory
if temp_migrations_dir . exists ( ) :
shutil . rmtree ( temp_migrations_dir )