mirror of
https://github.com/certbot/certbot.git
synced 2026-01-26 07:41:33 +03:00
[Windows] Fix ErrorHandler tests, by disabling signal error handling (#6868)
This PR is a part of the effort to remove the last broken unit tests in certbot codebase for Windows, as described in #6850. It solves the problems associated to ErrorHandler in Windows (enlighted by tests errors) by ... wipping out the problem: no signal is handled by ErrorHandler on Windows. See the relevant inline comment in certbot.error_handler for explanation and sources.
This commit is contained in:
committed by
Brad Warren
parent
6ce6c67932
commit
ea568d4dc2
@@ -19,14 +19,30 @@ logger = logging.getLogger(__name__)
|
||||
# potentially occur from inside Python. Signals such as SIGILL were not
|
||||
# included as they could be a sign of something devious and we should terminate
|
||||
# immediately.
|
||||
_SIGNALS = [signal.SIGTERM]
|
||||
if os.name != "nt":
|
||||
_SIGNALS = [signal.SIGTERM]
|
||||
for signal_code in [signal.SIGHUP, signal.SIGQUIT,
|
||||
signal.SIGXCPU, signal.SIGXFSZ]:
|
||||
# Adding only those signals that their default action is not Ignore.
|
||||
# This is platform-dependent, so we check it dynamically.
|
||||
if signal.getsignal(signal_code) != signal.SIG_IGN:
|
||||
_SIGNALS.append(signal_code)
|
||||
else:
|
||||
# POSIX signals are not implemented natively in Windows, but emulated from the C runtime.
|
||||
# As consumed by CPython, most of handlers on theses signals are useless, in particular
|
||||
# SIGTERM: for instance, os.kill(pid, signal.SIGTERM) will call TerminateProcess, that stops
|
||||
# immediately the process without calling the attached handler. Besides, non-POSIX signals
|
||||
# (CTRL_C_EVENT and CTRL_BREAK_EVENT) are implemented in a console context to handle the
|
||||
# CTRL+C event to a process launched from the console. Only CTRL_C_EVENT has a reliable
|
||||
# behavior in fact, and maps to the handler to SIGINT. However in this case, a
|
||||
# KeyboardInterrupt is raised, that will be handled by ErrorHandler through the context manager
|
||||
# protocol. Finally, no signal on Windows is electable to be handled using ErrorHandler.
|
||||
#
|
||||
# Refs: https://stackoverflow.com/a/35792192, https://maruel.ca/post/python_windows_signal,
|
||||
# https://docs.python.org/2/library/os.html#os.kill,
|
||||
# https://www.reddit.com/r/Python/comments/1dsblt/windows_command_line_automation_ctrlc_question
|
||||
_SIGNALS = []
|
||||
|
||||
|
||||
class ErrorHandler(object):
|
||||
"""Context manager for running code that must be cleaned up on failure.
|
||||
|
||||
@@ -10,7 +10,6 @@ import mock
|
||||
from acme.magic_typing import Callable, Dict, Union
|
||||
# pylint: enable=unused-import, no-name-in-module
|
||||
|
||||
import certbot.tests.util as test_util
|
||||
|
||||
def get_signals(signums):
|
||||
"""Get the handlers for an iterable of signums."""
|
||||
@@ -66,9 +65,9 @@ class ErrorHandlerTest(unittest.TestCase):
|
||||
self.init_func.assert_called_once_with(*self.init_args,
|
||||
**self.init_kwargs)
|
||||
|
||||
# On Windows, this test kills pytest itself !
|
||||
@test_util.broken_on_windows
|
||||
def test_context_manager_with_signal(self):
|
||||
if not self.signals:
|
||||
self.skipTest(reason='Signals cannot be handled on Windows.')
|
||||
init_signals = get_signals(self.signals)
|
||||
with signal_receiver(self.signals) as signals_received:
|
||||
with self.handler:
|
||||
@@ -98,9 +97,9 @@ class ErrorHandlerTest(unittest.TestCase):
|
||||
**self.init_kwargs)
|
||||
bad_func.assert_called_once_with()
|
||||
|
||||
# On Windows, this test kills pytest itself !
|
||||
@test_util.broken_on_windows
|
||||
def test_bad_recovery_with_signal(self):
|
||||
if not self.signals:
|
||||
self.skipTest(reason='Signals cannot be handled on Windows.')
|
||||
sig1 = self.signals[0]
|
||||
sig2 = self.signals[-1]
|
||||
bad_func = mock.MagicMock(side_effect=lambda: send_signal(sig1))
|
||||
@@ -149,10 +148,9 @@ class ExitHandlerTest(ErrorHandlerTest):
|
||||
**self.init_kwargs)
|
||||
func.assert_called_once_with()
|
||||
|
||||
# On Windows, this test kills pytest itself !
|
||||
@test_util.broken_on_windows
|
||||
def test_bad_recovery_with_signal(self):
|
||||
super(ExitHandlerTest, self).test_bad_recovery_with_signal()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
||||
Reference in New Issue
Block a user