Add end to end tests

This commit is contained in:
programmer programmer 2022-10-20 01:32:33 +02:00
parent 4f38526dfb
commit be6e2a9540
7 changed files with 429 additions and 0 deletions

5
tests/default.toml Normal file
View File

@ -0,0 +1,5 @@
[qbittorrent]
host = "127.0.0.1" # qbittorrent webui-api hostname/ip
port = $FREEPORT # qbittorrent webui-api port
login = "admin" # qbittorrent webui-api user
password = "adminadmin" # qbittorrent webui-api password

85
tests/qbittorrent-nox.sh Executable file
View File

@ -0,0 +1,85 @@
#! /usr/bin/env bash
# qbittorrent-nox.sh start|stop DIR PORT
# DIR will contain the qbittorrent-nox profile, as well as "pid" and "qBottorrent.log"
# PORT configures port for qbittorrent-nox web API
# Wait for qBittorrent WEB API to come online at address $1
# waitforqBittorrentStart "http://localhost:1312"
function waitforqBittorrentStart() {
#set +x
TIMESTAMP=$(date +%s)
END=$((TIMESTAMP+10))
ERR=0
while true; do
NEWTIMESTAMP=$(date +%s)
if [ $NEWTIMESTAMP -gt $END ]; then
ERR=1
break
fi
if curl --silent "$1" 2>&1 > /dev/null; then
break
else
sleep 0.1
fi
done
return $ERR
}
# Wait for qBittorrent to be done cleanly exiting
# Necessary because otherwise it will leave temporary files behind!
# waitforQbittorrentStop 1234
function waitforqBittorrentStop() {
TIMESTAMP=$(date +%s)
END=$((TIMESTAMP+15))
ERR=0
while true; do
NEWTIMESTAMP=$(date +%s)
if [ $NEWTIMESTAMP -gt $END ]; then
ERR=1
break
fi
if ! ps x | grep -P "^\s+$PID\s+" 2>&1 > /dev/null; then
# process died successfully
break
else
sleep 0.1
fi
done
return $ERR
}
start() {
echo "y" | qbittorrent-nox --profile="$1" --webui-port="$2" 2>&1 > "$1"/qBittorrent.log &
echo $! > "$1"/pid
if waitforqBittorrentStart "http://localhost:$2"; then
return 0
else
return 1
fi
}
stop() {
PID="$(cat "$1"/pid)"
kill $PID
if ! waitforqBittorrentStop $PID; then
echo "qBittorrent does not quit. Using SIGKILL"
kill -9 $PID
fi
}
case "$1" in
"start")
QBTNOX_DIR="$2"
QBTNOX_PORT="$3"
start "$QBTNOX_DIR" "$QBTNOX_PORT"
STATUS=$?
;;
"stop")
QBTNOX_DIR="$2"
stop "$QBTNOX_DIR"
STATUS=$?
;;
esac
exit $STATUS

44
tests/runners/local.sh Executable file
View File

@ -0,0 +1,44 @@
#! /usr/bin/bash
DEPENDENCIES=("qbittorrent-nox" "bats" "curl" "grep" "cat" "sed")
if [[ "${QBTNOX_DIR:-plz}" = "plz" ]]; then
export QBTNOX_DIR="$(mktemp -d)"
fi
ORIGDIR="$(pwd)"
cd "$(dirname "$0")"
source ../utils.sh
SUBCOMMAND="${1:-test}"
if [[ "$SUBCOMMAND" = "test" ]] && [[ "${TESTRUNNER:-plz}" = "plz" ]]; then
depsCheck
fi
export FREEPORT="$(findFreePort)"
API="http://localhost:$FREEPORT"
# Subcommand is test and checks succeeded
subcommand "$SUBCOMMAND"
STATUS=$?
if [ $STATUS -eq 0 ]; then
if [[ "$SUBCOMMAND" = "test" ]]; then
cat ../default.toml | envsubst > "$QBTNOX_DIR"/config.toml
export CFGFILE="$QBTNOX_DIR"/config.toml
if ../qbittorrent-nox.sh start "$QBTNOX_DIR" "$FREEPORT"; then
runTests "$API"
STATUS=$?
../qbittorrent-nox.sh stop "$QBTNOX_DIR"
else
echo "qBittorrent did not start"
STATUS=1
fi
fi
fi
if [[ "${TESTRUNNER:-plz}" = "plz" ]]; then
rm -R "$QBTNOX_DIR"
fi
cd "$ORIGDIR"
exit $STATUS

56
tests/runners/nix.sh Executable file
View File

@ -0,0 +1,56 @@
#! /usr/bin/env bash
DEPENDENCIES=("nix" "nix-shell")
# TODO: find grep package name for --pure environment
NIX_DEPENDENCIES=("bats" "curl" "qbittorrent-nox")
if [[ "${QBTNOX_DIR:-plz}" = "plz" ]]; then
export QBTNOX_DIR="$(mktemp -d)"
fi
ORIGDIR="$(pwd)"
cd "$(dirname "$0")"
source ../utils.sh
SUBCOMMAND="${1:-test}"
# Ensure nix shell with bats and curl... if we are running tests
if [[ "$SUBCOMMAND" = "test" ]] && [[ "${IN_NIX_SHELL:-plz}" = "plz" ]]; then
# Did test.sh perform depsCheck already?
if [[ "${TESTRUNNER:-plz}" = "plz" ]]; then
depsCheck
fi
# Are we in nix-shell already?
# TODO: redo --pure when grep dep is found
IN_NIX_SHELL=1 nix-shell -p ${NIX_DEPENDENCIES[@]} --run "\"$ORIGDIR\"/\"$0\" "$@""
exit $?
fi
export FREEPORT="$(findFreePort)"
API="http://localhost:$FREEPORT"
# Subcommand is test and checks succeeded
subcommand "$SUBCOMMAND"
STATUS=$?
if [ $STATUS -eq 0 ]; then
if [[ "$SUBCOMMAND" = "test" ]]; then
cat ../default.toml | envsubst > "$QBTNOX_DIR"/config.toml
export CFGFILE="$QBTNOX_DIR"/config.toml
if ../qbittorrent-nox.sh start "$QBTNOX_DIR" "$FREEPORT"; then
runTests "$API"
STATUS=$?
../qbittorrent-nox.sh stop "$QBTNOX_DIR"
else
echo "qBittorrent did not start"
STATUS=1
fi
fi
fi
if [[ "${TESTRUNNER:-plz}" = "plz" ]]; then
rm -R "$QBTNOX_DIR"
fi
cd "$ORIGDIR"
exit $STATUS

94
tests/test.sh Executable file
View File

@ -0,0 +1,94 @@
#! /usr/bin/env bash
# LET TEST RUNNERS KNOW WE ALREADY PERFORM CHECKS
export TESTRUNNER="YEAH"
export QBTNOX_DIR="$(mktemp -d)"
ORIGDIR="$(pwd)"
cd "$(dirname "$0")"
help() {
echo "test.sh RUNNER"
echo " Run the test suite. Requires bats and qBittorrent as dependencies. Dependencies are found by one of the following runners:"
echo " - local: the local system's \$PATH"
echo " - nix: nixos.org package repositories (requires working nix setup)"
echo " - docker: Debian stable base image + APT packages (requires working docker setup/daemon)"
echo " (default) if no explicit runner is requested, they are tried in order."
}
# FIND THE QBT BINARY
cd ..
BIN_NAME="$(grep -Po '^name = (.*)' Cargo.toml | sed 's/[" ]//g' | sed 's/name=//')"
if [ -f target/release/$BIN_NAME ]; then
cargo build --release
export BIN_PATH="$(realpath target/release/"$BIN_NAME")"
else
cargo build
export BIN_PATH="$(realpath target/debug/"$BIN_NAME")"
fi
echo "Using build $BIN_PATH"
cd tests
SUCCESS=0
RUNNER="${1:-default}"
shift
case "$RUNNER" in
"--help"|"-h"|"help")
help
;;
# "docker")
# echo "Running tests under: docker ("$QBTNOX_DIR")"
# if ./runners/docker.sh deps-check; then
# ./runners/docker.sh test
# SUCCESS=$?
# else
# SUCCESS=1
# fi
# ;;
"nix")
echo "Running tests under: nix ("$QBTNOX_DIR")"
if ./runners/nix.sh deps-check; then
./runners/nix.sh test
SUCCESS=$?
else
SUCCESS=1
fi
;;
"local")
echo "Running tests under: local ("$QBTNOX_DIR")"
if ./runners/.local.sh deps-check; then
./runners/local.sh test
SUCCESS=$?
else
SUCCESS=1
fi
;;
*)
echo "Autodiscovery for runner"
if ./runners/local.sh deps-check; then
echo "Running tests under: local ("$QBTNOX_DIR")"
./runners/local.sh test
SUCCESS=$?
elif ./runners/nix.sh deps-check; then
echo "Running tests under: nix ("$QBTNOX_DIR")"
./runners/nix.sh test
SUCCESS=$?
# elif ./runners/docker.sh deps-check; then
# echo "Running tests under: docker"
# ./runners/docker.sh test
# SUCCESS=$?
else
echo "Failed to find a test runner! Please setup qbittorrent-nox and bats on your system, or alternatively setup the nix package manager or the docker container manager to install them dynamically."
SUCCESS=1
fi
;;
esac
if [ -d "$QBTNOX_DIR" ]; then
rm -R "$QBTNOX_DIR"
fi
cd "$ORIGDIR"
exit $SUCCESS

51
tests/units/main.bats Normal file
View File

@ -0,0 +1,51 @@
#! /usr/bin/env bats
setup() {
bats_require_minimum_version 1.5.0
}
@test "wrong server" {
cat "$CFGFILE" | sed "s/$FREEPORT/22/" > "$CFGFILE".wrongserver.toml
cat "$CFGFILE".wrongserver.toml
run -1 "$BIN_PATH" -c "$CFGFILE".wrongserver.toml list
echo "$output"
echo "$output" | grep "request error: error sending request"
}
@test "wrong login" {
cat "$CFGFILE" | sed 's/admin/user/g' > "$CFGFILE".wronguser.toml
cat "$CFGFILE".wronguser.toml
run -1 "$BIN_PATH" -c "$CFGFILE".wronguser.toml list
echo "$output"
echo "$output" | grep "Failed to login.*user"
}
@test "empty list" {
run "$BIN_PATH" -c "$CFGFILE" list
echo "$output"
[[ "$output" = "[]" ]]
}
@test "add ISO" {
run "$BIN_PATH" -c "$CFGFILE" add --paused "magnet:?xt=urn:btih:a982743fdb1115a0e501cabb75cca85c828f9445&dn=tails-amd64-4.29-img&tr=udp%3a%2f%2ftracker.torrent.eu.org%3a451&tr=udp%3a%2f%2ftracker.coppersurfer.tk%3a6969"
echo "$output"
[[ "$output" = "" ]]
}
@test "add broken magnet" {
run -1 "$BIN_PATH" -c "$CFGFILE" add --paused "magnet:?qsdjksqdjsqdsqdsqldkqs"
echo "$output"
echo "$output" | grep "Other error:"
}
@test "get info about ISO" {
run "$BIN_PATH" -c "$CFGFILE" get "a982743fdb1115a0e501cabb75cca85c828f9445"
echo "$output"
echo "$output" | grep 'a982743fdb1115a0e501cabb75cca85c828f9445'
}
@test "non-empty list" {
run "$BIN_PATH" -c "$CFGFILE" list
echo "$output"
echo "$output" | grep "a982743fdb1115a0e501cabb75cca85c828f9445"
}

94
tests/utils.sh Executable file
View File

@ -0,0 +1,94 @@
#! /usr/bin/bash
#echo "-- " "$0" "$@" "(utils)"
function help() {
echo "$(basename "$0") SUBCOMMAND"
echo " test: run the test suite using this runner"
echo " deps-check: check for this runner's dependencies"
}
function depsCheck() {
# Explicit arguments, or $DEPENDENCIES
echo "-- Dependency checks for "$(basename "$0")""
if [ ! $# -eq 0 ]; then
DEPS=("$@")
else
DEPS=("${DEPENDENCIES[@]}")
fi
MISSING=()
for i in "${DEPS[@]}"; do
if ! command -v "$i" >/dev/null 2>&1; then
MISSING+=("$i")
fi
done
if [ ${#MISSING[@]} -gt 0 ]; then
echo "ERROR: missing dependencies: "${MISSING[@]}""
return 1
fi
}
function subcommand() {
SUBCOMMAND="${1:-test}"
#echo " Subcommand "$1" evaluated to "$SUBCOMMAND""
case "$SUBCOMMAND" in
"help"|"--help"|"-h")
help
return 1
;;
"deps-check")
depsCheck
return $?
;;
"test")
echo "Running tests from "$QBTNOX_DIR""
return $?
;;
*)
echo "$(basename "$0") ERROR: wrong subcommand "$SUBCOMMAND""
return 2
;;
esac
}
# $1 exit code
# $2 reason
# $3 orig dir to return to
function abortIfError() {
if [ ! $1 -eq 0 ]; then
cd "$ORIGDIR"
echo "$2"
#set +x
if [ $# -eq 3 ]; then
cd "$3"
fi
exit $1
fi
}
# finds a free TCP port
# https://stackoverflow.com/questions/28989069/how-to-find-a-free-tcp-port/45539101#45539101
function findFreePort() {
BASE_PORT=16998
INCREMENT=1
port=$BASE_PORT
isfree=$(netstat -taln | grep $port)
while [[ -n "$isfree" ]]; do
port=$[port+INCREMENT]
isfree=$(netstat -taln | grep $port)
done
echo "$port"
}
# runTests APIADDR
function runTests {
echo "Running tests at "$1""
if bats ../units/; then
echo "OK"
else
echo "FAIL"
fi
}