156 lines
6.6 KiB
Bash
Executable file
156 lines
6.6 KiB
Bash
Executable file
#!/bin/bash
|
|
# The MIT License (MIT)
|
|
#
|
|
# Copyright (C) 2026 Scott Duensing
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to
|
|
# deal in the Software without restriction, including without limitation the
|
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
# sell copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
# IN THE SOFTWARE.
|
|
|
|
# run.sh -- the DVX package server's tests, as singemaster's are run: fixtures made, the server
|
|
# started on a port of its own with a configuration of its own, the suites run against it, the
|
|
# server stopped. Then both services in one calog process, each answering on its own port.
|
|
#
|
|
# server/test/run.sh (from anywhere; needs bin/host/dvxpkg from a DVX build, calog, and singemaster)
|
|
#
|
|
# calog and singemaster are beside this repository (../../calog and ../../singemaster from the
|
|
# server folder) unless CALOG_HOME and SINGE_HOME say where they are; CALOG is the calog program
|
|
# (CALOG_HOME/bin/calog unless it is set).
|
|
#
|
|
# CALOG_HOME=/opt/calog SINGE_HOME=/opt/singemaster server/test/run.sh
|
|
#
|
|
# Exit status 0 when every suite passed.
|
|
|
|
set -u
|
|
cd "$(dirname "$0")/.." || exit 1
|
|
CALOG_HOME=${CALOG_HOME:-$(cd ../../calog 2>/dev/null && pwd)}
|
|
CALOG=${CALOG:-$CALOG_HOME/bin/calog}
|
|
SINGE=${SINGE_HOME:-$(cd ../../singemaster 2>/dev/null && pwd)}
|
|
DVXPKG=$(cd .. && pwd)/bin/host/dvxpkg
|
|
PORT=18101
|
|
MASTER_PORT=18102
|
|
ADMIN=testoperatortoken0123456789abcdef
|
|
DATA=$(pwd)/test/data
|
|
|
|
# calog's library (its examples' web and mail servers) and singemaster's shared modules, and the
|
|
# programs the run needs: said at once when they are not where they are looked for
|
|
if [ -z "$CALOG_HOME" ] || [ ! -f "$CALOG_HOME/examples/httpd.lua" ]; then
|
|
echo "calog is not beside this repository (set CALOG_HOME)"; exit 1
|
|
fi
|
|
[ -x "$CALOG" ] || { echo "calog is not at $CALOG (set CALOG)"; exit 1; }
|
|
if [ -z "$SINGE" ] || [ ! -f "$SINGE/lib/service.lua" ]; then
|
|
echo "singemaster is not beside this repository (set SINGE_HOME)"; exit 1
|
|
fi
|
|
[ -x "$DVXPKG" ] || { echo "the package tool is not at $DVXPKG (build DVX first)"; exit 1; }
|
|
|
|
rm -rf "$DATA" && mkdir -p "$DATA/stage"
|
|
|
|
# The repository's key pair (its secret stays here, as on the operator's computer) and a publisher's
|
|
"$DVXPKG" keygen "DVX Test Repository" "$DATA/REPO" > /dev/null
|
|
"$DVXPKG" keygen "Acme Test" "$DATA/ACME" > /dev/null
|
|
|
|
# package <name> <template text> <file in the package> [key]: a .DPK in $DATA
|
|
package() {
|
|
local stage="$DATA/stage/$1"
|
|
mkdir -p "$(dirname "$stage/$3")"
|
|
printf 'contents of %s\n' "$3" > "$stage/$3"
|
|
printf '%b' "$2" > "$DATA/$1.ini"
|
|
"$DVXPKG" build "$DATA/$1.ini" "$stage" "$DATA/$1.dpk" ${4:+"$4"} > /dev/null || echo "fixture $1 failed"
|
|
}
|
|
package cards '[package]\nid = acme.cards\nname = Cards\nversion = 1.0.0\nkind = library\nsummary = Card games; for everyone\n' LIBS/ACME/CARDS/CARDS.LIB "$DATA/ACME.SEC"
|
|
package cards2 '[package]\nid = acme.cards\nname = Cards\nversion = 1.1.0\nkind = library\n' LIBS/ACME/CARDS/CARDS.LIB
|
|
package chess '[package]\nid = acme.chess\nname = Chess\nversion = 2.0\nkind = app\n[depends]\nacme.cards = 1.0\n' APPS/ACME/CHESS/CHESS.APP
|
|
package dvxown '[package]\nid = kpunch.extra\nname = Extra\nversion = 1.0.0\nkind = font\n' SHARED/FONTS/KPUNCH/EXTRA.DFN
|
|
package dice '[package]\nid = acme.dice\nname = Dice\nversion = 1.0.0\nkind = app\n' APPS/ACME/DICE/DICE.APP
|
|
package dice2 '[package]\nid = acme.dice\nname = Dice\nversion = 1.1.0\nkind = app\n' APPS/ACME/DICE/DICE.APP
|
|
package dice3 '[package]\nid = acme.dice\nname = Dice\nversion = 1.2.0\nkind = app\n' APPS/ACME/DICE/DICE.APP
|
|
printf 'not a package' > "$DATA/junk.dpk"
|
|
|
|
cat > "$DATA/dvx.conf" <<CONF
|
|
bindHost = 127.0.0.1
|
|
bindPort = $PORT
|
|
publicOrigin = http://127.0.0.1:$PORT
|
|
dataDir = $DATA/server
|
|
database = $DATA/server/dvx.db
|
|
pbkdf2Iterations = 1000
|
|
mailFrom = test@example.com
|
|
dvxpkg = $DVXPKG
|
|
repoKey = $DATA/REPO.KEY
|
|
serveContexts = 3
|
|
uploadMax = 1048576
|
|
adminToken = $ADMIN
|
|
CONF
|
|
|
|
stop() { # stop <pid>: ask, then insist, so a stuck server cannot hang the run
|
|
kill "$1" 2>/dev/null
|
|
for _ in $(seq 1 40); do
|
|
kill -0 "$1" 2>/dev/null || break
|
|
sleep 0.25
|
|
done
|
|
kill -9 "$1" 2>/dev/null
|
|
wait "$1" 2>/dev/null
|
|
}
|
|
|
|
wait_for() { # wait_for <port>
|
|
for _ in $(seq 1 40); do
|
|
curl -s -m 1 "http://127.0.0.1:$1/v1/health" > /dev/null 2>&1 && return 0
|
|
sleep 0.25
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Something already answering on a test port would be tested in place of the server under test
|
|
for port in $PORT $MASTER_PORT; do
|
|
curl -s -m 1 "http://127.0.0.1:$port/" > /dev/null 2>&1 && { echo "port $port is already in use"; exit 1; }
|
|
done
|
|
|
|
"$CALOG" dvxserver.lua -- "singe=$SINGE" "calog=$CALOG_HOME" "$DATA/dvx.conf" > "$DATA/server.log" 2>&1 &
|
|
SERVER=$!
|
|
wait_for $PORT || { echo "the server did not start:"; cat "$DATA/server.log"; stop $SERVER; exit 1; }
|
|
|
|
STATUS=0
|
|
for suite in testPackages testReview; do
|
|
printf '%-16s ' "$suite"
|
|
"$CALOG" "test/$suite.lua" -- "http://127.0.0.1:$PORT" "$DATA" "$DVXPKG" "$ADMIN" "$CALOG" "$SINGE" | grep -E "^FAIL|passed,"
|
|
[ "${PIPESTATUS[0]}" -ne 0 ] && STATUS=1
|
|
done
|
|
|
|
stop $SERVER
|
|
|
|
# Both services in one process: singemaster's master.lua and this one, each with its own settings
|
|
mkdir -p "$DATA/master"
|
|
cat > "$DATA/master.conf" <<CONF
|
|
bindHost = 127.0.0.1
|
|
bindPort = $MASTER_PORT
|
|
publicOrigin = http://127.0.0.1:$MASTER_PORT
|
|
dataDir = $DATA/master
|
|
database = $DATA/master/master.db
|
|
pbkdf2Iterations = 1000
|
|
mailFrom = test@example.com
|
|
CONF
|
|
"$CALOG" "$SINGE/master.lua" dvxserver.lua -- "singe=$SINGE" "calog=$CALOG_HOME" "master=$DATA/master.conf" "dvx=$DATA/dvx.conf" > "$DATA/both.log" 2>&1 &
|
|
BOTH=$!
|
|
printf '%-16s ' "oneProcess"
|
|
if wait_for $PORT && wait_for $MASTER_PORT \
|
|
&& curl -s "http://127.0.0.1:$PORT/v1/health" | grep -q '"dvx-packages"' \
|
|
&& curl -s "http://127.0.0.1:$MASTER_PORT/v1/health" | grep -q '"singe-master"'; then
|
|
echo "2 passed, 0 failed"
|
|
else
|
|
echo "FAIL both services in one process"; cat "$DATA/both.log"; STATUS=1
|
|
fi
|
|
stop $BOTH
|
|
exit $STATUS
|