Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions .github/workflows/windows-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ jobs:
platform: [x64, Win32]
configuration: [Release]
steps:
# The engine's test scripts are #!/bin/bash and the engine has no .gitattributes,
# so an autocrlf checkout would rewrite them and bash would die on $'\r'. Files
# land exactly as stored either way, which is what the Windows tooling wants too.
- name: Check out with the line endings the repos actually store
shell: pwsh
run: git config --global core.autocrlf false

- name: Checkout httrack-windows
uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -366,6 +373,97 @@ jobs:
}
if ($bad) { throw ($bad -join "`n") }
Write-Host "::notice::all three binaries report $name $want"
# The engine ships ~90 tests and not one of them has ever run on Windows -- they
# only run under `make check` on Linux/macOS. These are the offline ones: no
# network, no server, just httrack.exe driven from PATH. They are the engine's
# tests, but ours is the binary that ships, and this code has never been executed
# on this platform.
- name: Run the engine test suite (offline tests)
shell: bash
working-directory: httrack/tests
run: |
set -u
bin="$(cygpath -u "$GITHUB_WORKSPACE")/httrack-windows/WinHTTrack/bin/${{ matrix.platform }}/${{ matrix.configuration }}"
export PATH="$bin:$PATH"

# httrack.exe is a native binary, so MSYS rewrites any argument shaped like a
# POSIX path -- and a URL path is shaped exactly like one. The mime self-test was
# handed "/a/b.html" and the engine received "C:/Program Files/Git/a/b.html".
# Switch the rewriting off, and hand the tests a temp dir that is already a Windows
# path, so nothing needs translating in either direction.
export MSYS_NO_PATHCONV=1
export MSYS2_ARG_CONV_EXCL='*'
export TMPDIR="$(cygpath -m "${RUNNER_TEMP}")"
echo "TMPDIR=$TMPDIR"
command -v httrack >/dev/null || { echo "::error::httrack.exe is not on PATH ($bin)"; exit 1; }
echo "httrack: $(command -v httrack)"

pass=0; fail=0; skip=0; failed=""
for t in 00_runnable.test 01_engine-*.test 01_zlib-*.test; do
rc=0
bash "$t" >"$t.log" 2>&1 || rc=$?
case "$rc" in
0) pass=$((pass+1)); echo "PASS $t" ;;
77) skip=$((skip+1)); echo "SKIP $t -- $(tail -n 1 "$t.log")" ;;
*) fail=$((fail+1)); failed="$failed $t"
echo "FAIL $t (exit $rc)"
# Several of these assert with `test "$(httrack ...)" == "..." || exit 1`,
# which says nothing at all on failure. Re-run under a trace so the log
# holds the call that failed and what it actually printed.
bash -x "$t" >>"$t.log" 2>&1 || true
sed 's/^/ /' "$t.log" | tail -n 25 ;;
esac
done
total=$((pass + fail + skip))
echo "--- ran=$total pass=$pass fail=$fail skip=$skip ---"

# A skipped test is not a passing test. Every gate in these scripts exits 77 --
# no python3, no HTTPS, no codec -- so a suite that quietly degrades to
# "everything skipped" would otherwise report success having tested nothing.
[ "$total" -ge 45 ] || { echo "::error::only $total tests were discovered: the glob found nothing"; exit 1; }
[ "$pass" -ge 40 ] || { echo "::error::only $pass tests actually ran and passed ($skip skipped)"; exit 1; }
[ "$fail" -eq 0 ] || { echo "::error::failing tests:$failed"; exit 1; }

# The cache tests pipe stderr to /dev/null and print one word, so a failure says
# "FAIL" and nothing else. Run the two self-tests verbatim and keep everything they
# say: the engine side needs the assertion, not the verdict.
- name: Cache self-tests, verbatim
if: always()
shell: bash
working-directory: httrack/tests
run: |
bin="$(cygpath -u "$GITHUB_WORKSPACE")/httrack-windows/WinHTTrack/bin/${{ matrix.platform }}/${{ matrix.configuration }}"
export PATH="$bin:$PATH"
export MSYS_NO_PATHCONV=1
export MSYS2_ARG_CONV_EXCL='*'
export TMPDIR="$(cygpath -m "${RUNNER_TEMP}")"
command -v httrack >/dev/null || exit 0
for t in cache cache-corrupt; do
d="$TMPDIR/selftest-$t"
mkdir -p "$d"
echo "===== httrack -#test=$t $d"
httrack "-#test=$t" "$d" 2>&1 || echo "(exit $?)"
echo
done
# filterbounds prints nothing at all and the test just sees an empty string.
# An exit code tells us whether it died: 0xC00000FD is a stack overflow, and this
# self-test drives the matcher deep on purpose.
echo "===== httrack -#test=filterbounds"
httrack "-#test=filterbounds"; echo "exit=$? (139/0xC00000FD would be a stack overflow)"

echo "===== httrack -#test=sniff 'image/svg+xml' with a BOM"
printf '\xef\xbb\xbf <?xml version="1.0"?>' > "$TMPDIR/bom.txt"
httrack "-#test=sniff" 'image/svg+xml' "text:$(cat "$TMPDIR/bom.txt")" 2>&1 || echo "(exit $?)"

# A 25-line tail cannot tell a real Windows bug from a POSIX assumption in the
# test. Keep every test's whole output.
- name: Upload the test logs
if: always()
uses: actions/upload-artifact@v4
with:
name: engine-tests-${{ matrix.platform }}-${{ matrix.configuration }}
path: httrack/tests/*.log
if-no-files-found: warn

# Code signing, 1 of 2: the payload. SignPath signs an Inno installer as an opaque
# PE and cannot reach the files inside it, so sign these BEFORE ISCC packages them.
Expand Down
Loading