139 lines
4.4 KiB
Python
139 lines
4.4 KiB
Python
"""Unit tests for VideoConfig parsing and LoRASpec validation.
|
|
|
|
Pure-python, no model imports, no CUDA, no ffmpeg. Safe for Windows CI.
|
|
"""
|
|
import pytest
|
|
|
|
from server.video import VideoConfig, LoRASpec
|
|
|
|
|
|
def test_defaults_when_raw_is_empty():
|
|
cfg = VideoConfig.from_dict({})
|
|
assert cfg.enabled is False
|
|
assert cfg.backend == "lightx2v"
|
|
assert cfg.mode == "reflective"
|
|
assert cfg.resolution == 480
|
|
assert cfg.fps == 16
|
|
assert cfg.library_base_clip_count == 4
|
|
assert cfg.reflective_prompt_reply_words == 18
|
|
assert cfg.loras == []
|
|
|
|
|
|
def test_defaults_when_raw_is_none():
|
|
cfg = VideoConfig.from_dict(None) # type: ignore[arg-type]
|
|
assert cfg.enabled is False
|
|
|
|
|
|
def test_library_section_override():
|
|
cfg = VideoConfig.from_dict(
|
|
{"enabled": True, "mode": "library", "library": {"base_clip_count": 7, "base_clip_seconds": 3}}
|
|
)
|
|
assert cfg.enabled is True
|
|
assert cfg.mode == "library"
|
|
assert cfg.library_base_clip_count == 7
|
|
assert cfg.library_base_clip_seconds == 3
|
|
|
|
|
|
def test_reflective_section_override():
|
|
cfg = VideoConfig.from_dict(
|
|
{
|
|
"reflective": {
|
|
"clip_seconds": 9,
|
|
"clip_prompt_template": "my template: {reply_hint}",
|
|
"prompt_reply_words": 5,
|
|
}
|
|
}
|
|
)
|
|
assert cfg.reflective_clip_seconds == 9
|
|
assert cfg.reflective_prompt_template == "my template: {reply_hint}"
|
|
assert cfg.reflective_prompt_reply_words == 5
|
|
|
|
|
|
def test_lora_parse_minimal():
|
|
cfg = VideoConfig.from_dict({"loras": [{"path": "/tmp/a.safetensors"}]})
|
|
assert len(cfg.loras) == 1
|
|
lora = cfg.loras[0]
|
|
assert lora.path == "/tmp/a.safetensors"
|
|
assert lora.weight == 1.0
|
|
assert lora.target == "both"
|
|
assert lora.name is None
|
|
|
|
|
|
def test_lora_parse_full():
|
|
cfg = VideoConfig.from_dict(
|
|
{
|
|
"loras": [
|
|
{
|
|
"path": "/tmp/a.safetensors",
|
|
"weight": 0.7,
|
|
"target": "both",
|
|
"name": "style-a",
|
|
},
|
|
{
|
|
"path": "/tmp/b.safetensors",
|
|
"weight": 0.4,
|
|
"target": "both",
|
|
"name": "style-b",
|
|
},
|
|
]
|
|
}
|
|
)
|
|
assert len(cfg.loras) == 2
|
|
assert cfg.loras[0].target == "both"
|
|
assert cfg.loras[0].name == "style-a"
|
|
assert cfg.loras[1].target == "both"
|
|
assert cfg.loras[1].weight == 0.4
|
|
|
|
|
|
def test_lora_legacy_moe_target_coerced_to_both():
|
|
"""Legacy MoE configs with target='high_noise'/'low_noise' get coerced."""
|
|
cfg = VideoConfig.from_dict(
|
|
{
|
|
"loras": [
|
|
{"path": "/tmp/hi.safetensors", "target": "high_noise"},
|
|
{"path": "/tmp/lo.safetensors", "target": "low_noise"},
|
|
{"path": "/tmp/x.safetensors", "target": "bogus"},
|
|
]
|
|
}
|
|
)
|
|
assert all(l.target == "both" for l in cfg.loras)
|
|
|
|
|
|
def test_lora_entries_without_path_are_dropped():
|
|
cfg = VideoConfig.from_dict(
|
|
{"loras": [{"weight": 0.5}, {"path": "/tmp/ok.safetensors"}, None]}
|
|
)
|
|
assert len(cfg.loras) == 1
|
|
assert cfg.loras[0].path == "/tmp/ok.safetensors"
|
|
|
|
|
|
def test_models_section_override():
|
|
cfg = VideoConfig.from_dict(
|
|
{
|
|
"models": {
|
|
"wan22_base_repo": "/local/weights/wan22",
|
|
"wan22_dit_repo": "/local/weights/wan22-dit",
|
|
"wan22_dit_quant_scheme": "gguf-Q4_K_M",
|
|
"wan22_config_json": "/local/cfg/turbo.json",
|
|
"wan22_model_cls": "wan2.2",
|
|
"musetalk_path": "/local/weights/musetalk",
|
|
}
|
|
}
|
|
)
|
|
assert cfg.wan22_base_repo == "/local/weights/wan22"
|
|
assert cfg.wan22_dit_repo == "/local/weights/wan22-dit"
|
|
assert cfg.wan22_dit_quant_scheme == "gguf-Q4_K_M"
|
|
assert cfg.wan22_config_json == "/local/cfg/turbo.json"
|
|
assert cfg.wan22_model_cls == "wan2.2"
|
|
assert cfg.musetalk_model_path == "/local/weights/musetalk"
|
|
|
|
|
|
def test_models_section_defaults_to_5b_turbo():
|
|
cfg = VideoConfig.from_dict({})
|
|
assert cfg.wan22_base_repo == "Wan-AI/Wan2.2-TI2V-5B"
|
|
assert cfg.wan22_dit_repo == "hum-ma/Wan2.2-TI2V-5B-Turbo-GGUF"
|
|
assert cfg.wan22_dit_quant_scheme == "gguf-Q8_0"
|
|
assert cfg.wan22_t5_quantized is True
|
|
assert cfg.wan22_model_cls == "wan2.2"
|
|
assert cfg.wan22_config_json == "/app/configs/lightx2v/wan22_i2v_gguf_5b_turbo.json"
|