Skip to content
Merged
Show file tree
Hide file tree
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
20 changes: 20 additions & 0 deletions test/e2e/assert-compose-fixture-lifecycle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ grep -Fq 'Restoring fixture service: fixture-web' "$tmpdir/assertion-failure.log
cat "$tmpdir/assertion-failure.log" >&2
exit 1
}
grep -Fq -- '--- Varnish runtime diagnostics (VCL_Error, FetchError, Backend_health) ---' "$tmpdir/assertion-failure.log" || {
echo "FAIL: assertion failure should include a Varnish runtime diagnostics section" >&2
cat "$tmpdir/assertion-failure.log" >&2
exit 1
}
grep -Fq "No Varnish container found for Compose fixture $failure_project; skipping runtime log dump." "$tmpdir/assertion-failure.log" || {
echo "FAIL: assertion failure without Varnish should explain why runtime logs were skipped" >&2
cat "$tmpdir/assertion-failure.log" >&2
exit 1
}
assert_project_is_clean "$failure_project"

timeout_project="${project_prefix}-readiness-timeout"
Expand All @@ -122,6 +132,16 @@ grep -Fq 'GET /not-ready HTTP/1.1' "$tmpdir/readiness-timeout.log" || {
cat "$tmpdir/readiness-timeout.log" >&2
exit 1
}
grep -Fq -- '--- Varnish runtime diagnostics (VCL_Error, FetchError, Backend_health) ---' "$tmpdir/readiness-timeout.log" || {
echo "FAIL: readiness failure should include a Varnish runtime diagnostics section" >&2
cat "$tmpdir/readiness-timeout.log" >&2
exit 1
}
grep -Fq "No Varnish container found for Compose fixture $timeout_project; skipping runtime log dump." "$tmpdir/readiness-timeout.log" || {
echo "FAIL: readiness failure without Varnish should explain why runtime logs were skipped" >&2
cat "$tmpdir/readiness-timeout.log" >&2
exit 1
}
assert_project_is_clean "$timeout_project"

echo "OK: Compose fixture lifecycle contract passed"
20 changes: 1 addition & 19 deletions test/e2e/assert-hostile-unsafe-location.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ run_referenced_invalidation_case() {
assert_header_absent "${prefix}-mutation" X-Varnish-Cache-Ref-Host "${method} ${prefix} mutation"
assert_header_absent "${prefix}-mutation" X-Varnish-Cache-Ref-URL "${method} ${prefix} mutation"
if [[ "$expected_ref" == *" "* || "$expected_ref" == *$'\t'* ]]; then
assert_no_reference_ban_syntax_errors
assert_no_vcl_errors "${method} ${ref_header} reference containing unencoded whitespace"
fi

http_request "${prefix}-after" "${base_url}${target_path}"
Expand Down Expand Up @@ -190,24 +190,6 @@ run_variant_port_invalidation_case() {
echo "OK: ${variant_host} Location invalidated the bare-host target"
}

assert_no_reference_ban_syntax_errors() {
local varnish_id
local varnish_log

varnish_id="$(docker ps \
--filter "label=com.docker.compose.project=${TEST_PROJECT:?TEST_PROJECT must be set}" \
--filter "label=com.docker.compose.service=varnish" \
--format '{{.ID}}' \
| head -n 1)"
varnish_log="$(docker exec "$varnish_id" varnishlog -d -g raw -i VCL_Error)"

if grep -Fq 'ban(): Expected && between conditions' <<<"$varnish_log"; then
echo "FAIL: Varnish logged a ban syntax error for an unencoded-whitespace reference"
printf '%s\n' "$varnish_log"
exit 1
fi
}

case_id="$(openssl rand -hex 4)"
tab="$(printf '\t')"

Expand Down
59 changes: 46 additions & 13 deletions test/e2e/compose-fixture.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
set -euo pipefail

script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
source "$(dirname "$script_path")/varnish-container.sh"
fixture_project=""
fixture_compose_files=()
fixture_restore_services=()
Expand Down Expand Up @@ -44,6 +45,30 @@ fixture_compose() {
docker compose "${args[@]}" "$@"
}

fixture_dump_vsl() {
local varnish_container
echo "--- Varnish runtime diagnostics (VCL_Error, FetchError, Backend_health) ---" >&2

if ! varnish_container="$(find_varnish_container "${COMPOSE_FIXTURE_PROJECT:?}")"; then
echo "FAIL: could not find a Varnish container for Compose fixture ${COMPOSE_FIXTURE_PROJECT}" >&2
return 0
fi
if [ -z "$varnish_container" ]; then
echo "No Varnish container found for Compose fixture ${COMPOSE_FIXTURE_PROJECT}; skipping runtime log dump." >&2
return 0
fi

if ! docker exec "$varnish_container" varnishlog -d -g raw -i VCL_Error,FetchError,Backend_health >&2; then
echo "FAIL: could not read Varnish runtime logs from container ${varnish_container}" >&2
fi
}

fixture_dump_failure_diagnostics() {
echo "--- Compose service logs ---" >&2
fixture_compose logs >&2 || true
fixture_dump_vsl
}

fixture_cleanup() {
local original_status=$?
local cleanup_status=0
Expand Down Expand Up @@ -171,23 +196,26 @@ compose_fixture_run() {
local compose_file_list
compose_file_list="$(IFS=:; echo "${fixture_compose_files[*]}")"
export COMPOSE_FILE="$compose_file_list"
if [ "${#env_assignments[@]}" -gt 0 ]; then
for assignment in "${env_assignments[@]}"; do
export "$assignment"
done
fi
if [ -n "$project" ]; then
fixture_project="$project"
export COMPOSE_PROJECT_NAME="$project"
elif [ -n "${COMPOSE_PROJECT_NAME:-}" ]; then
fixture_project="$COMPOSE_PROJECT_NAME"
else
fixture_project=""
fixture_project="$(fixture_compose config --format json | python3 -c 'import json,sys; print(json.load(sys.stdin).get("name", ""))')"
fi
[ -n "$fixture_project" ] || fail "could not determine Compose fixture project name"
export COMPOSE_PROJECT_NAME="$fixture_project"
export COMPOSE_FIXTURE_ACTIVE=true
export COMPOSE_FIXTURE_PROJECT="${project:-${COMPOSE_PROJECT_NAME:-}}"
export COMPOSE_FIXTURE_PROJECT="$fixture_project"
export COMPOSE_FIXTURE_SCRIPT="$script_path"
export COMPOSE_FIXTURE_READINESS_URL="$readiness_url"
export COMPOSE_FIXTURE_TIMEOUT="$timeout"
export COMPOSE_FIXTURE_CURL_TIMEOUT="$curl_timeout"
if [ "${#env_assignments[@]}" -gt 0 ]; then
for assignment in "${env_assignments[@]}"; do
export "$assignment"
done
fi

if [ "${#restore_services[@]}" -gt 0 ]; then
fixture_restore_services=("${restore_services[@]}")
Expand All @@ -198,12 +226,12 @@ compose_fixture_run() {
if [ "${#services[@]}" -gt 0 ]; then
if ! fixture_compose up -d --build "${services[@]}"; then
echo "FAIL: Compose fixture failed to start" >&2
fixture_compose logs >&2 || true
fixture_dump_failure_diagnostics
return 1
fi
elif ! fixture_compose up -d --build; then
echo "FAIL: Compose fixture failed to start" >&2
fixture_compose logs >&2 || true
fixture_dump_failure_diagnostics
return 1
fi

Expand All @@ -219,8 +247,13 @@ compose_fixture_run() {
fi
if curl -sf --max-time "$request_timeout" "$readiness_url" >/dev/null 2>&1; then
echo "$ready_message"
"${assertion_command[@]}"
return $?
if "${assertion_command[@]}"; then
return 0
else
local assertion_status=$?
fixture_dump_failure_diagnostics
return "$assertion_status"
fi
fi
remaining=$((deadline - SECONDS))
[ "$remaining" -gt 0 ] || break
Expand All @@ -232,7 +265,7 @@ compose_fixture_run() {
done

echo "FAIL: Services did not become ready within ${timeout}s" >&2
fixture_compose logs >&2 || true
fixture_dump_failure_diagnostics
return 1
}

Expand Down
50 changes: 44 additions & 6 deletions test/e2e/http-cache-assert.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env bash

source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/varnish-container.sh"

response_headers_path() {
printf '%s/%s.headers\n' "${TEST_TMPDIR:?TEST_TMPDIR must be set}" "$1"
}
Expand Down Expand Up @@ -68,12 +70,7 @@ http_request() {
local host_header
local loopback_url

varnish_container="$(
docker ps \
--filter "label=com.docker.compose.project=${TEST_PROJECT:?TEST_PROJECT must be set}" \
--format '{{.ID}} {{.Label "com.docker.compose.service"}}' \
| awk '$2 ~ /^varnish/ { print $1; exit }'
)"
varnish_container="$(find_varnish_container "${TEST_PROJECT:?TEST_PROJECT must be set}")"

if [ -z "$varnish_container" ]; then
echo "FAIL: Could not find Varnish container for project $TEST_PROJECT"
Expand Down Expand Up @@ -137,6 +134,47 @@ assert_http_status() {
fi
}

assert_no_vcl_errors() {
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
echo "FAIL: assert_no_vcl_errors requires a context and optional fixed-string pattern" >&2
exit 2
fi

local context="$1"
local project="${TEST_PROJECT:?TEST_PROJECT must be set}"
local pattern="${2-}"
local varnish_container
local varnish_log
local matching_logs

varnish_container="$(find_varnish_container "$project")"
if [ -z "$varnish_container" ]; then
echo "FAIL: ${context}: could not find Varnish container for project ${project}" >&2
exit 1
fi

if ! varnish_log="$(docker exec "$varnish_container" varnishlog -d -g raw -i VCL_Error)"; then
echo "FAIL: ${context}: could not read Varnish VCL_Error log for project ${project}" >&2
exit 1
fi

if [ "$#" -eq 2 ]; then
matching_logs="$(printf '%s\n' "$varnish_log" | grep -F -- "$pattern" || true)"
else
matching_logs="$varnish_log"
fi

if [ -n "$matching_logs" ]; then
if [ "$#" -eq 2 ]; then
echo "FAIL: ${context}: unexpected Varnish VCL_Error records matching '${pattern}'" >&2
else
echo "FAIL: ${context}: unexpected Varnish VCL_Error records" >&2
fi
printf '%s\n' "$matching_logs" >&2
exit 1
fi
}

assert_cache_state() {
local name="$1"
local expected_state="$2"
Expand Down
10 changes: 10 additions & 0 deletions test/e2e/varnish-container.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

find_varnish_container() {
local project="$1"

docker ps \
--filter "label=com.docker.compose.project=${project}" \
--format '{{.ID}} {{.Label "com.docker.compose.service"}}' \
| awk '$2 ~ /^varnish/ { print $1; exit }'
}
Loading