"""Disk-space pre-check in `download_journal_data`.""" import os from unittest.mock import patch import pytest from local_deep_research.journal_quality.downloader import ( download_journal_data, ) @pytest.fixture def tmp_data_dir(tmp_path): with patch( "local_deep_research.journal_quality.downloader._get_data_dir", return_value=tmp_path, ): yield tmp_path def _fake_disk_usage(free_bytes): class _Usage: total = 10 * 1024**3 used = total - free_bytes free = free_bytes return _Usage() def _stamp_live_sentinel(path): """Write the current PID into the sentinel so the downloader's PID-based liveness check treats it as "owner alive" and short-circuits with "already in progress" rather than reclaiming it as orphan. An empty `.touch()`'d sentinel fails the int() parse in `_sentinel_owner_alive` and is now correctly treated as orphan. """ path.write_text(str(os.getpid())) def test_disk_space_below_threshold_refuses_download(tmp_data_dir): with patch( "shutil.disk_usage", return_value=_fake_disk_usage(500 * 1024**2), # 500 MB free ): success, msg = download_journal_data(force=True) assert success is False assert "Insufficient disk space" in msg assert "0.5 GB available" in msg def test_disk_space_above_threshold_proceeds_past_check(tmp_data_dir): # Simulate a concurrent download in progress so we can assert that # the disk check was cleared (we wouldn't reach this error otherwise). sentinel = tmp_data_dir / ".downloading" _stamp_live_sentinel(sentinel) with patch( "shutil.disk_usage", return_value=_fake_disk_usage(5 * 1024**3), # 5 GB free ): success, msg = download_journal_data(force=True) assert success is False assert "already in progress" in msg def test_disk_usage_os_error_does_not_block_download(tmp_data_dir): sentinel = tmp_data_dir / ".downloading" _stamp_live_sentinel(sentinel) with patch("shutil.disk_usage", side_effect=OSError("permission denied")): success, msg = download_journal_data(force=True) # OSError must not short-circuit — the function logs and proceeds, # so we still hit the sentinel short-circuit below. assert success is False assert "already in progress" in msg