You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

152 lines
5.7 KiB

"""
Test safe seeding with lock detection and retry logic
"""
import time
from django.core.management.base import BaseCommand
from django.db import connection
from django.db.utils import OperationalError, IntegrityError
from apps.hadis.models import HadisSect, HadisStatus, HadisTag
class Command(BaseCommand):
help = 'Test safe seeding with lock detection'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.retry_delay = 1 # seconds
self.max_retries = 3
def handle(self, **options):
self.stdout.write("🧪 Testing safe seeding with lock detection...")
# Check database status
self.check_database_locks()
# Test creating a few records
self.test_sect_creation()
self.test_status_creation()
self.test_tag_creation()
self.stdout.write(self.style.SUCCESS("✅ All tests completed successfully!"))
def safe_execute_with_retry(self, operation_name, operation_func, *args, **kwargs):
"""Execute database operation with retry logic for handling locks"""
for attempt in range(self.max_retries):
try:
self.stdout.write(f" Attempting {operation_name} (attempt {attempt + 1}/{self.max_retries})")
result = operation_func(*args, **kwargs)
self.stdout.write(f" ✓ {operation_name} completed successfully")
return result
except OperationalError as e:
error_msg = str(e).lower()
if 'database is locked' in error_msg or 'deadlock' in error_msg:
self.stdout.write(
self.style.WARNING(
f" ⚠ Database lock detected in {operation_name}: {str(e)}"
)
)
if attempt < self.max_retries - 1:
self.stdout.write(f" ⏳ Waiting {self.retry_delay} seconds before retry...")
time.sleep(self.retry_delay)
self.retry_delay = min(self.retry_delay * 1.5, 5)
else:
self.stdout.write(
self.style.ERROR(f" ❌ Max retries reached for {operation_name}")
)
raise
else:
self.stdout.write(
self.style.ERROR(f" ❌ Non-lock error in {operation_name}: {str(e)}")
)
raise
except IntegrityError as e:
if 'unique' in str(e).lower() or 'duplicate' in str(e).lower():
self.stdout.write(
self.style.WARNING(f" ⚠ Record already exists in {operation_name}: {str(e)}")
)
return None
else:
self.stdout.write(
self.style.ERROR(f" ❌ Integrity error in {operation_name}: {str(e)}")
)
raise
except Exception as e:
self.stdout.write(
self.style.ERROR(f" ❌ Unexpected error in {operation_name}: {str(e)}")
)
raise
def check_database_locks(self):
"""Check for existing database locks"""
try:
with connection.cursor() as cursor:
cursor.execute("SELECT 1;")
cursor.fetchone()
self.stdout.write("✓ Database connection is working")
except Exception as e:
self.stdout.write(
self.style.WARNING(f"Could not check database: {str(e)}")
)
def create_test_sect(self):
"""Create a test sect"""
sect, created = HadisSect.objects.get_or_create(
sect_type='test',
defaults={
'title': 'Test Sect',
'is_active': True,
'order': 999
}
)
if created:
self.stdout.write(" ✅ Created test sect")
else:
self.stdout.write(" ✓ Test sect already exists")
return sect
def create_test_status(self):
"""Create a test status"""
status, created = HadisStatus.objects.get_or_create(
title='Test Status',
defaults={
'color': 'blue',
'order': 999
}
)
if created:
self.stdout.write(" ✅ Created test status")
else:
self.stdout.write(" ✓ Test status already exists")
return status
def create_test_tag(self):
"""Create a test tag"""
tag, created = HadisTag.objects.get_or_create(
title='Test Tag',
defaults={'status': True}
)
if created:
self.stdout.write(" ✅ Created test tag")
else:
self.stdout.write(" ✓ Test tag already exists")
return tag
def test_sect_creation(self):
"""Test sect creation with retry logic"""
self.stdout.write("🕌 Testing sect creation...")
self.safe_execute_with_retry("Create test sect", self.create_test_sect)
def test_status_creation(self):
"""Test status creation with retry logic"""
self.stdout.write("📊 Testing status creation...")
self.safe_execute_with_retry("Create test status", self.create_test_status)
def test_tag_creation(self):
"""Test tag creation with retry logic"""
self.stdout.write("🏷️ Testing tag creation...")
self.safe_execute_with_retry("Create test tag", self.create_test_tag)