1
0
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:
Adrien Ferrand
2019-03-29 00:50:42 +01:00
committed by Brad Warren
parent 6ce6c67932
commit ea568d4dc2
2 changed files with 22 additions and 8 deletions

View File

@@ -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.

View File

@@ -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