Skip to content

Commit 325b40c

Browse files
okkenflub
authored andcommitted
docs + config setting support + test mod
1 parent 063f077 commit 325b40c

File tree

3 files changed

+76
-11
lines changed

3 files changed

+76
-11
lines changed

README.rst

+34
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,39 @@ function:
340340
pytest.fail("+++ Timeout +++")
341341
342342
343+
344+
Session Timeout
345+
===============
346+
347+
The above mentioned timeouts are all per test function. You can also set a
348+
session timeout in seconds. The following example shows a session timeout
349+
of 10 minutes (600 seconds)::
350+
351+
pytest --session-timeout=600
352+
353+
You can also set the session timeout the `pytest configuration file`__
354+
using the ``session_timeout`` option:
355+
356+
.. code:: ini
357+
358+
[pytest]
359+
session_timeout = 600
360+
361+
Friendly timeouts
362+
-----------------
363+
364+
Session timeouts are "friendly" timeouts. The plugin checks the session time at the end of
365+
each test function, and stops further tests from running if the session timeout is exceeded.
366+
367+
Combining session and function
368+
------------------------------
369+
370+
It works fine to combine both session and function timeouts.
371+
For example, to limit test functions to 5 seconds and the full session to 100 seconds::
372+
373+
pytest --timeout=5 --session-timeout=100
374+
375+
343376
Changelog
344377
=========
345378

@@ -353,6 +386,7 @@ Unreleased
353386
This change also switches all output from ``sys.stderr`` to ``sys.stdout``.
354387
Thanks Pedro Algarvio.
355388
- Pytest 7.0.0 is now the minimum supported version. Thanks Pedro Algarvio.
389+
- Add ``--session-timeout`` option and ``session_timeout`` setting.
356390

357391
2.2.0
358392
-----

pytest_timeout.py

+13-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
__all__ = ("is_debugging", "Settings")
2222
SESSION_TIMEOUT_KEY = pytest.StashKey[float]()
23+
SESSION_EXPIRE_KEY = pytest.StashKey[float]()
2324

2425

2526
HAVE_SIGALRM = hasattr(signal, "SIGALRM")
@@ -104,6 +105,7 @@ def pytest_addoption(parser):
104105
type="bool",
105106
default=False,
106107
)
108+
parser.addini("session_timeout", SESSION_TIMEOUT_DESC)
107109

108110

109111
class TimeoutHooks:
@@ -159,12 +161,18 @@ def pytest_configure(config):
159161
config._env_timeout_func_only = settings.func_only
160162
config._env_timeout_disable_debugger_detection = settings.disable_debugger_detection
161163

162-
timeout = config.getoption("--session-timeout")
164+
timeout = config.getoption("session_timeout")
165+
if timeout is None:
166+
ini = config.getini("session_timeout")
167+
if ini:
168+
timeout = _validate_timeout(config.getini("session_timeout"), "config file")
163169
if timeout is not None:
164170
expire_time = time.time() + timeout
165171
else:
166172
expire_time = 0
167-
config.stash[SESSION_TIMEOUT_KEY] = expire_time
173+
timeout = 0
174+
config.stash[SESSION_TIMEOUT_KEY] = timeout
175+
config.stash[SESSION_EXPIRE_KEY] = expire_time
168176

169177

170178
@pytest.hookimpl(hookwrapper=True)
@@ -185,9 +193,9 @@ def pytest_runtest_protocol(item):
185193
hooks.pytest_timeout_cancel_timer(item=item)
186194

187195
# check session timeout
188-
expire_time = item.session.config.stash[SESSION_TIMEOUT_KEY]
196+
expire_time = item.session.config.stash[SESSION_EXPIRE_KEY]
189197
if expire_time and (expire_time < time.time()):
190-
timeout = item.session.config.getoption("--session-timeout")
198+
timeout = item.session.config.stash[SESSION_TIMEOUT_KEY]
191199
item.session.shouldfail = f"session-timeout: {timeout} sec exceeded"
192200

193201

@@ -223,7 +231,7 @@ def pytest_report_header(config):
223231
)
224232
)
225233

226-
session_timeout = config.getoption("--session-timeout")
234+
session_timeout = config.getoption("session_timeout")
227235
if session_timeout:
228236
timeout_header.append("session timeout: %ss" % session_timeout)
229237
if timeout_header:

test_pytest_timeout.py

+29-6
Original file line numberDiff line numberDiff line change
@@ -623,17 +623,40 @@ def test_session_timeout(pytester):
623623
624624
@pytest.fixture()
625625
def slow_setup_and_teardown():
626-
time.sleep(0.5)
626+
time.sleep(1)
627627
yield
628-
time.sleep(0.5)
628+
time.sleep(1)
629629
630630
def test_one(slow_setup_and_teardown):
631-
time.sleep(0.5)
631+
time.sleep(1)
632632
633633
def test_two(slow_setup_and_teardown):
634-
time.sleep(0.5)
634+
time.sleep(1)
635635
"""
636636
)
637-
result = pytester.runpytest_subprocess("--session-timeout", "1.25")
638-
result.stdout.fnmatch_lines(["*!! session-timeout: 1.25 sec exceeded !!!*"])
637+
result = pytester.runpytest_subprocess("--session-timeout", "2")
638+
result.stdout.fnmatch_lines(["*!! session-timeout: 2.0 sec exceeded !!!*"])
639+
result.assert_outcomes(passed=1)
640+
641+
642+
def test_ini_session_timeout(pytester):
643+
pytester.makepyfile(
644+
"""
645+
import time
646+
647+
def test_one():
648+
time.sleep(2)
649+
650+
def test_two():
651+
time.sleep(2)
652+
"""
653+
)
654+
pytester.makeini(
655+
"""
656+
[pytest]
657+
session_timeout = 1
658+
"""
659+
)
660+
result = pytester.runpytest_subprocess()
661+
result.stdout.fnmatch_lines(["*!! session-timeout: 1.0 sec exceeded !!!*"])
639662
result.assert_outcomes(passed=1)

0 commit comments

Comments
 (0)