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
set -euxo pipefail
ipv4='192.5.0'
ipv4='192.5'
# change to this directory
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_args=''
@ -15,21 +15,23 @@ xmpp_proxy_bind=''
run_blocked=0
rebuild_image=0
ecdsa=0
while getopts ":i:drbeno" o; do
threads=1
while getopts ":it:drbeno" o; do
case "${o}" in
i)
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)
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)
build=1
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)
ecdsa=1
@ -57,8 +59,16 @@ shift $((OPTIND-1))
rm -rf /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() {
set +x
network_name="$1"
shift
num="$1"
shift
args=()
if [ "$1" == "-d" ]
then
@ -78,68 +88,89 @@ run_container() {
shift
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() {
network_name="$1"
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!
podman network rm -f xmpp-proxy-net4
podman network rm -f -t 0 "$network_name"
set -e
}
run_test() {
dir="$1"
shift
network_name="$1"
(
set -e
podman network exists xmpp-proxy-net4 && cleanup
set +exo pipefail
num="$(echo "$dir" | grep -o '^[0-9]*' | sed 's/^0//')"
# 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
cp -a ./ "/tmp/xp-logs/$dir/"
cd "/tmp/xp-logs/$dir/"
sed -i "s/192\.5\.0\./$ipv4.$num./g" *
# 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
[ -f ./prosody1.cfg.lua ] && run_container -d -v ./prosody1.cfg.lua:/etc/prosody/prosody.cfg.lua:ro 20 server1 prosody
[ -f ./prosody2.cfg.lua ] && run_container -d -v ./prosody2.cfg.lua:/etc/prosody/prosody.cfg.lua:ro 30 server2 prosody
# or the ejabberd servers
[ -f ./ejabberd1.yml ] && run_container -d -v ./ejabberd1.yml:/etc/ejabberd/ejabberd.yml:ro 20 server1 /usr/bin/ejabberdctl foreground
[ -f ./ejabberd2.yml ] && run_container -d -v ./ejabberd2.yml:/etc/ejabberd/ejabberd.yml:ro 30 server2 /usr/bin/ejabberdctl foreground
[ -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 "$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 todo: ejabberd register fails if server isn't started first, do something to avoid this hacky sleep
[ -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 "$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-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-proxy3.toml ] && run_container -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 ./nginx2.conf ] && run_container -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
[ -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 "$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 "$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 "$network_name" $num -d -v ./nginx1.conf:/etc/nginx/nginx.conf:ro 70 web1 nginx
[ -f ./nginx2.conf ] && run_container "$network_name" $num -d -v ./nginx2.conf:/etc/nginx/nginx.conf:ro 80 web2 nginx
# run the actual tests
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
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
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
[ $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')"
[ -z "$dir_pattern" ] && dir_pattern='.'
success=()
error=()
skipped=()
echo -n | tee "$success" "$error" "$skipped"
for dir in */
do
# all variables the functions use
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
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 +e
printf '%s\0' */ | xargs -0 --max-procs=$threads -n1 bash -c 'try_run "$@"' _
set +x
cat <<EOF
skipped: ${skipped[@]}
skipped: $(sort "$skipped" | tr '\n' ' ')
successful: ${success[@]}
successful: $(sort "$success" | tr '\n' ' ')
failed: ${error[@]}
failed: $(sort "$error" | tr '\n' ' ')
EOF
exit ${#error[@]}
exit $(tr ' ' '\n' < "$error" | wc -l)
)