Fast_deploy / ComfyUI-MiniMaxH3-Context-Loop /tests /_checkpoint_local_output_unit_test.py
dzmdd's picture
Upload folder using huggingface_hub (part 2)
bc50ea0 verified
Raw History Blame Contribute Delete
6.44 kB
#!/usr/bin/env python3
"""Local manager output uses exact saved takes without promoting any pointer."""
import importlib.util
import json
import math
from pathlib import Path
import tempfile
from unittest.mock import patch
ROOT = Path(__file__).resolve().parents[1]
spec = importlib.util.spec_from_file_location(
"local_output_helpers", ROOT / "tests/_checkpoint_revision_unit_test.py")
h = importlib.util.module_from_spec(spec)
spec.loader.exec_module(h)
chain = h.chain
def snapshot(root):
return {str(path.relative_to(root)): path.read_bytes()
for path in root.rglob("*") if path.is_file()}
def rejected(call, text):
try:
call()
except (OSError, ValueError) as exc:
assert text in str(exc), str(exc)
else:
raise AssertionError("Expected failure: " + text)
def main():
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
h.folder_paths.output_directory = temporary
run = root / "h3_chains" / "local_test"
old1, _ = h.write_revision(run, 1, "1" * 32, 11, run_name=run.name)
old2, _ = h.write_revision(run, 2, "2" * 32, 12, predecessor=old1, run_name=run.name)
new1, _ = h.write_revision(run, 1, "3" * 32, 21, active=True, run_name=run.name)
new2, _ = h.write_revision(run, 2, "4" * 32, 22, active=True, predecessor=new1, run_name=run.name)
(run / "plan.json").write_text(json.dumps({
"run_name":run.name, "shots":[{"id":f"scene_{i}"} for i in range(1, 4)],
}))
(run / "manifest.json").write_text('{"keep": "project final"}')
(run / "editorial.json").write_text(json.dumps({
"scene_order":[{"scene":i, "scene_id":f"scene_{i}"} for i in range(1, 4)],
}))
# Workflow ownership is deliberately nightly-only. The stable port
# still guarantees no changes to any project-wide active pointers.
selection = {"run_name":run.name, "output_mode":"workflow_local",
"scope_start_scene":1, "scope_end_scene":3,
"lineage":[{"scene":1, "revision":"1" * 32},
{"scene":2, "revision":"2" * 32}]}
node = chain.MiniMaxH3ChainCheckpointManager()
assert math.isnan(node.IS_CHANGED())
assert node.passthrough() == (None,)
before = snapshot(root)
with patch.object(chain, "_atomic_json", side_effect=AssertionError("local output wrote JSON")):
result = node.passthrough(json.dumps(selection))[0]
assert [row["revision"] for row in result["segments"]] == ["1" * 32, "2" * 32]
assert result["selection_complete"] is False and result["planned_clip_count"] == 3
assert snapshot(root) == before, "local selection modified project files"
assert node.passthrough({k:v for k, v in selection.items() if k != "output_mode"})[0] == result, \
"pinning alone does not change upscale source hashes"
# A second workflow's exact output and the project's active state remain
# independent. Changing shared pointers after the pin does not move it.
second = {**selection, "lineage":[{"scene":1,"revision":"3" * 32},
{"scene":2,"revision":"4" * 32}]}
assert node.passthrough(second)[0]["segments"][1]["revision"] == "4" * 32
for i, metadata in enumerate((old1, old2), start=1):
(run / "checkpoints" / f"clip_{i:04d}.json").write_text(json.dumps(metadata))
changed = snapshot(root)
assert node.passthrough(second)[0]["segments"][1]["revision"] == "4" * 32
assert node.passthrough(selection)[0] == result
assert snapshot(root) == changed
rejected(lambda: node.passthrough({**selection, "output_mode":"global"}), "unknown output")
rejected(lambda: node.passthrough({**selection, "lineage":[
{"scene":1,"revision":"3" * 32}, {"scene":2,"revision":"2" * 32}]}), "depends on")
rejected(lambda: node.passthrough({**selection, "lineage":[
{"scene":1,"revision":"../escape"}]}), "32-character")
rejected(lambda: node.passthrough({**selection, "lineage":[selection["lineage"][1]]}), "contiguous")
# Legacy reference caches can be read in place, but a local output must
# not adopt/copy them into this run as a side effect.
descriptor = {"format":"h3_reference_cache_v2", "signature":"cache-test",
"reference_fingerprint":"refs", "metadata":"cache/ref.json",
"tensors":"cache/ref.safetensors", "tensors_sha256":"0" * 64}
metadata_path = root / old2["segment"]["revision_metadata"]
old2["segment"]["reference_cache"] = descriptor
metadata_path.write_text(json.dumps(old2))
changed = snapshot(root)
with patch.object(chain, "_run_local_reference_cache", return_value=None), \
patch.object(chain, "_load_reference_cache_descriptor", return_value=descriptor), \
patch.object(chain, "_adopt_reference_cache_for_run", side_effect=AssertionError("local cache migration")):
assert node.passthrough(selection)[0]["segments"][1]["reference_cache"] == descriptor
assert snapshot(root) == changed
# Canonical pointers still exist. They must not serve as fallback when
# an immutable selection is removed or fails integrity verification.
prefix_path = root / old1["segment"]["revision_metadata"]
prefix_data = prefix_path.read_bytes()
prefix_path.unlink()
changed = snapshot(root)
rejected(lambda: node.passthrough(selection), "no longer available")
assert snapshot(root) == changed, "local output recreated a missing prefix"
prefix_path.write_bytes(prefix_data)
metadata_path.unlink()
changed = snapshot(root)
rejected(lambda: node.passthrough(selection), "no longer available")
assert snapshot(root) == changed
metadata_path.write_text(json.dumps(old2))
video = root / old2["segment"]["segment"]
video.write_bytes(b"corrupt")
changed = snapshot(root)
rejected(lambda: node.passthrough(selection), "integrity")
assert snapshot(root) == changed
print("Checkpoint local output: read-only, exact revisions, stable source hash, legacy cache and fail-closed checks pass")
if __name__ == "__main__":
main()