Add CI test workflow and harden execute() edge cases
- Add .github/workflows/test.yml: runs the pytest suite on push/PR across Python 3.10/3.11/3.12. comfy_api is mocked in conftest.py, so no ComfyUI install is required. - execute(): pass a zero-dimension (malformed/empty) input tensor through unchanged instead of crashing the resizer. - execute(): warn when "Prioritize Min Resolution" forces a large upscale (>4x) on an extreme aspect ratio, pointing at the strict mode as the size-capping alternative. - Add regression tests for the zero-dim passthrough and the extreme-upscale warning. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SqaVwWKNn9bsmmhUkJXhZ2
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
pytest:
|
||||
name: pytest (Python ${{ matrix.python-version }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.10", "3.11", "3.12"]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install test dependencies
|
||||
# comfy_api is mocked in conftest.py, so a full ComfyUI install isn't needed.
|
||||
# numpy silences torch's "Failed to initialize NumPy" import warning.
|
||||
run: python -m pip install --upgrade pip pytest torch numpy
|
||||
- name: Run tests
|
||||
run: python -m pytest -q
|
||||
@@ -393,6 +393,29 @@ class ConstrainResolution(io.ComfyNode):
|
||||
width, height, min_res, max_res, multiple_of, constraint_mode
|
||||
)
|
||||
|
||||
# Degenerate input (empty/malformed tensor) collapses to a 0 target,
|
||||
# which would crash the resizer. Pass the image through untouched instead.
|
||||
if target_width == 0 or target_height == 0:
|
||||
logger.warning(
|
||||
"Input has a zero dimension (%dx%d); passing image through unchanged.",
|
||||
width, height
|
||||
)
|
||||
return io.NodeOutput(
|
||||
image, image, width, height,
|
||||
original_aspect_ratio, original_aspect_ratio
|
||||
)
|
||||
|
||||
# Warn when Prioritize Min Resolution forces a large upscale (extreme aspect
|
||||
# ratios can blow up the long side and risk OOM). Strict mode caps this instead.
|
||||
if constraint_mode == ConstraintMode.MIN_RES.value:
|
||||
upscale_factor = max(target_width / width, target_height / height)
|
||||
if upscale_factor > 4:
|
||||
logger.warning(
|
||||
"Upscaling by %.1fx to %dx%d to satisfy min_res on an extreme aspect ratio. "
|
||||
"Use 'Prioritize Max Resolution (Strict)' to cap output size and avoid large upscales.",
|
||||
upscale_factor, target_width, target_height
|
||||
)
|
||||
|
||||
# Resize image to target dimensions
|
||||
resized_image = cls.resize_image(image, target_width, target_height, resize_method)
|
||||
|
||||
|
||||
@@ -180,3 +180,27 @@ class TestCropImage:
|
||||
image = torch.rand(1, 120, 200, 3)
|
||||
out = ConstrainResolution.crop_image(image, 100, 100, position)
|
||||
assert out.shape == (1, 100, 100, 3)
|
||||
|
||||
|
||||
class TestExecuteGuards:
|
||||
def test_zero_dimension_input_passes_through(self):
|
||||
"""A malformed tensor with a zero dimension must pass through, not crash the resizer."""
|
||||
image = torch.rand(1, 0, 500, 3)
|
||||
resized, original, out_w, out_h, _, _ = run_node(image)
|
||||
assert resized.shape == image.shape
|
||||
assert original.shape == image.shape
|
||||
assert (out_w, out_h) == (500, 0)
|
||||
|
||||
def test_extreme_ratio_min_res_warns(self, caplog):
|
||||
"""Extreme aspect ratio in MIN_RES mode should warn about the large upscale."""
|
||||
image = torch.rand(1, 100, 1000, 3)
|
||||
with caplog.at_level("WARNING"):
|
||||
run_node(image, constraint_mode=MIN)
|
||||
assert any("Upscaling by" in r.message for r in caplog.records)
|
||||
|
||||
def test_normal_image_does_not_warn(self, caplog):
|
||||
"""A normal image must not trigger the upscale warning."""
|
||||
image = torch.rand(1, 800, 1000, 3)
|
||||
with caplog.at_level("WARNING"):
|
||||
run_node(image, constraint_mode=MIN)
|
||||
assert not any("Upscaling by" in r.message for r in caplog.records)
|
||||
|
||||
Reference in New Issue
Block a user