probe: wait for local stimulus readiness

This commit is contained in:
Brad Stein 2026-05-01 10:45:32 -03:00
parent 46c8d60d62
commit 08d424b023
7 changed files with 48 additions and 8 deletions

6
Cargo.lock generated
View File

@ -1652,7 +1652,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]] [[package]]
name = "lesavka_client" name = "lesavka_client"
version = "0.16.13" version = "0.16.14"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -1686,7 +1686,7 @@ dependencies = [
[[package]] [[package]]
name = "lesavka_common" name = "lesavka_common"
version = "0.16.13" version = "0.16.14"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64", "base64",
@ -1698,7 +1698,7 @@ dependencies = [
[[package]] [[package]]
name = "lesavka_server" name = "lesavka_server"
version = "0.16.13" version = "0.16.14"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64", "base64",

View File

@ -4,7 +4,7 @@ path = "src/main.rs"
[package] [package]
name = "lesavka_client" name = "lesavka_client"
version = "0.16.13" version = "0.16.14"
edition = "2024" edition = "2024"
[dependencies] [dependencies]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "lesavka_common" name = "lesavka_common"
version = "0.16.13" version = "0.16.14"
edition = "2024" edition = "2024"
build = "build.rs" build = "build.rs"

View File

@ -192,8 +192,10 @@ async function pollCommand() {
} }
setInterval(pollCommand, 200); setInterval(pollCommand, 200);
setInterval(() => postJson('/status', { ready: true, page_message: running ? 'running heartbeat' : 'ready heartbeat' }), 1000); setInterval(() => postJson('/status', { ready: true, page_message: running ? 'running heartbeat' : 'ready heartbeat' }), 1000);
postJson('/status', { ready: true, page_message: 'page ready' }); void postJson('/status', { ready: true, page_message: 'page ready' });
setStatus('ready\nPoint the real webcam at this window.\nKeep speakers audible to the selected microphone.'); setStatus(`ready
Point the real webcam at this window.
Keep speakers audible to the selected microphone.`);
</script> </script>
</body> </body>
</html>""" </html>"""

View File

@ -100,6 +100,41 @@ sys.exit(1)
PY PY
} }
wait_for_stimulus_page_ready() {
local timeout_seconds=$1
local deadline=$(( $(date +%s) + timeout_seconds ))
local status_json=""
until status_json="$(curl -fsS "http://127.0.0.1:${STIMULUS_PORT}/status" 2>/dev/null)"; do
if (( $(date +%s) >= deadline )); then
echo "Timed out waiting for local stimulus status endpoint" >&2
return 1
fi
sleep 0.2
done
while true; do
if STATUS_JSON="${status_json}" python3 - <<'PY'
import json
import os
import sys
status = json.loads(os.environ["STATUS_JSON"])
sys.exit(0 if status.get("ready") and status.get("page_message") != "booting" else 1)
PY
then
return 0
fi
if (( $(date +%s) >= deadline )); then
echo "local stimulus page did not become ready before timeout" >&2
echo "last stimulus status: ${status_json}" >&2
echo "stimulus server log: ${ARTIFACT_DIR}/stimulus-server.log" >&2
echo "stimulus browser log: ${ARTIFACT_DIR}/stimulus-browser.log" >&2
return 1
fi
sleep 0.5
status_json="$(curl -fsS "http://127.0.0.1:${STIMULUS_PORT}/status" 2>/dev/null || true)"
done
}
start_server_tunnel_if_needed() { start_server_tunnel_if_needed() {
if [[ "${LESAVKA_SERVER_ADDR}" != "auto" ]]; then if [[ "${LESAVKA_SERVER_ADDR}" != "auto" ]]; then
RESOLVED_LESAVKA_SERVER_ADDR="${LESAVKA_SERVER_ADDR}" RESOLVED_LESAVKA_SERVER_ADDR="${LESAVKA_SERVER_ADDR}"
@ -150,6 +185,7 @@ PREFS
"http://127.0.0.1:${STIMULUS_PORT}/" \ "http://127.0.0.1:${STIMULUS_PORT}/" \
>"${ARTIFACT_DIR}/stimulus-browser.log" 2>&1 & >"${ARTIFACT_DIR}/stimulus-browser.log" 2>&1 &
STIMULUS_BROWSER_PID=$! STIMULUS_BROWSER_PID=$!
wait_for_stimulus_page_ready 15
echo "==> position check" echo "==> position check"
echo " Point the real webcam at the stimulus window and keep the selected microphone hearing the tone." echo " Point the real webcam at the stimulus window and keep the selected microphone hearing the tone."

View File

@ -10,7 +10,7 @@ bench = false
[package] [package]
name = "lesavka_server" name = "lesavka_server"
version = "0.16.13" version = "0.16.14"
edition = "2024" edition = "2024"
autobins = false autobins = false

View File

@ -90,6 +90,7 @@ fn mirrored_sync_script_uses_real_client_capture_path() {
"BROWSER_SYNC_DRIVER_COMMAND=\"${driver_command}\"", "BROWSER_SYNC_DRIVER_COMMAND=\"${driver_command}\"",
"SYNC_ANALYZE_EVENT_WIDTH_CODES=\"${PROBE_EVENT_WIDTH_CODES}\"", "SYNC_ANALYZE_EVENT_WIDTH_CODES=\"${PROBE_EVENT_WIDTH_CODES}\"",
"run_upstream_browser_av_sync.sh", "run_upstream_browser_av_sync.sh",
"wait_for_stimulus_page_ready 15",
"Point the real webcam at the stimulus window", "Point the real webcam at the stimulus window",
] { ] {
assert!( assert!(
@ -114,6 +115,7 @@ fn local_stimulus_matches_sync_analyzer_pulse_contract() {
"event_width_codes", "event_width_codes",
"widthCode", "widthCode",
"oscillator.frequency.value = 880", "oscillator.frequency.value = 880",
"setStatus(`ready",
"Point the real webcam at this window", "Point the real webcam at this window",
] { ] {
assert!( assert!(