""" 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)