Files
exportAnything-ComfyUI-Diff…/tests/test_advertisement_music3_api_fixture.py

200 lines
9.4 KiB
Python

from __future__ import annotations
import copy
import hashlib
import importlib.util
import json
import re
import sys
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
BUILDER_PATH = ROOT / "tools" / "build_advertisement_music3_glowbloom_api.py"
SPEC = importlib.util.spec_from_file_location("advertisement_music3_api_builder", BUILDER_PATH)
assert SPEC is not None and SPEC.loader is not None
builder = importlib.util.module_from_spec(SPEC)
sys.modules[SPEC.name] = builder
SPEC.loader.exec_module(builder)
class AdvertisementMusic3APIFixtureTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.known_good_bytes = builder.KNOWN_GOOD_UI.read_bytes()
cls.source = builder._load_guarded_json(
builder.SOURCE_API,
canonical_hash=builder.SOURCE_API_CANONICAL_SHA256,
)
cls.graph = builder.build_graph(cls.source)
def test_known_good_v6_is_hash_guarded_and_unchanged(self):
self.assertEqual(
hashlib.sha256(self.known_good_bytes).hexdigest(),
builder.KNOWN_GOOD_UI_SHA256,
)
def test_graph_is_acyclic_and_reference_prep_has_explicit_format_size(self):
builder.validate_graph(self.graph)
self.assertEqual(self.graph["803"]["inputs"]["generation_width"], 480)
self.assertEqual(self.graph["803"]["inputs"]["generation_height"], 864)
self.assertFalse(
any(
isinstance(value, list) and value[0] == "187"
for value in self.graph["803"]["inputs"].values()
)
)
def test_graph_rejects_a_dependency_cycle(self):
graph = copy.deepcopy(self.graph)
graph["803"]["inputs"]["generation_width"] = ["187", 10]
with self.assertRaisesRegex(builder.FixtureError, "dependency cycle"):
builder.validate_graph(graph)
def test_runtime_baseline_is_self_contained(self):
classes = {node["class_type"] for node in self.graph.values()}
self.assertIn("DiffusionGemmaAdvertisementMemoryBarrier", classes)
self.assertIn("DiffusionGemmaAdvertisementDirectorPacketRepair", classes)
self.assertNotIn("PathchSageAttentionKJ", classes)
self.assertNotIn("easy cleanGpuUsed", classes)
self.assertNotIn("FL_UnloadAllModels", classes)
self.assertNotIn("EasyCache", classes)
self.assertNotIn("TorchCompileModel", classes)
self.assertEqual(self.graph["716"]["inputs"]["model"], ["713", 0])
self.assertEqual(self.graph["182"]["inputs"]["model_path"], builder.DIRECTOR_MODEL_PATH)
def test_visible_h3_labels_match_the_actual_reference_and_step_contracts(self):
self.assertEqual(
self.graph["710:658"]["_meta"]["title"],
"Shared H3 schedule — simple / 7 sampling steps",
)
self.assertEqual(self.graph["710:658"]["inputs"]["steps"], 7)
expected = (
"H3 GENERATION LANE 1 — P1+P2 performer + P3 product + Audio 1",
"H3 GENERATION LANE 2 — P1+P2 performer + P3 product + P4 relay + Audio 1",
"H3 GENERATION LANE 3 — P1+P2 performer + P3 product + P4 relay + Audio 1",
"H3 GENERATION LANE 4 — P1+P2 performer + P3 product + P4 relay + Audio 1",
)
for node_id, title in zip(("710:667", "710:684", "710:692", "710:700"), expected):
self.assertEqual(self.graph[node_id]["_meta"]["title"], title)
def test_manifest_describes_the_exact_api_graph_and_uses_real_hashes(self):
manifest = builder._manifest(self.graph)
self.assertEqual(manifest["api_audio_sources"], ["MiniMax Music 3"])
self.assertEqual(
manifest["companion_ui_only_audio_sources"],
["Upload song", "Legacy ACE-Step"],
)
self.assertEqual(manifest["models"], builder.MODEL_INVENTORY)
self.assertEqual(set(manifest["models"]), {"director", "minimax_h3", "minimax_music3"})
self.assertEqual(len(manifest["models"]["minimax_h3"]), 5)
for asset in manifest["assets"].values():
self.assertRegex(asset["sha256"], re.compile(r"^[0-9a-f]{64}$"))
def test_director_transport_repair_is_narrow_and_observable(self):
self.assertEqual(self.graph["185"]["inputs"]["mode"], "off")
self.assertEqual(
self.graph["185"]["_meta"]["title"],
"5b. H3 Grounding Guard — OFF baseline (contract validation stays active)",
)
self.assertEqual(
self.graph["820"]["class_type"],
"DiffusionGemmaAdvertisementDirectorPacketRepair",
)
self.assertEqual(self.graph["820"]["inputs"]["director_final_json"], ["186", 0])
self.assertEqual(self.graph["820"]["inputs"]["director_raw_response"], ["186", 2])
self.assertEqual(self.graph["820"]["inputs"]["director_metadata_json"], ["186", 3])
self.assertEqual(self.graph["820"]["inputs"]["grounding_status"], ["186", 4])
self.assertEqual(self.graph["820"]["inputs"]["grounding_report_json"], ["186", 5])
self.assertEqual(self.graph["820"]["inputs"]["reference_contract_json"], ["802", 0])
self.assertEqual(self.graph["187"]["inputs"]["final_json"], ["820", 0])
self.assertEqual(self.graph["902"]["inputs"]["source"], ["186", 2])
def test_music3_and_reference_topology_matches_advertisement_contract(self):
self.assertEqual(
self.graph["806"]["inputs"]["clip_name"],
builder.MUSIC3_MODELS["text_encoder"],
)
self.assertEqual(
self.graph["807"]["inputs"]["unet_name"],
builder.MUSIC3_MODELS["diffusion_model"],
)
self.assertEqual(
self.graph["808"]["inputs"]["vae_name"],
builder.MUSIC3_MODELS["vae"],
)
for lane, node_id in enumerate(("710:667", "710:684", "710:692", "710:700"), start=1):
inputs = self.graph[node_id]["inputs"]
self.assertNotIn("model", inputs)
self.assertEqual(inputs["ref_images.ref_image_0"], ["803", 0])
self.assertEqual(inputs["ref_images.ref_image_1"], ["803", 1])
self.assertEqual(inputs["ref_images.ref_image_2"], ["803", 2])
self.assertEqual("ref_images.ref_image_3" in inputs, lane > 1)
for node_id in ("710:658", "710:660", "710:686", "710:694", "710:702"):
self.assertEqual(self.graph[node_id]["inputs"]["model"], ["716", 0])
def test_fixture_has_master_two_real_cutdowns_and_honest_qa(self):
save_nodes = [
node for node in self.graph.values() if node["class_type"] == "SaveVideo"
]
self.assertEqual(len(save_nodes), 3)
self.assertTrue(all("REVIEW DRAFT" in node["_meta"]["title"] for node in save_nodes))
self.assertTrue(
all("/review_drafts/" in node["inputs"]["filename_prefix"] for node in save_nodes)
)
checks = json.loads(self.graph["836"]["inputs"]["checks_json"])
self.assertEqual(checks["technical_integrity"]["status"], "pass")
self.assertEqual(checks["product_identity"], "not_measured")
self.assertEqual(checks["performer_identity"], "not_measured")
self.assertEqual(checks["copy_legibility"], "not_measured")
self.assertEqual(checks["audio_sync"], "not_measured")
self.assertEqual(self.graph["900"]["class_type"], "PreviewAny")
self.assertEqual(self.graph["900"]["inputs"]["source"], ["815", 4])
self.assertEqual(self.graph["901"]["class_type"], "PreviewAny")
self.assertEqual(self.graph["901"]["inputs"]["source"], ["187", 4])
self.assertEqual(self.graph["902"]["class_type"], "PreviewAny")
self.assertEqual(self.graph["902"]["inputs"]["source"], ["186", 2])
def test_one_settings_node_controls_every_duplicate_prone_consumer(self):
self.assertEqual(
self.graph["849"]["class_type"],
"DiffusionGemmaAdvertisementWorkflowControls",
)
for node_id, input_name, slot in (
("801", "production_duration_seconds", 0),
("804", "target_duration_seconds", 0),
("183", "target_duration_seconds", 0),
("673", "target_duration_seconds", 0),
("676", "production_duration_seconds", 0),
("815", "excerpt_duration_seconds", 0),
("816", "duration", 0),
("817", "target_duration_seconds", 0),
("818", "excerpt_duration_seconds", 0),
("673", "custom_shot_count", 1),
("821", "native_shot_count", 1),
("675", "performance_mode", 2),
("823", "performance_mode", 2),
("835", "cutdown_15_start_seconds", 3),
("835", "cutdown_6_start_seconds", 4),
("801", "deliverables_json", 5),
("676", "deliverables_json", 5),
("801", "aspect_ratio", 6),
("676", "aspect_ratio", 6),
("673", "generation_mode", 7),
("673", "shot_count", 8),
("673", "shot_count_override", 9),
("673", "audio_mode", 10),
("673", "dialogue_mode", 11),
("676", "excerpt_start_seconds", 12),
("676", "generation_model", 13),
("676", "max_h3_shot_seconds", 14),
("187", "resolution_aspect_ratio_override", 15),
):
self.assertEqual(self.graph[node_id]["inputs"][input_name], ["849", slot])
self.assertEqual(self.graph["818"]["inputs"]["expected_bpm"], ["814", 5])
if __name__ == "__main__":
unittest.main()