From 5a3bd902fe9e0ce5a33589b8b784a98139aa1ab3 Mon Sep 17 00:00:00 2001 From: ScottW514 Date: Mon, 17 Aug 2026 17:02:16 -0400 Subject: [PATCH] Drop the nice(1) dependency from the load test; ship htop on the dev image The image has no `nice` binary - BusyBox ships renice only - so motion.step-timing-under-load could not spawn its CPU hog at all. Set the niceness from the parent with os.setpriority once the child exists, and assert the value that actually took: a hog left at nice 0 would be a harsher test than intended, and one left unset must not pass silently. Add htop to the dev image for bench diagnostics. The release image is unchanged - it carries neither forgetest nor htop. --- forgetest/forgetest/suite/motion.py | 19 ++++++++++++++++--- .../images/forgefirm-image-dev.bb | 1 + 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/forgetest/forgetest/suite/motion.py b/forgetest/forgetest/suite/motion.py index 78cbb6a..8fa0bf2 100644 --- a/forgetest/forgetest/suite/motion.py +++ b/forgetest/forgetest/suite/motion.py @@ -1011,10 +1011,23 @@ def step_timing_under_load(ctx): load = None try: # One SCHED_OTHER hog at the same nice as forgectrl's HTTP threads: - # the realistic competitor, and the one the fix must outrank. - load = subprocess.Popen(["nice", "-n", "5", "sh", "-c", "while :; do :; done"], + # the realistic competitor, and the one the fix must outrank. The + # image has no `nice` binary (BusyBox ships renice only), so the + # niceness is applied from here once the child exists, and the value + # that actually took is recorded - a hog left at nice 0 would be a + # harsher test than intended, and one left unset must not pass + # silently. + load = subprocess.Popen(["sh", "-c", "while :; do :; done"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - ctx.log("CPU hog started (pid %d, nice 5)", load.pid) + try: + os.setpriority(os.PRIO_PROCESS, load.pid, 5) + hog_nice = os.getpriority(os.PRIO_PROCESS, load.pid) + except OSError as exc: + hog_nice = None + ctx.log("could not set the hog niceness: %s", exc) + ev["hog_nice"] = hog_nice + ctx.check(hog_nice == 5, "CPU hog is at nice %s, expected 5", hog_nice) + ctx.log("CPU hog started (pid %d, nice %s)", load.pid, hog_nice) with ctx.grbl() as g: clean_slate(ctx, g) ctrl0 = cpu_ticks(pid) diff --git a/meta-forgefirm/recipes-forgefirm/images/forgefirm-image-dev.bb b/meta-forgefirm/recipes-forgefirm/images/forgefirm-image-dev.bb index f19a7d2..82eab32 100644 --- a/meta-forgefirm/recipes-forgefirm/images/forgefirm-image-dev.bb +++ b/meta-forgefirm/recipes-forgefirm/images/forgefirm-image-dev.bb @@ -9,6 +9,7 @@ DESCRIPTION = "OpenGlow/ForgeFIRM development image for Glowforge" IMAGE_INSTALL += " \ forgectrl \ forgetest \ + htop \ " # debug-tweaks (passwordless root, root SSH login) belongs ONLY to the dev