Scenarios run at once, and free_port only finds a port nothing listens on just then. When another scenario's server took it first, this one's exited with EADDRINUSE and the scenario talked to someone else's forge, getting a 404 or no answer (identity-backup, identity-sessions and identity-enroll failed now and then that way). private_server now waits for the server to say it is listening on its port, and tries another port if it exited instead.
- commit
- 22348072565d397e36ffa46982f27725a2b73a48
- parent
- 47539151070d5340c701a6460c1994a816295aeb
- author
- cat <admin@dev.site>
- kind
- fix risk score 1.0 of 3, Jev's estimate
| M | test/ | 24 | ++++++++++++++++++++---- |
@@ -245,12 +245,28 @@ wait_http() {
245245 246246 # private_server: lib/private-server.ts on a free port, in the background,247247 # for this forge (with FORGE_BASE_URL as it is now). Sets PRIV, its URL.248+# Scenarios run at once, so another one's server can take the free port249+# first; then this one's exits (EADDRINUSE), and it tries another port250+# rather than talk to someone else's forge.248251 private_server() {249- PRIV_PORT=$(free_port)250- FORGE_PRIVATE_PORT=$PRIV_PORT node "$T_HOME/lib/private-server.ts" >>"$T/private.log" 2>&1 &251- T_PIDS="$T_PIDS $!"252+ n=0253+ while :; do254+ PRIV_PORT=$(free_port)255+ log=$T/private.$PRIV_PORT.log256+ FORGE_PRIVATE_PORT=$PRIV_PORT node "$T_HOME/lib/private-server.ts" >"$log" 2>&1 &257+ pid=$!258+ k=0259+ until grep -q "^private pages on 127.0.0.1:$PRIV_PORT" "$log" || ! kill -0 "$pid" 2>/dev/null || [ "$k" -ge 150 ]; do260+ sleep 0.1261+ k=$((k + 1))262+ done263+ if kill -0 "$pid" 2>/dev/null && grep -q "^private pages on" "$log"; then break; fi264+ kill "$pid" 2>/dev/null || true265+ n=$((n + 1))266+ [ "$n" -lt 5 ] || { cat "$log" >&2; fail "the private server did not start"; }267+ done268+ T_PIDS="$T_PIDS $pid"252269 PRIV=http://127.0.0.1:$PRIV_PORT253- wait_http "$PRIV/"254270 }255271 256272 # stop_servers: stop what the scenario started in the background so far.