oppo-node / tests /test_self_healing_worker.py
DJ-Goanna-Coding's picture
Deploy from GitHub Actions
c87f72b verified
"""
Comprehensive tests for self_healing_worker.py
Tests cover:
- SelfHealingWorker initialization
- Script health checking
- Python script validation
- Bash script validation
- Auto-repair functionality
- Backup creation
- Health reporting
"""
import pytest
import json
import ast
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
import sys
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from workers.self_healing_worker import SelfHealingWorker, ScriptHealth
class TestScriptHealth:
"""Test ScriptHealth class"""
def test_script_health_init(self, temp_dir):
"""Test ScriptHealth initialization"""
test_path = temp_dir / "test.py"
health = ScriptHealth(test_path)
assert health.path == test_path
assert health.syntax_valid == False
assert health.imports_valid == False
assert health.executable == False
assert health.last_run_success is None
assert isinstance(health.errors, list)
assert isinstance(health.warnings, list)
assert health.last_check is not None
class TestSelfHealingWorkerInit:
"""Test SelfHealingWorker initialization"""
def test_init_default_values(self):
"""Test that SelfHealingWorker initializes correctly"""
worker = SelfHealingWorker()
assert worker.base_path is not None
assert worker.scripts_path is not None
assert worker.services_path is not None
assert worker.data_path is not None
assert isinstance(worker.stats, dict)
def test_init_creates_directories(self, temp_dir, monkeypatch):
"""Test that initialization creates necessary directories"""
monkeypatch.chdir(temp_dir)
worker = SelfHealingWorker()
assert worker.monitoring_path.exists()
def test_init_stats_structure(self):
"""Test that stats dict has correct structure"""
worker = SelfHealingWorker()
assert "total_scripts" in worker.stats
assert "healthy_scripts" in worker.stats
assert "repaired_scripts" in worker.stats
assert "failed_repairs" in worker.stats
assert "scan_time" in worker.stats
class TestSelfHealingWorkerPythonScriptCheck:
"""Test Python script health checking"""
def test_check_python_script_valid(self, temp_dir):
"""Test checking a valid Python script"""
worker = SelfHealingWorker()
script_file = temp_dir / "valid.py"
script_file.write_text("""#!/usr/bin/env python3
import os
from pathlib import Path
def hello():
return "Hello"
""")
health = worker.check_python_script(script_file)
assert health.syntax_valid == True
assert health.imports_valid == True
def test_check_python_script_syntax_error(self, temp_dir):
"""Test checking Python script with syntax error"""
worker = SelfHealingWorker()
script_file = temp_dir / "invalid.py"
script_file.write_text("""
def broken(:
pass
""")
health = worker.check_python_script(script_file)
assert health.syntax_valid == False
assert len(health.errors) > 0
def test_check_python_script_missing_imports(self, temp_dir):
"""Test checking script with potentially missing imports"""
worker = SelfHealingWorker()
script_file = temp_dir / "test.py"
script_file.write_text("""
def test():
pass
""")
health = worker.check_python_script(script_file)
# Should still be valid even without imports
assert health.syntax_valid == True
def test_check_python_script_not_executable(self, temp_dir):
"""Test checking non-executable script"""
worker = SelfHealingWorker()
script_file = temp_dir / "test.py"
script_file.write_text("print('hello')")
health = worker.check_python_script(script_file)
# Should have warning about not being executable
assert health.executable == False
def test_check_python_script_nonexistent(self, temp_dir):
"""Test checking non-existent script"""
worker = SelfHealingWorker()
script_file = temp_dir / "nonexistent.py"
health = worker.check_python_script(script_file)
assert len(health.errors) > 0
class TestSelfHealingWorkerBashScriptCheck:
"""Test Bash script health checking"""
def test_check_bash_script_valid(self, temp_dir):
"""Test checking a valid Bash script"""
worker = SelfHealingWorker()
script_file = temp_dir / "valid.sh"
script_file.write_text("""#!/bin/bash
echo "Hello, World!"
""")
health = worker.check_bash_script(script_file)
assert health.syntax_valid == True
def test_check_bash_script_syntax_error(self, temp_dir):
"""Test checking Bash script with syntax error"""
worker = SelfHealingWorker()
script_file = temp_dir / "invalid.sh"
script_file.write_text("""#!/bin/bash
if [ true
echo "missing fi"
""")
health = worker.check_bash_script(script_file)
assert health.syntax_valid == False
assert len(health.errors) > 0
class TestSelfHealingWorkerImportCheck:
"""Test import validation"""
def test_check_imports_valid(self):
"""Test checking valid imports"""
worker = SelfHealingWorker()
content = """
import os
import sys
from pathlib import Path
"""
result = worker.check_imports(content)
assert result == True
def test_check_imports_invalid_syntax(self):
"""Test checking imports with invalid syntax"""
worker = SelfHealingWorker()
content = """
import os
def broken(:
"""
result = worker.check_imports(content)
assert result == False
class TestSelfHealingWorkerAutoRepair:
"""Test auto-repair functionality"""
def test_auto_repair_adds_python_shebang(self, temp_dir):
"""Test that auto-repair adds missing Python shebang"""
worker = SelfHealingWorker()
worker.data_path = temp_dir / "data"
worker.data_path.mkdir()
script_file = temp_dir / "test.py"
script_file.write_text("""
print("Hello")
""")
health = ScriptHealth(script_file)
health.syntax_valid = True
result = worker.auto_repair_script(script_file, health)
content = script_file.read_text()
assert content.startswith("#!/usr/bin/env python3")
def test_auto_repair_adds_bash_shebang(self, temp_dir):
"""Test that auto-repair adds missing Bash shebang"""
worker = SelfHealingWorker()
worker.data_path = temp_dir / "data"
worker.data_path.mkdir()
script_file = temp_dir / "test.sh"
script_file.write_text("""
echo "Hello"
""")
health = ScriptHealth(script_file)
result = worker.auto_repair_script(script_file, health)
content = script_file.read_text()
assert content.startswith("#!/bin/bash")
def test_auto_repair_makes_executable(self, temp_dir):
"""Test that auto-repair makes script executable"""
worker = SelfHealingWorker()
worker.data_path = temp_dir / "data"
worker.data_path.mkdir()
script_file = temp_dir / "test.py"
script_file.write_text("#!/usr/bin/env python3\nprint('hello')")
import os
os.chmod(script_file, 0o644) # Not executable
health = ScriptHealth(script_file)
health.executable = False
worker.auto_repair_script(script_file, health)
# Check if file is now executable
assert os.access(script_file, os.X_OK)
def test_auto_repair_adds_pathlib_import(self, temp_dir):
"""Test that auto-repair adds missing pathlib import"""
worker = SelfHealingWorker()
worker.data_path = temp_dir / "data"
worker.data_path.mkdir()
script_file = temp_dir / "test.py"
script_file.write_text("""#!/usr/bin/env python3
import os
def test():
p = Path("test")
return p
""")
health = ScriptHealth(script_file)
worker.auto_repair_script(script_file, health)
content = script_file.read_text()
assert "from pathlib import Path" in content
def test_auto_repair_creates_backup(self, temp_dir):
"""Test that auto-repair creates a backup"""
worker = SelfHealingWorker()
worker.data_path = temp_dir / "data"
worker.data_path.mkdir()
script_file = temp_dir / "test.py"
script_file.write_text("print('hello')")
health = ScriptHealth(script_file)
worker.auto_repair_script(script_file, health)
backup_dir = temp_dir / "data" / "backups" / "scripts"
assert backup_dir.exists()
backups = list(backup_dir.glob("test.py.*.bak"))
assert len(backups) > 0
class TestSelfHealingWorkerBackup:
"""Test backup functionality"""
def test_backup_script(self, temp_dir):
"""Test creating script backup"""
worker = SelfHealingWorker()
worker.data_path = temp_dir / "data"
script_file = temp_dir / "test.py"
script_file.write_text("print('hello')")
backup_path = worker.backup_script(script_file)
assert backup_path is not None
assert backup_path.exists()
assert "test.py" in backup_path.name
assert ".bak" in backup_path.name
def test_backup_script_preserves_content(self, temp_dir):
"""Test that backup preserves original content"""
worker = SelfHealingWorker()
worker.data_path = temp_dir / "data"
script_file = temp_dir / "test.py"
original_content = "print('original')"
script_file.write_text(original_content)
backup_path = worker.backup_script(script_file)
assert backup_path.read_text() == original_content
class TestSelfHealingWorkerScanning:
"""Test script scanning functionality"""
def test_scan_all_scripts(self, temp_dir, monkeypatch):
"""Test scanning all scripts"""
monkeypatch.chdir(temp_dir)
worker = SelfHealingWorker()
# Create test scripts
scripts_dir = temp_dir / "scripts"
scripts_dir.mkdir()
(scripts_dir / "test1.py").write_text("#!/usr/bin/env python3\nprint('test1')")
(scripts_dir / "test2.py").write_text("#!/usr/bin/env python3\nprint('test2')")
worker.scripts_path = scripts_dir
health_map = worker.scan_all_scripts()
assert len(health_map) >= 2
assert worker.stats["total_scripts"] >= 2
def test_scan_all_scripts_empty_directory(self, temp_dir, monkeypatch):
"""Test scanning empty directory"""
monkeypatch.chdir(temp_dir)
worker = SelfHealingWorker()
scripts_dir = temp_dir / "scripts"
scripts_dir.mkdir()
worker.scripts_path = scripts_dir
health_map = worker.scan_all_scripts()
assert len(health_map) == 0
class TestSelfHealingWorkerReporting:
"""Test health reporting functionality"""
def test_generate_health_report(self, temp_dir):
"""Test generating health report"""
worker = SelfHealingWorker()
script_path = temp_dir / "test.py"
health = ScriptHealth(script_path)
health.syntax_valid = True
health.imports_valid = True
worker.stats["total_scripts"] = 1
worker.stats["healthy_scripts"] = 1
health_map = {"test.py": health}
report = worker.generate_health_report(health_map)
assert "timestamp" in report
assert "summary" in report
assert "scripts" in report
assert report["summary"]["total_scripts"] == 1
assert report["summary"]["healthy_scripts"] == 1
def test_save_health_report(self, temp_dir):
"""Test saving health report to file"""
worker = SelfHealingWorker()
worker.monitoring_path = temp_dir
worker.health_report_path = temp_dir / "health_report.json"
report = {
"timestamp": "2026-04-14",
"summary": {"total_scripts": 5},
"scripts": {}
}
worker.save_health_report(report)
assert worker.health_report_path.exists()
with open(worker.health_report_path, 'r') as f:
loaded_report = json.load(f)
assert loaded_report["summary"]["total_scripts"] == 5
class TestSelfHealingWorkerIntegration:
"""Integration tests for SelfHealingWorker"""
def test_run_full_heal(self, temp_dir, monkeypatch):
"""Test full healing workflow"""
monkeypatch.chdir(temp_dir)
worker = SelfHealingWorker()
# Create test scripts
scripts_dir = temp_dir / "scripts"
scripts_dir.mkdir()
(scripts_dir / "valid.py").write_text("#!/usr/bin/env python3\nprint('valid')")
(scripts_dir / "needs_shebang.py").write_text("print('no shebang')")
worker.scripts_path = scripts_dir
worker.monitoring_path = temp_dir
worker.health_report_path = temp_dir / "health.json"
worker.data_path = temp_dir / "data"
report = worker.run_full_heal(auto_repair=True)
assert "summary" in report
assert report["summary"]["total_scripts"] >= 1
assert worker.health_report_path.exists()
def test_run_full_heal_no_repair(self, temp_dir, monkeypatch):
"""Test full scan without auto-repair"""
monkeypatch.chdir(temp_dir)
worker = SelfHealingWorker()
scripts_dir = temp_dir / "scripts"
scripts_dir.mkdir()
(scripts_dir / "test.py").write_text("print('test')")
worker.scripts_path = scripts_dir
worker.monitoring_path = temp_dir
worker.health_report_path = temp_dir / "health.json"
report = worker.run_full_heal(auto_repair=False)
assert worker.stats["repaired_scripts"] == 0