letsbe-sysadmin/tests/integration_docker_test.py

82 lines
2.9 KiB
Python
Raw Permalink Normal View History

"""Integration test for DockerExecutor with real Docker."""
import asyncio
import sys
import tempfile
from pathlib import Path
from unittest.mock import MagicMock, patch
# Add parent directory to path for imports
sys.path.insert(0, str(Path(__file__).parent.parent))
def main():
# Create a real temp directory structure
with tempfile.TemporaryDirectory() as tmp:
stacks_root = Path(tmp) / "stacks"
stack_dir = stacks_root / "test-app"
stack_dir.mkdir(parents=True)
# Create a minimal compose file
compose_content = """services:
test:
image: alpine:latest
command: echo 'Hello from integration test'
"""
compose_file = stack_dir / "docker-compose.yml"
compose_file.write_text(compose_content)
print(f"Created stack at: {stack_dir}")
print(f"Compose file: {compose_file}")
# Import executor with mocked logger
with patch("app.executors.base.get_logger", return_value=MagicMock()):
from app.executors.docker_executor import DockerExecutor
executor = DockerExecutor()
# Mock settings to use our temp directory
mock_settings = MagicMock()
mock_settings.allowed_stacks_root = str(stacks_root)
async def run_test():
with patch("app.executors.docker_executor.get_settings", return_value=mock_settings):
# Test 1: Without pull
print("\n=== Test 1: pull=False ===")
result = await executor.execute({
"compose_dir": str(stack_dir),
"pull": False,
"timeout": 60,
})
print(f"Success: {result.success}")
print(f"compose_file: {result.data.get('compose_file')}")
print(f"pull_ran: {result.data.get('pull_ran')}")
if result.error:
print(f"Error: {result.error}")
up_logs = result.data.get("logs", {}).get("up", "")
print(f"Logs (up): {up_logs[:300] if up_logs else 'empty'}")
# Test 2: With pull
print("\n=== Test 2: pull=True ===")
result2 = await executor.execute({
"compose_dir": str(stack_dir),
"pull": True,
"timeout": 60,
})
print(f"Success: {result2.success}")
print(f"pull_ran: {result2.data.get('pull_ran')}")
pull_logs = result2.data.get("logs", {}).get("pull", "")
print(f"Logs (pull): {pull_logs[:300] if pull_logs else 'empty'}")
return result.success and result2.success
success = asyncio.run(run_test())
print(f"\n{'=' * 50}")
print(f"INTEGRATION TEST: {'PASSED' if success else 'FAILED'}")
print(f"{'=' * 50}")
return success
if __name__ == "__main__":
success = main()
sys.exit(0 if success else 1)