Files
Text-Texture-Generator-for-…/tests/e2e/conftest.py
2025-10-13 00:10:24 +02:00

126 lines
3.7 KiB
Python

"""
E2E test fixtures for Docker-based Blender testing.
Manages Docker container lifecycle for real Blender tests.
"""
import pytest
import docker
import shutil
import zipfile
from pathlib import Path
import time
@pytest.fixture(scope="module")
def docker_client():
"""Provide Docker client for container management."""
try:
client = docker.from_env()
# Verify Docker is running
client.ping()
return client
except docker.errors.DockerException as e:
pytest.skip(f"Docker not available: {e}")
@pytest.fixture(scope="module")
def blender_image(docker_client):
"""Build Blender Docker image if not exists."""
image_tag = "text-texture-generator-e2e:latest"
dockerfile_path = Path(__file__).parent / "docker"
try:
# Try to get existing image
docker_client.images.get(image_tag)
print(f"Using existing Docker image: {image_tag}")
except docker.errors.ImageNotFound:
print(f"Building Docker image: {image_tag}")
# Build image
docker_client.images.build(
path=str(dockerfile_path),
tag=image_tag,
rm=True
)
return image_tag
@pytest.fixture(scope="function")
def blender_container(docker_client, blender_image, tmp_path):
"""
Spin up Blender container for test execution.
Yields container instance, cleans up after test.
"""
container = None
try:
# Start container with addon mounted
container = docker_client.containers.run(
blender_image,
command="/bin/sleep 3600", # Keep alive for test duration
detach=True,
remove=False, # We'll remove manually after cleanup
volumes={
str(tmp_path): {"bind": "/addon-test", "mode": "rw"}
}
)
# Wait for container to be ready
timeout = 10
start = time.time()
while time.time() - start < timeout:
container.reload()
if container.status == "running":
break
time.sleep(0.5)
if container.status != "running":
pytest.fail(f"Container failed to start: {container.status}")
yield container
finally:
# Cleanup
if container:
try:
container.stop(timeout=5)
container.remove()
except Exception as e:
print(f"Warning: Container cleanup failed: {e}")
@pytest.fixture(scope="function")
def addon_package(tmp_path, request):
"""
Package the addon as a zip file for installation in Blender.
Detects version type from test file name and patches VERSION_TYPE accordingly.
Returns path to the packaged addon zip.
"""
src_dir = Path(__file__).parent.parent.parent / "src"
# Determine version type from test module name
test_file = request.node.fspath.basename
version_type = "free" if "free_version" in test_file else "full"
# Copy src to temp and patch constants.py
temp_src = tmp_path / "src_temp"
shutil.copytree(src_dir, temp_src)
constants_file = temp_src / "utils" / "constants.py"
content = constants_file.read_text()
content = content.replace('VERSION_TYPE = "free"', f'VERSION_TYPE = "{version_type}"')
constants_file.write_text(content)
# Create zip from patched source
addon_zip = tmp_path / "text_texture_generator.zip"
with zipfile.ZipFile(addon_zip, 'w', zipfile.ZIP_DEFLATED) as zf:
for file_path in temp_src.rglob("*"):
if file_path.is_file():
arc_name = f"text_texture_generator/{file_path.relative_to(temp_src)}"
zf.write(file_path, arc_name)
return addon_zip