mirror of
https://github.com/xroche/httrack.git
synced 2026-07-27 11:03:13 +03:00
Compare commits
2 Commits
fix/failed
...
fix/test57
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc69161ffc | ||
|
|
42eadb8516 |
134
.github/probe.sh
vendored
Normal file
134
.github/probe.sh
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
#!/bin/bash
|
||||
# Throwaway probe v2.
|
||||
set -u
|
||||
cd "$(dirname "$0")/../tests"
|
||||
. ./testlib.sh
|
||||
|
||||
python=$(find_python)
|
||||
echo "python=$python uname=$(uname -s) bash=$BASH_VERSION rm=$(rm --version | head -1)"
|
||||
|
||||
# ---- D: can rm -rf fail AT ALL here, and does it say so? (dirty controls) ----
|
||||
hold() { # hold <dir> <mode>: a live python.exe pinning something in <dir>
|
||||
local d=$1 m=$2
|
||||
"$python" -c "
|
||||
import os,sys,time
|
||||
d,m=sys.argv[1],sys.argv[2]
|
||||
if m=='file':
|
||||
h=open(os.path.join(d,'held.log'),'w'); h.write('x'*100)
|
||||
elif m=='cwd':
|
||||
os.chdir(d)
|
||||
elif m=='mmap':
|
||||
import mmap
|
||||
h=open(os.path.join(d,'held.bin'),'w+b'); h.write(b'x'*4096); h.flush()
|
||||
mm=mmap.mmap(h.fileno(),0)
|
||||
sys.stdout.write('ready\n'); sys.stdout.flush()
|
||||
time.sleep(120)
|
||||
" "$d" "$m" &
|
||||
local p=$!
|
||||
for _ in $(seq 1 100); do
|
||||
kill -0 "$p" 2>/dev/null || break
|
||||
sleep 0.1
|
||||
done
|
||||
echo "$p"
|
||||
}
|
||||
|
||||
for m in file cwd mmap; do
|
||||
d="$TMPDIR/dirty.$m"
|
||||
mkdir -p "$d"
|
||||
p=$(hold "$d" "$m")
|
||||
sleep 1
|
||||
err=$(rm -rf "$d" 2>&1) && rc=0 || rc=$?
|
||||
printf 'D-%s: rc=%s stderr=<%s> still-there=%s\n' \
|
||||
"$m" "$rc" "$err" "$(test -e "$d" && echo yes || echo no)"
|
||||
kill -9 "$p" 2>/dev/null || true
|
||||
wait "$p" 2>/dev/null || true
|
||||
rm -rf "$d" 2>/dev/null || true
|
||||
done
|
||||
|
||||
# ---- E5b: 57's exact cleanup shape, with the REAL server, run through
|
||||
# run_with_timeout exactly like the Windows workflow does. 60 iterations.
|
||||
cat >"$TMPDIR/shape.sh" <<'EOF'
|
||||
set -euo pipefail
|
||||
. ./testlib.sh
|
||||
python=$(find_python)
|
||||
server=$(nativepath "./proxy-connect-server.py")
|
||||
tmpdir=$(mktemp -d)
|
||||
pids=
|
||||
cleanup() {
|
||||
for pid in $pids; do stop_server "$pid"; done
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
start() {
|
||||
local dir="$1" mode="$2" ports
|
||||
mkdir -p "$dir"
|
||||
ports="$dir/ports.txt"
|
||||
: >"$ports"
|
||||
"$python" "$server" "$(nativepath "$dir")" "$mode" >"$ports" 2>"$dir/server.err" &
|
||||
pids="$pids $!"
|
||||
for _ in $(seq 1 100); do
|
||||
grep -q "^ready" "$ports" 2>/dev/null && break
|
||||
sleep 0.1
|
||||
done
|
||||
proxy_port=$(awk '/^PROXY/{print $2}' "$ports")
|
||||
origin_port=$(awk '/^ORIGIN/{print $2}' "$ports")
|
||||
}
|
||||
start "$tmpdir/ok" ok
|
||||
# poke the proxy so its handler threads open proxy.log, and the origin so it
|
||||
# opens origin-headers.log -- that is what has handles out at kill time.
|
||||
for _ in 1 2 3; do
|
||||
"$python" -c "
|
||||
import socket,sys
|
||||
p=int(sys.argv[1]); o=int(sys.argv[2])
|
||||
s=socket.create_connection(('127.0.0.1',p)); s.sendall(b'CONNECT 127.0.0.1:%d HTTP/1.1\r\n\r\n'%o)
|
||||
s.recv(100); s.sendall(b'GET / HTTP/1.1\r\nHost: x\r\n\r\n'); s.recv(100)
|
||||
" "$proxy_port" "$origin_port" >/dev/null 2>&1 || true
|
||||
done
|
||||
start "$tmpdir/flood" flood
|
||||
# a mirror-sized tree, freshly written, like httrack leaves behind
|
||||
mkdir -p "$tmpdir/ok/out/hts-cache"
|
||||
i=0
|
||||
while test "$i" -lt 300; do
|
||||
printf 'ORIGIN-PAGE-564 %s' "$i" >"$tmpdir/ok/out/f$i.html"
|
||||
i=$((i + 1))
|
||||
done
|
||||
echo "OK: shape ran"
|
||||
EOF
|
||||
bad=0 codes=
|
||||
for i in $(seq 1 60); do
|
||||
out=$(run_with_timeout 120 bash "$TMPDIR/shape.sh" 2>&1) && rc=0 || rc=$?
|
||||
if test "$rc" -ne 0; then
|
||||
bad=$((bad + 1))
|
||||
codes="$codes $rc"
|
||||
test "$bad" -gt 6 || printf ' [shape #%s] rc=%s out=<%s>\n' "$i" "$rc" "$out"
|
||||
fi
|
||||
done
|
||||
echo "E5b full-shape via run_with_timeout: $bad/60 nonzero, codes:$codes"
|
||||
|
||||
# ---- F1: does the harness's own exit capture ever invent a nonzero? ----
|
||||
bad=0 codes=
|
||||
for i in $(seq 1 300); do
|
||||
run_with_timeout 60 bash -c 'trap "rm -rf /tmp/nonexistent.$$" EXIT; exit 0' && rc=0 || rc=$?
|
||||
test "$rc" -eq 0 || {
|
||||
bad=$((bad + 1))
|
||||
codes="$codes $rc"
|
||||
}
|
||||
done
|
||||
echo "F1 run_with_timeout over a trivially-zero child: $bad/300 nonzero, codes:$codes"
|
||||
|
||||
# ---- F2: same, but the child also backgrounds and reaps children ----
|
||||
bad=0 codes=
|
||||
for i in $(seq 1 150); do
|
||||
run_with_timeout 60 bash -c '
|
||||
set -euo pipefail
|
||||
d=$(mktemp -d); pids=
|
||||
for _ in 1 2; do sleep 5 & pids="$pids $!"; done
|
||||
cleanup() { for p in $pids; do kill "$p" 2>/dev/null || true; wait "$p" 2>/dev/null || true; done; rm -rf "$d"; }
|
||||
trap cleanup EXIT
|
||||
: >"$d/x"' && rc=0 || rc=$?
|
||||
test "$rc" -eq 0 || {
|
||||
bad=$((bad + 1))
|
||||
codes="$codes $rc"
|
||||
}
|
||||
done
|
||||
echo "F2 trap-with-background-reaps: $bad/150 nonzero, codes:$codes"
|
||||
22
.github/workflows/zz-probe.yml
vendored
Normal file
22
.github/workflows/zz-probe.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: zz-probe
|
||||
on:
|
||||
push:
|
||||
branches: [fix/test57-windows-cleanup]
|
||||
|
||||
jobs:
|
||||
probe:
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: probe
|
||||
shell: bash
|
||||
working-directory: tests
|
||||
run: |
|
||||
set -u
|
||||
export MSYS_NO_PATHCONV=1
|
||||
export MSYS2_ARG_CONV_EXCL='*'
|
||||
TMPDIR="$(cygpath -m "$RUNNER_TEMP")"
|
||||
export TMPDIR
|
||||
. ./testlib.sh
|
||||
bash ../.github/probe.sh
|
||||
Reference in New Issue
Block a user