test_faulthandler.py
Overview
The [test_faulthandler.py](/projects/286/67400) file contains a suite of automated tests verifying the integration and functionality of the `faulthandler` support within the pytest testing framework. `faulthandler` is a Python module that helps diagnose crashes by dumping Python tracebacks explicitly on faults like segmentation faults, abort signals, or timeouts.
This test file ensures that:
Crashes trigger expected tracebacks during test failures.
The
faulthandlerbehavior during interpreter shutdown is correct.The pytest plugin options to enable or disable
faulthandlerwork as intended.Timeout-based traceback dumping occurs as configured.
The plugin correctly cancels tracebacks when entering interactive debugging.
The system handles edge cases such as invalid stderr file descriptors and pre-initialized
faulthandler.
These tests are primarily functional and integration tests, using the pytest framework's own testing utilities (`pytester`) to run subprocesses and verify outputs.
Detailed Explanations
Imports
io,sys: Standard libraries used for I/O and interpreter interaction.Pytesterfrom_pytest.pytester: pytest's test runner helper class used to create test files and run pytest subprocesses.pytest: The pytest testing framework used for parametric tests and markers.
Functions
All test functions use the `pytester` fixture or `pytest` directly to create temporary test files and run pytest subprocesses to verify `faulthandler` behavior.
test_enabled(pytester: Pytester) -> None
Purpose: Verifies that a test that triggers a crash via
faulthandler._sigabrt()produces a fatal Python error with a traceback.Parameters:
pytester: pytest's helper fixture to create test files and run pytest.
Returns: None
Implementation:
Dynamically creates a test file with a function that calls
faulthandler._sigabrt().Runs pytest in a subprocess.
Asserts that the subprocess stderr contains the phrase "Fatal Python error" indicating a crash.
Checks the return code is non-zero (failure).
Usage Example:
def test_enabled(pytester): # see above
setup_crashing_test(pytester: Pytester) -> None
Purpose: Helper function that creates a test file registering
faulthandler._sigabrtto be called at exit.Parameters:
pytester: pytest helper for file creation.
Returns: None
Implementation:
Creates a test Python file that registers a crash on interpreter exit (
atexit.register(faulthandler._sigabrt)).
Usage: Used by other test functions to simulate crash during shutdown scenarios.
test_crash_during_shutdown_captured(pytester: Pytester) -> None
Purpose: Tests that if
faulthandleris enabled during pytest configuration, crashes during interpreter shutdown are captured with tracebacks.Parameters:
pytester
Returns: None
Implementation:
Uses
setup_crashing_testto create the crash-on-exit test.Runs pytest subprocess with
-Xfaulthandleroption to enablefaulthandler.Checks for "Fatal Python error" in stderr and non-zero exit code.
Usage: Ensures
faulthandlerre-enables during shutdown when configured.
test_crash_during_shutdown_not_captured(pytester: Pytester) -> None
Purpose: Verifies that if
faulthandlerwas not enabled during pytest configuration, crashes during shutdown are not captured (no tracebacks).Parameters:
pytester
Returns: None
Implementation:
Sets up crashing test.
Runs pytest subprocess without
-Xfaulthandler.Asserts no "Fatal Python error" in stderr but exit code is non-zero.
Usage: Prevents false positives in crash detection when
faulthandleris disabled.
test_disabled(pytester: Pytester) -> None
Purpose: Tests that using the pytest command line option to disable
faulthandler(-p no:faulthandler) actually disables it.Parameters:
pytester
Returns: None
Implementation:
Creates a test that asserts
faulthandler.is_enabled()isFalse.Runs pytest subprocess with
-p no:faulthandler.Verifies the test passes and exit code is zero.
Usage: Validates plugin disabling works correctly.
test_timeout(pytester: Pytester, enabled: bool) -> None
Purpose: Tests that tracebacks are dumped after a timeout if
faulthandleris enabled, and not dumped otherwise.Parameters:
pytesterenabled: bool flag whether the plugin is enabled or disabled.
Returns: None
Implementation:
Uses
pytest.mark.parametrizeto run withenabled=Trueandenabled=False.Creates a test that sleeps briefly.
Writes a pytest ini configuration with
faulthandler_timeout = 0.01.Runs pytest subprocess with or without disabling plugin.
Checks stderr for the traceback message "most recent call first" only if enabled.
Asserts test passed.
Usage: Ensures timeout-based tracebacks behave correctly.
test_cancel_timeout_on_hook(monkeypatch, hook_name) -> None
Purpose: Confirms that scheduled traceback dumping due to timeout is cancelled before entering pdb or interactive exception hooks.
Parameters:
monkeypatch: pytest fixture to patch attributes.hook_name: str, either"pytest_enter_pdb"or"pytest_exception_interact".
Returns: None
Implementation:
Monkeypatches
faulthandler.cancel_dump_traceback_laterto add a marker to a list.Calls the hook function explicitly from the pytest faulthandler plugin.
Asserts that the cancel function was called exactly once.
Usage: Prevents interfering tracebacks during debugging or interactive exception handling.
test_already_initialized_crash(pytester: Pytester) -> None
Purpose: Verifies that even if
faulthandleris already initialized (enabled), crashes still produce tracebacks.Parameters:
pytester
Returns: None
Implementation:
Creates a test file that calls
faulthandler._sigabrt().Runs pytest subprocess with
-X faulthandlerto pre-enable.Checks for crash output and non-zero exit code.
Usage: Tests robustness of crash handling regardless of prior initialization.
test_get_stderr_fileno_invalid_fd() -> None
Purpose: Tests that
get_stderr_filenohandles the case whensys.stderrhas an invalid file descriptor.Parameters: None
Returns: None
Implementation:
Defines a class
StdErrWrappermimicking an object with afileno()method returning-1.Monkeypatches
sys.stderrto an instance of this wrapper.Calls
get_stderr_fileno()from the pytest faulthandler plugin.Asserts the returned file descriptor is still
2(real stderr fd).
Usage: Ensures compatibility with wrapped stderr objects that don't expose valid fds.
Important Implementation Details
Uses
pytesterfixture extensively to create isolated test files and run pytest subprocesses, simulating real test scenarios.Runs subprocesses with interpreter options like
-Xfaulthandlerto control fault handler enabling.Utilizes
pytest.mark.parametrizeto run tests with multiple configurations.Monkeypatching is used to simulate and verify internal behaviors and edge cases.
Tests verify outputs by matching standard error and standard output lines, and by checking exit codes.
The use of
faulthandler._sigabrt()simulates a process abort to trigger fault handling.The file tests integration between pytest and the
faulthandlermodule, rather than thefaulthandlermodule itself.
Interactions with Other Parts of the System
Interacts with the
faulthandlerPython standard library module for fault handling.Uses pytest's internal testing utilities (
pytesterfrom_pytest.pytester) to create test files and run pytest in subprocesses.Interacts with the pytest plugin
_pytest.faulthandlerfor accessingget_stderr_filenoand hooks likepytest_enter_pdbandpytest_exception_interact.Tests ensure the pytest faulthandler plugin correctly manages enabling/disabling, timeouts, and crash handling.
The tests implicitly depend on the Python interpreter supporting
-Xfaulthandleroption (Python 3.7+).Ensures compatibility with other pytest plugins by disabling
faulthandlerplugin explicitly in some tests.
Visual Diagram
classDiagram
class test_faulthandler {
+test_enabled(pytester)
+setup_crashing_test(pytester)
+test_crash_during_shutdown_captured(pytester)
+test_crash_during_shutdown_not_captured(pytester)
+test_disabled(pytester)
+test_timeout(pytester, enabled)
+test_cancel_timeout_on_hook(monkeypatch, hook_name)
+test_already_initialized_crash(pytester)
+test_get_stderr_fileno_invalid_fd()
}
test_faulthandler ..> Pytester : uses
test_faulthandler ..> pytest : uses
test_faulthandler ..> faulthandler : tests integration
test_faulthandler ..> _pytest.faulthandler : accesses hooks & functions
Summary
The [test_faulthandler.py](/projects/286/67400) file is a critical integration test suite that validates the pytest faulthandler plugin's functionality. It tests various scenarios involving fault detection, crash tracebacks, plugin enabling/disabling, timeouts, and compatibility with interpreter shutdown and debugging hooks. The tests leverage pytest's own testing infrastructure to simulate real-world usage and edge cases, ensuring robust and reliable fault diagnostics during test execution.