From: Aleš Mrázek Date: Mon, 13 Jul 2026 09:37:54 +0000 (+0200) Subject: fixup! controller: dispatcher to inject notify feature to supervisord X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fenvironments%2Fdocs-python-refac-o5rd0i%2Fdeployments%2F9525;p=thirdparty%2Fknot-resolver.git fixup! controller: dispatcher to inject notify feature to supervisord --- diff --git a/python/knot_resolver/controller/notify/notify_dispatcher.py b/python/knot_resolver/controller/notify/notify_dispatcher.py index 5e701645c..be670da34 100644 --- a/python/knot_resolver/controller/notify/notify_dispatcher.py +++ b/python/knot_resolver/controller/notify/notify_dispatcher.py @@ -121,7 +121,7 @@ if NOTIFY_SUPPORT: if not is_subprocess_x_type_notify(subprocess): self._logger.warning( - "ignoring notify message '%s' from %s, that is not configured to send it", + "ignoring notify message %s from %s, that is not configured to send it", data, subprocess.config.name, ) @@ -140,8 +140,8 @@ if NOTIFY_SUPPORT: subprocess.config.name, ) else: - self._logger.warn( - "ignoring unrecognized data on $NOTIFY_SOCKET sent from '%s', PID=%d, data='%b'", + self._logger.warning( + "ignoring unrecognized data on $NOTIFY_SOCKET sent from '%s', PID=%d, data=%s", subprocess.config.name, pid, data, diff --git a/tests/python/knot_resolver/controller/notify/test_notify_dispatcher.py b/tests/python/knot_resolver/controller/notify/test_notify_dispatcher.py new file mode 100644 index 000000000..113ec1a1b --- /dev/null +++ b/tests/python/knot_resolver/controller/notify/test_notify_dispatcher.py @@ -0,0 +1,100 @@ +import logging +import os +from types import SimpleNamespace +from unittest.mock import MagicMock, Mock + +from supervisor.events import ProcessStateStartingEvent, ProcessStateStoppingEvent +from supervisor.process import Subprocess +from supervisor.supervisord import Supervisor + +from knot_resolver.controller.config import X_TYPE_NOTIFY, X_TYPE_VAR_NAME +from knot_resolver.controller.notify.notify_dispatcher import NotifyDispatcher, NotifyPlugin +from knot_resolver.controller.notify.notify_socket import send_notify_message + + +def test_notify_plugin() -> None: + plugin = NotifyPlugin() + assert plugin.starting_subprocesses == {} + + fake_pid1 = 123 + subprocess1 = MagicMock(spec=Subprocess) + subprocess1.pid = fake_pid1 + + starting_event1 = MagicMock(spec=ProcessStateStartingEvent) + starting_event1.process = subprocess1 + + plugin.track_starting_subprocesses(starting_event1) + assert fake_pid1 in plugin.starting_subprocesses + + fake_pid2 = 321 + subprocess2 = MagicMock(spec=Subprocess) + subprocess2.pid = fake_pid2 + + starting_event2 = MagicMock(spec=ProcessStateStartingEvent) + starting_event2.process = subprocess2 + + plugin.track_starting_subprocesses(starting_event2) + assert fake_pid2 in plugin.starting_subprocesses + + stopping_event = MagicMock(spec=ProcessStateStoppingEvent) + stopping_event.process = subprocess1 + + plugin.track_starting_subprocesses(stopping_event) + assert fake_pid1 not in plugin.starting_subprocesses + assert fake_pid2 in plugin.starting_subprocesses + + +def test_notify_dispatcher(caplog) -> None: + plugin = NotifyPlugin() + + supervisor = MagicMock(spec=Supervisor) + supervisor.options = Mock() + supervisor.options.logger = logging.getLogger(__name__) + + subprocess = MagicMock(spec=Subprocess) + subprocess.pid = os.getpid() + + dispatcher = NotifyDispatcher(supervisor, plugin) + + caplog.clear() + with caplog.at_level(logging.INFO): + send_notify_message(READY=1) + dispatcher.handle_read_event() + assert any("ignoring notify message from unregistered subprocess" in record.message for record in caplog.records) + + starting_event = MagicMock(spec=ProcessStateStartingEvent) + starting_event.process = subprocess + plugin.track_starting_subprocesses(starting_event) + + caplog.clear() + with caplog.at_level(logging.INFO): + send_notify_message(READY=1) + dispatcher.handle_read_event() + assert any("that is not configured to send it" in record.message for record in caplog.records) + + subprocess.config = SimpleNamespace( + name="subprocess", + environment={ + X_TYPE_VAR_NAME: X_TYPE_NOTIFY, + }, + ) + + caplog.clear() + with caplog.at_level(logging.INFO): + send_notify_message(READY=1) + dispatcher.handle_read_event() + assert any("received READY notify message" in record.message for record in caplog.records) + + caplog.clear() + with caplog.at_level(logging.INFO): + send_notify_message(STOPPING=1) + dispatcher.handle_read_event() + assert any("received STOPPING notify message" in record.message for record in caplog.records) + + caplog.clear() + with caplog.at_level(logging.INFO): + send_notify_message(UNRECOGNIZED=1) + dispatcher.handle_read_event() + assert any("ignoring unrecognized data on $NOTIFY_SOCKET" in record.message for record in caplog.records) + + dispatcher.close()