Improve scan progress reporting
This commit is contained in:
@@ -117,6 +117,56 @@ def test_scan_command_runs_stage2_for_pending_files(tmp_path, monkeypatch) -> No
|
||||
assert "passed_stage2=1" in result.stdout
|
||||
|
||||
|
||||
def test_scan_command_reports_discovery_and_stage_progress(tmp_path, monkeypatch) -> None:
|
||||
root = tmp_path / "videos"
|
||||
root.mkdir()
|
||||
risky = root / "risky.mp4"
|
||||
risky.write_bytes(b"risky")
|
||||
|
||||
def fake_run_ffprobe(path, **kwargs):
|
||||
return ProbeExecutionResult(
|
||||
status="completed",
|
||||
command=("ffprobe", str(path)),
|
||||
exit_code=0,
|
||||
stdout_text='{"format":{"format_name":"mov,mp4,m4a,3gp,3g2,mj2","duration":"20.0"},"streams":[{"codec_type":"video"}]}',
|
||||
stderr_text="",
|
||||
elapsed_ms=1,
|
||||
)
|
||||
|
||||
def fake_run_ffmpeg(path, **kwargs):
|
||||
return FfmpegExecutionResult(
|
||||
status="completed",
|
||||
command=("ffmpeg", str(path)),
|
||||
exit_code=0,
|
||||
stdout_text="frame=10",
|
||||
stderr_text="",
|
||||
elapsed_ms=2,
|
||||
reason_code=None,
|
||||
)
|
||||
|
||||
monkeypatch.setattr("tgvideo_check.cli.run_ffprobe", fake_run_ffprobe)
|
||||
monkeypatch.setattr("tgvideo_check.cli.run_ffmpeg_verification", fake_run_ffmpeg)
|
||||
|
||||
result = runner.invoke(
|
||||
app,
|
||||
[
|
||||
"scan",
|
||||
str(root),
|
||||
"--db",
|
||||
str(tmp_path / "scan_state.db"),
|
||||
],
|
||||
)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Discovery: scanning 1 root(s)" in result.stdout
|
||||
assert (
|
||||
"Discovery summary: found=1 reused=0 pending_stage1=1 pending_stage2=0 completed=0"
|
||||
in result.stdout
|
||||
)
|
||||
assert "Stage1 progress: 1/1 (100%) pending_stage2=1" in result.stdout
|
||||
assert "Stage2 progress: 1/1 (100%) passed_stage2=1" in result.stdout
|
||||
|
||||
|
||||
def test_scan_resume_preserves_reason_code_in_exported_report(tmp_path, monkeypatch) -> None:
|
||||
root = tmp_path / "videos"
|
||||
root.mkdir()
|
||||
|
||||
@@ -6,6 +6,7 @@ from tgvideo_check.models import StoredFile
|
||||
from tgvideo_check.scheduler import (
|
||||
build_stage_plan,
|
||||
execute_stage_batch,
|
||||
iter_stage_batch_results,
|
||||
select_pending_stage1_files,
|
||||
select_pending_stage2_files,
|
||||
)
|
||||
@@ -144,3 +145,27 @@ def test_execute_stage_batch_uses_multiple_threads_when_workers_allow() -> None:
|
||||
execute_stage_batch(batch, worker)
|
||||
|
||||
assert len(thread_ids) >= 2
|
||||
|
||||
|
||||
def test_iter_stage_batch_results_yields_items_as_they_finish() -> None:
|
||||
batch = build_stage_plan(
|
||||
stage1_files=[
|
||||
make_stored_file(file_id=1, discovery_order=0, stage1_status="pending_stage1"),
|
||||
make_stored_file(file_id=2, discovery_order=1, stage1_status="pending_stage1"),
|
||||
],
|
||||
stage2_files=[],
|
||||
stage1_workers=2,
|
||||
stage2_workers=1,
|
||||
queue_limit=64,
|
||||
)[0]
|
||||
|
||||
def worker(item: StoredFile) -> int:
|
||||
if item.file_id == 1:
|
||||
time.sleep(0.05)
|
||||
else:
|
||||
time.sleep(0.01)
|
||||
return item.file_id * 10
|
||||
|
||||
results = list(iter_stage_batch_results(batch, worker))
|
||||
|
||||
assert [(item.file_id, output) for item, output in results] == [(2, 20), (1, 10)]
|
||||
|
||||
Reference in New Issue
Block a user