diff --git a/test/isolation.sh b/test/isolation.sh index 44c67b0..e092b62 100755 --- a/test/isolation.sh +++ b/test/isolation.sh @@ -1,15 +1,24 @@ #!/bin/sh -# Untrusted HTML must neither run JavaScript nor fetch anything (CDN scripts/styles, public images, file://). -# Each probe page is rendered next to an identical page without the probe: the PNGs must be byte-identical. +# Untrusted HTML must neither run JavaScript nor fetch anything. +# - Fetches: a probe server on the same Docker network logs every request; each page below points at it, +# and the log must stay empty (a sanity request from the host proves the log works). Works offline. +# - JavaScript and file://: each page is rendered next to an identical page without the probe, +# the PNGs must be byte-identical. # Usage: test/isolation.sh [image] (default dockette/docshot:latest) IMAGE=${1:-dockette/docshot:latest} PORT=39995 -NAME=docshot-isolation -DIR=$(mktemp -d) -trap 'docker rm -f $NAME >/dev/null 2>&1; rm -rf "$DIR"' EXIT +PROBE_PORT=39996 +NET=docshot-isolation +DIR= +cleanup() { docker rm -f $NET-app $NET-probe >/dev/null 2>&1; docker network rm $NET >/dev/null 2>&1; rm -rf "$DIR"; } +trap cleanup EXIT -docker rm -f $NAME >/dev/null 2>&1 -docker run -d --name $NAME -p $PORT:3000 "$IMAGE" >/dev/null || exit 1 +cleanup +DIR=$(mktemp -d) +docker network create $NET >/dev/null || exit 1 +docker run -d --name $NET-probe --network $NET --network-alias probe -p $PROBE_PORT:8080 busybox \ + sh -c 'mkdir /www && exec httpd -f -vv -p 8080 -h /www' >/dev/null || exit 1 +docker run -d --name $NET-app --network $NET -p $PORT:3000 "$IMAGE" >/dev/null || exit 1 i=0 until curl -fsS -m 2 "http://localhost:$PORT/readyz" >/dev/null 2>&1; do i=$((i + 1)); [ $i -gt 60 ] && { echo "isolation: docshot did not become ready"; exit 1; } @@ -20,19 +29,27 @@ page() { printf '" \ + "" | render fetch +curl -fsS -m 5 "http://localhost:$PROBE_PORT/sanity" >/dev/null 2>&1 +log=$(docker logs $NET-probe 2>&1) +echo "$log" | grep -q sanity || bad probe-server "request log not working" +for r in script style import css-url img iframe object beacon fetch; do + if echo "$log" | grep -q "/$r"; then bad "fetch-$r" "docshot requested $P/$r"; else ok "fetch-$r"; fi +done + +# JavaScript, public fetch (only meaningful online) and file://: output must not change. probe() { # name, probe head, probe body, control head, control body page "$2" "$3" | render "$1-probe" page "$4" "$5" | render "$1-control" - if [ -s "$DIR/$1-control.png" ] && cmp -s "$DIR/$1-probe.png" "$DIR/$1-control.png"; then - echo "isolation: $1 ok" - else - echo "isolation: $1 FAILED (probe changed the rendered page)"; fail=1 - fi + if [ -s "$DIR/$1-control.png" ] && cmp -s "$DIR/$1-probe.png" "$DIR/$1-control.png"; then ok "$1"; else bad "$1" "probe changed the rendered page"; fi } - probe script '' '' '' '' -probe cdn-script '' '' '' '' -probe cdn-style '' '' '' '' probe remote-image '' '' '' '' probe file-iframe '' '' '' ''