Test stability with synthetic load
The synthetic-loads panel in the Monitor activity lets you apply synthetic CPU and memory load to a running node, on demand, to verify that the watchdog system actually catches what it claims to catch. Use it to:
- Reproduce a reported "the app freezes under load" issue.
- Verify a fix for a starvation-class bug.
- Demonstrate the audio liveness watchdog working in practice.
Open the panel
- In HUB (or any node window), open the Monitor activity from the menu.
- Click the stress button in the toolbar to open the synthetic-loads panel. You'll see a CPU load slider, a MEM load slider, an ● active indicator, and a danger-red Clear button.
There is no "Active" toggle — any non-zero slider is live immediately, and Clear is the off switch.
Apply CPU load
Drag the CPU load slider to 90.
Within ~2 s, all CPU cores will be saturated by a CPU-burner pool. The exact
CPU usage is calibrated per second by the burner itself, so the value shown in
the Monitor CPU heatmap (and your system monitor) tracks the slider closely.
The same Stress engine powers the long-running CPU stability tests in
testStressConcurrent — this is not a toy load.
To stop: drag the slider back to 0, or press Clear.
Verify the audio watchdog catches starvation
This is the canonical test for the audio recovery system:
- Start BanterLab in normal interactive mode with both Alice and Bob on the bus.
- Confirm audio is flowing — you should see chirp detections.
- In the Monitor activity, apply 95 % CPU load.
- Within ~4 s you should see in the log:
AudioInputNode: stream stalled silently …followed byBanterAutoTest: stream stalled silently … rebuilding QAudioSource (rebuild #1)and[HUB-EVENT] {"type":"liveness_rebuild", ...}.
- Press Clear. Audio should recover.
If you do not see these messages, the audio watchdog is not catching the starvation — that is a bug to file.
Apply memory load
Drag the MEM load slider to a non-zero value. The memory trasher allocates and touches a percentage of available RAM, walking the allocation every cycle so the kernel can't sparse-allocate around it.
Watch for swap pressure in the Monitor memory/swap charts. Memory load is more linear-time than CPU load — it takes a few seconds to reach the target value.
Note: the sliders drive the underlying
libstressengine directly, with no software cap on the percentage. Dragging CPU to 100 % on a production machine running a real ablation run will starve it. Use deliberately — and remember the load keeps running until you press Clear, even if you navigate away (a danger-red return button in the header brings you back).
Do it headlessly
The same load is available to automation via the system.load.* OPAL tasks:
hub --opal 'system.load.set cpu=95'
hub --opal 'system.load.clear'