techfreakworm commited on
Commit
bcbf933
·
unverified ·
1 Parent(s): a5c71e2

test: pytest fixtures (master_workflow, canonical_inputs, fake_hf_cache)

Browse files
Files changed (2) hide show
  1. tests/__init__.py +0 -0
  2. tests/conftest.py +158 -0
tests/__init__.py ADDED
File without changes
tests/conftest.py ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Shared pytest fixtures and CLI flags."""
2
+ import json
3
+ import os
4
+ import pathlib
5
+ from typing import Any
6
+
7
+ import pytest
8
+
9
+ REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent
10
+
11
+ DEFAULT_MASTER_WORKFLOW = pathlib.Path(
12
+ os.environ.get(
13
+ "LTX23_MASTER_WORKFLOW",
14
+ pathlib.Path.home() / "Projects/comfyui/user/default/workflows"
15
+ / "1. LTX 2.3 All-In-One 260406-05.json",
16
+ )
17
+ )
18
+
19
+
20
+ def pytest_addoption(parser: pytest.Parser) -> None:
21
+ parser.addoption("--gpu", action="store_true", help="Run L4 GPU smoke tests.")
22
+ parser.addoption(
23
+ "--comfy-real",
24
+ action="store_true",
25
+ help="Use bundled ComfyUI for L2 graph validation (slower).",
26
+ )
27
+
28
+
29
+ def pytest_collection_modifyitems(
30
+ config: pytest.Config, items: list[pytest.Item]
31
+ ) -> None:
32
+ if not config.getoption("--gpu"):
33
+ skip_gpu = pytest.mark.skip(reason="GPU smoke tests skipped (use --gpu)")
34
+ for item in items:
35
+ if "gpu" in item.keywords:
36
+ item.add_marker(skip_gpu)
37
+
38
+
39
+ @pytest.fixture(scope="session")
40
+ def master_workflow() -> dict[str, Any]:
41
+ """The full LTX 2.3 All-In-One workflow JSON (loaded from user's ComfyUI)."""
42
+ if not DEFAULT_MASTER_WORKFLOW.exists():
43
+ pytest.skip(
44
+ f"Master workflow not found at {DEFAULT_MASTER_WORKFLOW}. "
45
+ "Set LTX23_MASTER_WORKFLOW env var to its path."
46
+ )
47
+ return json.loads(DEFAULT_MASTER_WORKFLOW.read_text())
48
+
49
+
50
+ @pytest.fixture
51
+ def canonical_inputs() -> dict[str, dict[str, Any]]:
52
+ """Known-good Gradio input dicts per mode (used by L1/L2 tests)."""
53
+ return {
54
+ "t2v": {
55
+ "prompt": "a tiger walking through a misty forest at dawn, cinematic",
56
+ "negative_prompt": "",
57
+ "preset": "balanced",
58
+ "width": 512,
59
+ "height": 768,
60
+ "frames": 81,
61
+ "fps": 24,
62
+ "seed": 42,
63
+ "camera_lora": "none",
64
+ "camera_strength": 0.8,
65
+ "detailer_on": False,
66
+ "detailer_strength": 0.5,
67
+ },
68
+ "i2v": {
69
+ "prompt": "the subject turns toward the camera and smiles",
70
+ "image": "/tmp/portrait.png",
71
+ "preset": "balanced",
72
+ "width": 512,
73
+ "height": 768,
74
+ "frames": 81,
75
+ "fps": 24,
76
+ "seed": 42,
77
+ "camera_lora": "none",
78
+ "camera_strength": 0.8,
79
+ "detailer_on": True,
80
+ "detailer_strength": 0.5,
81
+ "ic_lora": "union",
82
+ "ic_strength": 0.5,
83
+ "pose_on": False,
84
+ },
85
+ "a2v": {
86
+ "prompt": "a dancer moves to the beat in a neon-lit studio",
87
+ "audio": "/tmp/track.wav",
88
+ "preset": "balanced",
89
+ "width": 512,
90
+ "height": 768,
91
+ "frames": 81,
92
+ "fps": 24,
93
+ "seed": 42,
94
+ "audio_cfg": 7.0,
95
+ },
96
+ "lipsync": {
97
+ "prompt": "the person speaks the audio with natural mouth movement",
98
+ "image": "/tmp/portrait.png",
99
+ "audio": "/tmp/speech.wav",
100
+ "preset": "balanced",
101
+ "image_strength": 0.7,
102
+ "frames": 81,
103
+ "fps": 24,
104
+ "seed": 42,
105
+ },
106
+ "keyframe": {
107
+ "prompt": "smooth transition between the two frames",
108
+ "first_frame": "/tmp/start.png",
109
+ "last_frame": "/tmp/end.png",
110
+ "preset": "balanced",
111
+ "frames": 81,
112
+ "fps": 24,
113
+ "seed": 42,
114
+ },
115
+ "style": {
116
+ "prompt": "in the style of a renaissance oil painting",
117
+ "input_video": "/tmp/source.mp4",
118
+ "preset": "balanced",
119
+ "frames": 81,
120
+ "fps": 24,
121
+ "seed": 42,
122
+ "ic_lora": "motion-track",
123
+ "ic_strength": 0.5,
124
+ },
125
+ }
126
+
127
+
128
+ @pytest.fixture
129
+ def fake_hf_cache(tmp_path: pathlib.Path) -> pathlib.Path:
130
+ """A fake ~/.cache/huggingface/hub layout with placeholder files."""
131
+ hub = tmp_path / "huggingface" / "hub"
132
+ layouts = {
133
+ "models--Lightricks--LTX-2.3": [
134
+ "ltx-2.3-22b-distilled.safetensors",
135
+ "ltx-2.3-spatial-upscaler-x2-1.0.safetensors",
136
+ "ltx-2.3-22b-distilled-lora-384.safetensors",
137
+ ],
138
+ "models--google--gemma-3-12b-it-qat-q4_0-unquantized": [
139
+ "model-00001-of-00005.safetensors",
140
+ "model-00002-of-00005.safetensors",
141
+ "model-00003-of-00005.safetensors",
142
+ "model-00004-of-00005.safetensors",
143
+ "model-00005-of-00005.safetensors",
144
+ "model.safetensors.index.json",
145
+ "tokenizer.model",
146
+ "preprocessor_config.json",
147
+ ],
148
+ "models--Kijai--LTX2.3_comfy": [
149
+ "LTX23_video_vae_bf16.safetensors",
150
+ "LTX23_audio_vae_bf16.safetensors",
151
+ ],
152
+ }
153
+ for repo, files in layouts.items():
154
+ snapshot_dir = hub / repo / "snapshots" / "deadbeef"
155
+ snapshot_dir.mkdir(parents=True, exist_ok=True)
156
+ for filename in files:
157
+ (snapshot_dir / filename).write_text("") # placeholder
158
+ return hub