Files
hse-2026/homework/03-http-server/tests/entrypoint.sh
T
2026-09-24 21:30:37 +03:00

129 lines
4.1 KiB
Bash

#!/bin/bash
set -u
set -o pipefail
fatal() {
printf 'harness: %s\n' "$*" >&2
exit 1
}
wait_for_docker() {
attempts=30
while [ "$attempts" -gt 0 ]; do
docker info >/dev/null 2>&1 && return 0
attempts=$((attempts - 1))
sleep 1
done
return 1
}
cleanup() {
docker ps -q --filter ancestor=hw3img | while IFS= read -r container_id; do
[ -n "$container_id" ] || continue
docker rm --force "$container_id" >/dev/null 2>&1 || true
done
}
run_tests() {
local arg
local -a original_args=("$@")
local -a test_args=(-docker -test.timeout=10m)
while (($#)); do
arg="$1"
shift
case "$arg" in
-run|-count|-timeout|-parallel|-skip)
if (($# == 0)); then
fatal "$arg requires a value"
fi
test_args+=("-test.${arg#-}" "$1")
shift
;;
-run=*|-count=*|-timeout=*|-parallel=*|-skip=*)
test_args+=("-test.${arg#-}")
;;
-v|-short|-failfast|-v=*|-short=*|-failfast=*)
test_args+=("-test.${arg#-}")
;;
-test.*|-docker)
test_args+=("$arg")
;;
*)
# Keep Go's flag handling for less common test and build options.
go test --docker -timeout 10m "${original_args[@]}"
return $?
;;
esac
done
/usr/local/bin/hw3test "${test_args[@]}"
}
validate_score_file() {
score_lines="$(grep -c '^SCORE:' "$1" || true)"
valid_score_lines="$(grep -Ec '^SCORE: [0-9]+([.][0-9]{1,2})?$' "$1" || true)"
[ "$score_lines" -eq 1 ] && [ "$valid_score_lines" -eq 1 ] \
|| fatal "test command must report exactly one valid SCORE line"
}
configure_registry_proxy() {
proxy_url="${DISTSYS_REGISTRY_PROXY_URL:-}"
ca_file="/run/distsys-registry-proxy/ca.crt"
[ -n "$proxy_url" ] || return 1
printf '%s' "$proxy_url" | grep -Eq '^http://[A-Za-z0-9.-]+(:[0-9]+)?$' || {
printf 'warning: invalid registry proxy URL; using direct Docker pulls\n' >&2
return 1
}
[ -f "$ca_file" ] && [ ! -L "$ca_file" ] || {
printf 'warning: registry proxy CA is unavailable; using direct Docker pulls\n' >&2
return 1
}
downloaded_ca="$(mktemp)" || return 1
if ! wget -q -T 5 -O "$downloaded_ca" "${proxy_url}/ca.crt" \
|| ! cmp -s "$ca_file" "$downloaded_ca"; then
rm -f "$downloaded_ca"
printf 'warning: registry proxy is unavailable or its CA differs; using direct Docker pulls\n' >&2
return 1
fi
rm -f "$downloaded_ca"
cp "$ca_file" /usr/local/share/ca-certificates/distsys-registry-proxy.crt
update-ca-certificates >/dev/null
proxy_no_proxy='localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16'
export HTTP_PROXY="$proxy_url" HTTPS_PROXY="$proxy_url" NO_PROXY="$proxy_no_proxy"
export http_proxy="$proxy_url" https_proxy="$proxy_url" no_proxy="$proxy_no_proxy"
}
configure_registry_proxy || unset HTTP_PROXY HTTPS_PROXY NO_PROXY http_proxy https_proxy no_proxy
if [ "${HW3_REQUIRE_ZRAM:-0}" = 1 ]; then
/usr/local/bin/verify-zram-scratch.sh || fatal "HW3_REQUIRE_ZRAM=1 but /hw/tests/tmp is not mounted from a zram ext4 device"
fi
# Start docker daemon
trap cleanup EXIT
dockerd-entrypoint.sh --storage-driver=overlay2 >/var/log/dockerd-entrypoint.log 2>&1 &
if ! wait_for_docker; then
tail -n 200 /var/log/dockerd-entrypoint.log >&2 || true
fatal "inner Docker daemon did not become ready"
fi
# Build server image
docker build solution -t hw3img || fatal "could not build solution image"
# Run tests
cd tests
export NO_COLOR=1
test_status=0
run_tests "$@" 2>&1 | tee tests.log || test_status=$?
validate_score_file tests.log
# Go reports a non-zero status when some grading groups fail. A valid score is
# the grading result; absence of a score remains an infrastructure failure.
if [ "$test_status" -ne 0 ]; then
printf 'harness: grading tests exited with status %s after reporting a score\n' \
"$test_status" >&2
fi