Files
2026-07-13 12:32:21 +08:00

224 lines
7.2 KiB
Bash
Executable File

#!/bin/bash
# This script runs the database upgrade tests from the
# spec/05-migration directory. It uses docker compose to stand up a
# simple environment with postgres database server and a Kong node.
# The node contains the oldest supported version, the current version
# of Kong is accessed via the local virtual environment. The testing is then
# done as described in https://docs.google.com/document/d/1Df-iq5tNyuPj1UNG7bkhecisJFPswOfFqlOS3V4wXSc/edit?usp=sharing
# Normally, the testing environment and the git worktree that is
# required by this script are removed when the tests have run. By
# setting the UPGRADE_ENV_PREFIX environment variable, the docker
# compose environment's prefix can be defined. The environment will
# then not be automatically cleaned, which is useful during test
# development as it greatly speeds up test runs.
# Optionally, the test to run can be specified as a command line
# option. If it is not specified, the script will determine the tests
# to run based on the migration steps that are performed during the
# database up migration from the base to the current version.
set -e
trap "echo exiting because of error" 0
export KONG_PG_HOST=localhost
export KONG_TEST_PG_HOST=localhost
function usage() {
cat 1>&2 <<EOF
usage: $0 [ -i <venv-script> ] [ <test> ... ]
<venv-script> Script to source to set up Kong's virtual environment.
EOF
}
args=$(getopt i: $*)
if [ $? -ne 0 ]
then
usage
exit 1
fi
set -- $args
while :; do
case "$1" in
-i)
venv_script=$2
shift
shift
;;
--)
shift
break
;;
*)
usage
exit 1
;;
esac
done
TESTS=$*
ENV_PREFIX=${UPGRADE_ENV_PREFIX:-$(openssl rand -hex 8)}
COMPOSE="docker compose -p $ENV_PREFIX -f scripts/upgrade-tests/docker-compose.yml"
NETWORK_NAME=$ENV_PREFIX
OLD_CONTAINER=$ENV_PREFIX-kong_old-1
function prepare_container() {
docker exec $1 apt-get update
docker exec $1 apt-get install -y build-essential curl m4 unzip git
docker exec $1 bash -c "ln -sf /usr/local/kong/include/* /usr/include"
docker exec $1 bash -c "ln -sf /usr/local/kong/lib/* /usr/lib"
# the following two lines will not be needed on 3.11+
docker exec -u 0 $1 apt-get install -y lua5.1
docker cp scripts/upgrade-tests/luarocks-system-lua $1:/usr/local/bin/luarocks
}
function build_containers() {
# Kong version >= 3.3 moved non Bazel-built dev setup to make dev-legacy
if (( $(echo "$OLD_KONG_VERSION" | sed 's/\.//g') >= 330 )); then
old_make_target="dev-legacy"
else
old_make_target="dev"
fi
echo "Building containers"
[ -d worktree/$OLD_KONG_VERSION ] || git worktree add worktree/$OLD_KONG_VERSION $OLD_KONG_VERSION
$COMPOSE up --wait
prepare_container $OLD_CONTAINER
docker exec -w /kong $OLD_CONTAINER make $old_make_target CRYPTO_DIR=/usr/local/kong
if [ -f kong-latest.rockspec ]; then
version=$(grep -E '^\s*(major|minor|patch)\s*=' kong/meta.lua \
| sed -E 's/[^0-9]*([0-9]+).*/\1/' \
| paste -sd. -)
tmpfile=$(mktemp kong-rockspec.XXXX)
sed "s/^version *= *\".*\"/version = \"$version-0\"/" kong-latest.rockspec > "$tmpfile"
mv "$tmpfile" kong-latest.rockspec
mv kong-latest.rockspec kong-$version-0.rockspec
fi
make dev-legacy CRYPTO_DIR=/usr/local/kong
}
function initialize_test_list() {
echo "Determining tests to run"
# Prepare list of tests to run
if [ -z "$TESTS" ]
then
all_tests_file=$(mktemp)
available_tests_file=$(mktemp)
docker exec $OLD_CONTAINER kong migrations reset --yes || true
docker exec $OLD_CONTAINER kong migrations bootstrap
kong migrations status \
| jq -r '.new_migrations | .[] | (.namespace | gsub("[.]"; "/")) as $namespace | .migrations[] | "\($namespace)/\(.)_spec.lua" | gsub("^kong"; "spec/05-migration")' \
| sort > $all_tests_file
ls 2>/dev/null $(cat $all_tests_file) \
| sort > $available_tests_file
if [ "$IGNORE_MISSING_TESTS" = "1" ]
then
TESTS=$(cat $available_tests_file)
else
if ! cmp -s $available_tests_file $all_tests_file
then
echo "Not all migrations have corresponding tests, cannot continue. Missing test(s):"
echo
comm -13 $available_tests_file $all_tests_file \
| perl -pe 's/^/ /g'
echo
rm $available_tests_file $all_tests_file
exit 1
fi
TESTS=$(cat $all_tests_file)
fi
rm $available_tests_file $all_tests_file
fi
echo "Going to run:"
echo $TESTS | perl -pe 's/(^| )/\n /g'
# Make tests available in OLD container
TESTS_TAR=/tmp/upgrade-tests-$$.tar
tar cf ${TESTS_TAR} spec/upgrade_helpers.lua $TESTS
docker cp ${TESTS_TAR} ${OLD_CONTAINER}:${TESTS_TAR}
docker exec ${OLD_CONTAINER} mkdir -p /upgrade-test/bin /upgrade-test/spec
docker exec ${OLD_CONTAINER} ln -sf /kong/bin/kong /upgrade-test/bin
docker exec ${OLD_CONTAINER} bash -c "ln -sf /kong/spec/* /upgrade-test/spec"
docker exec ${OLD_CONTAINER} tar -xf ${TESTS_TAR} -C /upgrade-test
docker cp spec/helpers/http_mock ${OLD_CONTAINER}:/upgrade-test/spec/helpers
docker cp spec/helpers/http_mock.lua ${OLD_CONTAINER}:/upgrade-test/spec/helpers
rm ${TESTS_TAR}
}
function run_tests() {
# Run the tests
BUSTED_ENV="env KONG_DATABASE=$1 KONG_DNS_RESOLVER= KONG_TEST_PG_DATABASE=kong OLD_KONG_VERSION=$OLD_KONG_VERSION"
shift
set $TESTS
for TEST in $TESTS
do
docker exec $OLD_CONTAINER kong migrations reset --yes || true
docker exec $OLD_CONTAINER kong migrations bootstrap
echo
echo --------------------------------------------------------------------------------
echo Running $TEST
echo ">> Setting up tests"
docker exec -w /upgrade-test $OLD_CONTAINER $BUSTED_ENV /kong/bin/busted -t setup $TEST
echo ">> Running migrations"
kong migrations up --force
echo ">> Testing old_after_up,all_phases"
docker exec -w /upgrade-test $OLD_CONTAINER $BUSTED_ENV /kong/bin/busted -t old_after_up,all_phases $TEST
echo ">> Testing new_after_up,all_phases"
$BUSTED_ENV bin/busted -t new_after_up,all_phases $TEST
echo ">> Finishing migrations"
kong migrations finish
echo ">> Testing new_after_finish,all_phases"
$BUSTED_ENV bin/busted -t new_after_finish,all_phases $TEST
done
}
function cleanup() {
sudo git worktree remove worktree/$OLD_KONG_VERSION --force
$COMPOSE down
}
source $venv_script
# Load supported "old" versions to run migration tests against
old_versions=()
mapfile -t old_versions < "scripts/upgrade-tests/source-versions"
for old_version in "${old_versions[@]}"; do
export OLD_KONG_VERSION=$old_version
export OLD_KONG_IMAGE=kong:$OLD_KONG_VERSION-ubuntu
echo "Running tests using $OLD_KONG_VERSION as \"old version\" of Kong"
build_containers
initialize_test_list
run_tests postgres
[ -z "$UPGRADE_ENV_PREFIX" ] && cleanup
done
deactivate
trap "" 0