Files
foxhunt/scripts/fix_async_audit_queue_tests_v2.py
jgrusewski a7973d4bf7 🐍 Wave 112: Python fix scripts for audit tests
- fix_all_audit_tests.py: Comprehensive audit test fixes
- fix_async_audit_queue_tests.py: Async queue test fixes (v1)
- fix_async_audit_queue_tests_v2.py: Async queue test fixes (v2)
- fix_audit_compliance.py: Compliance test fixes
2025-10-05 22:23:43 +02:00

166 lines
5.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Fixed migration script for AsyncAuditQueue API changes.
"""
import re
import sys
from pathlib import Path
def fix_file_content(content: str) -> str:
"""Apply all fixes to file content."""
# Fix 1: AsyncAuditQueue::new() - add parameters and .await
# Pattern: AsyncAuditQueue::new(wal_path_expr)
# Replace: AsyncAuditQueue::new(wal_path_expr, Arc::clone(&pool), 100, 100).await.expect("...")
content = re.sub(
r'AsyncAuditQueue::new\(([^)]+)\)(?!\s*\.await)',
r'AsyncAuditQueue::new(\1, Arc::clone(&pool), 100, 100).await.expect("Failed to create AsyncAuditQueue")',
content
)
# Fix 2: Remove Arc::new() wrapper from AsyncAuditQueue (it returns Arc now)
content = re.sub(
r'Arc::new\(AsyncAuditQueue::new\(([^)]+), Arc::clone\(&pool\), 100, 100\)\.await\.expect\("Failed to create AsyncAuditQueue"\)\)',
r'AsyncAuditQueue::new(\1, Arc::clone(&pool), 100, 100).await.expect("Failed to create AsyncAuditQueue")',
content
)
# Fix 3: AuditTrailEngine::new() - add pool and wal_path parameters
# Only fix if it doesn't already have .await
content = re.sub(
r'AuditTrailEngine::new\(([^,)]+)\)(?!\s*\.await)',
r'AuditTrailEngine::new(\1, Arc::clone(&pool), wal_path.clone()).await.expect("Failed to create AuditTrailEngine")',
content
)
# Fix 4: PostgresPool::new() with 2 args -> PostgresPool::connect() with 1 arg
content = re.sub(
r'PostgresPool::new\(([^,)]+),\s*\d+\)',
r'PostgresPool::connect(\1).await.expect("Failed to connect to PostgreSQL")',
content
)
# Fix 5: Add missing pool setup at start of test functions if needed
# This is done more carefully per-function
lines = content.split('\n')
result = []
i = 0
while i < len(lines):
line = lines[i]
result.append(line)
# Check if this is an async test function
if 'async fn test_' in line or 'async fn bench_' in line:
# Look for opening brace
j = i + 1
while j < len(lines) and '{' not in lines[j]:
result.append(lines[j])
j += 1
if j < len(lines):
result.append(lines[j]) # Add the line with {
# Check if next few lines already have pool setup
has_pool = False
for k in range(j + 1, min(j + 5, len(lines))):
if 'let pool =' in lines[k] or 'setup_test_postgres_pool' in lines[k]:
has_pool = True
break
# Check if function uses AsyncAuditQueue or AuditTrailEngine
needs_pool = False
for k in range(j + 1, min(j + 30, len(lines))):
if 'AsyncAuditQueue::new' in lines[k] or 'AuditTrailEngine::new' in lines[k]:
needs_pool = True
break
# Add pool setup if needed
if needs_pool and not has_pool:
result.append(' // Setup PostgreSQL pool for audit persistence')
result.append(' let pool = setup_test_postgres_pool().await;')
result.append(' let wal_path = std::env::temp_dir().join(format!("foxhunt_audit_test_{}.wal", uuid::Uuid::new_v4()));')
result.append('')
i = j
i += 1
content = '\n'.join(result)
# Fix 6: Remove old AuditTrailConfig fields
old_fields_patterns = [
r'\s+enabled:\s*\w+,?\s*\n',
r'\s+compression_algorithm:\s*CompressionAlgorithm::\w+,?\s*\n',
r'\s+encryption_algorithm:\s*EncryptionAlgorithm::\w+,?\s*\n',
r'\s+encryption_key:\s*vec!\[.*?\],?\s*\n',
r'\s+postgres_pool:\s*[^,\n]+,?\s*\n',
r'\s+file_path:\s*[^,\n]+,?\s*\n',
r'\s+enable_checksums:\s*\w+,?\s*\n',
r'\s+enable_tamper_detection:\s*\w+,?\s*\n',
r'\s+enable_best_execution_tracking:\s*\w+,?\s*\n',
r'\s+enable_mifid_reporting:\s*\w+,?\s*\n',
]
for pattern in old_fields_patterns:
content = re.sub(pattern, '', content)
# Fix 7: Fix enum variants
content = content.replace('EncryptionAlgorithm::Aes256Gcm', 'EncryptionAlgorithm::AES256GCM')
# Fix 8: Remove duplicate PostgresPool::connect().await.expect().await patterns
content = re.sub(
r'PostgresPool::connect\(([^)]+)\)\.await\.expect\("([^"]+)"\)\.await',
r'PostgresPool::connect(\1).await.expect("\2")',
content
)
return content
def process_file(file_path: Path) -> bool:
"""Process a single test file."""
print(f"Processing {file_path.name}...")
try:
original = file_path.read_text()
fixed = fix_file_content(original)
if fixed != original:
file_path.write_text(fixed)
print(f" ✅ Fixed {file_path.name}")
return True
else:
print(f" ⏭️ No changes for {file_path.name}")
return False
except Exception as e:
print(f" ❌ Error: {e}")
return False
def main():
test_dir = Path(__file__).parent.parent / 'trading_engine' / 'tests'
if not test_dir.exists():
print(f"Error: {test_dir} not found")
return 1
test_files = sorted(test_dir.glob('*.rs'))
if not test_files:
print(f"Error: No test files in {test_dir}")
return 1
print(f"Found {len(test_files)} test files\n")
updated = sum(1 for f in test_files if process_file(f))
print(f"\n{'='*60}")
print(f"Updated {updated}/{len(test_files)} files")
print(f"{'='*60}")
return 0
if __name__ == '__main__':
sys.exit(main())