# SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project import json from graphlib import TopologicalSorter from pathlib import Path import pytest from comfyui_vllm_omni import nodes as omni_nodes pytestmark = [pytest.mark.core_model, pytest.mark.cpu] WORKFLOW = ( Path(__file__).resolve().parents[4] / "apps/ComfyUI-vLLM-Omni/example_workflows/vLLM-Omni MiniMax-H3 Reference to Video.json" ) @pytest.fixture def workflow(): return json.loads(WORKFLOW.read_text()) def test_reference_workflow_connections(workflow): nodes = {node["id"]: node for node in workflow["nodes"]} links = {link[0]: link for link in workflow["links"]} assert len(nodes) == len(workflow["nodes"]) assert len(links) == len(workflow["links"]) graph: dict[int, set[int]] = {node_id: set() for node_id in nodes} for link_id, source, output_slot, target, input_slot, kind in links.values(): output = nodes[source]["outputs"][output_slot] input_ = nodes[target]["inputs"][input_slot] assert output["type"] == input_["type"] == kind assert link_id in output["links"] assert input_["link"] == link_id graph[target].add(source) assert len(tuple(TopologicalSorter(graph).static_order())) == len(nodes) for node in nodes.values(): for slot, input_ in enumerate(node.get("inputs", [])): if input_["link"] is not None: assert links[input_["link"]][3:5] == [node["id"], slot] for slot, output in enumerate(node.get("outputs", [])): for link_id in output.get("links") or []: assert links[link_id][1:3] == [node["id"], slot] def test_reference_workflow_matches_omni_node_interfaces(workflow): for node in workflow["nodes"]: if not node["type"].startswith("VLLMOmni"): continue cls = getattr(omni_nodes, node["type"]) schema = cls.INPUT_TYPES() inputs = {**schema.get("required", {}), **schema.get("optional", {})} for input_ in node["inputs"]: assert input_["type"] == inputs[input_["name"]][0] assert tuple(output["type"] for output in node["outputs"]) == cls.RETURN_TYPES expected_widgets = len(schema.get("required", {})) if "seed" in schema.get("required", {}): expected_widgets += 1 assert len(node["widgets_values"]) == expected_widgets refs = next(node for node in workflow["nodes"] if node["type"] == "VLLMOmniVideoReferences") assert [input_["name"] for input_ in refs["inputs"]] == list( omni_nodes.VLLMOmniVideoReferences.INPUT_TYPES()["optional"] ) def test_reference_workflow_default_route_and_output(workflow): nodes = {node["id"]: node for node in workflow["nodes"]} links = {link[0]: link for link in workflow["links"]} generate = next(node for node in nodes.values() if node["type"] == "VLLMOmniGenerateVideo") inputs = {input_["name"]: input_["link"] for input_ in generate["inputs"]} assert inputs["frame"] is None assert inputs["lora"] is None for name, kind in ( ("references", "VLLMOmniVideoReferences"), ("sampling_params", "VLLMOmniDiffusionSampling"), ("model_params", "VLLMOmniMiniMaxH3Params"), ): assert nodes[links[inputs[name]][1]]["type"] == kind save = next(node for node in nodes.values() if node["type"] == "SaveVideo") assert links[save["inputs"][0]["link"]][1] == generate["id"] assert save["widgets_values"] == ["video/MiniMax-H3-Ref2VA", "mp4", "h264"] def test_reference_workflow_defaults_and_portable_assets(workflow): by_type = {node["type"]: node for node in workflow["nodes"]} values = by_type["VLLMOmniGenerateVideo"]["widgets_values"] assert values[0] == "http://localhost:8000/v1" assert values[1] == "MiniMaxAI/MiniMax-H3" assert "" in values[2] assert values[4:8] == [1344, 768, 24, 5.167] num_frames = round(values[7] * values[6]) assert num_frames == 124 assert values[3] == "" assert (num_frames - 5) % 17 == 0 assert 4 <= values[7] <= 15 assert by_type["VLLMOmniDiffusionSampling"]["widgets_values"] == [1, 50, 1.0, 1.0, False, False, 42, "fixed"] assert by_type["VLLMOmniMiniMaxH3Params"]["widgets_values"] == [3.0, 12.0] assert by_type["VLLMOmniRemoteLoRA"]["widgets_values"][0] == "" for kind in ("LoadImage", "LoadVideo", "LoadAudio"): filename = by_type[kind]["widgets_values"][0] assert filename and Path(filename).name == filename assert ":" not in filename and "\\" not in filename assert set(by_type) == { "LoadImage", "LoadVideo", "LoadAudio", "SaveVideo", "MarkdownNote", "VLLMOmniVideoReferences", "VLLMOmniGenerateVideo", "VLLMOmniDiffusionSampling", "VLLMOmniMiniMaxH3Params", "VLLMOmniRemoteLoRA", }