Make integration/test.sh able to run tests in parallel

why oh why did I write this in bash... I do this every time... will I ever learn?
This commit is contained in:
Travis Burtrum 2022-05-21 02:41:30 -04:00
parent 56846d8e50
commit 06a4b7684c
1 changed files with 84 additions and 76 deletions

View File

@ -1,12 +1,12 @@
#!/bin/sh #!/bin/sh
set -euxo pipefail set -euxo pipefail
ipv4='192.5.0' ipv4='192.5'
# change to this directory # change to this directory
cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")"
usage() { echo "Usage: $0 [-i 192.5.0] [-d] [-r] [-b] [-n]" 1>&2; exit 1; } usage() { echo "Usage: $0 [-i 192.5] [-d] [-r] [-b] [-n]" 1>&2; exit 1; }
build=0 build=0
build_args='' build_args=''
@ -15,21 +15,23 @@ xmpp_proxy_bind=''
run_blocked=0 run_blocked=0
rebuild_image=0 rebuild_image=0
ecdsa=0 ecdsa=0
while getopts ":i:drbeno" o; do threads=1
while getopts ":it:drbeno" o; do
case "${o}" in case "${o}" in
i) i)
ipv4=${OPTARG} ipv4=${OPTARG}
echo "you must change the IP in all the containers for this to work, broken for now, exiting..." ;;
exit 1 t)
threads=${OPTARG}
;; ;;
d) d)
build=1 build=1
xmpp_proxy_bind='-v ../../target/debug/xmpp-proxy:/usr/bin/xmpp-proxy:ro' xmpp_proxy_bind="-v $PWD/../target/debug/xmpp-proxy:/usr/bin/xmpp-proxy:ro"
;; ;;
r) r)
build=1 build=1
build_args='--release' build_args='--release'
xmpp_proxy_bind='-v ../../target/release/xmpp-proxy:/usr/bin/xmpp-proxy:ro' xmpp_proxy_bind="-v $PWD/../target/release/xmpp-proxy:/usr/bin/xmpp-proxy:ro"
;; ;;
e) e)
ecdsa=1 ecdsa=1
@ -57,8 +59,16 @@ shift $((OPTIND-1))
rm -rf /tmp/xp-logs/ rm -rf /tmp/xp-logs/
mkdir -p /tmp/xp-logs/ mkdir -p /tmp/xp-logs/
success=/tmp/xp-logs/success.txt
error=/tmp/xp-logs/error.txt
skipped=/tmp/xp-logs/skipped.txt
run_container() { run_container() {
set +x set +x
network_name="$1"
shift
num="$1"
shift
args=() args=()
if [ "$1" == "-d" ] if [ "$1" == "-d" ]
then then
@ -78,68 +88,89 @@ run_container() {
shift shift
set -x set -x
podman run "${args[@]}" --rm --log-driver=k8s-file "--log-opt=path=/tmp/xp-logs/$dir-$name.log" --network xmpp-proxy-net4 --dns-search example.org --dns "$ipv4.10" --hostname "$name" --name "$name" --ip "$ipv4.$ip" "$img" "$@" podman run "${args[@]}" --rm --log-driver=k8s-file "--log-opt=path=/tmp/xp-logs/$dir-$name.log" --network "$network_name" --dns-search example.org --dns "$ipv4.$num.10" --hostname "$name" --name "$num-$name" --ip "$ipv4.$num.$ip" "$img" "$@"
} }
cleanup() { cleanup() {
network_name="$1"
set +e set +e
podman stop -i -t 0 dns server1 server2 xp1 xp2 xp3 web1 web2 scansion
podman rm -f dns server1 server2 xp1 xp2 xp3 web1 web2 scansion
# this shuts down all containers first too, handy! # this shuts down all containers first too, handy!
podman network rm -f xmpp-proxy-net4 podman network rm -f -t 0 "$network_name"
set -e set -e
} }
run_test() { run_test() {
dir="$1"
shift
network_name="$1"
( (
set -e set +exo pipefail
podman network exists xmpp-proxy-net4 && cleanup num="$(echo "$dir" | grep -o '^[0-9]*' | sed 's/^0//')"
# create the network # create the network
podman network create --disable-dns --internal --subnet $ipv4.0/24 xmpp-proxy-net4 podman network create --disable-dns --internal --subnet $ipv4.$num.0/24 "$network_name"
#podman network create --disable-dns --internal --ipv6 --subnet 2001:db8::/64 xmpp-proxy-net6 #podman network create --disable-dns --internal --ipv6 --subnet 2001:db8::/64 xmpp-proxy-net6
cp -a ./ "/tmp/xp-logs/$dir/"
cd "/tmp/xp-logs/$dir/"
sed -i "s/192\.5\.0\./$ipv4.$num./g" *
# start the dns server # start the dns server
run_container -d -v ./example.org.zone:/var/named/example.org.zone:ro 10 dns named -g -u named -d 99 run_container "$network_name" $num -d -v ./example.org.zone:/var/named/example.org.zone:ro 10 dns named -g -u named -d 99
# start the prosody servers if required # start the prosody servers if required
[ -f ./prosody1.cfg.lua ] && run_container -d -v ./prosody1.cfg.lua:/etc/prosody/prosody.cfg.lua:ro 20 server1 prosody [ -f ./prosody1.cfg.lua ] && run_container "$network_name" $num -d -v ./prosody1.cfg.lua:/etc/prosody/prosody.cfg.lua:ro 20 server1 prosody && podman exec $num-server1 prosodyctl register romeo one.example.org pass && podman exec $num-server1 prosodyctl register juliet two.example.org pass
[ -f ./prosody2.cfg.lua ] && run_container -d -v ./prosody2.cfg.lua:/etc/prosody/prosody.cfg.lua:ro 30 server2 prosody [ -f ./prosody2.cfg.lua ] && run_container "$network_name" $num -d -v ./prosody2.cfg.lua:/etc/prosody/prosody.cfg.lua:ro 30 server2 prosody && podman exec $num-server2 prosodyctl register juliet two.example.org pass
# or the ejabberd servers # or the ejabberd servers todo: ejabberd register fails if server isn't started first, do something to avoid this hacky sleep
[ -f ./ejabberd1.yml ] && run_container -d -v ./ejabberd1.yml:/etc/ejabberd/ejabberd.yml:ro 20 server1 /usr/bin/ejabberdctl foreground [ -f ./ejabberd1.yml ] && run_container "$network_name" $num -d -v ./ejabberd1.yml:/etc/ejabberd/ejabberd.yml:ro 20 server1 /usr/bin/ejabberdctl foreground && sleep 0.8 && podman exec $num-server1 ejabberdctl register romeo one.example.org pass && podman exec $num-server1 ejabberdctl register juliet two.example.org pass
[ -f ./ejabberd2.yml ] && run_container -d -v ./ejabberd2.yml:/etc/ejabberd/ejabberd.yml:ro 30 server2 /usr/bin/ejabberdctl foreground [ -f ./ejabberd2.yml ] && run_container "$network_name" $num -d -v ./ejabberd2.yml:/etc/ejabberd/ejabberd.yml:ro 30 server2 /usr/bin/ejabberdctl foreground && sleep 0.8 && podman exec $num-server2 ejabberdctl register juliet two.example.org pass
[ -f ./xmpp-proxy1.toml ] && run_container -d $xmpp_proxy_bind -v ./xmpp-proxy1.toml:/etc/xmpp-proxy/xmpp-proxy.toml:ro 40 xp1 xmpp-proxy [ -f ./xmpp-proxy1.toml ] && run_container "$network_name" $num -d $xmpp_proxy_bind -v ./xmpp-proxy1.toml:/etc/xmpp-proxy/xmpp-proxy.toml:ro 40 xp1 xmpp-proxy
[ -f ./xmpp-proxy2.toml ] && run_container -d $xmpp_proxy_bind -v ./xmpp-proxy2.toml:/etc/xmpp-proxy/xmpp-proxy.toml:ro 50 xp2 xmpp-proxy [ -f ./xmpp-proxy2.toml ] && run_container "$network_name" $num -d $xmpp_proxy_bind -v ./xmpp-proxy2.toml:/etc/xmpp-proxy/xmpp-proxy.toml:ro 50 xp2 xmpp-proxy
[ -f ./xmpp-proxy3.toml ] && run_container -d $xmpp_proxy_bind -v ./xmpp-proxy3.toml:/etc/xmpp-proxy/xmpp-proxy.toml:ro 60 xp3 xmpp-proxy [ -f ./xmpp-proxy3.toml ] && run_container "$network_name" $num -d $xmpp_proxy_bind -v ./xmpp-proxy3.toml:/etc/xmpp-proxy/xmpp-proxy.toml:ro 60 xp3 xmpp-proxy
[ -f ./nginx1.conf ] && run_container -d -v ./nginx1.conf:/etc/nginx/nginx.conf:ro 70 web1 nginx [ -f ./nginx1.conf ] && run_container "$network_name" $num -d -v ./nginx1.conf:/etc/nginx/nginx.conf:ro 70 web1 nginx
[ -f ./nginx2.conf ] && run_container -d -v ./nginx2.conf:/etc/nginx/nginx.conf:ro 80 web2 nginx [ -f ./nginx2.conf ] && run_container "$network_name" $num -d -v ./nginx2.conf:/etc/nginx/nginx.conf:ro 80 web2 nginx
# we don't care if these fail
set +e
podman exec server1 prosodyctl register romeo one.example.org pass
podman exec server1 prosodyctl register juliet two.example.org pass
podman exec server2 prosodyctl register romeo one.example.org pass
podman exec server2 prosodyctl register juliet two.example.org pass
podman exec server1 ejabberdctl register romeo one.example.org pass
podman exec server1 ejabberdctl register juliet two.example.org pass
podman exec server2 ejabberdctl register romeo one.example.org pass
podman exec server2 ejabberdctl register juliet two.example.org pass
set -e
# run the actual tests # run the actual tests
tests="$(cat tests || echo "-d .")" tests="$(cat tests || echo "-d .")"
run_container -w /scansion/ 89 scansion scansion $tests run_container "$network_name" $num -w /scansion/ 89 scansion scansion $tests
# juliet_messages_romeo.scs juliet_presence.scs romeo_messages_juliet.scs romeo_presence.scs # juliet_messages_romeo.scs juliet_presence.scs romeo_messages_juliet.scs romeo_presence.scs
cleanup
) )
} }
try_run() {
export dir="$(echo "$1" | tr -d '/')"
set +exo pipefail
echo "$dir" | grep -E "$dir_pattern" &>/dev/null
[ $? -ne 0 ] && echo "$dir" >> "$skipped" && return
set -e
cd "$dir"
[ $run_blocked -eq 0 ] && [ -e blocked ] && echo "$dir" >> "$skipped" && cd .. && return
set +e
network_name="xmpp-proxy-$dir"
run_test "$dir" "$network_name"
if [ $? -eq 0 ]
then
echo "$dir" >> "$success"
else
echo "$dir" >> "$error"
fi
# this usually takes a few seconds, but we don't care, background it and ignore output
cleanup "$network_name" >/dev/null &
set -e
cd ..
}
( (
set -euxo pipefail set -euxo pipefail
podman network exists xmpp-proxy-net4 && cleanup export -f cleanup
podman network ls | grep -o 'xmpp-proxy-[^ ]*' | xargs -n1 --no-run-if-empty cleanup || true
podman image exists "$img" || rebuild_image=1 podman image exists "$img" || rebuild_image=1
[ $rebuild_image -eq 0 ] || podman build -f Dockerfile --build-arg="ECDSA=$ecdsa" --build-arg="BUILD=$build" -t "$img" .. [ $rebuild_image -eq 0 ] || podman build -f Dockerfile --build-arg="ECDSA=$ecdsa" --build-arg="BUILD=$build" -t "$img" ..
@ -155,49 +186,26 @@ fi
dir_pattern="$(echo "$@" | tr -d '/' | sed -r 's/ +/|/g')" dir_pattern="$(echo "$@" | tr -d '/' | sed -r 's/ +/|/g')"
[ -z "$dir_pattern" ] && dir_pattern='.' [ -z "$dir_pattern" ] && dir_pattern='.'
success=() echo -n | tee "$success" "$error" "$skipped"
error=()
skipped=()
for dir in */ # all variables the functions use
do export dir_pattern ipv4 build build_args img xmpp_proxy_bind run_blocked rebuild_image ecdsa success error skipped
# all the functions
export -f try_run run_test run_container
export dir="$(echo "$dir" | tr -d '/')" set +e
printf '%s\0' */ | xargs -0 --max-procs=$threads -n1 bash -c 'try_run "$@"' _
set +e
echo "$dir" | grep -E "$dir_pattern" &>/dev/null
[ $? -ne 0 ] && skipped+=("$dir") && continue
set -e
cd "$dir"
[ $run_blocked -eq 0 ] && [ -e blocked ] && skipped+=("$dir") && cd .. && continue
set +e
run_test
if [ $? -eq 0 ]
then
success+=("$dir")
else
error+=("$dir")
cleanup
fi
set -e
cd ..
done
set +x set +x
cat <<EOF cat <<EOF
skipped: ${skipped[@]} skipped: $(sort "$skipped" | tr '\n' ' ')
successful: ${success[@]} successful: $(sort "$success" | tr '\n' ' ')
failed: ${error[@]} failed: $(sort "$error" | tr '\n' ' ')
EOF EOF
exit ${#error[@]} exit $(tr ' ' '\n' < "$error" | wc -l)
) )