timescaledb/scripts/test_update_from_version.sh
Fabrízio de Royes Mello bdfac2969a Fix partial view definition on CAggs
When creating a CAgg using a column on the projection that is not part
of the `GROUP BY` clause but is functionally dependent of the primary
key of the referenced table is leading to a problem in dump/restore
because the wrong dependencies created changing the order and way dump
is generated.

Fixed it by copying the `Query` data structure of the `direct view` and
changing the necessary properties instead of creating it from scratch.
2024-07-25 09:48:53 -03:00

138 lines
5.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# During the update test the following databases will be created:
# - baseline: fresh installation of $TO_VERSION
# - updated: install $FROM_VERSION, update to $TO_VERSION
# - restored: restore from updated dump
# - repair: install $FROM_VERSION, update to $TO_VERSION and run integrity tests
set -e
set -u
FROM_VERSION=${FROM_VERSION:-$(grep '^downgrade_to_version ' version.config | awk '{ print $3 }')}
TO_VERSION=${TO_VERSION:-$(grep '^version ' version.config | awk '{ print $3 }')}
TEST_REPAIR=${TEST_REPAIR:-false}
TEST_VERSION=${TEST_VERSION:-v8}
OUTPUT_DIR=${OUTPUT_DIR:-update_test/${FROM_VERSION}_to_${TO_VERSION}}
PGDATA="${OUTPUT_DIR}/data"
# Get an unused port to allow for parallel execution
PGHOST=localhost
PGPORT=${PGPORT:-$(python -c 'import socket; s=socket.socket(); s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) ; s.bind(("", 0)); print(s.getsockname()[1]); s.close()')}
PGDATABASE=postgres
export PGHOST PGPORT PGDATABASE PGDATA
run_sql() {
local db=${2:-$PGDATABASE}
psql -X -q -d "${db}" -v ON_ERROR_STOP=1 -v VERBOSITY=verbose -v WITH_ROLES=true -v WITH_SUPERUSER=true -v WITH_CHUNK=true -c "${1}"
}
run_sql_file() {
local db=${2:-$PGDATABASE}
psql -X -d "${db}" -v ON_ERROR_STOP=1 -v VERBOSITY=verbose -v WITH_ROLES=true -v WITH_SUPERUSER=true -v WITH_CHUNK=true -f "${1}"
}
check_version() {
psql -X -c "DO \$\$BEGIN PERFORM from pg_available_extension_versions WHERE name='timescaledb' AND version='$1'; IF NOT FOUND THEN RAISE 'Version $1 not available'; END IF; END\$\$;" > /dev/null
}
trap cleanup EXIT
cleanup() {
# Save status here so that we can return the status of the last
# command in the script and not the last command of the cleanup
# function
local status="$?"
set +e # do not exit immediately on failure in cleanup handler
pg_ctl stop > /dev/null
rm -rf "${PGDATA}"
exit ${status}
}
mkdir -p "${OUTPUT_DIR}"
rm -rf "${OUTPUT_DIR}/data"
mkdir -p "${OUTPUT_DIR}/data"
UNIX_SOCKET_DIR=$(readlink -f "${OUTPUT_DIR}")
initdb > "${OUTPUT_DIR}/initdb.log" 2>&1
pg_ctl -l "${OUTPUT_DIR}/postgres.log" start -o "-c unix_socket_directories='${UNIX_SOCKET_DIR}' -c timezone=GMT -c client_min_messages=warning -c port=${PGPORT} -c max_prepared_transactions=100 -c shared_preload_libraries=timescaledb -c timescaledb.telemetry_level=off -c max_worker_processes=0"
pg_isready -t 30 > /dev/null
echo -e "\nUpdate test version ${TEST_VERSION} for ${FROM_VERSION} -> ${TO_VERSION}\n"
# caller should ensure that the versions are available
check_version "${FROM_VERSION}"
check_version "${TO_VERSION}"
run_sql_file test/sql/updates/setup.roles.sql > /dev/null
echo "Creating baseline database"
{
run_sql "CREATE DATABASE baseline;"
PGDATABASE=baseline
run_sql "CREATE EXTENSION timescaledb VERSION \"${TO_VERSION}\";"
run_sql_file test/sql/updates/pre.testing.sql
run_sql_file test/sql/updates/setup.${TEST_VERSION}.sql
run_sql "CHECKPOINT;"
run_sql_file test/sql/updates/setup.check.sql
} > "${OUTPUT_DIR}/baseline.log" 2>&1
echo "Creating updated database"
{
run_sql "CREATE DATABASE updated;" > "${OUTPUT_DIR}/updated.log"
PGDATABASE=updated
run_sql "CREATE EXTENSION timescaledb VERSION \"${FROM_VERSION}\";"
run_sql_file test/sql/updates/pre.testing.sql
run_sql_file test/sql/updates/setup.${TEST_VERSION}.sql
run_sql "CHECKPOINT;" >> "${OUTPUT_DIR}/updated.log"
run_sql "ALTER EXTENSION timescaledb UPDATE TO \"${TO_VERSION}\";"
run_sql_file test/sql/updates/setup.check.sql
} > "${OUTPUT_DIR}/updated.log" 2>&1
echo "Creating restored database"
{
run_sql "CREATE DATABASE restored;"
PGDATABASE=restored
run_sql "CREATE EXTENSION timescaledb VERSION \"${TO_VERSION}\";"
run_sql "ALTER DATABASE restored SET timescaledb.restoring='on';"
pg_dump -Fc -d updated > "${OUTPUT_DIR}/updated.dump"
pg_restore -d restored "${OUTPUT_DIR}/updated.dump"
run_sql "ALTER DATABASE restored RESET timescaledb.restoring;"
} > "${OUTPUT_DIR}/restored.log" 2>&1
run_sql_file test/sql/updates/post.${TEST_VERSION}.sql baseline > "${OUTPUT_DIR}/post.baseline.log"
run_sql_file test/sql/updates/post.${TEST_VERSION}.sql updated > "${OUTPUT_DIR}/post.updated.log"
run_sql_file test/sql/updates/post.${TEST_VERSION}.sql restored > "${OUTPUT_DIR}/post.restored.log"
if [ "${TEST_REPAIR}" = "true" ]; then
echo "Creating repair database"
{
run_sql "CREATE DATABASE repair;"
PGDATABASE=repair
run_sql "CREATE EXTENSION timescaledb VERSION \"${FROM_VERSION}\";"
run_sql_file test/sql/updates/setup.repair.sql baseline
run_sql "ALTER EXTENSION timescaledb UPDATE TO \"${TO_VERSION}\";"
run_sql_file test/sql/updates/post.repair.sql baseline
run_sql_file test/sql/updates/post.integrity_test.sql baseline
} > "${OUTPUT_DIR}/repair.log" 2>&1
fi
diff -u "${OUTPUT_DIR}/post.baseline.log" "${OUTPUT_DIR}/post.updated.log" | tee "${OUTPUT_DIR}/baseline_vs_updated.diff"
if [ ! -s "${OUTPUT_DIR}/baseline_vs_updated.diff" ]; then
rm "${OUTPUT_DIR}/baseline_vs_updated.diff"
fi
diff -u "${OUTPUT_DIR}/post.baseline.log" "${OUTPUT_DIR}/post.restored.log" | tee "${OUTPUT_DIR}/baseline_vs_restored.diff"
if [ ! -s "${OUTPUT_DIR}/baseline_vs_restored.diff" ]; then
rm "${OUTPUT_DIR}/baseline_vs_restored.diff"
fi
if [ -f "${OUTPUT_DIR}/baseline_vs_updated.diff" ] || [ -f "${OUTPUT_DIR}/baseline_vs_restored.diff" ]; then
echo "Update test for ${FROM_VERSION} -> ${TO_VERSION} failed"
exit 1
fi