Files
infix/test/env
T
Ahmed KaricandMattias Walström 8227f1bcde test: enable running infix tests from external projects
Minor adjustments have been made to enable calling infix tests from an
external project (i.e. 'make test' target).
This essentially allows running any external test (or a group of tests)
using the infix-9pm tool.
2024-08-30 12:26:39 +02:00

252 lines
5.5 KiB
Bash
Executable File

#!/bin/sh
set -e
testdir=$(dirname "$(readlink -f "$0")")
. "$testdir/.env"
usage()
{
cat <<EOF
usage: test/env [<OPTS>] -f <IMAGE> -q <QENETH-DIR> <COMMAND> [<ARGS>...]
test/env [<OPTS>] -C -t <TOPOLOGY> <COMMAND> [<ARGS>...]
Run <COMMAND> in a pre-packaged container with all the packages
required for running the test suite installed.
Options:
-b <BASE-DIR>
Use this directory as the top-level bind mount inside the container.
If not specified, Infix's top directory is used.
-c
Clean up cruft, lingering images, old containers, unused volumes.
Used by GitHub action to prevent issues with running tests.
-C
Don't containerize the command, run it directly in the current
namespaces
-D
Prefer Docker over podman. This is implied when -t is specified,
as podman does not allow the necessary network permissions to be
granted to the container
-f <IMAGE>
Specify images required for test, squashfs image is required
if testing with kernel. bios and disk image is required if
testing with bios.
-h
Show this help message
-K
Even if /dev/kvm is usable, do not map it the container. This is
useful to see how tests will run in a CI setting, where KVM is
typically not available
-p <BUNDLE>
Infix RAUC bundle to use for upgrade tests.
-q <QENETH-DIR>
Directory containing a topology.dot.in, suitable for consumption
by qeneth. A copy of this network is created, and launched. The
resulting topology is used as the default physical topology when
running tests
-r
Use random container names instead of "infamyN". Useful for the
unit tests running in CI environments which may see occasional
name clashes for "infamy0" due to race conditions.
-t <TOPOLOGY>
Rather than starting a qeneth network, attach to this existing
topology. If the command is containerized, it will be launched
in the host's network namespace
EOF
}
start_topology()
{
qenethdir="$1"
files="$*"
[ "$files" ] || { true && return; }
[ "$qenethdir" ] || { true && return; }
rm -rf "$envdir/qeneth"
cp -a "$qenethdir" "$envdir/qeneth"
# Map files in to qeneth
for f in $files; do
filename="$(basename "$f")"
file=$(readlink -f "$f")
ln -sf "$file" "$envdir/qeneth/$filename"
done
(cd "$envdir/qeneth/" && $qeneth generate && $qeneth start)
INFAMY_ARGS="$INFAMY_ARGS $envdir/qeneth/topology.dot"
cat <<EOF >"$envdir/bin/qeneth"
#!/bin/sh
set -x
cd $envdir/qeneth && exec $testdir/qeneth/qeneth "\$@"
EOF
chmod +x "$envdir/bin/qeneth"
}
name()
{
nm=infamy
id=0
if [ -n "$random" ]; then
# Let podman/docker allocate random hostname and container name
return
fi
names=$($(runner) ps -f name='infamy.*' --format '{{.Names}}')
while true; do
name="$nm$id"
unset hit
for n in $names; do
if [ "$name" = "$n" ]; then
hit=true
break;
fi
done
if [ -n "$hit" ]; then
id=$((id + 1))
continue
fi
break;
done
echo "--hostname $name --name $name"
}
# Global options
containerize=yes
[ -c /dev/kvm ] && kvm="--device=/dev/kvm"
files=
basedir="$ixdir"
while getopts "b:cCDf:hiKp:q:rt:" opt; do
case ${opt} in
b)
basedir="$OPTARG"
;;
c)
$(runner) image prune -af
$(runner) volume prune -f
$(runner) container prune -f
exit 0
;;
C)
containerize=
;;
D)
runners="docker podman"
;;
f)
files="$files $OPTARG"
;;
h)
usage && exit 0
;;
i)
interactive="--interactive"
;;
K)
kvm=
;;
p)
INFAMY_ARGS="$INFAMY_ARGS -p $OPTARG"
;;
q)
qenethdir="$OPTARG"
network="--sysctl net.ipv6.conf.all.disable_ipv6=0"
;;
r)
random=true
;;
t)
topology="$OPTARG"
network="--network host --volume $topology:$topology:ro"
runners="docker podman"
;;
*)
>&2 echo "Unknown option -$opt"
usage
exit 1
;;
esac
done
if [ "$containerize" ]; then
volumes="--volume $basedir:$basedir --workdir=$ixdir/test"
case "$(runner)" in
docker)
volumes="$volumes --env HOST_CHOWN_PATH=$ixdir/test"
volumes="$volumes --env HOST_CHOWN_UID=$(id -u)"
volumes="$volumes --env HOST_CHOWN_GID=$(id -g)"
;;
podman)
;;
esac
mkdir -p "$HOME/.infix"
touch "$HOME/.infix/.ash_history"
# shellcheck disable=SC2016
exec $(runner) run \
--cap-add=NET_RAW \
--cap-add=NET_ADMIN \
--device=/dev/net/tun \
--env PYTHONHASHSEED=${PYTHONHASHSEED:-$(shuf -i 0-$(((1 << 32) - 1)) -n 1)} \
--env VIRTUAL_ENV_DISABLE_PROMPT=yes \
--env INFAMY_EXTRA_ARGS="$INFAMY_EXTRA_ARGS" \
--env PROMPT_DIRTRIM="$ixdir" \
--env PS1="$(build_ps1)" \
--expose 9001-9010 --publish-all \
-v "$HOME/.infix/.ash_history":/root/.ash_history \
$(name) \
$interactive \
--rm \
--security-opt seccomp=unconfined \
$network \
--tty \
$volumes \
$kvm \
$INFIX_TEST \
"$0" -C "$@"
else
if [ ! -f ~/.9pm.rc ]; then
cat <<-EOF >~/.9pm.rc
# Generated by Infix env
SSH_OPTS: "-o StrictHostKeyChecking=no"
LOG_PATH: "$logdir"
EOF
fi
fi
shift $((OPTIND - 1))
if [ $# -lt 1 ]; then
usage && exit 1
fi
# shellcheck disable=SC1091
. "$envdir/bin/activate"
export PYTHONPATH="$testdir"
INFAMY_ARGS="$INFAMY_ARGS -y $envdir/yangdir"
start_topology "$qenethdir" "$files"
[ "$topology" ] && INFAMY_ARGS="$INFAMY_ARGS $topology"
export INFAMY_ARGS
if [ -n "$INFAMY_EXTRA_ARGS" ]; then
exec "$@" -o="$INFAMY_EXTRA_ARGS"
fi
exec "$@"