Files
olivv-cs-ComfyUI-FunPack/tests/test_funpack_log.py
T
digital-garbage d80c17bfaa maint: remove the chunk-causal lane
Validated on the rental and it does not earn its place: 3.5 minutes against 1
for the same clip, worse picture, garbage audio. Some of that was mine — no
weight prefetch across the 50 blocks, a host-offloaded K/V cache, and an extra
commit forward per chunk — but fixing those only buys parity on speed, and the
technique's real win is unbounded length, which H3 already covers natively at
the lengths in use here.

Gone: h3_causal.py, the four h3_causal_* sampler widgets and their Engine
Settings rows, `chunk_causal` on the diffusion loader, and five test files.

KEPT, because it is not about this at all: the LoRA key RENAME table. Stripping
a wrapper head leaves `blocks.0...`, comfy's key map has no bare form, and the
file silently applies nothing — 532 keys, zero applied, no error. That was
breaking any PEFT-style adapter named this way, not just the one that found it.
Its tests moved to test_lora_shape_mismatch.py alongside the MATCHED NOTHING
diagnostics.

Two INPUT_TYPES widgets go with this (h3_causal_* on the sampler, chunk_causal
on the loader). A saved workflow carrying them loads fine — both were optional
and are matched by name — but the values are ignored from here.

Tests: 1700 python, 68 JS.
2026-08-26 23:39:32 +03:00

216 lines
8.7 KiB
Python

"""The console voice: say what did not happen, without saying it twenty times."""
import sys
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import funpack_log as L # noqa: E402
@pytest.fixture(autouse=True)
def _clean():
L.reset()
yield
L.reset()
def test_a_standing_condition_is_stated_once_not_every_run(capsys):
for _ in range(5):
L.note_on_change("family", "FunPackEnhancements", "non-LTX model — enhancements skipped")
assert capsys.readouterr().out.count("non-LTX") == 1
def test_a_standing_condition_speaks_again_when_the_answer_changes(capsys):
L.note_on_change("family", "T", "non-LTX model — enhancements skipped")
L.note_on_change("family", "T", "LTX model — enhancements active")
L.note_on_change("family", "T", "non-LTX model — enhancements skipped")
out = capsys.readouterr().out
assert out.count("non-LTX") == 2 and out.count("enhancements active") == 1
def test_a_new_run_does_not_reset_standing_conditions(capsys):
L.note_on_change("family", "T", "non-LTX")
L.begin_run()
L.note_on_change("family", "T", "non-LTX")
assert capsys.readouterr().out.count("non-LTX") == 1
def test_a_failure_says_what_stopped_and_what_the_output_looks_like(capsys):
L.failed("FunPackSceneChain", "anchor pin restore", ValueError("shape mismatch"),
"the scene keeps its unpinned latent")
out = capsys.readouterr().out
assert "anchor pin restore: Failed" in out
# The effect, not the exception: an exception message rarely says what the output looks
# like, and that is the half rule 1 exists for. The error is one FUNPACK_LOG away.
assert "The scene keeps its unpinned latent" in out
L.reset()
L.set_verbose(True)
try:
L.failed("FunPackSceneChain", "anchor pin restore", ValueError("shape mismatch"),
"the scene keeps its unpinned latent")
assert "shape mismatch" in capsys.readouterr().out
finally:
L.set_verbose(False)
def test_a_per_step_failure_is_collapsed_to_one_line_per_run(capsys):
for _ in range(20):
L.failed("T", "taste steering", RuntimeError("boom"), "the step runs unsteered")
assert capsys.readouterr().out.count("taste steering: Failed") == 1
def test_the_next_run_reports_the_same_failure_again(capsys):
L.failed("T", "taste steering", RuntimeError("boom"), "unsteered")
L.begin_run()
L.failed("T", "taste steering", RuntimeError("boom"), "unsteered")
assert capsys.readouterr().out.count("taste steering: Failed") == 2
def test_a_failure_without_an_error_object_still_reads_as_a_sentence(capsys):
L.failed("T", "guide append", None, "the scene renders without the guide")
assert "guide append: Failed" in capsys.readouterr().out
def test_a_deliberate_skip_reads_differently_from_a_failure(capsys):
L.skipped("T", "SLA attention", "Triton is not installed")
out = capsys.readouterr().out
assert "SLA attention: Inactive | Triton is not installed" in out
assert "Failed" not in out
def test_note_once_keys_on_the_message_so_distinct_values_each_speak(capsys):
L.note_once("T", "scene 1 of 3")
L.note_once("T", "scene 2 of 3")
L.note_once("T", "scene 2 of 3")
assert capsys.readouterr().out.count("scene") == 2
def test_note_once_can_be_pinned_to_one_key_so_a_varying_line_says_it_once(capsys):
L.note_once("T", "dropped 1 frame", key="dropped")
L.note_once("T", "dropped 7 frames", key="dropped")
assert capsys.readouterr().out.count("dropped") == 1
def test_note_always_speaks(capsys):
for _ in range(3):
L.note("T", "scene finished")
assert capsys.readouterr().out.count("scene finished") == 3
def test_the_helpers_report_whether_they_actually_printed():
assert L.note_on_change("k", "T", "a") is True
assert L.note_on_change("k", "T", "a") is False
assert L.failed("T", "x", None, "y") is True
assert L.failed("T", "x", None, "y") is False
# --- wiring ---------------------------------------------------------------------
# The helper is only worth anything if the modules that swallow failures actually use it.
def test_the_sampler_and_studio_share_one_logger():
import samplers
import conditioning
import ltx_enhancements
assert samplers._log is L
assert conditioning._log is L
assert ltx_enhancements._log is L
def test_a_standing_condition_and_a_failure_do_not_share_a_reset(capsys):
# begin_run() must clear failures (so the next run reports them again) without clearing
# standing conditions (so a model family is not re-announced every generation).
L.note_on_change("family", "T", "non-LTX")
L.failed("T", "guide append", None, "no guide")
capsys.readouterr()
L.begin_run()
L.note_on_change("family", "T", "non-LTX")
L.failed("T", "guide append", None, "no guide")
out = capsys.readouterr().out
assert "non-LTX" not in out # standing: still true, still silent
assert "guide append: Failed" in out # failure: news again this run
# ── the shape: one line, one clause ─────────────────────────────────────────
#
# A paragraph per feature is how a log stops being read, and a log nobody reads reports
# nothing. The reasoning is still written at every call site — it is worth having the first
# time someone hits a problem — so FUNPACK_LOG=verbose prints it in full.
def test_a_feature_reads_as_state_then_reason(capsys):
L.feature("FunPack", "K/V conditioning patch", False, "non-LTX model loaded")
assert capsys.readouterr().out == \
"[FunPack] K/V conditioning patch: Inactive | Non-LTX model loaded\n"
def test_an_active_feature_needs_no_reason(capsys):
L.feature("FunPack", "Region lock", True)
assert capsys.readouterr().out == "[FunPack] Region lock: Active\n"
def test_an_inactive_feature_without_a_reason_says_so_rather_than_trailing_off(capsys):
"""Inactive is only half an answer. A missing why is a gap worth seeing, not hiding."""
L.feature("FunPack", "Region lock", False)
assert "Inactive | No reason given" in capsys.readouterr().out
def test_the_explanation_is_cut_and_the_answer_is_kept(capsys):
L.feature("FunPack", "Taste push", False,
"needs 3 liked runs on this key. The Refiner learns the direction from your "
"ratings and there is nothing to learn from yet.")
assert capsys.readouterr().out == \
"[FunPack] Taste push: Inactive | Needs 3 liked runs on this key\n"
def test_verbose_prints_the_whole_thing(capsys):
L.set_verbose(True)
try:
L.feature("FunPack", "Taste push", False,
"needs 3 liked runs on this key. The Refiner learns the direction from "
"your ratings.")
assert "The Refiner learns the direction" in capsys.readouterr().out
finally:
L.set_verbose(False)
def test_an_em_dash_is_not_a_cut(capsys):
"""It introduces the reason as often as the essay, and a renderer that guesses wrong eats
the one part of the line worth reading."""
L.feature("FunPack", "Region lock", False, "not a MiniMax H3 model — an H3-only lane")
assert "an H3-only lane" in capsys.readouterr().out
def test_a_single_long_sentence_is_trimmed_rather_than_left_to_run(capsys):
L.feature("FunPack", "Thing", False, "because " + "a" * 400)
line = capsys.readouterr().out.strip()
assert len(line) < 220 and line.endswith("…")
def test_a_feature_repeats_only_when_its_state_changes(capsys):
"""A standing condition is news once. Twenty identical lines are what makes a log stop
being read at all."""
for _ in range(5):
L.feature("FunPack", "Region lock", False, "not a MiniMax H3 model")
assert capsys.readouterr().out.count("Region lock") == 1
L.feature("FunPack", "Region lock", True, "384 of 1024 patches")
assert "Region lock: Active" in capsys.readouterr().out
def test_a_skip_and_an_inactive_feature_read_the_same(capsys):
"""They are the same fact — the user should not have to learn two spellings of it."""
L.feature("FunPack", "SLA attention", False, "Triton is not installed")
L.reset()
L.skipped("FunPack", "SLA attention", "Triton is not installed")
lines = [x for x in capsys.readouterr().out.strip().splitlines()]
assert lines[0] == lines[1]
def test_a_diagnostic_can_ask_for_its_whole_payload(capsys):
"""The rare line whose PAYLOAD is the detail — two sets of key names to compare — where
trimming removes the only reason to print it."""
L.note("FunPack", "LoRA matched NOTHING. Its keys: a.b.c. This model wants: d.e.f.",
full=True)
out = capsys.readouterr().out
assert "a.b.c" in out and "d.e.f" in out