#!/usr/bin/env python3 """ Production Deployment Test Script Tests all components before going live """ import os import sys import json import time from pathlib import Path from datetime import datetime # Add project to path sys.path.insert(0, str(Path(__file__).parent)) def test_environment(): """Test environment variables are set""" print("\n=== Testing Environment Variables ===") required_vars = [ 'WORDPRESS_USERNAME', 'WORDPRESS_API_KEY', 'YOUTUBE_CHANNEL_URL', 'INSTAGRAM_USERNAME', 'INSTAGRAM_PASSWORD', 'TIKTOK_TARGET', 'NAS_PATH' ] missing = [] for var in required_vars: value = os.getenv(var) if value: # Don't print sensitive values if 'PASSWORD' in var or 'KEY' in var: print(f"✓ {var}: ***SET***") else: print(f"✓ {var}: {value[:20]}..." if len(value) > 20 else f"✓ {var}: {value}") else: print(f"✗ {var}: MISSING") missing.append(var) if missing: print(f"\n❌ Missing variables: {', '.join(missing)}") return False print("\n✅ All environment variables set") return True def test_directories(): """Test required directories exist and are writable""" print("\n=== Testing Directory Structure ===") dirs_to_test = [ Path("/opt/hvac-kia-content"), Path("/var/log/hvac-content"), Path(os.getenv('NAS_PATH', '/mnt/nas/hvacknowitall')) ] all_good = True for dir_path in dirs_to_test: if dir_path.exists(): # Test write permissions test_file = dir_path / f"test_{datetime.now():%Y%m%d_%H%M%S}.txt" try: test_file.write_text("test") test_file.unlink() print(f"✓ {dir_path}: Exists and writable") except PermissionError: print(f"✗ {dir_path}: Exists but not writable") all_good = False else: print(f"✗ {dir_path}: Does not exist") all_good = False if all_good: print("\n✅ All directories accessible") else: print("\n❌ Directory issues found") return all_good def test_config_validation(): """Test configuration validation""" print("\n=== Testing Configuration Validation ===") try: from run_production import validate_config validate_config() print("✅ Configuration validation passed") return True except Exception as e: print(f"❌ Configuration validation failed: {e}") return False def test_scrapers(): """Test each scraper can initialize""" print("\n=== Testing Scraper Initialization ===") from src.base_scraper import ScraperConfig from pathlib import Path test_config = ScraperConfig( source_name="test", brand_name="hvacknowitall", data_dir=Path("/tmp/test_data"), logs_dir=Path("/tmp/test_logs"), timezone="America/Halifax" ) scrapers_to_test = [ ("WordPress", "src.wordpress_scraper", "WordPressScraper"), ("YouTube", "src.youtube_scraper", "YouTubeScraper"), ("Instagram", "src.instagram_scraper", "InstagramScraper"), ("TikTok", "src.tiktok_scraper_advanced", "TikTokScraperAdvanced"), ("MailChimp", "src.rss_scraper", "RSSScraperMailChimp"), ("Podcast", "src.rss_scraper", "RSSScraperPodcast") ] all_good = True for name, module_path, class_name in scrapers_to_test: try: module = __import__(module_path, fromlist=[class_name]) scraper_class = getattr(module, class_name) scraper = scraper_class(test_config) print(f"✓ {name}: Initialized successfully") except Exception as e: print(f"✗ {name}: Failed to initialize - {e}") all_good = False if all_good: print("\n✅ All scrapers initialized") else: print("\n⚠️ Some scrapers failed to initialize") return all_good def test_systemd_files(): """Test systemd service files exist""" print("\n=== Testing Systemd Files ===") systemd_files = [ Path("systemd/hvac-content-aggregator.service"), Path("systemd/hvac-content-aggregator.timer"), Path("systemd/hvac-content-aggregator@.service"), Path("systemd/hvac-tiktok-captions.service"), Path("systemd/hvac-tiktok-captions.timer") ] all_good = True for file_path in systemd_files: if file_path.exists(): print(f"✓ {file_path}: Exists") else: print(f"✗ {file_path}: Missing") all_good = False if all_good: print("\n✅ All systemd files present") else: print("\n❌ Some systemd files missing") return all_good def test_python_dependencies(): """Test all required Python packages are installed""" print("\n=== Testing Python Dependencies ===") required_packages = [ "requests", "pytz", "python-dotenv", "feedparser", "markitdown", "scrapling", "instaloader", "yt-dlp", "tenacity" ] all_good = True for package in required_packages: try: __import__(package.replace("-", "_")) print(f"✓ {package}: Installed") except ImportError: print(f"✗ {package}: Not installed") all_good = False if all_good: print("\n✅ All dependencies installed") else: print("\n❌ Some dependencies missing") print("Run: pip install -r requirements.txt") return all_good def test_dry_run(): """Test a dry run of the production script""" print("\n=== Testing Dry Run ===") try: # Import and test validation only from run_production import validate_environment, validate_config validate_environment() print("✓ Environment validation passed") validate_config() print("✓ Configuration validation passed") print("\n✅ Dry run successful") return True except Exception as e: print(f"\n❌ Dry run failed: {e}") return False def main(): """Run all tests""" print("=" * 50) print("HVAC Know It All - Production Deployment Test") print("=" * 50) # Load environment from dotenv import load_dotenv load_dotenv() tests = [ ("Environment Variables", test_environment), ("Python Dependencies", test_python_dependencies), ("Configuration Validation", test_config_validation), ("Scraper Initialization", test_scrapers), ("Systemd Files", test_systemd_files), ("Dry Run", test_dry_run) ] # Don't test directories in development if os.path.exists("/opt/hvac-kia-content"): tests.insert(2, ("Directory Structure", test_directories)) results = [] for test_name, test_func in tests: try: result = test_func() results.append((test_name, result)) except Exception as e: print(f"\n❌ {test_name} crashed: {e}") results.append((test_name, False)) # Summary print("\n" + "=" * 50) print("TEST SUMMARY") print("=" * 50) passed = 0 failed = 0 for test_name, result in results: status = "✅ PASS" if result else "❌ FAIL" print(f"{status}: {test_name}") if result: passed += 1 else: failed += 1 print(f"\nTotal: {passed} passed, {failed} failed") if failed == 0: print("\n🎉 READY FOR PRODUCTION DEPLOYMENT 🎉") return 0 else: print(f"\n⚠️ Fix {failed} issue(s) before deployment") return 1 if __name__ == "__main__": sys.exit(main())