energy tests: hold under a host loaded past a hundred runnable threads #166

Merged
dcharlot merged 1 commit from energy/load-robust-tests into main 2026-10-07 09:58:45 -04:00
Owner

Two existing tests failed on the dev Mac, which is also the macOS CI runner, at load averages of 101–179. Neither failure was in the meters.

eoc-meter the_probe_burns_its_tick_of_thread_cpu_between_samples

  • Failure. A tick burned 9.6 ms of the thread's CPU, under the 12.5 ms floor (load average 101). Its 500 ms wall cap had cut it short. The test's own message names that cap as the one thing allowed to shorten a tick, but ProbeRun kept no tick's wall time, so the test couldn't tell a starved tick from a skipped one.
  • Change. ProbeRun records tick_walls, each tick's wall time. It is recorded for the tests and decides nothing.
  • New rule.
    • A tick that ran its whole wall cap passes only if it still spun, burning at least 1 ms of CPU.
    • Any other tick must still burn at least 12.5 ms, as before.
  • Mutations caught.
    • A tick that sleeps through its wall cap: "ran its whole 504.6ms wall cap and burned only 87.375µs of this thread's CPU: it waited, not spun".
    • A tick that sleeps 25 ms: "burned only 81.25µs".

jouleclaw-energy process_cpu

  • Failure. The /bin/sh child, run for a fixed 300 ms, got 0.076 J of CPU against a 0.2 J sanity floor at load average 170. It failed 3 of 3 runs.
  • Change. The child now runs until its own counter reads 0.2 J, for at least 300 ms and at most 5 s, as eoc-meter's equivalent test already does. The parent's window still spans the child's whole run.
  • Result. Child 0.310 J in 335 ms, parent window 121 µJ.

Verified at load averages of 105–333:

  • cargo test -p eoc-meter: 80 tests pass.
  • cargo test -p jouleclaw-energy --features ioreport: 121 tests pass.
  • eoc-meter checks clean for Linux.

🤖 Generated with Claude Code

Two existing tests failed on the dev Mac, which is also the macOS CI runner, at load averages of 101–179. Neither failure was in the meters. **eoc-meter `the_probe_burns_its_tick_of_thread_cpu_between_samples`** - **Failure.** A tick burned 9.6 ms of the thread's CPU, under the 12.5 ms floor (load average 101). Its 500 ms wall cap had cut it short. The test's own message names that cap as the one thing allowed to shorten a tick, but `ProbeRun` kept no tick's wall time, so the test couldn't tell a starved tick from a skipped one. - **Change.** `ProbeRun` records `tick_walls`, each tick's wall time. It is recorded for the tests and decides nothing. - **New rule.** - A tick that ran its whole wall cap passes only if it still spun, burning at least 1 ms of CPU. - Any other tick must still burn at least 12.5 ms, as before. - **Mutations caught.** - A tick that sleeps through its wall cap: "ran its whole 504.6ms wall cap and burned only 87.375µs of this thread's CPU: it waited, not spun". - A tick that sleeps 25 ms: "burned only 81.25µs". **jouleclaw-energy `process_cpu`** - **Failure.** The `/bin/sh` child, run for a fixed 300 ms, got 0.076 J of CPU against a 0.2 J sanity floor at load average 170. It failed 3 of 3 runs. - **Change.** The child now runs until its own counter reads 0.2 J, for at least 300 ms and at most 5 s, as eoc-meter's equivalent test already does. The parent's window still spans the child's whole run. - **Result.** Child 0.310 J in 335 ms, parent window 121 µJ. **Verified at load averages of 105–333:** - `cargo test -p eoc-meter`: 80 tests pass. - `cargo test -p jouleclaw-energy --features ioreport`: 121 tests pass. - eoc-meter checks clean for Linux. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
energy tests: hold under a host loaded past a hundred runnable threads
All checks were successful
energy meters on real hardware / RAPL and NVML on jetson-hub (pull_request) Successful in 33s
jouleclaw public surface must stay documented / Public-surface audit (jouleclaw-rs) (pull_request) Successful in 58s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m7s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m53s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m27s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m8s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m9s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 1m52s
standards workspaces build + test / aac-rs (pull_request) Successful in 1m2s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m14s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 50s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 33s
standards workspaces build + test / map-rs (pull_request) Successful in 32s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m10s
standards workspaces build + test / mesh-rs (pull_request) Successful in 28s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m5s
standards workspaces build + test / openpay (pull_request) Successful in 1m34s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m37s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 3m55s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 9m18s
35e4ea0cb7
Two tests failed on the dev Mac, which is also the macOS CI runner, at
load averages of 101-179. Neither failure was in the meters:

- eoc-meter `the_probe_burns_its_tick_of_thread_cpu_between_samples`.
  A tick burned only 9.6 ms of the thread's CPU, under the 12.5 ms
  floor, because its 500 ms wall cap cut it short. The test's own
  message names that cap as the one thing allowed to shorten a tick,
  but the test could not tell it apart: ProbeRun recorded no tick's
  wall time. It now records each tick's wall time (`tick_walls`;
  recorded, never decided on). A tick that ran its whole wall cap is
  accepted as cut short, but only if it still spun, burning at least
  1 ms of CPU. Any other tick must burn at least half its 25 ms, as
  before.
- jouleclaw-energy `process_cpu`. The `/bin/sh` child, run for a fixed
  300 ms, got 0.076 J of CPU against a 0.2 J sanity floor (load average
  170). It failed 3 of 3 runs. The child now runs until its own counter
  reads 0.2 J (at least 300 ms, at most 5 s), as eoc-meter's equivalent
  test already does. The parent's window still spans the child's whole
  run.

Both pass at a load average of 333. Both tick mutations are caught: a
tick that sleeps through its wall cap ("ran its whole 504.6ms wall cap
and burned only 87.375µs ... it waited, not spun"), and one that sleeps
25 ms.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!166
No description provided.