Skip to content

Commit 7312b70

Browse files
committed
NF: @assert_cwd_unchanged() to check if test went somewhere else and chdir back
Side effects from tests, like going to another directory are pain, we should avoid them
1 parent 55c7930 commit 7312b70

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

heudiconv/tests/utils.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1+
from functools import wraps
2+
import os
13
import os.path as op
4+
import sys
5+
26
import heudiconv.heuristics
37

8+
49
HEURISTICS_PATH = op.join(heudiconv.heuristics.__path__[0])
510
TESTS_DATA_PATH = op.join(op.dirname(__file__), 'data')
611

12+
import logging
13+
lgr = logging.getLogger(__name__)
14+
715

816
def gen_heudiconv_args(datadir, outdir, subject, heuristic_file,
917
anon_cmd=None, template=None, xargs=None):
@@ -58,3 +66,51 @@ def fetch_data(tmpdir, dataset, getpath=None):
5866
getdir = targetdir + (op.sep + getpath if getpath is not None else '')
5967
ds.get(getdir)
6068
return targetdir
69+
70+
71+
def assert_cwd_unchanged(ok_to_chdir=False):
72+
"""Decorator to test whether the current working directory remains unchanged
73+
74+
Provenance: based on the one in datalad, but simplified.
75+
76+
Parameters
77+
----------
78+
ok_to_chdir: bool, optional
79+
If True, allow to chdir, so this decorator would not then raise exception
80+
if chdir'ed but only return to original directory
81+
"""
82+
83+
def decorator(func=None): # =None to avoid pytest treating it as a fixture
84+
@wraps(func)
85+
def newfunc(*args, **kwargs):
86+
cwd_before = os.getcwd()
87+
exc = None
88+
try:
89+
return func(*args, **kwargs)
90+
except Exception as exc_:
91+
exc = exc_
92+
finally:
93+
try:
94+
cwd_after = os.getcwd()
95+
except OSError as e:
96+
lgr.warning("Failed to getcwd: %s" % e)
97+
cwd_after = None
98+
99+
if cwd_after != cwd_before:
100+
os.chdir(cwd_before)
101+
if not ok_to_chdir:
102+
lgr.warning(
103+
"%s changed cwd to %s. Mitigating and changing back to %s"
104+
% (func, cwd_after, cwd_before))
105+
# If there was already exception raised, we better reraise
106+
# that one since it must be more important, so not masking it
107+
# here with our assertion
108+
if exc is None:
109+
assert cwd_before == cwd_after, \
110+
"CWD changed from %s to %s" % (cwd_before, cwd_after)
111+
112+
if exc is not None:
113+
raise exc
114+
return newfunc
115+
116+
return decorator

0 commit comments

Comments
 (0)