364 lines
12 KiB
Python
Executable File
364 lines
12 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
System Test Script for Video Player
|
|
Tests all components of the video player system
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import json
|
|
import time
|
|
import subprocess
|
|
from pathlib import Path
|
|
import logging
|
|
|
|
class SystemTester:
|
|
"""Test all components of the video player system"""
|
|
|
|
def __init__(self):
|
|
self.logger = self.setup_logging()
|
|
self.test_results = {}
|
|
|
|
def setup_logging(self):
|
|
"""Setup logging for test script"""
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(levelname)s - %(message)s'
|
|
)
|
|
return logging.getLogger(__name__)
|
|
|
|
def print_header(self, title: str):
|
|
"""Print formatted header"""
|
|
print("\n" + "="*60)
|
|
print(f" {title}")
|
|
print("="*60)
|
|
|
|
def test_python_modules(self) -> bool:
|
|
"""Test if all required Python modules are available"""
|
|
self.print_header("Testing Python Modules")
|
|
|
|
required_modules = [
|
|
'vlc',
|
|
'RPi.GPIO',
|
|
'psutil',
|
|
'yaml',
|
|
'dotenv'
|
|
]
|
|
|
|
all_available = True
|
|
|
|
for module in required_modules:
|
|
try:
|
|
__import__(module)
|
|
print(f"✅ {module} - Available")
|
|
self.test_results[f"module_{module}"] = True
|
|
except ImportError as e:
|
|
print(f"❌ {module} - Not available: {e}")
|
|
self.test_results[f"module_{module}"] = False
|
|
all_available = False
|
|
|
|
return all_available
|
|
|
|
def test_system_commands(self) -> bool:
|
|
"""Test if required system commands are available"""
|
|
self.print_header("Testing System Commands")
|
|
|
|
required_commands = [
|
|
'vlc',
|
|
'python3',
|
|
'systemctl'
|
|
]
|
|
|
|
all_available = True
|
|
|
|
for command in required_commands:
|
|
try:
|
|
result = subprocess.run([command, '--version'],
|
|
capture_output=True, text=True, timeout=5)
|
|
if result.returncode == 0:
|
|
print(f"✅ {command} - Available")
|
|
self.test_results[f"command_{command}"] = True
|
|
else:
|
|
print(f"❌ {command} - Not working properly")
|
|
self.test_results[f"command_{command}"] = False
|
|
all_available = False
|
|
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
print(f"❌ {command} - Not found")
|
|
self.test_results[f"command_{command}"] = False
|
|
all_available = False
|
|
|
|
return all_available
|
|
|
|
def test_gpio_access(self) -> bool:
|
|
"""Test GPIO access"""
|
|
self.print_header("Testing GPIO Access")
|
|
|
|
try:
|
|
import RPi.GPIO as GPIO
|
|
GPIO.setmode(GPIO.BCM)
|
|
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
|
GPIO.cleanup()
|
|
print("✅ GPIO access - Working")
|
|
self.test_results["gpio_access"] = True
|
|
return True
|
|
except Exception as e:
|
|
print(f"❌ GPIO access - Failed: {e}")
|
|
self.test_results["gpio_access"] = False
|
|
return False
|
|
|
|
def test_configuration_files(self) -> bool:
|
|
"""Test configuration files"""
|
|
self.print_header("Testing Configuration Files")
|
|
|
|
config_dir = Path("/etc/video_player")
|
|
required_files = [
|
|
"config.json",
|
|
"channels.json",
|
|
"ir_mapping.json"
|
|
]
|
|
|
|
all_exist = True
|
|
|
|
for file_name in required_files:
|
|
file_path = config_dir / file_name
|
|
if file_path.exists():
|
|
try:
|
|
with open(file_path, 'r') as f:
|
|
json.load(f)
|
|
print(f"✅ {file_name} - Valid JSON")
|
|
self.test_results[f"config_{file_name}"] = True
|
|
except json.JSONDecodeError as e:
|
|
print(f"❌ {file_name} - Invalid JSON: {e}")
|
|
self.test_results[f"config_{file_name}"] = False
|
|
all_exist = False
|
|
else:
|
|
print(f"❌ {file_name} - Not found")
|
|
self.test_results[f"config_{file_name}"] = False
|
|
all_exist = False
|
|
|
|
return all_exist
|
|
|
|
def test_video_files(self) -> bool:
|
|
"""Test video files in the configured folder"""
|
|
self.print_header("Testing Video Files")
|
|
|
|
try:
|
|
config_file = Path("/etc/video_player/config.json")
|
|
if not config_file.exists():
|
|
print("❌ Configuration file not found")
|
|
self.test_results["video_files"] = False
|
|
return False
|
|
|
|
with open(config_file, 'r') as f:
|
|
config = json.load(f)
|
|
|
|
video_folder = Path(config.get('video_folder', '/home/pi/Videos'))
|
|
|
|
if not video_folder.exists():
|
|
print(f"❌ Video folder does not exist: {video_folder}")
|
|
self.test_results["video_files"] = False
|
|
return False
|
|
|
|
video_extensions = {'.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm', '.m4v'}
|
|
video_files = []
|
|
|
|
for file_path in video_folder.rglob('*'):
|
|
if file_path.is_file() and file_path.suffix.lower() in video_extensions:
|
|
video_files.append(file_path)
|
|
|
|
print(f"✅ Found {len(video_files)} video files in {video_folder}")
|
|
for video_file in video_files[:5]: # Show first 5
|
|
print(f" - {video_file.name}")
|
|
|
|
if len(video_files) > 5:
|
|
print(f" ... and {len(video_files) - 5} more")
|
|
|
|
self.test_results["video_files"] = True
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Video files test failed: {e}")
|
|
self.test_results["video_files"] = False
|
|
return False
|
|
|
|
def test_service_status(self) -> bool:
|
|
"""Test systemd service status"""
|
|
self.print_header("Testing Service Status")
|
|
|
|
try:
|
|
result = subprocess.run(['systemctl', 'is-active', 'video-player'],
|
|
capture_output=True, text=True, timeout=5)
|
|
|
|
if result.returncode == 0:
|
|
status = result.stdout.strip()
|
|
if status == 'active':
|
|
print("✅ Service - Running")
|
|
self.test_results["service_status"] = True
|
|
return True
|
|
else:
|
|
print(f"⚠️ Service - {status}")
|
|
self.test_results["service_status"] = False
|
|
return False
|
|
else:
|
|
print("❌ Service - Not found or not running")
|
|
self.test_results["service_status"] = False
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Service test failed: {e}")
|
|
self.test_results["service_status"] = False
|
|
return False
|
|
|
|
def test_ir_remote_system(self) -> bool:
|
|
"""Test IR remote system"""
|
|
self.print_header("Testing IR Remote System")
|
|
|
|
try:
|
|
# Test if IR remote module can be imported
|
|
sys.path.insert(0, '/opt/video_player')
|
|
from ir_remote import IRRemote, NECProtocol, RC5Protocol
|
|
|
|
print("✅ IR Remote modules - Imported successfully")
|
|
|
|
# Test protocol initialization
|
|
nec_protocol = NECProtocol()
|
|
rc5_protocol = RC5Protocol()
|
|
|
|
print("✅ IR Protocols - Initialized successfully")
|
|
|
|
self.test_results["ir_remote"] = True
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ IR Remote system test failed: {e}")
|
|
self.test_results["ir_remote"] = False
|
|
return False
|
|
|
|
def test_vlc_integration(self) -> bool:
|
|
"""Test VLC integration"""
|
|
self.print_header("Testing VLC Integration")
|
|
|
|
try:
|
|
import vlc
|
|
|
|
# Create VLC instance
|
|
instance = vlc.Instance(['--quiet'])
|
|
player = instance.media_player_new()
|
|
|
|
print("✅ VLC Instance - Created successfully")
|
|
print("✅ VLC Player - Created successfully")
|
|
|
|
self.test_results["vlc_integration"] = True
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ VLC integration test failed: {e}")
|
|
self.test_results["vlc_integration"] = False
|
|
return False
|
|
|
|
def test_permissions(self) -> bool:
|
|
"""Test file and directory permissions"""
|
|
self.print_header("Testing Permissions")
|
|
|
|
required_paths = [
|
|
"/opt/video_player",
|
|
"/etc/video_player",
|
|
"/var/log/video_player.log"
|
|
]
|
|
|
|
all_accessible = True
|
|
|
|
for path in required_paths:
|
|
path_obj = Path(path)
|
|
if path_obj.exists():
|
|
if os.access(path_obj, os.R_OK):
|
|
print(f"✅ {path} - Readable")
|
|
else:
|
|
print(f"❌ {path} - Not readable")
|
|
all_accessible = False
|
|
|
|
if os.access(path_obj, os.W_OK):
|
|
print(f"✅ {path} - Writable")
|
|
else:
|
|
print(f"❌ {path} - Not writable")
|
|
all_accessible = False
|
|
else:
|
|
print(f"❌ {path} - Does not exist")
|
|
all_accessible = False
|
|
|
|
self.test_results["permissions"] = all_accessible
|
|
return all_accessible
|
|
|
|
def run_all_tests(self) -> bool:
|
|
"""Run all tests"""
|
|
self.print_header("Video Player System Test")
|
|
|
|
print("Running comprehensive system tests...")
|
|
|
|
tests = [
|
|
self.test_python_modules,
|
|
self.test_system_commands,
|
|
self.test_gpio_access,
|
|
self.test_configuration_files,
|
|
self.test_video_files,
|
|
self.test_service_status,
|
|
self.test_ir_remote_system,
|
|
self.test_vlc_integration,
|
|
self.test_permissions
|
|
]
|
|
|
|
passed_tests = 0
|
|
total_tests = len(tests)
|
|
|
|
for test in tests:
|
|
try:
|
|
if test():
|
|
passed_tests += 1
|
|
except Exception as e:
|
|
print(f"❌ Test {test.__name__} failed with exception: {e}")
|
|
|
|
# Print summary
|
|
self.print_header("Test Summary")
|
|
|
|
print(f"Tests passed: {passed_tests}/{total_tests}")
|
|
print(f"Success rate: {(passed_tests/total_tests)*100:.1f}%")
|
|
|
|
if passed_tests == total_tests:
|
|
print("🎉 All tests passed! System is ready to use.")
|
|
return True
|
|
else:
|
|
print("⚠️ Some tests failed. Please check the issues above.")
|
|
return False
|
|
|
|
def generate_report(self):
|
|
"""Generate a test report"""
|
|
report_file = "/tmp/video_player_test_report.json"
|
|
|
|
try:
|
|
with open(report_file, 'w') as f:
|
|
json.dump(self.test_results, f, indent=2)
|
|
|
|
print(f"\n📊 Test report saved to: {report_file}")
|
|
except Exception as e:
|
|
print(f"❌ Failed to save test report: {e}")
|
|
|
|
def main():
|
|
"""Main entry point"""
|
|
if len(sys.argv) > 1 and sys.argv[1] == '--help':
|
|
print("Video Player System Test")
|
|
print("Usage: python3 test_system.py")
|
|
print("This script tests all components of the video player system.")
|
|
return
|
|
|
|
tester = SystemTester()
|
|
success = tester.run_all_tests()
|
|
tester.generate_report()
|
|
|
|
if success:
|
|
sys.exit(0)
|
|
else:
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|