130 lines
4.3 KiB
Python
130 lines
4.3 KiB
Python
"""
|
|
Verification script for Bug #66: CrashLoopBackOff fix.
|
|
|
|
Root cause: Two uncommitted changes caused Django migration drift in the
|
|
Docker container:
|
|
1. MODEL_CHOICES labels changed from 'Seedance 2.0' to 'AirDrama' in models.py
|
|
but migration 0004 (which records this change) was untracked by git.
|
|
2. Index name='generation__user_id_371350_idx' was added to models.py but not
|
|
committed — the migration already had this name.
|
|
|
|
Without migration 0004 in the Docker image, Django detected model-migration
|
|
mismatch at startup, causing the pod to enter CrashLoopBackOff.
|
|
|
|
Fix: Commit both models.py (with explicit index name) and migration 0004.
|
|
"""
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
|
|
# Ensure we're in the backend directory
|
|
BACKEND_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
if os.path.basename(BACKEND_DIR) != 'backend':
|
|
BACKEND_DIR = os.path.join(BACKEND_DIR, 'backend')
|
|
|
|
os.chdir(BACKEND_DIR)
|
|
sys.path.insert(0, BACKEND_DIR)
|
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
|
|
|
|
|
|
def test_django_check():
|
|
"""Verify Django system check passes with no issues."""
|
|
result = subprocess.run(
|
|
[sys.executable, 'manage.py', 'check'],
|
|
capture_output=True, text=True, cwd=BACKEND_DIR,
|
|
)
|
|
assert result.returncode == 0, f"Django check failed:\n{result.stderr}"
|
|
print("PASS: Django system check — no issues found")
|
|
|
|
|
|
def test_no_pending_migrations():
|
|
"""Verify there are no pending migrations (the root cause of Bug #66)."""
|
|
result = subprocess.run(
|
|
[sys.executable, 'manage.py', 'makemigrations', '--check', '--dry-run'],
|
|
capture_output=True, text=True, cwd=BACKEND_DIR,
|
|
)
|
|
assert result.returncode == 0, (
|
|
f"Pending migrations detected (this was the Bug #66 root cause):\n"
|
|
f"{result.stdout}\n{result.stderr}"
|
|
)
|
|
print("PASS: No pending migrations detected")
|
|
|
|
|
|
def test_index_name_matches_migration():
|
|
"""Verify the model index name matches what's in the migration file."""
|
|
import django
|
|
django.setup()
|
|
|
|
from apps.generation.models import GenerationRecord
|
|
|
|
meta_indexes = GenerationRecord._meta.indexes
|
|
assert len(meta_indexes) >= 1, "GenerationRecord should have at least 1 index"
|
|
|
|
user_created_index = meta_indexes[0]
|
|
assert user_created_index.name == 'generation__user_id_371350_idx', (
|
|
f"Index name mismatch: got '{user_created_index.name}', "
|
|
f"expected 'generation__user_id_371350_idx'"
|
|
)
|
|
print("PASS: Index name matches migration file")
|
|
|
|
|
|
def test_migration_0004_exists():
|
|
"""Verify migration 0004 for model choice label change exists."""
|
|
migration_path = os.path.join(
|
|
BACKEND_DIR, 'apps', 'generation', 'migrations',
|
|
'0004_alter_generationrecord_model.py'
|
|
)
|
|
assert os.path.exists(migration_path), (
|
|
f"Migration 0004 not found at {migration_path}"
|
|
)
|
|
print("PASS: Migration 0004 exists")
|
|
|
|
|
|
def test_model_choices_match_migration():
|
|
"""Verify MODEL_CHOICES values match what migration 0004 expects."""
|
|
import django
|
|
django.setup()
|
|
|
|
from apps.generation.models import GenerationRecord
|
|
|
|
choices_dict = dict(GenerationRecord.MODEL_CHOICES)
|
|
assert choices_dict.get('seedance_2.0') == 'AirDrama', (
|
|
f"Expected 'AirDrama', got {choices_dict.get('seedance_2.0')!r}"
|
|
)
|
|
assert choices_dict.get('seedance_2.0_fast') == 'AirDrama Fast', (
|
|
f"Expected 'AirDrama Fast', got {choices_dict.get('seedance_2.0_fast')!r}"
|
|
)
|
|
print("PASS: MODEL_CHOICES labels match migration 0004")
|
|
|
|
|
|
def test_wsgi_loads():
|
|
"""Verify WSGI application loads (gunicorn entrypoint)."""
|
|
import django
|
|
django.setup()
|
|
|
|
from config.wsgi import application
|
|
assert application is not None, "WSGI application failed to load"
|
|
print("PASS: WSGI application loads successfully")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
tests = [
|
|
test_django_check,
|
|
test_no_pending_migrations,
|
|
test_index_name_matches_migration,
|
|
test_migration_0004_exists,
|
|
test_model_choices_match_migration,
|
|
test_wsgi_loads,
|
|
]
|
|
passed = failed = 0
|
|
for test in tests:
|
|
try:
|
|
test()
|
|
passed += 1
|
|
except Exception as e:
|
|
print(f"FAIL: {test.__name__}: {e}")
|
|
failed += 1
|
|
|
|
print(f"\nResults: {passed} passed, {failed} failed")
|
|
sys.exit(1 if failed else 0)
|