Compare commits

..

2 Commits

Author SHA1 Message Date
Xavier Roche
6e2aae251e Never let the log salvage's cleanup fail the test
dump_crawl_logs runs on the timeout path, where the caller is already
handling a failure: rm -rf can fail on Windows while the killed httrack
still holds a file, and under set -e that would abort the branch whose
whole job is to salvage the evidence.

Renumber the test to 60: #611 adds a 59 too.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-07-16 23:04:49 +02:00
Xavier Roche
a9ff9abd42 Salvage a killed crawl's logs into the Windows test artifact
A test the suite watchdog kills at 600s left nothing to diagnose it with.
local-crawl.sh sends the crawl's output to its tmpdir and hts-log.txt lives
there too, but the artifact only uploads tests/*.log, so the killed test's
entry was a single truncated line. The hard kill also skips local-crawl.sh's
cleanup trap, so the tmpdir survives on the runner and is then discarded.

Dump those logs into the test's own .log on a timeout, and clear the tmpdir so
a later timeout cannot re-report it. hts-log.txt is where "More than N seconds
passed.. giving up" lands, which is the question #605 asks of a wedge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-07-16 19:04:10 +02:00
4 changed files with 77 additions and 3 deletions

View File

@@ -158,13 +158,21 @@ jobs:
pass=0 fail=0 skip=0 failed="" skipped=""
for t in 00_runnable.test 01_engine-*.test 01_zlib-*.test \
*_local-*.test 13_crawl_proxy_https.test 58_watchdog.test; do
*_local-*.test 13_crawl_proxy_https.test 58_watchdog.test \
60_crawl-log-salvage.test; do
rc=0
run_with_timeout 600 bash "$t" >"$t.log" 2>&1 || rc=$?
case "$rc" in
0) pass=$((pass + 1)); echo "PASS $t" ;;
77) skip=$((skip + 1)) skipped="$skipped $t"; echo "SKIP $t" ;;
124) fail=$((fail + 1)) failed="$failed $t"; echo "FAIL $t (timed out, tree killed)" ;;
124)
fail=$((fail + 1)) failed="$failed $t"
echo "FAIL $t (timed out, tree killed)"
# Re-running a wedge traced would just hang again: salvage the
# killed crawl's own logs into the artifact instead.
dump_crawl_logs >>"$t.log"
tail -n 25 "$t.log" | sed 's/^/ /'
;;
*)
fail=$((fail + 1)) failed="$failed $t"
echo "FAIL $t (exit $rc)"

View File

@@ -0,0 +1,46 @@
#!/bin/bash
#
# Unit-tests dump_crawl_logs (testlib.sh): the killed test's hts-log.txt must
# reach the uploaded logs, or a Windows wedge past --max-time stays
# undiagnosable (#605).
set -euo pipefail
testdir=$(cd "$(dirname "$0")" && pwd)
# shellcheck source=tests/testlib.sh
. "${testdir}/testlib.sh"
TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/httrack_salv.XXXXXX")
export TMPDIR
trap 'rm -rf "$TMPDIR"' EXIT
fail() {
echo "FAIL: $*" >&2
exit 1
}
verdict="More than 120 seconds passed.. giving up"
# Vacuity control: with nothing left behind the assertions below cannot pass on
# ambient output.
test -z "$(dump_crawl_logs)" || fail "dumped something with no crawl tmpdir"
# A killed local-crawl.sh leaves exactly this shape.
d="${TMPDIR}/httrack_local.probe"
mkdir -p "$d/crawl"
echo "$verdict" >"$d/crawl/hts-log.txt"
echo "httrack stdout marker" >"$d/log"
# Append to an unterminated line, as a killed test's own log always ends.
art="${TMPDIR}/artifact.log"
printf '[running httrack ...] ..\t' >"$art"
dump_crawl_logs >>"$art"
grep -qF "$verdict" "$art" || fail "hts-log.txt verdict not salvaged"
grep -qF "httrack stdout marker" "$art" || fail "httrack stdout not salvaged"
grep -q '^--- .*hts-log.txt' "$art" || fail "dump glued its header onto the unterminated line"
# Cleared, so the next timing-out test cannot re-report this crawl as its own.
test ! -d "$d" || fail "salvaged tmpdir left behind"
test -z "$(dump_crawl_logs)" || fail "salvaged crawl reported twice"
echo "crawl log salvage OK"

View File

@@ -136,6 +136,7 @@ TESTS = \
55_local-chunked.test \
56_local-proxy-noleak.test \
57_local-proxy-connect.test \
58_watchdog.test
58_watchdog.test \
60_crawl-log-salvage.test
CLEANFILES = check-network_sh.cache

View File

@@ -44,6 +44,25 @@ stop_server() {
return 0
}
# Dump and clear the crawl logs a hard-killed test leaves in TMPDIR (its cleanup
# trap never ran): hts-log.txt alone records "More than N seconds passed.. giving
# up", so a wedge past --max-time is undiagnosable without it (#605).
dump_crawl_logs() {
local d f
for d in "${TMPDIR:-/tmp}"/httrack_local.*; do
test -d "$d" || continue
for f in "$d/crawl/hts-log.txt" "$d/log" "$d/log.2"; do
test -f "$f" || continue
# Leading newline: the killed test's last line has no terminator.
printf '\n--- %s (last 200 lines)\n' "$f"
tail -n 200 "$f"
done
# so a later test's dump cannot re-report this one; never fatal, the
# caller is already handling a failure and Windows may still hold a file
rm -rf "$d" || true
done
}
# Kill a backgrounded job and its whole descendant tree. POSIX: the caller must
# have put the job in its own process group (run_with_timeout does) so we signal
# the group; a bare kill would orphan the grandchildren. Windows: the tree is