diff --git a/oslo_service/service.py b/oslo_service/service.py index 33a57b8e..2e56d30a 100644 --- a/oslo_service/service.py +++ b/oslo_service/service.py @@ -28,6 +28,7 @@ import io import logging import os import random +import select import signal import six import sys @@ -203,7 +204,8 @@ class SignalHandler(object): For Python 3.5 and later, deal with the changes in PEP 475 that prevent a signal from interrupting eventlet's call to poll() or sleep(). """ - self.__force_interrupt_on_signal = sys.version_info >= (3, 5) + self.__force_interrupt_on_signal = (sys.version_info >= (3, 5) and + hasattr(select, 'poll')) if self.__force_interrupt_on_signal: try: diff --git a/oslo_service/tests/test_service.py b/oslo_service/tests/test_service.py index ed678069..0114eb58 100644 --- a/oslo_service/tests/test_service.py +++ b/oslo_service/tests/test_service.py @@ -477,6 +477,18 @@ class ProcessLauncherTest(base.ServiceBaseTestCase): m.assert_called_once_with(signal.SIGTERM, 'test') signal_handler.clear() + @mock.patch('sys.version_info', (3, 5)) + @mock.patch.object(service, 'select', spec=[]) + def test_setup_signal_interruption_no_select_poll(self, mock_select): + # NOTE(claudiub): SignalHandler is a singleton, which means that it + # might already be initialized. We need to clear to clear the cache + # in order to prevent race conditions between tests. + service.SignalHandler.__class__._instances.clear() + signal_handler = service.SignalHandler() + self.addCleanup(service.SignalHandler.__class__._instances.clear) + self.assertFalse( + signal_handler._SignalHandler__force_interrupt_on_signal) + @mock.patch('signal.alarm') @mock.patch("os.kill") @mock.patch("oslo_service.service.ProcessLauncher.stop")