|
#!/usr/bin/env bash |
|
|
|
real="$1" |
|
|
|
cleanup() { |
|
if [ "$real" == "real" ]; then |
|
echo "" |
|
fastly service delete --force # uses service_id in fastly.toml |
|
fi |
|
} |
|
trap 'cleanup' ERR |
|
|
|
if [ "$real" == "real" ]; then |
|
fastly compute publish --non-interactive # uses [setup] in fastly.toml to create backend resource |
|
else |
|
fastly compute serve --verbose & # run in the background |
|
bg_pid=$! # store the Fastly CLI's Process ID |
|
fi |
|
|
|
if [ "$real" == "real" ]; then |
|
service_id=$(yq eval '.service_id' fastly.toml) |
|
domain=$(fastly domain list --service-id "$service_id" --version latest --json | jq -r '.[0].Name') |
|
endpoint="https://$domain" |
|
else |
|
endpoint="http://127.0.0.1:7676" |
|
fi |
|
|
|
if [ "$real" != "real" ]; then |
|
# wait for the `serve` command to have spun up a local server |
|
server_port=7676 |
|
max_attempts=10 |
|
attempt=0 |
|
while ! nc -z localhost "$server_port"; do |
|
if (( attempt == max_attempts )); then |
|
echo "" |
|
echo "The local server did not start within the specified number of attempts." |
|
kill "$bg_pid" # terminate the Fastly CLI running `serve` command in the background |
|
sleep 2 # give just enough time for Viceroy to setup its listener |
|
kill "$(lsof -i :7676 | awk 'NR==2 {print $2}')" # terminal Viceroy (CLI might not have a chance to setup signal monitoring to terminate it yet) |
|
exit 1 |
|
fi |
|
sleep 1 |
|
(( attempt++ )) |
|
done |
|
fi |
|
|
|
# NOTE: "Fastly-Debug:1" forces the display of the `Surrogate-Control` header. |
|
# We don't set Fastly-Debug because we want to validate Surrogate-Control is omitted from the response. |
|
# |
|
# IMPORTANT: Compute doesn't strip Surrogate-Control for POST requests. |
|
# This is to support VCL service chaining where VCL needs to cache the response. |
|
# Meaning the VCL service requires the Surrogate-Control still. |
|
# The Compute team will investigate if it's possible to fix this so that a |
|
# Compute service will strip the header if not fronted by another Fastly |
|
# service. Now, although POST requests don't strip Surrogate-Control and GET |
|
# requests do, the Viceroy testing tool NEVER strips Surrogate-Control and this |
|
# appears to be related to the fact that it has no cache semantics support. |
|
|
|
function check_cacheable() { |
|
local url=$1 |
|
local needle="x-cache: HIT" |
|
retries=5 |
|
while [ "$retries" -gt 0 ]; do |
|
response=$(curl -D - -s "$url") |
|
if [[ $url == *"Surrogate-Control"* ]]; then |
|
if [[ $response == *"surrogate-control"* ]]; then |
|
echo "" |
|
echo "❌ Surrogate-Control failed to be stripped from the response for $url" |
|
echo "" |
|
fi |
|
fi |
|
if [[ $url == *"Cache-Control"* ]]; then |
|
if [[ $response != *"cache-control"* ]]; then |
|
echo "" |
|
echo "❌ Cache-Control failed to be found in the response for $url" |
|
echo "" |
|
fi |
|
fi |
|
if [[ $response == *"$needle"* ]]; then |
|
echo "" |
|
echo "✅ Found '$needle' in the response from $url" |
|
echo "" |
|
success="true" |
|
break |
|
else |
|
((retries--)) |
|
success="false" |
|
sleep 1 |
|
fi |
|
done |
|
if [ "$success" != "true" ]; then |
|
echo "" |
|
echo "❌ Failed after 5 retries to find '$needle' in the response from $url" |
|
echo "" |
|
fi |
|
} |
|
|
|
echo "" |
|
echo "Validating cacheable endpoints..." |
|
|
|
check_cacheable "$endpoint/anything/status=200" |
|
check_cacheable "$endpoint/anything/status=203" |
|
check_cacheable "$endpoint/anything/status=300" |
|
check_cacheable "$endpoint/anything/status=301" |
|
check_cacheable "$endpoint/anything/status=404" |
|
check_cacheable "$endpoint/anything/status=410" |
|
check_cacheable "$endpoint/anything/status=200?header=Cache-Control:max-age=120" |
|
check_cacheable "$endpoint/anything/status=200?header=Surrogate-Control:max-age=120" |
|
check_cacheable "$endpoint/anything/status=200?header=Surrogate-Control:max-age=240&header=Cache-Control:max-age=120" |
|
|
|
function check_uncacheable() { |
|
local url=$1 |
|
local method=${2:-"GET"} |
|
local needle="x-cache: HIT" |
|
retries=5 |
|
surrogate_error_displayed="false" |
|
cache_error_displayed="false" |
|
while [ "$retries" -gt 0 ]; do |
|
response=$(curl -X "$method" -D - -s "$url") |
|
if [[ $url == *"Surrogate-Control"* && $surrogate_error_displayed == "false" && $method != "POST" ]]; then |
|
if [[ $response == *"surrogate-control"* ]]; then |
|
echo "" |
|
echo "❌ Surrogate-Control failed to be stripped from the response for $method $url" |
|
echo "" |
|
surrogate_error_displayed="true" |
|
fi |
|
fi |
|
if [[ $url == *"Cache-Control"* && $cache_error_displayed == "false" ]]; then |
|
if [[ $response != *"cache-control"* ]]; then |
|
echo "" |
|
echo "❌ Cache-Control failed to be found in the response for $method $url" |
|
echo "" |
|
cache_error_displayed="true" |
|
fi |
|
fi |
|
if [[ $response == *"$needle"* ]]; then |
|
echo "" |
|
echo "❌ Found '$needle' in the response from $method $url" |
|
echo "" |
|
success="false" |
|
break |
|
else |
|
((retries--)) |
|
success="true" |
|
sleep 1 |
|
fi |
|
done |
|
if [ "$success" == "true" ]; then |
|
echo "" |
|
echo "✅ After 5 retries '$needle' was NOT found in the response from $method $url" |
|
echo "" |
|
fi |
|
} |
|
|
|
echo "Validating uncacheable endpoints..." |
|
|
|
check_uncacheable "$endpoint/anything/status=200?header=Set-Cookie:foo=bar" |
|
check_uncacheable "$endpoint/anything/status=200?header=Cache-Control:no-store" |
|
check_uncacheable "$endpoint/anything/status=200?header=Cache-Control:private" |
|
check_uncacheable "$endpoint/anything/status=200?header=Surrogate-Control:no-store" |
|
check_uncacheable "$endpoint/anything/status=200?header=Surrogate-Control:private" |
|
check_uncacheable "$endpoint/anything/status=200" "POST" |
|
check_uncacheable "$endpoint/anything/status=200?header=Cache-Control:max-age=120" "POST" |
|
check_uncacheable "$endpoint/anything/status=200?header=Surrogate-Control:max-age=120" "POST" |
|
check_uncacheable "$endpoint/anything/status=200?header=Surrogate-Control:max-age=240&header=Cache-Control:max-age=120" "POST" |
|
check_uncacheable "$endpoint/anything/status=302" # https://www.fastly.com/documentation/reference/vcl/variables/backend-response/beresp-cacheable/ suggested this was cacheable, but it's not |
|
check_uncacheable "$endpoint/anything/status=400" |
|
check_uncacheable "$endpoint/anything/status=500" |
|
check_uncacheable "$endpoint/anything/status=503" |
|
|
|
if [ "$real" != "real" ]; then |
|
kill "$bg_pid" # terminate the Fastly CLI running `serve` command in the background |
|
kill "$(lsof -i :7676 | awk 'NR==2 {print $2}')" 2>/dev/null # terminal Viceroy if still running (although CLI should have signals setup at this point and would have terminated it already) |
|
fi |
|
|
|
cleanup |
|
|
|
# NOTE: 3600s (1hr) is XQD's default TTL (VCL services have a 2min TTL). |