# # This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. from contextlib import contextmanager import os from unittest import mock import pytest from gunicorn import systemd @contextmanager def check_environ(unset=True): """ A context manager that asserts post-conditions of ``listen_fds`` at exit. This helper is used to ease checking of the test post-conditions for the systemd socket activation tests that parametrize the call argument. """ with mock.patch.dict(os.environ): old_fds = os.environ.get('LISTEN_FDS', None) old_pid = os.environ.get('LISTEN_PID', None) yield if unset: assert 'LISTEN_FDS' not in os.environ, \ "LISTEN_FDS should have been unset" assert 'LISTEN_PID' not in os.environ, \ "LISTEN_PID should have been unset" else: new_fds = os.environ.get('LISTEN_FDS', None) new_pid = os.environ.get('LISTEN_PID', None) assert new_fds == old_fds, \ "LISTEN_FDS should not have been changed" assert new_pid == old_pid, \ "LISTEN_PID should not have been changed" @pytest.mark.parametrize("unset", [True, False]) def test_listen_fds_ignores_wrong_pid(unset): with mock.patch.dict(os.environ): os.environ['LISTEN_FDS'] = str(5) os.environ['LISTEN_PID'] = str(1) with check_environ(False): # early exit — never changes the environment assert systemd.listen_fds(unset) == 0, \ "should ignore listen fds not intended for this pid" @pytest.mark.parametrize("unset", [True, False]) def test_listen_fds_returns_count(unset): with mock.patch.dict(os.environ): os.environ['LISTEN_FDS'] = str(5) os.environ['LISTEN_PID'] = str(os.getpid()) with check_environ(unset): assert systemd.listen_fds(unset) == 5, \ "should return the correct count of fds"