test(docker): #5152's tests read rows with SQL and the clock they render against
- The status test imported the plugin's models after the app had mapped
them ("already defined"); it reads docker_host_status with SQL.
- The swarm-expiry count awaited inside a generator expression.
- The page test's since came from the module's NOW, so |ago said "5m 4s";
it is built at test time and the assertion checks the minutes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -422,6 +422,7 @@ def test_an_empty_snapshot_from_a_docker_that_answered_clears_the_host(app):
|
|||||||
|
|
||||||
@_NEEDS_DB
|
@_NEEDS_DB
|
||||||
def test_docker_status_is_recorded_once_a_host_has_had_docker(app):
|
def test_docker_status_is_recorded_once_a_host_has_had_docker(app):
|
||||||
|
from sqlalchemy import text
|
||||||
from steward.models.hosts import Host
|
from steward.models.hosts import Host
|
||||||
|
|
||||||
persist = _persist_fn(app)
|
persist = _persist_fn(app)
|
||||||
@@ -430,7 +431,6 @@ def test_docker_status_is_recorded_once_a_host_has_had_docker(app):
|
|||||||
t3 = t1 + timedelta(seconds=60)
|
t3 = t1 + timedelta(seconds=60)
|
||||||
|
|
||||||
async def _go():
|
async def _go():
|
||||||
from plugins.docker.models import DockerHostStatus
|
|
||||||
seen = []
|
seen = []
|
||||||
async with app.db_sessionmaker() as s:
|
async with app.db_sessionmaker() as s:
|
||||||
async with s.begin():
|
async with s.begin():
|
||||||
@@ -440,14 +440,20 @@ def test_docker_status_is_recorded_once_a_host_has_had_docker(app):
|
|||||||
await s.flush()
|
await s.flush()
|
||||||
gone = {"status": "unavailable", "detail": "no Docker socket at /var/run/docker.sock"}
|
gone = {"status": "unavailable", "detail": "no Docker socket at /var/run/docker.sock"}
|
||||||
await persist(s, never, [], status=dict(gone, at=t1))
|
await persist(s, never, [], status=dict(gone, at=t1))
|
||||||
seen.append(await s.get(DockerHostStatus, never.id))
|
await s.flush()
|
||||||
|
|
||||||
|
async def row(host):
|
||||||
|
return (await s.execute(text(
|
||||||
|
"SELECT status, detail, since, reported_at FROM docker_host_status "
|
||||||
|
"WHERE host_id = :h"), {"h": host.id})).first()
|
||||||
|
|
||||||
|
seen.append(await row(never))
|
||||||
for status, at in (({"status": "ok", "detail": None}, t1),
|
for status, at in (({"status": "ok", "detail": None}, t1),
|
||||||
(gone, t2), (gone, t3),
|
(gone, t2), (gone, t3),
|
||||||
({"status": "error", "detail": "permission denied on /var/run/docker.sock"}, t3)):
|
({"status": "error", "detail": "permission denied on /var/run/docker.sock"}, t3)):
|
||||||
await persist(s, had, [], status=dict(status, at=at))
|
await persist(s, had, [], status=dict(status, at=at))
|
||||||
await s.flush()
|
await s.flush()
|
||||||
row = await s.get(DockerHostStatus, had.id)
|
seen.append(tuple(await row(had)))
|
||||||
seen.append((row.status, row.detail, row.since, row.reported_at))
|
|
||||||
return seen
|
return seen
|
||||||
|
|
||||||
never, ok, gone1, gone2, err = asyncio.run(_go())
|
never, ok, gone1, gone2, err = asyncio.run(_go())
|
||||||
@@ -476,9 +482,11 @@ def test_a_node_that_is_no_longer_a_manager_loses_its_swarm_rows(app):
|
|||||||
await s.flush()
|
await s.flush()
|
||||||
|
|
||||||
async def counts():
|
async def counts():
|
||||||
return tuple((await s.execute(text(
|
out = []
|
||||||
f"SELECT count(*) FROM {t} WHERE host_id = :h"), {"h": h.id})).scalar()
|
for t in ("docker_swarm_services", "docker_swarm_nodes"):
|
||||||
for t in ("docker_swarm_services", "docker_swarm_nodes"))
|
out.append((await s.execute(text(
|
||||||
|
f"SELECT count(*) FROM {t} WHERE host_id = :h"), {"h": h.id})).scalar())
|
||||||
|
return tuple(out)
|
||||||
|
|
||||||
await persist(s, h, [], swarm, status={"status": "ok", "detail": None, "at": t1})
|
await persist(s, h, [], swarm, status={"status": "ok", "detail": None, "at": t1})
|
||||||
manager = await counts()
|
manager = await counts()
|
||||||
|
|||||||
@@ -80,10 +80,11 @@ async def test_a_healthy_board_has_no_attention_card(app):
|
|||||||
|
|
||||||
|
|
||||||
async def test_a_host_whose_docker_stopped_answering_says_so(app):
|
async def test_a_host_whose_docker_stopped_answering_says_so(app):
|
||||||
|
now = datetime.now(timezone.utc) # not the module's NOW: |ago reads the clock
|
||||||
down = [{"host_id": "h1", "host_name": "nas", "status": "unavailable",
|
down = [{"host_id": "h1", "host_name": "nas", "status": "unavailable",
|
||||||
"detail": "no Docker socket at /var/run/docker.sock", "since": NOW - timedelta(minutes=5)},
|
"detail": "no Docker socket at /var/run/docker.sock", "since": now - timedelta(minutes=5)},
|
||||||
{"host_id": "h2", "host_name": "web-1", "status": "error",
|
{"host_id": "h2", "host_name": "web-1", "status": "error",
|
||||||
"detail": "permission denied on /var/run/docker.sock", "since": NOW - timedelta(minutes=1)}]
|
"detail": "permission denied on /var/run/docker.sock", "since": now - timedelta(minutes=1)}]
|
||||||
async with app.test_request_context("/plugins/docker/rows"):
|
async with app.test_request_context("/plugins/docker/rows"):
|
||||||
page = await render_plugin_template(
|
page = await render_plugin_template(
|
||||||
app, "docker", "docker/rows.html", docker_down=down, attention=[], says=svc.PROBLEM_SAYS,
|
app, "docker", "docker/rows.html", docker_down=down, attention=[], says=svc.PROBLEM_SAYS,
|
||||||
@@ -92,7 +93,7 @@ async def test_a_host_whose_docker_stopped_answering_says_so(app):
|
|||||||
page = re.sub(r">\s+<", "><", " ".join(page.split()))
|
page = re.sub(r">\s+<", "><", " ".join(page.split()))
|
||||||
card = page[page.index("Docker not answering"):page.index("</section>")]
|
card = page[page.index("Docker not answering"):page.index("</section>")]
|
||||||
assert '<span class="badge badge-warn">No Docker</span><a href="/hosts/h1">nas</a>' in card
|
assert '<span class="badge badge-warn">No Docker</span><a href="/hosts/h1">nas</a>' in card
|
||||||
assert "no Docker socket at /var/run/docker.sock · since <time" in card and ">5m ago</time>" in card
|
assert "no Docker socket at /var/run/docker.sock · since <time" in card and ">5m " in card
|
||||||
assert '<span class="badge badge-crit">Error</span><a href="/hosts/h2">web-1</a>' in card
|
assert '<span class="badge badge-crit">Error</span><a href="/hosts/h2">web-1</a>' in card
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user