Files
Lyra/worker/tests/test_download_progress.py
T
Jonathan bc42e546f0 fix(worker): raise http.client header limit so Qobuz tracks stop failing
Bruno Mars "24K Magic" track 1 repeatedly downloaded as a 0-byte file. The
worker log showed the real cause: streamrip's track download hit
HTTPException("got more than 100 headers") — Qobuz's CDN returns >100 response
headers for some tracks and Python's http.client rejects them at the default
_MAXHEADERS=100, so streamrip skips the track and leaves an empty placeholder.

- Raise http.client._MAXHEADERS to 1000 on import of the Qobuz adapter, so those
  responses parse and the track downloads.
- _count_staged_audio now skips 0-byte files (a failed-track placeholder is not a
  real track) — improves the download-progress estimate and stops counting dead
  tracks. (A verify-level "reject 0-byte tracks" safety net is a follow-up under
  #16 per-track duration matching — it needs the pipeline fakes to write real
  files, deferred to avoid disproportionate churn here.)

worker 223 tests / 7-skip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 13:17:20 +02:00

65 lines
2.1 KiB
Python

import os
import threading
from lyra_worker.pipeline import _count_staged_audio, _make_on_progress
from tests.conftest import insert_request
def _dp(conn, job_id):
with conn.cursor() as cur:
cur.execute('SELECT "downloadProgress" FROM "Job" WHERE id = %s', (job_id,))
return cur.fetchone()[0]
def test_on_progress_marks_reporting_and_writes(conn):
job_id = insert_request(conn)
reports = threading.Event()
cb = _make_on_progress(conn, job_id, reports)
cb(0.3)
assert reports.is_set() # signals the poller to yield
assert _dp(conn, job_id) == 0.3
def test_on_progress_throttles_tiny_moves(conn):
job_id = insert_request(conn)
cb = _make_on_progress(conn, job_id, threading.Event())
cb(0.30)
cb(0.305) # <1% and <0.5s later → throttled, not written
assert _dp(conn, job_id) == 0.3
cb(0.6) # >=1% move → written
assert _dp(conn, job_id) == 0.6
def test_on_progress_clamps_out_of_range(conn):
job_id = insert_request(conn)
_make_on_progress(conn, job_id, threading.Event())(1.5)
assert _dp(conn, job_id) == 1.0
_make_on_progress(conn, job_id, threading.Event())(-0.2)
assert _dp(conn, job_id) == 0.0
def test_count_staged_audio_counts_nested_audio_files_only(tmp_path):
nested = tmp_path / "Artist" / "Album"
nested.mkdir(parents=True)
(nested / "01.flac").write_bytes(b"audio")
(nested / "02.flac").write_bytes(b"audio")
(nested / "03.flac").write_bytes(b"audio")
(nested / "cover.jpg").write_bytes(b"img")
assert _count_staged_audio(str(tmp_path)) == 3
def test_count_staged_audio_skips_zero_byte_files(tmp_path):
# a 0-byte file is a failed-track placeholder (e.g. streamrip skipping a track) → not a track
(tmp_path / "01 Good.flac").write_bytes(b"audio")
(tmp_path / "02 Dead.flac").write_bytes(b"")
assert _count_staged_audio(str(tmp_path)) == 1
def test_count_staged_audio_empty_dir_is_zero(tmp_path):
assert _count_staged_audio(str(tmp_path)) == 0
def test_count_staged_audio_missing_dir_is_zero():
assert _count_staged_audio("/nonexistent/path/for/sure") == 0