Zum Inhalt

pipeline/tests/test_e2e.py

# SPDX-License-Identifier: AGPL-3.0-or-later

"""End-to-end pipeline test.

Skipped by default. Opt in with `AUTOSPLAT_E2E=1` (and have ffmpeg, colmap,
and the brush binary available). Marked `slow` so `pytest -m "not slow"`
also skips it.
"""

from __future__ import annotations

import os
import shutil
from pathlib import Path

import pytest

from autosplat.config import load_config
from autosplat.pipeline import run_pipeline

pytestmark = pytest.mark.slow


def _e2e_enabled() -> bool:
    return os.environ.get("AUTOSPLAT_E2E", "").lower() in ("1", "true", "yes")


def _tooling_available() -> tuple[bool, str]:
    cfg = load_config(include_xdg=False)
    if shutil.which("ffmpeg") is None:
        return False, "ffmpeg not in PATH"
    if shutil.which("colmap") is None:
        return False, "colmap not in PATH"
    if not cfg.paths.brush_binary.exists():
        return False, f"brush binary missing at {cfg.paths.brush_binary}"
    return True, ""


@pytest.mark.skipif(not _e2e_enabled(), reason="set AUTOSPLAT_E2E=1 to run")
@pytest.mark.needs_ffmpeg
@pytest.mark.needs_colmap
@pytest.mark.needs_brush
def test_pipeline_end_to_end(tmp_path: Path, repo_root: Path) -> None:
    """Full pipeline on tests/fixtures/tiny_video.mp4 → scene.ply."""
    fixture = repo_root / "tests" / "fixtures" / "tiny_video.mp4"
    assert fixture.exists(), f"Fixture missing: {fixture}"

    ok, why = _tooling_available()
    if not ok:
        pytest.skip(why)

    cfg = load_config(include_xdg=False)

    # Override training budget hard so the test completes in minutes, not hours.
    cfg.brush.max_steps = 500
    cfg.brush.densify_until_iter = 250
    cfg.viewer.auto_open = False  # no browser pops during tests
    cfg.export.copy_to_outputs = False  # keep everything in tmp_path

    result = run_pipeline(fixture, cfg, output_dir_override=tmp_path / "captures")

    assert result.output_ply.exists(), "Pipeline did not produce a PLY"
    assert result.output_ply.stat().st_size > 100 * 1024, "PLY suspiciously small"
    assert result.metadata_path.exists()