flow2 / tests /conftest.py
AndrianBalanescu
test-isolation: route all generated data writes through MOLDOVAN_DATA_ROOT
e397832
Raw History Blame Contribute Delete
3.54 kB
"""Pytest configuration and fixtures for AI Creative Studio & Moldovan AI Media Studio.
"""
import glob
import json
import os
import sys
import tempfile
from pathlib import Path
import pytest
PROJECT_ROOT = Path(__file__).resolve().parent.parent
MOLDOVAN_DIR = PROJECT_ROOT / "moldovan-qwen"
# Ensure root and subproject are on sys.path
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
if str(MOLDOVAN_DIR) not in sys.path:
sys.path.insert(0, str(MOLDOVAN_DIR))
# Set test environment flags
os.environ["HF_SKIP_PRELOAD"] = "1"
os.environ["TESTING"] = "1"
# Isolate ALL generated-media writes away from the real repo data/ tree.
# MOLDOVAN_DATA_ROOT is read by media_creator.py, studio_server.py, and
# daily_album_cron.py at import time; a per-process scratch root keeps the
# repo clean while still exercising real file I/O.
_REPO_DATA = MOLDOVAN_DIR / "data"
_DATA_ROOT = os.environ.get("MOLDOVAN_DATA_ROOT") or os.path.join(
tempfile.gettempdir(), "moldovan_qwen_test_data"
)
os.environ["MOLDOVAN_DATA_ROOT"] = _DATA_ROOT
def _seed_scratch_data_root() -> None:
"""Copy read-only seed sources from the repo data/ into the scratch root once.
Modules write generated artifacts under MOLDOVAN_DATA_ROOT, but they also
READ seed inputs (lexicon, regionalisms, corpus, phonetic dictionary,
master dictionary). Copy them so tests see real data while the repo
data/ tree stays untouched.
"""
import shutil
os.makedirs(_DATA_ROOT, exist_ok=True)
seeds = [
"moldovan_lexicon.json",
"regionalisme_moldovenesc.jsonl",
"moldovan_master_dictionary.json",
"phonetic_dictionary.json",
]
for name in seeds:
src = _REPO_DATA / name
dst = os.path.join(_DATA_ROOT, name)
if src.exists() and not os.path.exists(dst):
shutil.copy2(src, dst)
corpus_src = _REPO_DATA / "youtube_corpus"
corpus_dst = os.path.join(_DATA_ROOT, "youtube_corpus")
if corpus_src.exists() and not os.path.exists(corpus_dst):
shutil.copytree(corpus_src, corpus_dst)
# Read-only storyboards: DOM closure tests drive the timeline UI from these
# (44 sampled chips + selectable scenes). Server never writes here in tests.
scripts_src = _REPO_DATA / "generated_video_scripts"
scripts_dst = os.path.join(_DATA_ROOT, "generated_video_scripts")
if scripts_src.exists() and not os.path.exists(scripts_dst):
shutil.copytree(scripts_src, scripts_dst)
# Sanitize: drop absolute image references so scratch data is
# self-contained (no console 404s for images not copied to scratch).
for sp in glob.glob(os.path.join(scripts_dst, "*.json")):
try:
with open(sp, "r", encoding="utf-8") as f:
board = json.load(f)
for scene in board.get("scenes", []):
scene.pop("image_url", None)
scene.pop("image_path", None)
with open(sp, "w", encoding="utf-8") as f:
json.dump(board, f, ensure_ascii=False)
except Exception:
pass
_seed_scratch_data_root()
os.makedirs(os.path.join(_DATA_ROOT, "generated_music"), exist_ok=True)
@pytest.fixture(autouse=True)
def setup_test_env(monkeypatch):
"""Automatically ensure test flags and paths are set for all tests."""
monkeypatch.setenv("HF_SKIP_PRELOAD", "1")
monkeypatch.setenv("TESTING", "1")
monkeypatch.setenv("MOLDOVAN_DATA_ROOT", _DATA_ROOT)