Add new tests and functionality for image processing and geometry handling
- Introduced color_image.py for preparing standalone color images for tests. - Added hdr_image.py to create HDR textures for testing. - Implemented test_image_depth_panorama.py to evaluate panorama topology, UVs, and depth discontinuities. - Created test_shadeless.py to validate the opacity and HDR color endpoints of the Shadeless group. - Developed moge3_export.py for exporting dynamic MoGe-3 backbone and ONNX graphs. - Added material.py to inherit material slots onto generated geometry. - Built image_depth_panorama.py to construct a quad panorama with depth separation and sampling.
This commit is contained in:
93
tests/anyimage/server/test_input_validation.py
Normal file
93
tests/anyimage/server/test_input_validation.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
from PIL import Image
|
||||
|
||||
from tests.anyimage.server.support import load_server_module
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def media():
|
||||
return load_server_module("media.input")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("suffix", [".PNG", ".MP4", ".webp", ".mts"])
|
||||
def test_supported_format_is_case_insensitive(media, tmp_path, suffix):
|
||||
path = tmp_path / f"input{suffix}"
|
||||
path.touch()
|
||||
assert media.validate_input_path(path) == path
|
||||
|
||||
|
||||
@pytest.mark.parametrize("suffix", [".tiff", ""])
|
||||
def test_frontend_and_backend_share_format_reason(media, tmp_path, suffix):
|
||||
path = tmp_path / f"input{suffix}"
|
||||
path.touch()
|
||||
with pytest.raises(RuntimeError) as preflight:
|
||||
media.validate_input_path(path)
|
||||
with pytest.raises(RuntimeError) as backend:
|
||||
media.prepare_input(path, 16, tmp_path)
|
||||
assert str(preflight.value) == str(backend.value)
|
||||
assert f"Unsupported input format: {suffix or '(no extension)'}" in str(backend.value)
|
||||
assert "Supported images: .jpeg, .jpg, .png, .webp." in str(backend.value)
|
||||
assert "Supported videos:" in str(backend.value)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("suffix,kind", [(".png", "image"), (".mp4", "video")])
|
||||
def test_missing_path_precedes_format_validation(media, tmp_path, suffix, kind):
|
||||
with pytest.raises(RuntimeError, match=f"Source {kind} file does not exist"):
|
||||
media.validate_input_path(tmp_path / f"missing{suffix}")
|
||||
|
||||
|
||||
def test_directory_filtering_and_empty_reason(media, tmp_path):
|
||||
(tmp_path / "note.txt").touch()
|
||||
(tmp_path / "frame.exr").touch()
|
||||
with pytest.raises(RuntimeError, match="No supported image frames found"):
|
||||
media.validate_input_path(tmp_path)
|
||||
for name in ["b.PNG", "a.jpg"]:
|
||||
(tmp_path / name).touch()
|
||||
frames, temporary = media.prepare_input(tmp_path, 1, tmp_path, start_frame=2)
|
||||
assert frames == [tmp_path / "b.PNG"]
|
||||
assert temporary is None
|
||||
|
||||
|
||||
def test_image_subset_rejects_video(media, tmp_path):
|
||||
path = tmp_path / "clip.mp4"
|
||||
path.touch()
|
||||
with pytest.raises(RuntimeError) as error:
|
||||
media.validate_input_path(path, images_only=True)
|
||||
assert "Supported images:" in str(error.value)
|
||||
assert "Supported videos:" not in str(error.value)
|
||||
|
||||
|
||||
def test_image_decode_error_keeps_cause(media, tmp_path):
|
||||
path = tmp_path / "broken.png"
|
||||
path.write_bytes(b"broken")
|
||||
with pytest.raises(RuntimeError, match="Unable to read image") as error:
|
||||
with media.open_image(path):
|
||||
pytest.fail("Broken image must not reach processing")
|
||||
assert isinstance(error.value.__cause__, OSError)
|
||||
|
||||
|
||||
def test_processing_error_is_not_relabelled(media, tmp_path):
|
||||
path = tmp_path / "valid.png"
|
||||
Image.new("RGB", (2, 2)).save(path)
|
||||
failure = OSError("inference failed")
|
||||
with pytest.raises(OSError) as error:
|
||||
with media.open_image(path):
|
||||
raise failure
|
||||
assert error.value is failure
|
||||
|
||||
|
||||
def test_video_decode_error_closes_container(media, tmp_path):
|
||||
failure = ValueError("broken packet")
|
||||
def frames():
|
||||
raise failure
|
||||
yield
|
||||
container = SimpleNamespace(streams=SimpleNamespace(video=[object()]),
|
||||
decode=lambda _stream: frames(), close=Mock())
|
||||
with pytest.raises(RuntimeError, match="Unable to read video") as error:
|
||||
media.extract_video_frames("broken.mp4", tmp_path, 2,
|
||||
SimpleNamespace(open=lambda _path: container))
|
||||
assert error.value.__cause__ is failure
|
||||
container.close.assert_called_once()
|
||||
Reference in New Issue
Block a user