22from __future__ import annotations
33
44import io
5+ import os
56import sys
67
78from _pytest .pytester import Pytester
@@ -71,20 +72,15 @@ def test_disabled():
7172 assert result .ret == 0
7273
7374
74- @pytest .mark .parametrize (
75- "enabled" ,
76- [
77- pytest .param (
78- True , marks = pytest .mark .skip (reason = "sometimes crashes on CI (#7022)" )
79- ),
80- False ,
81- ],
82- )
75+ @pytest .mark .parametrize ("enabled" , [True , False ])
8376def test_timeout (pytester : Pytester , enabled : bool ) -> None :
8477 """Test option to dump tracebacks after a certain timeout.
8578
8679 If faulthandler is disabled, no traceback will be dumped.
8780 """
81+ if enabled and "CI" in os .environ :
82+ pytest .xfail (reason = "sometimes crashes on CI (#7022)" )
83+
8884 pytester .makepyfile (
8985 """
9086 import os, time
@@ -110,6 +106,41 @@ def test_timeout():
110106 assert result .ret == 0
111107
112108
109+ @pytest .mark .parametrize ("exit_on_timeout" , [True , False ])
110+ def test_timeout_and_exit (pytester : Pytester , exit_on_timeout : bool ) -> None :
111+ """Test option to force exit pytest process after a certain timeout."""
112+ if "CI" in os .environ :
113+ pytest .xfail (reason = "sometimes crashes on CI (#7022)" )
114+
115+ pytester .makepyfile (
116+ """
117+ import os, time
118+ def test_long_sleep_and_raise():
119+ time.sleep(1 if "CI" in os.environ else 0.1)
120+ raise AssertionError(
121+ "This test should have been interrupted before reaching this point."
122+ )
123+ """
124+ )
125+ pytester .makeini (
126+ f"""
127+ [pytest]
128+ faulthandler_timeout = 0.01
129+ faulthandler_exit_on_timeout = { "true" if exit_on_timeout else "false" }
130+ """
131+ )
132+ result = pytester .runpytest_subprocess ()
133+ tb_output = "most recent call first"
134+ result .stderr .fnmatch_lines ([f"*{ tb_output } *" ])
135+ if exit_on_timeout :
136+ result .stdout .no_fnmatch_line ("*1 failed*" )
137+ result .stdout .no_fnmatch_line ("*AssertionError*" )
138+ else :
139+ result .stdout .fnmatch_lines (["*1 failed*" ])
140+ result .stdout .fnmatch_lines (["*AssertionError*" ])
141+ assert result .ret == 1
142+
143+
113144@pytest .mark .parametrize ("hook_name" , ["pytest_enter_pdb" , "pytest_exception_interact" ])
114145def test_cancel_timeout_on_hook (monkeypatch , hook_name ) -> None :
115146 """Make sure that we are cancelling any scheduled traceback dumping due
0 commit comments