generated from nipype/pydra-tasks-template
-
Notifications
You must be signed in to change notification settings - Fork 2
/
conftest.py
120 lines (90 loc) · 3.1 KB
/
conftest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import os
import time
import logging
from pathlib import Path
from traceback import format_exc
import tempfile
import threading
from dataclasses import dataclass
import pytest
from _pytest.runner import TestReport
try:
from pydra import set_input_validator
set_input_validator(True)
except ImportError:
pass
from fileformats.core.utils import include_testing_package
include_testing_package(True)
# Set DEBUG logging for unittests
log_level = logging.WARNING
logger = logging.getLogger("fileformats")
logger.setLevel(log_level)
sch = logging.StreamHandler()
sch.setLevel(log_level)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
sch.setFormatter(formatter)
logger.addHandler(sch)
# For debugging in IDE's don't catch raised exceptions and let the IDE
# break at it
if os.getenv("_PYTEST_RAISE", "0") != "0":
@pytest.hookimpl(tryfirst=True)
def pytest_exception_interact(call):
raise call.excinfo.value
@pytest.hookimpl(tryfirst=True)
def pytest_internalerror(excinfo):
raise excinfo.value
@pytest.fixture
def work_dir():
work_dir = tempfile.mkdtemp()
return Path(work_dir)
def pass_after_timeout(seconds, poll_interval=0.1):
"""Cancel the test after a certain period, after which it is assumed that the arguments
passed to the underying command have passed its internal validation (so we don't have
to wait until the tool completes)
Parameters
----------
seconds : int
the number of seconds to wait until cancelling the test (and marking it as passed)
"""
def decorator(test_func):
def wrapper(*args, **kwargs):
@dataclass
class TestState:
"""A way of passing a reference to the result that can be updated by
the test thread"""
result = None
exception = None
state = TestState()
def test_runner():
try:
state.result = test_func(*args, **kwargs)
except Exception as e:
state.exception = e
# raise
# state.trace_back = format_exc()
# raise
thread = threading.Thread(target=test_runner)
thread.start()
# Calculate the end time for the timeout
end_time = time.time() + seconds
while thread.is_alive() and time.time() < end_time:
time.sleep(poll_interval)
if thread.is_alive():
thread.join()
return state.result
if state.trace_back:
raise state.exception
outcome = "passed after timeout"
rep = TestReport.from_item_and_call(
item=args[0],
when="call",
excinfo=None,
outcome=outcome,
sections=None,
duration=0,
keywords=None,
)
args[0].ihook.pytest_runtest_logreport(report=rep)
return state.result
return wrapper
return decorator