test(hosts): render the host_agent fragments whether or not the plugin is enabled (#5122)
The unit app does not register plugin blueprints, so render_template could not find _host_vitals.html or _host_metrics.html (TemplateNotFound, CI run 8384). tests/_templates.render_plugin_template renders a plugin's template through the app's own Jinja environment and request context, with the plugin's template folder ahead of the app's loader. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+15
-1
@@ -1,6 +1,9 @@
|
|||||||
"""Where Steward's templates live, for the guards that read every one."""
|
"""Where Steward's templates live, for the guards that read every one, and a
|
||||||
|
way to render a plugin's template in a test."""
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
||||||
|
from jinja2 import ChoiceLoader, FileSystemLoader
|
||||||
|
|
||||||
import steward
|
import steward
|
||||||
|
|
||||||
REPO = pathlib.Path(steward.__file__).parent.parent
|
REPO = pathlib.Path(steward.__file__).parent.parent
|
||||||
@@ -10,3 +13,14 @@ def template_files() -> list[pathlib.Path]:
|
|||||||
"""Every first-party .html template: core and each plugin's."""
|
"""Every first-party .html template: core and each plugin's."""
|
||||||
roots = [REPO / "steward" / "templates", *(REPO / "plugins").glob("*/templates")]
|
roots = [REPO / "steward" / "templates", *(REPO / "plugins").glob("*/templates")]
|
||||||
return sorted(p for root in roots for p in root.rglob("*.html"))
|
return sorted(p for root in roots for p in root.rglob("*.html"))
|
||||||
|
|
||||||
|
|
||||||
|
async def render_plugin_template(app, plugin: str, name: str, **ctx) -> str:
|
||||||
|
"""Render plugins/<plugin>/templates/<name> through the app's own Jinja
|
||||||
|
environment (its globals, filters and request context), whether or not the
|
||||||
|
plugin is enabled in this app. Call inside app.test_request_context()."""
|
||||||
|
env = app.jinja_env.overlay(loader=ChoiceLoader(
|
||||||
|
[FileSystemLoader(str(REPO / "plugins" / plugin / "templates")), app.jinja_env.loader]))
|
||||||
|
await app.update_template_context(ctx)
|
||||||
|
template = env.get_template(name)
|
||||||
|
return await template.render_async(**ctx) if env.is_async else template.render(**ctx)
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ from datetime import datetime, timedelta, timezone
|
|||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from quart import render_template
|
|
||||||
|
|
||||||
from steward.core.formatting import worst_reading
|
from steward.core.formatting import worst_reading
|
||||||
from steward.core.settings import to_thresholds_cfg
|
from steward.core.settings import to_thresholds_cfg
|
||||||
|
from tests._templates import render_plugin_template
|
||||||
from tests.test_style_tokens import hex_colours
|
from tests.test_style_tokens import hex_colours
|
||||||
|
|
||||||
TH = to_thresholds_cfg({}) # cpu/mem/disk warn 80 crit 90; load warn 80 crit 100
|
TH = to_thresholds_cfg({}) # cpu/mem/disk warn 80 crit 90; load warn 80 crit 100
|
||||||
@@ -29,8 +29,8 @@ async def _vitals(app, *, cpu=40.0, mem=50.0, stale=False, seen_min=1):
|
|||||||
readings = (("CPU", cpu, "cpu"), ("Memory", mem, "mem"), ("Disk /", 30.0, "disk"),
|
readings = (("CPU", cpu, "cpu"), ("Memory", mem, "mem"), ("Disk /", 30.0, "disk"),
|
||||||
("Load per core", 20, "load"))
|
("Load per core", 20, "load"))
|
||||||
async with app.test_request_context("/plugins/host_agent/vitals/h1"):
|
async with app.test_request_context("/plugins/host_agent/vitals/h1"):
|
||||||
page = await render_template(
|
page = await render_plugin_template(
|
||||||
"_host_vitals.html", reporting=True, stale=stale,
|
app, "host_agent", "_host_vitals.html", reporting=True, stale=stale,
|
||||||
reg=SimpleNamespace(last_seen_at=datetime.now(timezone.utc) - timedelta(minutes=seen_min),
|
reg=SimpleNamespace(last_seen_at=datetime.now(timezone.utc) - timedelta(minutes=seen_min),
|
||||||
agent_version="1.9.0"),
|
agent_version="1.9.0"),
|
||||||
cpu=cpu, mem=mem, disk_root=30.0, load_per_core=20,
|
cpu=cpu, mem=mem, disk_root=30.0, load_per_core=20,
|
||||||
@@ -63,8 +63,8 @@ async def test_a_stale_host_says_since_when_before_any_reading(app):
|
|||||||
async def test_the_metrics_page_grades_by_the_same_cutoffs(app):
|
async def test_the_metrics_page_grades_by_the_same_cutoffs(app):
|
||||||
# 75 % was amber under the old hard-coded 70/90; Settings → Thresholds says warn at 80.
|
# 75 % was amber under the old hard-coded 70/90; Settings → Thresholds says warn at 80.
|
||||||
async with app.test_request_context("/plugins/host_agent/h1/metrics"):
|
async with app.test_request_context("/plugins/host_agent/h1/metrics"):
|
||||||
page = await render_template(
|
page = await render_plugin_template(
|
||||||
"_host_metrics.html", host=SimpleNamespace(address="10.0.0.2"), stale=False,
|
app, "host_agent", "_host_metrics.html", host=SimpleNamespace(address="10.0.0.2"), stale=False,
|
||||||
reg=SimpleNamespace(distro=None, kernel=None, arch=None, agent_version=None,
|
reg=SimpleNamespace(distro=None, kernel=None, arch=None, agent_version=None,
|
||||||
last_seen_at=datetime.now(timezone.utc)),
|
last_seen_at=datetime.now(timezone.utc)),
|
||||||
hostlvl={"cpu_pct": 75.0, "mem_used_pct": 95.0, "temp_c_max": 72.0},
|
hostlvl={"cpu_pct": 75.0, "mem_used_pct": 95.0, "temp_c_max": 72.0},
|
||||||
|
|||||||
Reference in New Issue
Block a user