# APScheduler Test Plan ## Overview This document outlines a comprehensive test plan to verify APScheduler functionality and visibility in the Lin application. The plan includes both automated tests and manual verification steps. ## Test Objectives 1. **Verify APScheduler is properly initialized** during application startup 2. **Confirm logging configuration** shows APScheduler messages 3. **Test schedule loading functionality** from the database 4. **Verify job creation and execution** mechanisms 5. **Ensure scheduler persistence** and error handling ## Test Environment Setup ### Prerequisites - Python 3.8+ installed - All dependencies from `backend/requirements.txt` installed - Environment variables configured (Supabase credentials, etc.) - Access to the Lin application source code ### Test Files to Create #### 1. `test_scheduler_visibility.py` **Purpose**: Standalone test script to verify APScheduler logging and basic functionality ```python #!/usr/bin/env python3 """ Test script for APScheduler visibility and functionality. This script tests whether APScheduler is working and properly configured for logging. """ import sys import os import logging from pathlib import Path from datetime import datetime # Add the backend directory to the Python path backend_dir = Path(__file__).parent / "backend" sys.path.insert(0, str(backend_dir)) def setup_logging(): """Setup logging for the test script.""" logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) # Configure APScheduler logger specifically logging.getLogger('apscheduler').setLevel(logging.DEBUG) print("šŸ”§ Logging configured for APScheduler") def test_apscheduler_import(): """Test that APScheduler can be imported.""" try: from backend.scheduler.apscheduler_service import APSchedulerService print("āœ… APSchedulerService imported successfully") return True except Exception as e: print(f"āŒ Failed to import APSchedulerService: {e}") return False def test_scheduler_initialization(): """Test APScheduler initialization with mock app.""" try: from backend.scheduler.apscheduler_service import APSchedulerService # Create a mock app object class MockApp: def __init__(self): self.config = { 'SUPABASE_URL': 'https://test.supabase.co', 'SUPABASE_KEY': 'test_key', 'SCHEDULER_ENABLED': True } # Initialize the scheduler service app = MockApp() scheduler_service = APSchedulerService() # Mock the Supabase client initialization class MockSupabaseClient: def table(self, table_name): return self def select(self, columns): return self def execute(self): # Return empty schedule data for testing return type('obj', (object,), {'data': []})() scheduler_service.supabase_client = MockSupabaseClient() # Test initialization scheduler_service.init_app(app) if scheduler_service.scheduler is not None: print("āœ… APScheduler initialized successfully") print(f"šŸ“Š Current jobs: {len(scheduler_service.scheduler.get_jobs())}") return True else: print("āŒ APScheduler initialization failed") return False except Exception as e: print(f"āŒ Error testing APScheduler initialization: {e}") import traceback traceback.print_exc() return False def test_schedule_loading(): """Test the schedule loading functionality.""" try: from backend.scheduler.apscheduler_service import APSchedulerService # Create scheduler service scheduler_service = APSchedulerService() # Mock the Supabase client class MockSupabaseClient: def table(self, table_name): return self def select(self, columns): return self def execute(self): # Return mock schedule data mock_data = [ { 'id': 'test_schedule_1', 'schedule_time': 'Monday 09:00', 'adjusted_time': 'Monday 08:55', 'Social_network': { 'id_utilisateur': 'test_user_1', 'token': 'test_token', 'sub': 'test_sub' } } ] return type('obj', (object,), {'data': mock_data})() scheduler_service.supabase_client = MockSupabaseClient() # Test schedule loading scheduler_service.load_schedules() if scheduler_service.scheduler is not None: jobs = scheduler_service.scheduler.get_jobs() print(f"āœ… Schedule loading test completed") print(f"šŸ“Š Total jobs: {len(jobs)}") # Check for specific job types loader_jobs = [job for job in jobs if job.id == 'load_schedules'] content_jobs = [job for job in jobs if job.id.startswith('gen_')] publish_jobs = [job for job in jobs if job.id.startswith('pub_')] print(f"šŸ”„ Loader jobs: {len(loader_jobs)}") print(f"šŸ“ Content generation jobs: {len(content_jobs)}") print(f"šŸ“¤ Publishing jobs: {len(publish_jobs)}") return len(jobs) > 0 else: print("āŒ Scheduler not initialized for schedule loading test") return False except Exception as e: print(f"āŒ Error testing schedule loading: {e}") import traceback traceback.print_exc() return False def main(): """Main test function.""" print("šŸš€ Testing APScheduler visibility and functionality...") print("=" * 60) setup_logging() tests = [ ("APScheduler Import", test_apscheduler_import), ("Scheduler Initialization", test_scheduler_initialization), ("Schedule Loading", test_schedule_loading), ] passed = 0 total = len(tests) for test_name, test_func in tests: print(f"\nšŸ“‹ Running test: {test_name}") print("-" * 40) if test_func(): passed += 1 print(f"āœ… {test_name} PASSED") else: print(f"āŒ {test_name} FAILED") print("\n" + "=" * 60) print(f"šŸ“Š Test Results: {passed}/{total} tests passed") if passed == total: print("šŸŽ‰ All tests passed! APScheduler is working correctly.") return True else: print("āš ļø Some tests failed. Please check the error messages above.") return False if __name__ == "__main__": success = main() sys.exit(0 if success else 1) ``` #### 2. `test_scheduler_integration.py` **Purpose**: Test APScheduler integration with the actual Flask application ```python #!/usr/bin/env python3 """ Integration test for APScheduler with Flask application. Tests the actual application startup and scheduler initialization. """ import sys import os import subprocess import time from pathlib import Path def test_app_startup_with_scheduler(): """Test that the Flask application starts with APScheduler visible.""" try: # Change to the project directory project_dir = Path(__file__).parent os.chdir(project_dir) # Start the application print("šŸš€ Starting Flask application with APScheduler...") process = subprocess.Popen( [sys.executable, "start_app.py"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1, universal_newlines=True ) # Wait for startup and capture output startup_timeout = 30 # 30 seconds timeout start_time = time.time() scheduler_found = False while time.time() - start_time < startup_timeout: output = process.stdout.readline() if output: print(output.strip()) # Check for APScheduler initialization messages if "Initializing APScheduler" in output: scheduler_found = True print("āœ… APScheduler initialization message found!") # Check for successful startup if "running on http" in output.lower(): break # Terminate the process process.terminate() process.wait(timeout=10) if scheduler_found: print("āœ… APScheduler is visible during application startup") return True else: print("āŒ APScheduler messages not found in startup logs") return False except Exception as e: print(f"āŒ Error testing app startup: {e}") return False def main(): """Main integration test function.""" print("šŸ”— Testing APScheduler integration with Flask application...") print("=" * 60) success = test_app_startup_with_scheduler() print("\n" + "=" * 60) if success: print("šŸŽ‰ Integration test passed! APScheduler is working in the Flask app.") else: print("āš ļø Integration test failed. APScheduler may not be properly configured.") return success if __name__ == "__main__": success = main() sys.exit(0 if success else 1) ``` ## Test Execution Steps ### Step 1: Run Standalone Test ```bash # Navigate to project directory cd /path/to/your/project # Run the standalone test python test_scheduler_visibility.py ``` **Expected Output**: ``` šŸš€ Testing APScheduler visibility and functionality... ============================================================ šŸ”§ Logging configured for APScheduler šŸ“‹ Running test: APScheduler Import ---------------------------------------- āœ… APSchedulerService imported successfully āœ… APScheduler Import PASSED šŸ“‹ Running test: Scheduler Initialization ---------------------------------------- āœ… APScheduler initialized successfully šŸ“Š Current jobs: 1 āœ… Scheduler Initialization PASSED šŸ“‹ Running test: Schedule Loading ---------------------------------------- āœ… Schedule loading test completed šŸ“Š Total jobs: 3 šŸ”„ Loader jobs: 1 šŸ“ Content generation jobs: 1 šŸ“¤ Publishing jobs: 1 āœ… Schedule Loading PASSED ============================================================ šŸ“Š Test Results: 3/3 tests passed šŸŽ‰ All tests passed! APScheduler is working correctly. ``` ### Step 2: Run Integration Test ```bash # Run the integration test python test_scheduler_integration.py ``` **Expected Output**: ``` šŸ”— Testing APScheduler integration with Flask application... ============================================================ šŸš€ Starting Flask application with APScheduler... Starting Lin application on port 7860... ============================================================ ============================================================ Flask application starting... Access the application at: http://localhost:7860 http://127.0.0.1:7860 ============================================================ * Serving Flask app 'backend.app' * Debug mode: off INFO:backend.app:Initializing APScheduler... INFO:backend.apscheduler_service:Initializing APScheduler... INFO:backend.apscheduler_service:Initializing Supabase client... INFO:backend.apscheduler_service:Supabase client initialized INFO:backend.apscheduler_service:Creating BackgroundScheduler... INFO:backend.apscheduler_service:BackgroundScheduler created INFO:backend.apscheduler_service:Starting scheduler... INFO:backend.apscheduler_service:Scheduler started INFO:backend.apscheduler_service:Adding periodic job to load schedules... INFO:backend.apscheduler_service:Periodic job added INFO:backend.apscheduler_service:Loading schedules immediately... INFO:backend.apscheduler_service:Found 0 schedules in database INFO:backend.apscheduler_service:Updated APScheduler schedule INFO:backend.app:āœ… APScheduler initialized successfully INFO:backend.app:šŸ“Š Current jobs: 1 INFO:backend.app:šŸ”„ Schedule loading job added (runs every 5 minutes) * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:7860 * Running on http://10.108.66.211:7860 āœ… APScheduler initialization message found! āœ… APScheduler is visible during application startup ============================================================ šŸŽ‰ Integration test passed! APScheduler is working in the Flask app. ``` ## Manual Verification Steps ### 1. Check Application Startup Logs After implementing the logging configuration, start your application and look for: - `Initializing APScheduler...` - `BackgroundScheduler created` - `Scheduler started` - `Adding periodic job to load schedules...` - `Schedule loading job added (runs every 5 minutes)` ### 2. Verify Scheduler Functionality 1. Create a schedule via the API 2. Check logs for schedule loading messages 3. Verify that individual jobs are created 4. Monitor for job execution at scheduled times ### 3. Test Error Handling 1. Test with invalid Supabase credentials 2. Test with missing environment variables 3. Verify appropriate error messages are logged ## Troubleshooting Guide ### Common Issues and Solutions #### Issue 1: No APScheduler messages in logs **Solution**: Ensure logging configuration is added to `backend/app.py`: ```python import logging logging.basicConfig(level=logging.DEBUG) logging.getLogger('apscheduler').setLevel(logging.DEBUG) ``` #### Issue 2: Scheduler initialization fails **Solution**: Check environment variables and Supabase connection: - Verify `SUPABASE_URL` and `SUPABASE_KEY` are set - Check network connectivity to Supabase - Verify database tables exist #### Issue 3: Jobs not executing **Solution**: - Check that the application is running continuously - Verify job triggers are correctly configured - Check for any exceptions in job execution #### Issue 4: Test script fails **Solution**: - Ensure all dependencies are installed - Check Python path includes the backend directory - Verify mock data structure matches actual database schema ## Success Criteria The APScheduler implementation is considered successful when: 1. āœ… **Startup logs** show APScheduler initialization messages 2. āœ… **Test scripts** pass all tests 3. āœ… **Integration test** shows scheduler working in Flask app 4. āœ… **Manual verification** confirms job creation and execution 5. āœ… **Error handling** works appropriately 6. āœ… **Documentation** is updated with troubleshooting guide ## Next Steps 1. **Approve this test plan** 2. **Switch to Code mode** to implement the logging configuration 3. **Create the test scripts** outlined in this plan 4. **Execute the tests** to verify APScheduler visibility 5. **Update documentation** with the final solution