Files
andrew 7a49e2d507 0.6.4: Truthful maintenance digest + scheduled jobs queue for the lock instead of skipping
The Telegram digest reported healthy weekly jobs as "never run yet": its
maintenance section still globbed for cron-era per-script log filenames
(clean-index-*.log etc.) that jobs run through pipeline_runner no longer
write. It now reads job_runs, the scheduler's own record, so it reports the
last success (age + summary snippet from that run's log), flags a newer
failed or lock-skipped attempt on the same line, and distinguishes "never
succeeded (last attempt: skipped, lock busy)" from genuinely never
scheduled. Also matched the clear-bad-genres snippet grep to the script's
current summary wording, and dropped the now-unused newest_log helper.

The DB also showed WHY two jobs had never run: on Sunday the 08:30
strip-mb-tags run took 10m19s while holding the shared pipeline lock, so
strip-watermark-art (08:35) and scrub-watermark-text (08:40) hit flock-style
instant skip and lost their only slot of the week -- the 08:40 job missed by
19 seconds. Scheduled runs now wait up to 30 minutes for the lock
(SCHEDULED_LOCK_WAIT_SECONDS) and only then record skipped_lock, so
fixed-time blocks queue instead of starving; manual "Run now" keeps the
instant skip since a person expects an immediate answer.

Tests: scheduled-run queueing, lock-wait timeout, and manual instant-skip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:13:02 -06:00
..
2026-07-10 16:00:07 -06:00
2026-07-10 16:00:07 -06:00
2026-07-10 16:00:07 -06:00
2026-07-10 16:00:07 -06:00
2026-07-10 16:00:07 -06:00
2026-07-10 16:00:07 -06:00

Tests

Unit and safety tests for the control-plane app and the dedup file-deleter. They run against throwaway temp dirs and a temp SQLite database (set up in conftest.py); they never touch a real library, your /config, or the network.

Running them

The runtime image doesn't ship pytest, so install it into a throwaway run of the built image (which already has the app's own dependencies). Run as root so pip can write into the image's venv, and keep pytest's cache off so it doesn't create files in your working tree:

docker run --rm --user root -v "$PWD":/src -w /src -e PYTHONPATH=/src \
  --entrypoint bash alembic:latest \
  -c "pip install -q pytest && pytest -q -p no:cacheprovider"

Tests set their own temp ALEMBIC_CONFIG_DIR, MUSIC_DATA_DIR, and encryption key (see conftest.py), so nothing here touches a real library or config.

Or, if you have a matching Python environment locally:

pip install -r requirements-dev.txt
PYTHONPATH=. pytest -q

What's covered

  • Dedup safety (test_dedup_gating.py): dedup-library.sh deletes only the paths confirmed via --only-paths, and keeps the higher-ranked (FLAC) copy. This is the most important test: the script deletes files.
  • Runner (test_pipeline_runner.py): lock skip, use_lock=False bypass, success/failure/timeout recording, lock release.
  • Migrations (test_db.py): schema version, idempotent re-run, FK-safe job-run pruning, stale-run reconciliation.
  • Credential rendering (test_credential_service.py): config field substitution (including newline-injection safety), secret vs non-secret classification, cookie-expiry parsing.
  • Playlists (test_playlist_service.py): cron round-trips, name validation, config render/delete.
  • Diagnostics (test_diagnostics.py): the /health and /setup checks.