2
0

bars-stress.sh 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/env bash
  2. # Randomized stress test for the shell bars (dock / control-center / apps menu), driven entirely
  3. # through the mjdev compositor IPC socket — no real mouse needed. It injects pointer moves, clicks
  4. # and keys in randomized cycles mimicking real use:
  5. # reveal dock, open menu (click menu icon), hover control center, click desktop centre,
  6. # launch an app from the dock, close launched app windows.
  7. # It does NOT assert by itself — read the shell log afterwards (analyze section below) for
  8. # size flip-flops, position drift, show/hide floods and jams.
  9. #
  10. # Usage: bars-stress.sh [cycles] (default 32). Requires a running nested/real mjdevc.
  11. set -u
  12. SOCK="${MJDEV_SOCK:-${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/mjdev-compositor.sock}"
  13. CYCLES="${1:-32}"
  14. W=1280; H=720 # nested output (MJDEVC_OUTPUT)
  15. ESC=1 # evdev KEY_ESC
  16. [ -S "$SOCK" ] || { echo "no compositor socket at $SOCK"; exit 1; }
  17. # send one or more newline-terminated JSON commands on a single connection, hold it briefly so the
  18. # server processes the buffer before EOF (half-close race), return the response on stdout.
  19. ipc() { { printf '%s\n' "$@"; sleep 0.3; } | nc -U "$SOCK" 2>/dev/null; }
  20. rnd() { echo $(( RANDOM % ($2 - $1 + 1) + $1 )); }
  21. reveal_dock() { ipc "{\"cmd\":\"pointer-move\",\"x\":$(rnd 100 $((W-100))),\"y\":$((H-2))}" >/dev/null; }
  22. move_off() { ipc "{\"cmd\":\"pointer-move\",\"x\":$(rnd 300 900),\"y\":$(rnd 150 400)}" >/dev/null; }
  23. open_menu() { ipc "{\"cmd\":\"click\",\"x\":40,\"y\":$((H-40))}" >/dev/null; } # menu icon, dock far-left
  24. esc() { ipc "{\"cmd\":\"key\",\"code\":$ESC}" >/dev/null; }
  25. hover_cc() { ipc "{\"cmd\":\"pointer-move\",\"x\":$((W-2)),\"y\":$(rnd 50 $((H-50)))}" >/dev/null; }
  26. click_centre() { ipc "{\"cmd\":\"click\",\"x\":$((W/2)),\"y\":$((H/2))}" >/dev/null; }
  27. launch_app() { ipc "{\"cmd\":\"pointer-move\",\"x\":$(rnd 120 900),\"y\":$((H-2))}" \
  28. "{\"cmd\":\"click\",\"x\":$(rnd 120 900),\"y\":$((H-40))}" >/dev/null; }
  29. close_app_windows() {
  30. # close every listed (app) window by id so launches don't pile up
  31. local ids
  32. ids=$(ipc '{"cmd":"list-windows"}' | grep -oE '"id":[0-9]+' | grep -oE '[0-9]+')
  33. for id in $ids; do ipc "{\"cmd\":\"close\",\"id\":$id}" >/dev/null; sleep 0.2; done
  34. }
  35. ACTIONS=(reveal_dock open_menu esc hover_cc click_centre launch_app move_off)
  36. echo "stress: $CYCLES cycles via $SOCK"
  37. for ((i=1; i<=CYCLES; i++)); do
  38. # 2-3 random actions per cycle
  39. n=$(rnd 2 3)
  40. line="cycle $i:"
  41. for ((k=0; k<n; k++)); do
  42. a=${ACTIONS[$(rnd 0 $((${#ACTIONS[@]}-1)))]}
  43. line="$line $a"
  44. "$a"
  45. sleep 0.25
  46. done
  47. echo "$line"
  48. # periodically reap any apps we launched
  49. if (( i % 6 == 0 )); then close_app_windows; fi
  50. done
  51. # settle, final cleanup, park pointer in the centre
  52. sleep 1
  53. close_app_windows
  54. ipc "{\"cmd\":\"pointer-move\",\"x\":$((W/2)),\"y\":$((H/2))}" >/dev/null
  55. echo "stress: done"