From a0fad061e2feaeef1624df7114c795bf28a2bf17 Mon Sep 17 00:00:00 2001 From: ciaranbor Date: Tue, 10 Mar 2026 11:27:56 +0000 Subject: [PATCH] Include ongoing downloads in calculate_used_storage --- src/exo/download/tests/test_auto_eviction.py | 25 ++++++++++++++++++++ src/exo/shared/storage.py | 2 +- src/exo/shared/tests/test_storage.py | 4 ++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/exo/download/tests/test_auto_eviction.py b/src/exo/download/tests/test_auto_eviction.py index 6f6a0551..461b70dc 100644 --- a/src/exo/download/tests/test_auto_eviction.py +++ b/src/exo/download/tests/test_auto_eviction.py @@ -536,3 +536,28 @@ class TestClearRejections: assert isinstance(coordinator.download_status[MODEL_A], DownloadEvicted) # Rejected should be cleared to Pending assert isinstance(coordinator.download_status[MODEL_B], DownloadPending) + + async def test_clear_rejections_on_policy_only_change(self) -> None: + """clear_rejections fires even when only the policy changes (no limit change).""" + config = StorageConfig( + max_storage=Memory.from_gb(10), storage_policy="manual" + ) + rejected = DownloadRejected( + node_id=NODE_ID, + shard_metadata=_shard(MODEL_A, 4), + reason="Manual policy", + required=Memory.from_gb(4), + available=Memory.from_gb(1), + limit=Memory.from_gb(10), + ) + coordinator, _ = _make_coordinator( + config, + {MODEL_A: rejected, MODEL_B: _completed(MODEL_B, 3)}, + ) + + await coordinator.clear_rejections() + + # Rejected should be cleared to Pending + assert isinstance(coordinator.download_status[MODEL_A], DownloadPending) + # Completed should be unchanged + assert isinstance(coordinator.download_status[MODEL_B], DownloadCompleted) diff --git a/src/exo/shared/storage.py b/src/exo/shared/storage.py index a0436e99..29fd0c77 100644 --- a/src/exo/shared/storage.py +++ b/src/exo/shared/storage.py @@ -17,7 +17,7 @@ def calculate_used_storage(downloads: Sequence[DownloadProgress]) -> Memory: if isinstance(dp, DownloadCompleted): total = total + dp.total elif isinstance(dp, DownloadOngoing): - total = total + dp.download_progress.downloaded + total = total + dp.download_progress.total return total diff --git a/src/exo/shared/tests/test_storage.py b/src/exo/shared/tests/test_storage.py index 63ff8f7a..6450ca21 100644 --- a/src/exo/shared/tests/test_storage.py +++ b/src/exo/shared/tests/test_storage.py @@ -193,8 +193,8 @@ class TestCalculateUsedStorage: ), ] used = calculate_used_storage(downloads) - # 5 GiB completed + 3 GiB ongoing downloaded = 8 GiB - assert abs(used.in_gb - 8.0) < 0.01 + # 5 GiB completed + 10 GiB ongoing total = 15 GiB + assert abs(used.in_gb - 15.0) < 0.01 def test_empty_downloads(self) -> None: assert calculate_used_storage([]).in_bytes == 0