mirror of
https://github.com/apache/httpd.git
synced 2026-10-23 22:49:01 +03:00
Type=notify-reload. * test/modules/arch/linux/env.py (TransientService): Take the service type and whether to configure ExecReload=. (TransientService.systemctl): Take a timeout. (TransientService.reload, TransientService.rewrite_conf, error_log_size, error_log_since, systemd_version): New. * test/modules/arch/linux/README: Describe the new suite. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> GitHub: PR #729 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1937647 13f79535-47bb-0310-9956-ffa450edef68
110 lines
5.8 KiB
Plaintext
110 lines
5.8 KiB
Plaintext
mod_systemd tests
|
|
=================
|
|
|
|
What is different about this module
|
|
-----------------------------------
|
|
mod_systemd has no directives. Everything it does is driven by the
|
|
environment httpd was started with, and almost everything it produces goes
|
|
to the service manager rather than to a client:
|
|
|
|
- sd_notify(3) datagrams sent to $NOTIFY_SOCKET at four points: reading
|
|
the configuration (pre_config), configuration loaded (post_config),
|
|
the MPM starting (pre_mpm, the only notification carrying MAINPID),
|
|
and a status line refreshed by the monitor hook.
|
|
- listening sockets inherited from the service manager, found through
|
|
$LISTEN_FDS. mod_systemd registers the two optional functions
|
|
server/listen.c calls, so loading the module is what enables socket
|
|
activation and not loading it is what disables it.
|
|
- ap_extended_status forced on in pre_config, so that the monitor hook
|
|
has request counts to report.
|
|
- the watchdog keep-alive, WATCHDOG=1, sent while the service manager
|
|
asks for one. Which it does through the environment as well:
|
|
WatchdogSec= in the unit becomes $WATCHDOG_USEC, and $WATCHDOG_PID
|
|
names the process expected to report.
|
|
|
|
None of that is observable over HTTP, so the tests observe it directly.
|
|
|
|
How the tests run without systemd, and without privileges
|
|
---------------------------------------------------------
|
|
There is no need for a service manager to exercise the protocol. Only
|
|
test_005, the last test of test_006, and test_007 involve systemd at all;
|
|
the rest run anywhere, and need nothing from the systemd package beyond the
|
|
libsystemd httpd itself is linked against.
|
|
|
|
test_001_notify.py $NOTIFY_SOCKET is an ordinary AF_UNIX datagram
|
|
socket the test binds itself (env.NotifyListener).
|
|
sd_notify writes to whatever that variable names, so
|
|
the test reads httpd's notifications straight off the
|
|
socket. HttpdTestEnv.set_httpd_env() puts the
|
|
variable into the environment apachectl passes on.
|
|
|
|
test_002_monitor.py The periodic status line. ap_run_monitor() is
|
|
called once every ten turns of the parent's ~1s
|
|
loop, so these tests wait up to 25 seconds.
|
|
|
|
test_003_extended_status.py
|
|
The ExtendedStatus side effect, observed through
|
|
mod_status.
|
|
|
|
test_004_socket_activation.py
|
|
The test opens the listening socket itself and
|
|
hands it to httpd as descriptor 3 with LISTEN_FDS
|
|
and LISTEN_PID set, which is the whole protocol.
|
|
systemd-socket-activate would do the same, but its
|
|
--now option is newer than the systemd on some
|
|
distributions, and doing it directly needs no
|
|
systemd tooling at all.
|
|
|
|
test_006_watchdog.py The keep-alive. Mostly the same stand-in socket,
|
|
with $WATCHDOG_USEC set in the environment httpd is
|
|
started with; env.ForegroundServer runs httpd in the
|
|
foreground where $WATCHDOG_PID can name it, which
|
|
apachectl cannot do for a parent it has not forked
|
|
yet. The last test uses a real unit with
|
|
WatchdogSec=, where systemd's own
|
|
WatchdogTimestampMonotonic is the evidence that the
|
|
pings arrived.
|
|
|
|
The keep-alive is sent from the monitor hook, so it
|
|
is only as frequent as that hook is: about every ten
|
|
seconds. A WatchdogSec shorter than twice that
|
|
cannot be met, and mod_systemd says so (AH10621)
|
|
rather than letting a healthy server be killed.
|
|
|
|
test_005_service.py The real thing: a transient Type=notify unit run
|
|
with "systemd-run --user". This is what checks that
|
|
systemd holds the unit in "activating" until READY=1
|
|
arrives, tracks the right MainPID, and shows the
|
|
reported STATUS= as the unit's status text.
|
|
Skipped when the user has no systemd manager.
|
|
|
|
test_007_notify_reload.py
|
|
The reload protocol, as a transient
|
|
Type=notify-reload unit: that "systemctl reload"
|
|
waits for the new configuration to be in use, that a
|
|
configuration which does not parse fails the reload
|
|
without disturbing the running server, and that a
|
|
reload restarts it gracefully and only once. Also
|
|
skipped where systemd is older than 253, which is
|
|
where Type=notify-reload arrived.
|
|
|
|
The whole package is skipped unless mod_systemd was built, which needs
|
|
configure --enable-systemd. A static module is enough for everything
|
|
except the test which has to leave mod_systemd out of the configuration;
|
|
that one needs --enable-systemd=shared.
|
|
|
|
Running the systemd suites where there is no user session
|
|
---------------------------------------------------------
|
|
"systemctl --user" needs a per-user manager, which a login session has but
|
|
a CI container does not; enabling lingering needs privileges. Where that
|
|
is a problem, run the tests inside a container with systemd as pid 1,
|
|
which rootless podman supports on a cgroup v2 host:
|
|
|
|
podman run --rm -it --systemd=always \
|
|
-v $PWD:/src:z -w /src registry.fedoraproject.org/fedora:latest \
|
|
/usr/sbin/init
|
|
|
|
then, in another terminal, "podman exec" into it and run pytest as a
|
|
non-root user with XDG_RUNTIME_DIR set. The other four suites need none of
|
|
this and run anywhere.
|