-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow using tuples of Paths to represent units of work
- Loading branch information
1 parent
2672e30
commit b4d0b54
Showing
3 changed files
with
211 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
"""Test the file creation progress tracking utilities.""" | ||
from __future__ import annotations | ||
|
||
import asyncio | ||
import contextlib | ||
from typing import TYPE_CHECKING | ||
from unittest.mock import Mock | ||
|
||
import pytest | ||
from rich.progress import Progress, TaskID | ||
|
||
from adaptive_scheduler.utils import ( | ||
_remove_completed_paths, | ||
_track_file_creation_progress, | ||
_update_progress_for_paths, | ||
) | ||
|
||
if TYPE_CHECKING: | ||
from pathlib import Path | ||
|
||
|
||
def test_update_progress_for_paths(tmp_path: Path) -> None: | ||
"""Test the update progress for paths function.""" | ||
# Create test files | ||
create_test_files(tmp_path, ["file1", "file3", "file4"]) | ||
|
||
paths_dict: dict[str, set[Path | tuple[Path, ...]]] = { | ||
"category1": {tmp_path / "file1", tmp_path / "file2"}, | ||
"category2": {(tmp_path / "file3", tmp_path / "file4")}, | ||
} | ||
|
||
progress_mock = Mock(spec=Progress) | ||
task_id_mock = Mock(spec=TaskID) | ||
task_ids = {"category1": task_id_mock, "category2": task_id_mock} | ||
|
||
processed = _update_progress_for_paths( | ||
paths_dict, | ||
progress_mock, | ||
task_id_mock, | ||
task_ids, | ||
) | ||
|
||
assert processed == 2 # Only "file1" and the tuple ("file3", "file4") exist | ||
assert len(paths_dict["category1"]) == 1 # "file2" does not exist and should remain | ||
assert len(paths_dict["category2"]) == 0 # Tuple paths exist and should be removed | ||
progress_mock.update.assert_called() | ||
|
||
|
||
def create_test_files(tmp_path: Path, file_names: list[str]) -> None: | ||
"""Create test files in the given directory.""" | ||
for name in file_names: | ||
(tmp_path / name).touch() | ||
|
||
|
||
def test_remove_completed_paths(tmp_path: Path) -> None: | ||
"""Test the remove completed paths function.""" | ||
# Create test files | ||
existing_files = ["file1", "file3", "file4"] | ||
create_test_files(tmp_path, existing_files) | ||
|
||
paths_dict: dict[str, set[Path | tuple[Path, ...]]] = { | ||
"category1": {tmp_path / "file1", tmp_path / "file2"}, | ||
"category2": {(tmp_path / "file3", tmp_path / "file4")}, | ||
} | ||
|
||
new_paths_dict, n_completed = _remove_completed_paths(paths_dict) | ||
|
||
assert n_completed == {"category1": 1, "category2": 1} | ||
assert new_paths_dict == {"category1": {tmp_path / "file2"}} | ||
|
||
|
||
@pytest.mark.asyncio() | ||
async def test_track_file_creation_progress(tmp_path: Path) -> None: | ||
"""Test the track file creation progress function.""" | ||
# Create test files | ||
create_test_files(tmp_path, ["file1"]) | ||
|
||
paths_dict: dict[str, set[Path | tuple[Path, ...]]] = { | ||
"category1": {tmp_path / "file1", tmp_path / "file2"}, | ||
"category2": {(tmp_path / "file3", tmp_path / "file4")}, | ||
} | ||
|
||
progress = Progress(auto_refresh=False) | ||
task = asyncio.create_task( | ||
_track_file_creation_progress(paths_dict, progress, interval=1e-3), | ||
) | ||
|
||
# Allow some time for the task to process | ||
await asyncio.sleep(0.05) | ||
|
||
progress.stop() | ||
assert "Total" in progress._tasks[0].description | ||
assert progress._tasks[0].total == 3 | ||
assert progress._tasks[0].completed == 1 | ||
|
||
assert "category1" in progress._tasks[1].description | ||
assert progress._tasks[1].total == 2 | ||
assert progress._tasks[1].completed == 1 | ||
|
||
assert "category2" in progress._tasks[2].description | ||
assert progress._tasks[2].total == 1 | ||
assert progress._tasks[2].completed == 0 | ||
|
||
# Create one of the files of category2, should still not be completed | ||
create_test_files(tmp_path, ["file3"]) | ||
await asyncio.sleep(0.05) | ||
|
||
assert "category2" in progress._tasks[2].description | ||
assert progress._tasks[2].total == 1 | ||
assert progress._tasks[2].completed == 0 | ||
|
||
# Create the other file of category2, should now be completed | ||
create_test_files(tmp_path, ["file4"]) | ||
await asyncio.sleep(0.05) | ||
assert "category2" in progress._tasks[2].description | ||
assert progress._tasks[2].total == 1 | ||
assert progress._tasks[2].completed == 1 | ||
|
||
# Create the other file of category1, should now be completed | ||
create_test_files(tmp_path, ["file2"]) | ||
await asyncio.sleep(0.05) | ||
assert "category1" in progress._tasks[1].description | ||
assert progress._tasks[1].total == 2 | ||
assert progress._tasks[1].completed == 2 | ||
|
||
# Check the total progress | ||
assert "Total" in progress._tasks[0].description | ||
assert progress._tasks[0].total == 3 | ||
assert progress._tasks[0].completed == 3 | ||
|
||
# Stop the progress and the task | ||
progress.stop() | ||
task.cancel() | ||
with contextlib.suppress(asyncio.CancelledError): | ||
await task | ||
Check notice Code scanning / CodeQL Statement has no effect Note test
This statement has no effect.
|