Skip to content

Commit

Permalink
Port tests to pytest
Browse files Browse the repository at this point in the history
This brings a bunch of fixtures, and also brings in fixtures from
datalad-next (including a dependency on it).
  • Loading branch information
mih committed Jun 8, 2023
1 parent 0161f40 commit f31d8ad
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 117 deletions.
27 changes: 22 additions & 5 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,29 @@ environment:
# MacOS core tests
- ID: MacP38
DTS: datalad_osf
APPVEYOR_BUILD_WORKER_IMAGE: macOS
APPVEYOR_BUILD_WORKER_IMAGE: macos-monterey
PY: 3.8
INSTALL_GITANNEX: git-annex
DATALAD_LOCATIONS_SOCKETS: /Users/appveyor/DLTMP/sockets
CODECOV_BINARY: https://uploader.codecov.io/latest/macos/codecov


# do not run the CI if only documentation changes were made
# documentation builds are tested elsewhere and cheaper
skip_commits:
files:
- docs/
- changelog.d/
- .github/
- CHANGELOG.md
- CITATION.cff
- CONTRIBUTORS
- LICENSE
- Makefile
- README.md
- readthedocs.yml


# it is OK to specify paths that may not exist for a particular test run
cache:
# pip cache
Expand Down Expand Up @@ -152,8 +168,8 @@ install:


build_script:
- pip install -r requirements-devel.txt
- pip install .
- python -m pip install -r requirements-devel.txt
- python -m pip install .


#after_build:
Expand All @@ -172,8 +188,9 @@ test_script:
#- sh: mkdir __testhome__
#- cd __testhome__
# run test selecion (--traverse-namespace needed from Python 3.8 onwards)
- cmd: python -m nose --traverse-namespace -s -v -A "not (turtle)" --with-cov --cover-package datalad_osf %DTS%
- sh: python -m nose --traverse-namespace -s -v -A "not (turtle)" --with-cov --cover-package datalad_osf ${DTS}
- cmd: python -m pytest -s -v -m "not (turtle)" -k "%KEYWORDS%" --cov=datalad_osf --pyargs %DTS%
# also add --cov datalad, because some core test runs may not touch -next code
- sh: PATH=$PWD/../tools/coverage-bin:$PATH python -m pytest -s -v -m "not (turtle)" -k "$KEYWORDS" --cov=datalad_osf --pyargs ${DTS}


after_test:
Expand Down
3 changes: 0 additions & 3 deletions datalad_osf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@
)


from datalad import setup_package
from datalad import teardown_package

from ._version import get_versions
__version__ = get_versions()['version']
del get_versions
22 changes: 22 additions & 0 deletions datalad_osf/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from datalad.conftest import setup_package

from datalad_next.tests.fixtures import (
# no test can leave global config modifications behind
check_gitconfig_global,
# no test can leave secrets behind
check_plaintext_keyring,
# function-scope config manager
datalad_cfg,
# function-scope, Dataset instance
dataset,
# function-scope, Dataset instance with underlying repository
existing_dataset,
)

from datalad_osf.tests.fixtures import (
# standard test dataset setup used throughout the datalad-osf tests
minimal_dataset,
osf_credentials,
osf_credentials_or_skip,
osf_node,
)
48 changes: 48 additions & 0 deletions datalad_osf/tests/fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import pytest


@pytest.fixture(autouse=False, scope="function")
def minimal_dataset(existing_dataset):
ds = existing_dataset
(ds.pathobj / 'file1.txt').write_text('content')
(ds.pathobj / 'subdir').mkdir()
(ds.pathobj / 'subdir' / 'file2.txt').write_text('different content')
ds.save()

yield ds


@pytest.fixture(autouse=False, scope="session")
def osf_credentials():
"""Yields credential dict from get_credentials() suitable of OSF client"""
from datalad_osf.utils import get_credentials
cred = get_credentials(allow_interactive=False)
yield cred


@pytest.fixture(autouse=False, scope="function")
def osf_credentials_or_skip(osf_credentials):
if not any(osf_credentials.values()):
pytest.skip(reason='no OSF credentials')

yield osf_credentials


@pytest.fixture(autouse=False, scope="function")
def osf_node(osf_credentials_or_skip):
from datalad_osf.utils import (
create_node,
delete_node,
)
from osfclient import OSF
osf = OSF(**osf_credentials_or_skip)

title = 'Temporary DataLad CI project'
category = "data"

node_id, proj_url = create_node(
osf.session, title, category=category,
)
yield node_id

delete_node(osf.session, node_id)
80 changes: 24 additions & 56 deletions datalad_osf/tests/test_create_sibling_osf.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,24 @@
#
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##

from datalad.api import (
Dataset,
)
from datalad.tests.utils import (
assert_equal,
assert_in,
assert_not_in,
assert_result_count,
skip_if,
SkipTest,
with_tree
)
from datalad.utils import Path
from datalad_osf.utils import (
delete_node,
get_credentials,
)
from datalad_next.tests.utils import assert_result_count
from datalad_osf.utils import delete_node
from osfclient import OSF


minimal_repo = {'ds': {'file1.txt': 'content',
'subdir': {'file2.txt': 'different content'}
}
}


@with_tree(tree=minimal_repo)
def test_invalid_calls(path):

# - impossible w/o dataset
# - impossible w/o annex
# - mandatory arguments
raise SkipTest("TODO")
#def test_invalid_calls(minimal_dataset):
#
# # - impossible w/o dataset
# # - impossible w/o annex
# # - mandatory arguments
# raise SkipTest("TODO")


@skip_if(cond=not any(get_credentials().values()), msg='no OSF credentials')
@with_tree(tree=minimal_repo)
def test_create_osf_simple(path):
def test_create_osf_simple(osf_credentials_or_skip, minimal_dataset):

ds = Dataset(path).create(force=True)
ds.save()
ds = minimal_dataset

file1 = Path('ds') / "file1.txt"
file1 = ds.pathobj / "file1.txt"

create_results = ds.create_sibling_osf(name="osf")

Expand All @@ -67,41 +42,37 @@ def test_create_osf_simple(path):
# special remote is configured:
remote_log = ds.repo.call_git(['cat-file', 'blob',
'git-annex:remote.log'])
assert_in("node={}".format(create_results[0]['id']), remote_log)
assert "node={}".format(create_results[0]['id']) in remote_log

# copy files over
ds.repo.copy_to('.', "osf-storage")
whereis = ds.repo.whereis(str(file1))
here = ds.config.get("annex.uuid")
# files should be 'here' and on remote end:
assert_equal(len(whereis), 2)
assert_in(here, whereis)
assert len(whereis) == 2
assert here in whereis

# drop content here
ds.drop('.')
whereis = ds.repo.whereis(str(file1))
# now on remote end only
assert_equal(len(whereis), 1)
assert_not_in(here, whereis)
assert len(whereis) == 1
assert here not in whereis

# and get content again from remote:
ds.get('.')
whereis = ds.repo.whereis(str(file1))
assert_equal(len(whereis), 2)
assert_in(here, whereis)
assert len(whereis) == 2
assert here in whereis
finally:
# clean remote end:
cred = get_credentials(allow_interactive=False)
osf = OSF(**cred)
osf = OSF(**osf_credentials_or_skip)
delete_node(osf.session, create_results[0]['id'])


@skip_if(cond=not any(get_credentials().values()), msg='no OSF credentials')
@with_tree(tree=minimal_repo)
def test_create_osf_export(path):
def test_create_osf_export(osf_credentials_or_skip, minimal_dataset):

ds = Dataset(path).create(force=True)
ds.save()
ds = minimal_dataset

create_results = ds.create_sibling_osf(
title="CI dl-create",
Expand All @@ -121,12 +92,9 @@ def test_create_osf_export(path):

finally:
# clean remote end:
cred = get_credentials(allow_interactive=False)
osf = OSF(**cred)
osf = OSF(**osf_credentials_or_skip)
delete_node(osf.session, create_results[0]['id'])


@skip_if(cond=not any(get_credentials().values()), msg='no OSF credentials')
def test_create_osf_existing():

raise SkipTest("TODO")
# def test_create_osf_existing(osf_credentials_or_skip):
# raise SkipTest("TODO")
47 changes: 27 additions & 20 deletions datalad_osf/tests/test_public.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,32 @@
#
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##

from mock import patch

from datalad.api import clone
from datalad.support.exceptions import IncompleteResultsError
from datalad.tests.utils import (
from datalad_next.exceptions import IncompleteResultsError
from datalad_next.tests.utils import (
assert_in,
assert_raises,
eq_,
skip_if_on_windows,
with_tempfile,
)
import datalad_osf.utils as dlosf_utils


def no_credentials(*args, **kwargs):
return dict(token=None, username=None, password=None)


@with_tempfile
# make sure that even with locally configured credentials
# none actually reach the special remote
@patch('datalad_osf.utils.get_credentials', no_credentials)
def test_readonly_access(path):
def test_readonly_access(tmp_path, monkeypatch):
# obtain a prepared minimal dataset with pre-configured
# OSF remotes and prestaged data
ds = clone('https://github.com/datalad/testrepo--minimalds-osf.git', path)
# make sure that even with locally configured credentials
# none actually reach the special remote
with monkeypatch.context() as m:
m.setattr(dlosf_utils, 'get_credentials', no_credentials)
ds = clone(
'https://github.com/datalad/testrepo--minimalds-osf.git',
tmp_path,
)
# check that both OSF remotes were enabled
assert_in('osfannex', ds.repo.get_remotes())
assert_in('osftree', ds.repo.get_remotes())
Expand All @@ -54,11 +55,13 @@ def test_readonly_access(path):
# line-ending(?) issue
# https://github.com/datalad/datalad-osf/pull/106#issuecomment-653772696
@skip_if_on_windows
@with_tempfile
@patch('datalad_osf.utils.get_credentials', no_credentials)
def test_readonly_dataset_access(path):
def test_readonly_dataset_access(tmp_path, monkeypatch):
# clone from OSF; ds is self-contained at OSF
ds = clone('osf://q8xnk', path)
# make sure that even with locally configured credentials
# none actually reach the special remote
with monkeypatch.context() as m:
m.setattr(dlosf_utils, 'get_credentials', no_credentials)
ds = clone('osf://q8xnk', tmp_path)
# standard name storage remote
assert_in('osf-storage', ds.repo.get_remotes())
for avail in ds.repo.whereis('inannex'):
Expand All @@ -69,8 +72,12 @@ def test_readonly_dataset_access(path):
eq_(ds.repo.annexstatus([test_file])[test_file]['has_content'], True)


@with_tempfile
@patch('datalad_osf.utils.get_credentials', no_credentials)
def test_invalid_url(path):

assert_raises(IncompleteResultsError, clone, 'osf://q8xnk/somepath', path)
def test_invalid_url(tmp_path, monkeypatch):
# make sure that even with locally configured credentials
# none actually reach the special remote
with monkeypatch.context() as m:
m.setattr(dlosf_utils, 'get_credentials', no_credentials)
assert_raises(
IncompleteResultsError,
clone, 'osf://q8xnk/somepath', tmp_path,
)
1 change: 0 additions & 1 deletion datalad_osf/tests/test_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@
def test_register():
import datalad.api as da
assert hasattr(da, 'create_sibling_osf')

0 comments on commit f31d8ad

Please sign in to comment.