Files
AnyImage/tests/anyimage/server/test_model_pisa_sr.py
nan f48bbb3d05 Add tests for image layer, image plane, inventory, saved layout, commands, documentation, manifest, and packaging
- Implement tests for image layer functionality including alpha curve and depth layer behavior.
- Create tests for image plane evaluation and modifier input handling.
- Add tests to verify the saved asset inventory and its persistence.
- Introduce tests for the documentation command to ensure correct project version deployment.
- Validate the extension manifest structure and required permissions.
- Develop tests for the packaging process, ensuring correct platform handling and dependency management.
- Enhance image depth plane group functionality with new split threshold input and surface processing.
2026-09-09 22:18:59 +08:00

126 lines
4.4 KiB
Python

import hashlib
from types import SimpleNamespace
from unittest.mock import patch
import numpy as np
import pytest
from PIL import Image
from server.models import onnx_pisa_sr as pisa
from server.model_manager import ModelManager, ModelSessionCache
from server import model_catalog
class FakePisa:
def __init__(self):
self.noise = np.zeros((1, 4, 64, 64), dtype=np.float16)
self.stages = []
self.closed = False
self.decoder_inputs = []
def activate(self, component):
self.component = component
self.stages.append(component)
def run(self, tensor, final=False):
if self.component == "encoder":
return np.zeros((1,8,64,64), dtype=np.float16)
if self.component == "unet-pixel":
return np.full_like(tensor, .1)
if self.component == "unet-full":
return np.full_like(tensor, .2)
self.decoder_inputs.append(tensor.copy())
return np.zeros((1,3,512,512), dtype=np.float16)
def close(self):
self.closed = True
@pytest.mark.parametrize("size", [(1,1), (7,5), (256,256), (513,257)])
def test_preset_output_size_and_prediction_combination(size):
model = FakePisa()
output = pisa.infer(model, Image.new("RGB", size, (32,64,96)))
assert output.size == (size[0]*2, size[1]*2)
assert model.stages == ["encoder", "unet-pixel", "unet-full", "decoder"]
for latent in model.decoder_inputs:
np.testing.assert_allclose(latent, -.17, atol=.0002)
assert np.isfinite(np.asarray(output)).all()
def test_cancel_cleans_intermediate_files_and_session(tmp_path):
model = FakePisa()
original = pisa.TemporaryDirectory
def temporary(**kwargs):
return original(dir=tmp_path, **kwargs)
checks = 0
def cancel():
nonlocal checks
checks += 1
return checks == 4
with patch.object(pisa, "TemporaryDirectory", side_effect=temporary):
with pytest.raises(RuntimeError, match="cancelled"):
pisa.infer(model, Image.new("RGB", (256,256)), cancel)
assert model.closed
assert not list(tmp_path.iterdir())
def test_stage_releases_previous_session_before_loading(tmp_path):
np.save(tmp_path / "noise.npy", np.zeros((1,4,64,64), dtype=np.float16))
model = pisa.PisaSession(tmp_path, "cpu")
loaded = []
def create(path, device):
assert model.session is None
loaded.append(path.stem)
return SimpleNamespace(get_providers=lambda: ["CPUExecutionProvider"], disable_fallback=lambda: None)
with patch.object(pisa, "create_session", side_effect=create):
model.activate("unet-pixel")
model.activate("unet-full")
assert loaded == ["unet-pixel", "unet-full"]
def test_resource_error_closes_pipeline():
model = FakePisa()
with patch.object(model, "run", side_effect=RuntimeError("out of memory")):
with pytest.raises(pisa.UpscaleResourceError):
pisa.infer(model, Image.new("RGB", (256,256)))
assert model.closed
def test_pisa_readiness_checks_every_asset_and_corruption(tmp_path):
content = b"verified"
digest = hashlib.sha256(content).hexdigest()
files = tuple((name, len(content), digest) for name in ("encoder.onnx", "noise.npy"))
spec = SimpleNamespace(directory_name="pisa-sr", r2_files=files)
directory = tmp_path / "pisa-sr"
directory.mkdir()
manager = ModelManager(tmp_path)
with patch.object(model_catalog, "get_downloadable_model", return_value=spec):
assert not manager.ready("PISA_SR")
for name, _, _ in files:
(directory / name).write_bytes(content)
assert manager.ready("PISA_SR")
(directory / "noise.npy").write_bytes(b"damaged!")
assert not manager.ready("PISA_SR")
def test_pisa_cache_reuse_and_clear(tmp_path):
cache = ModelSessionCache()
with patch.object(pisa, "PisaSession", return_value=object()) as create:
first = cache.get_upscale(tmp_path / "pisa-sr", "cpu")
assert cache.get_upscale(tmp_path / "pisa-sr", "cpu") is first
assert create.call_count == 1
cache.close()
assert cache.upscale_model is None
def test_coreml_returns_explicit_support_reason(tmp_path):
with pytest.raises(RuntimeError, match="select CPU"):
pisa.PisaSession(tmp_path, "coreml")
def test_clear_closes_pisa_components_even_with_external_reference():
cache = ModelSessionCache()
model = FakePisa()
cache.upscale_model = model
cache.close()
assert model.closed