test: enforce soak resource budgets
This commit is contained in:
1 parent
d18d5b5fc4
commit
7356986259
2 files changed
+75
-5
No files matched your search
@@ -52,8 +52,15 @@ Environment controls:
|
|||||||
`target/debug/ferese-malformed-client`;
|
`target/debug/ferese-malformed-client`;
|
||||||
- `FERESE_PID`: compositor PID; automatic lookup is only a fallback;
|
- `FERESE_PID`: compositor PID; automatic lookup is only a fallback;
|
||||||
- `FERESE_SOAK_LOG`: result log, default `/tmp/ferese-soak-<pid>.log`.
|
- `FERESE_SOAK_LOG`: result log, default `/tmp/ferese-soak-<pid>.log`.
|
||||||
|
- `FERESE_SOAK_MAX_RSS_GROWTH_KIB`: maximum RSS growth, default `131072`
|
||||||
|
(128 MiB);
|
||||||
|
- `FERESE_SOAK_MAX_FD_GROWTH`: maximum open-file-descriptor growth, default
|
||||||
|
`32`;
|
||||||
|
- `FERESE_SOAK_MAX_THREAD_GROWTH`: maximum thread growth, default `8`.
|
||||||
|
|
||||||
Run the same workload once with the nested backend and once from a direct DRM
|
Run the same workload once with the nested backend and once from a direct DRM
|
||||||
session. A passing run requires the compositor to remain alive, IPC queries to
|
session. Samples are taken after spawned clients are reaped. A passing run
|
||||||
succeed, and RSS samples to stabilize rather than grow without bound. Preserve
|
requires the compositor to remain alive, IPC queries to succeed, and RSS, file
|
||||||
|
descriptor, and thread growth to stay within the declared budgets. Tighten the
|
||||||
|
defaults for release hardware when its normal cache behavior is known. Preserve
|
||||||
the soak log and the `ferese::render` summaries with the release artifacts.
|
the soak log and the `ferese::render` summaries with the release artifacts.
|
||||||
+66
-3
@@ -9,6 +9,9 @@ feresectl_program="${FERESECTL:-target/debug/feresectl}"
|
|||||||
malformed_client_program="${FERESE_MALFORMED_CLIENT:-target/debug/ferese-malformed-client}"
|
malformed_client_program="${FERESE_MALFORMED_CLIENT:-target/debug/ferese-malformed-client}"
|
||||||
compositor_pid="${FERESE_PID:-}"
|
compositor_pid="${FERESE_PID:-}"
|
||||||
log_path="${FERESE_SOAK_LOG:-/tmp/ferese-soak-$$.log}"
|
log_path="${FERESE_SOAK_LOG:-/tmp/ferese-soak-$$.log}"
|
||||||
|
max_rss_growth_kib="${FERESE_SOAK_MAX_RSS_GROWTH_KIB:-131072}"
|
||||||
|
max_fd_growth="${FERESE_SOAK_MAX_FD_GROWTH:-32}"
|
||||||
|
max_thread_growth="${FERESE_SOAK_MAX_THREAD_GROWTH:-8}"
|
||||||
|
|
||||||
if [[ -z "${WAYLAND_DISPLAY:-}" ]]; then
|
if [[ -z "${WAYLAND_DISPLAY:-}" ]]; then
|
||||||
echo "WAYLAND_DISPLAY must name the Ferese socket" >&2
|
echo "WAYLAND_DISPLAY must name the Ferese socket" >&2
|
||||||
@@ -20,6 +23,13 @@ if [[ ! "$soak_seconds" =~ ^[1-9][0-9]*$ ]]; then
|
|||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
for value in "$max_rss_growth_kib" "$max_fd_growth" "$max_thread_growth"; do
|
||||||
|
if [[ ! "$value" =~ ^[0-9]+$ ]]; then
|
||||||
|
echo "soak resource-growth limits must be non-negative integers" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
if [[ ! -x "$feresectl_program" ]]; then
|
if [[ ! -x "$feresectl_program" ]]; then
|
||||||
cargo build -p feresectl
|
cargo build -p feresectl
|
||||||
fi
|
fi
|
||||||
@@ -60,6 +70,36 @@ rss_kib() {
|
|||||||
awk '/^VmRSS:/ { print $2; exit }' "/proc/$compositor_pid/status"
|
awk '/^VmRSS:/ { print $2; exit }' "/proc/$compositor_pid/status"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_count() {
|
||||||
|
awk '/^Threads:/ { print $2; exit }' "/proc/$compositor_pid/status"
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_count() {
|
||||||
|
find "/proc/$compositor_pid/fd" -mindepth 1 -maxdepth 1 -printf . | wc -c
|
||||||
|
}
|
||||||
|
|
||||||
|
check_resource_budget() {
|
||||||
|
local rss_growth=$((current_rss - initial_rss))
|
||||||
|
local fd_growth=$((current_fds - initial_fds))
|
||||||
|
local thread_growth=$((current_threads - initial_threads))
|
||||||
|
|
||||||
|
if ((rss_growth > max_rss_growth_kib)); then
|
||||||
|
echo "FAIL RSS growth ${rss_growth} KiB exceeds ${max_rss_growth_kib} KiB" \
|
||||||
|
| tee -a "$log_path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ((fd_growth > max_fd_growth)); then
|
||||||
|
echo "FAIL file-descriptor growth $fd_growth exceeds $max_fd_growth" \
|
||||||
|
| tee -a "$log_path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ((thread_growth > max_thread_growth)); then
|
||||||
|
echo "FAIL thread growth $thread_growth exceeds $max_thread_growth" \
|
||||||
|
| tee -a "$log_path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
control() {
|
control() {
|
||||||
"$feresectl_program" "$@" >/dev/null
|
"$feresectl_program" "$@" >/dev/null
|
||||||
}
|
}
|
||||||
@@ -101,12 +141,17 @@ start_time="$SECONDS"
|
|||||||
deadline=$((start_time + soak_seconds))
|
deadline=$((start_time + soak_seconds))
|
||||||
iteration=0
|
iteration=0
|
||||||
initial_rss="$(rss_kib)"
|
initial_rss="$(rss_kib)"
|
||||||
|
initial_fds="$(fd_count)"
|
||||||
|
initial_threads="$(thread_count)"
|
||||||
maximum_rss="$initial_rss"
|
maximum_rss="$initial_rss"
|
||||||
|
maximum_fds="$initial_fds"
|
||||||
|
maximum_threads="$initial_threads"
|
||||||
|
|
||||||
{
|
{
|
||||||
echo "ferese native soak"
|
echo "ferese native soak"
|
||||||
echo "pid=$compositor_pid display=$WAYLAND_DISPLAY client=$client_program"
|
echo "pid=$compositor_pid display=$WAYLAND_DISPLAY client=$client_program"
|
||||||
echo "duration_seconds=$soak_seconds initial_rss_kib=$initial_rss"
|
echo "duration_seconds=$soak_seconds initial_rss_kib=$initial_rss initial_fds=$initial_fds initial_threads=$initial_threads"
|
||||||
|
echo "limits rss_growth_kib=$max_rss_growth_kib fd_growth=$max_fd_growth thread_growth=$max_thread_growth"
|
||||||
} | tee "$log_path"
|
} | tee "$log_path"
|
||||||
|
|
||||||
while ((SECONDS < deadline)); do
|
while ((SECONDS < deadline)); do
|
||||||
@@ -146,13 +191,23 @@ while ((SECONDS < deadline)); do
|
|||||||
reap_clients
|
reap_clients
|
||||||
|
|
||||||
current_rss="$(rss_kib)"
|
current_rss="$(rss_kib)"
|
||||||
|
current_fds="$(fd_count)"
|
||||||
|
current_threads="$(thread_count)"
|
||||||
if ((current_rss > maximum_rss)); then
|
if ((current_rss > maximum_rss)); then
|
||||||
maximum_rss="$current_rss"
|
maximum_rss="$current_rss"
|
||||||
fi
|
fi
|
||||||
|
if ((current_fds > maximum_fds)); then
|
||||||
|
maximum_fds="$current_fds"
|
||||||
|
fi
|
||||||
|
if ((current_threads > maximum_threads)); then
|
||||||
|
maximum_threads="$current_threads"
|
||||||
|
fi
|
||||||
|
check_resource_budget
|
||||||
|
|
||||||
if ((iteration % 100 == 0)); then
|
if ((iteration % 100 == 0)); then
|
||||||
printf 'iteration=%d elapsed=%d rss_kib=%d max_rss_kib=%d\n' \
|
printf 'iteration=%d elapsed=%d rss_kib=%d max_rss_kib=%d fds=%d max_fds=%d threads=%d max_threads=%d\n' \
|
||||||
"$iteration" "$((SECONDS - start_time))" "$current_rss" "$maximum_rss" \
|
"$iteration" "$((SECONDS - start_time))" "$current_rss" "$maximum_rss" \
|
||||||
|
"$current_fds" "$maximum_fds" "$current_threads" "$maximum_threads" \
|
||||||
| tee -a "$log_path"
|
| tee -a "$log_path"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -163,7 +218,15 @@ done
|
|||||||
control get-outputs
|
control get-outputs
|
||||||
control get-workspaces
|
control get-workspaces
|
||||||
final_rss="$(rss_kib)"
|
final_rss="$(rss_kib)"
|
||||||
|
final_fds="$(fd_count)"
|
||||||
|
final_threads="$(thread_count)"
|
||||||
|
current_rss="$final_rss"
|
||||||
|
current_fds="$final_fds"
|
||||||
|
current_threads="$final_threads"
|
||||||
|
check_resource_budget
|
||||||
|
|
||||||
printf 'PASS iterations=%d final_rss_kib=%d max_rss_kib=%d growth_kib=%d\n' \
|
printf 'PASS iterations=%d final_rss_kib=%d max_rss_kib=%d rss_growth_kib=%d final_fds=%d max_fds=%d fd_growth=%d final_threads=%d max_threads=%d thread_growth=%d\n' \
|
||||||
"$iteration" "$final_rss" "$maximum_rss" "$((final_rss - initial_rss))" \
|
"$iteration" "$final_rss" "$maximum_rss" "$((final_rss - initial_rss))" \
|
||||||
|
"$final_fds" "$maximum_fds" "$((final_fds - initial_fds))" \
|
||||||
|
"$final_threads" "$maximum_threads" "$((final_threads - initial_threads))" \
|
||||||
| tee -a "$log_path"
|
| tee -a "$log_path"
|
||||||
Reference in new issue
Block a user