Skip to main content
Version: develop (unreleased)

vqa/tests

Covers the utilities shipped inside the VQA Kasm image — the environment used to assess the quality of videos Tubematic has produced.

python -m pytest vqa/tests

Most of these files use class Test… grouping rather than flat test_ functions, unlike the other Python suites; test_host_side_imports.py and test_make_seed_db.py are flat.


FileGuards
test_edit_settings.pyedit_settings.py — the settings read/write utility, including assignment parsing (key=value, split on the first = only, empty values allowed) Every API call carries the API token from the secrets directory, and a missing token stops with the command that creates it.
test_host_side_imports.pyThat pipeline.py and mcp/server.py still import with only their own directory on sys.path and no PYTHONPATH, which is how the host-side VQA helpers load them. When the two modules gained a tubematic_core import, every helper died with ModuleNotFoundError, and nothing else could catch it: the container sets PYTHONPATH to the package, and the isolated-tree tests set it explicitly. make_seed_db.py is run end to end as the cheapest proof a real helper works. The fallback that adds the repo root must not fire when the package already resolves, because the repo root also carries an mcp directory whose name collides with the MCP SDK
test_make_seed_db.pymake_seed_db.py — the build-time seed database baked into the VQA image. The seed is written after migrating, so migration 0006 never stamps it: its voice must already carry its own model, or every reader sees an empty roster. The same goes for 0016: the seeded image_model must already be an OpenAI model, with no image_provider row
test_reset_db.pyreset_db.py — the destructive DB and artifact reset
test_review_video.pyreview_video.py — the on-demand AI review script. It finds the mp4 and scene-config.json from the video's id and project, never from the stored path columns: a planted video_path is not what gets reviewed, and the OUTPUT_VIDEOS_PATH override is honoured
test_stage_script.pystage_script.py — staging the script, broll and the ElevenLabs-bound text as plain files for human review. The one test that runs the real mcp/server.py also proves the staged text goes through _build_tts_text, the same function generate_voice uses, so an <ipa> tag for a voice on eleven_v3 is staged in its "/…/" form. The model comes from the video's voice, resolved exactly as generate_voice resolves it. A script generate_voice would refuse for that model — an <ipa> or <phoneme> tag the voice's model cannot speak — is not staged at all, and neither is a video with no voice in the roster, so the review file never shows text that would not be sent. The job directory comes from tubematic_core.jobfiles: an existing row whose id is ../outside, an absolute path, ., .. or a/b is found in the database yet writes nothing anywhere, and a job directory or staged file that is a symlink is refused, while a legacy a.b still stages
test_statusline.pystatusline.py — the Claude Code statusline showing context usage and rate-limit windows

What these encode​

edit_settings.py writes over POST /settings, never direct SQL. Some checks live only in post_settings — the live webhook probe, and keeping a re-sent masked secret from overwriting the real key — so a direct-SQL script reusing _coerce_setting would skip them. Do not "simplify" this into a DB write.

No settings key needs a restart. worker.py, mcp/server.py and pipeline.py all read the database per use with no in-process cache, so a write applies to the next read. --restart is opt-in, for a wedged container only.

The seed database sets gemini_review_enabled=false deliberately. The worker bounces any video with a non-empty suggestions list to REVISION_REQUESTED, so leaving review on would mean almost no video ever reaches VIDEO_READY in the VQA environment.

review_video.py derives paths rather than translating them. It used to map the stored container paths (/jobs/…, /output_videos/…) onto the host tree by prefix. The stored columns were once writable by any caller, so a row could name any host file to be uploaded for review; deriving the location from the ids, exactly as the worker does, makes such a row harmless. The isolated-tree test therefore copies tubematic_core along with the script.

stage_script.py owns mounted/jobs/<vid>/tts_text.txt with preview semantics. That is why videos.tts_text — the record of what was actually sent to ElevenLabs — is stored in the database instead, and deliberately not written to that path.