Testing Configuration Reloads
Configuration reload tests are native Uranium pytest scenarios (see
Writing Uranium Tests). Uranium has no dedicated reload directive; a test drives
the reload through the ATS service and validates the structured result the
server reports for the reload token.
Avoid the fire-and-forget pattern of running traffic_ctl config reload,
sleeping, and grepping diags.log for a message. It relies on log text that
can change, adds fixed delays, cannot tell which handler ran, and does not
detect a failed reload.
Triggering a Reload
ATS.traffic_ctl() runs traffic_ctl against the test's run root
and returns a CommandResult. Pass a token so the reload can be queried
afterward, and use monitor mode (-m) so the command blocks until the
reload reaches a terminal state:
from tools.uranium.services import ATS
def test_reload_ip_allow(ats: ATS) -> None:
"""Reload ip_allow.yaml after it changes.
:param ats: Isolated Traffic Server instance.
"""
ats.start()
(ats.config_directory / "ip_allow.yaml").touch()
result = ats.traffic_ctl("config", "reload", "-m", "-t", "ip-allow-touch", "-T", "30s")
assert result.returncode == 0, result.output
With -m, the exit code reflects the reload outcome: 0 for success,
2 when the reload failed, and 75 when the -T timeout expired. If
another reload is already in progress, -m attaches to it and reports its
outcome. See traffic_ctl config reload for
the full list and for the -w (initial wait), -r (refresh interval),
-T (timeout), --force, --data and --directive options.
ATS.rpc() sends one JSON-RPC request through traffic_ctl. Use it
with admin_config_reload when a test needs to control the request payload
directly, for example to submit inline configuration or to check the
errors array of the response.
Validating the Result
Check which handlers ran, and how each one finished, through the get_reload_config_status JSON-RPC method rather than the human-readable output of traffic_ctl:
import json
request = {
"jsonrpc": "2.0",
"id": "1",
"method": "get_reload_config_status",
"params": {"token": "ip-allow-touch"},
}
response = json.loads(ats.rpc(request).stdout)
root = response["result"]["tasks"][0]
assert root["status"] == "success", response
The root task's sub_tasks hold one entry per handler, each with its own
description, filename and status. Walk that tree to require that a
handler ran with an expected status, or that a handler which should not have
been triggered is absent.
When a reload is started without -m, poll
get_reload_config_status until the root task reaches success,
fail or timeout before asserting on it. Waiting only until a child task
succeeds can return before the reload as a whole has finished.
Record-triggered reloads (traffic_ctl config set without an explicit
config reload) do not create reload tasks and cannot be validated this way.