Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 68 additions & 6 deletions cortex/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,76 @@
import shutil
import tarfile
from unittest import mock

import pytest

import cortex

def test_download_subject():
# Test that newly downloaded subjects are added to the current database.

# remove fsaverage from the list of available subjects if present.
if "fsaverage" in cortex.db.subjects:
cortex.db._subjects.pop("fsaverage")
@pytest.fixture
def fake_fsaverage_tarball(tmp_path):
"""Build a minimal fsaverage.tar.gz that pycortex will recognize as a subject."""
subj_src = tmp_path / "src" / "fsaverage"
subj_src.mkdir(parents=True)
(subj_src / "marker").write_text("ok")
tarball = tmp_path / "fsaverage.tar.gz"
with tarfile.open(tarball, "w:gz") as tar:
tar.add(subj_src, arcname="fsaverage")
return tarball


@pytest.fixture
def isolated_filestore(tmp_path, monkeypatch):
"""Redirect cortex.db.filestore to an empty tmp dir and reset the subject cache."""
store = tmp_path / "store"
store.mkdir()
monkeypatch.setattr(cortex.db, "filestore", str(store))
original_subjects = cortex.db._subjects
cortex.db._subjects = None
yield store
cortex.db._subjects = original_subjects


def test_download_subject(isolated_filestore, fake_fsaverage_tarball, monkeypatch):
# Newly downloaded subjects are added to the current database.
def fake_retrieve(url, dest):
shutil.copy(fake_fsaverage_tarball, dest)
return dest, None

mock_retrieve = mock.Mock(side_effect=fake_retrieve)
monkeypatch.setattr(cortex.utils.urllib.request, "urlretrieve", mock_retrieve)

assert "fsaverage" not in cortex.db.subjects
cortex.utils.download_subject(subject_id='fsaverage')
assert "fsaverage" in cortex.db.subjects
# test that downloading it again works
assert mock_retrieve.call_count == 1


def test_download_subject_skips_when_present(isolated_filestore, monkeypatch):
# If the subject is already in the database and download_again is False,
# download_subject warns and returns without touching the network.
cortex.db._subjects = {"fsaverage": mock.MagicMock()}

mock_retrieve = mock.Mock()
monkeypatch.setattr(cortex.utils.urllib.request, "urlretrieve", mock_retrieve)

with pytest.warns(UserWarning, match="already present"):
cortex.utils.download_subject(subject_id='fsaverage')
mock_retrieve.assert_not_called()


def test_download_subject_download_again(
isolated_filestore, fake_fsaverage_tarball, monkeypatch
):
# download_again=True re-downloads even when the subject is already present.
def fake_retrieve(url, dest):
shutil.copy(fake_fsaverage_tarball, dest)
return dest, None

mock_retrieve = mock.Mock(side_effect=fake_retrieve)
monkeypatch.setattr(cortex.utils.urllib.request, "urlretrieve", mock_retrieve)

cortex.utils.download_subject(subject_id='fsaverage')
assert "fsaverage" in cortex.db.subjects
cortex.utils.download_subject(subject_id='fsaverage', download_again=True)
assert mock_retrieve.call_count == 2