timescaledb/scripts/test_updates.sh
Matvey Arye 9c7191e898 Change TIMESTAMP partitioning to be completely tz-independent
Previously, for timezones w/o tz. The range_end and range_start were
defined as UTC, but the constraints on the table were written as as
the local time at the time of chunk creation. This does not work well
if timezones change over the life of the hypertable.

This change removes the dependency on local time for all timestamp
partitioning. Namely, the range_start and range_end remain as UTC
but the constraints are now always written in UTC too. Since old
constraints correctly describe the data currently in the chunks, the
update script to handle this change changes range_start and range_end
instead of the constraints.

Fixes #300.
2017-11-20 09:27:30 -05:00

149 lines
4.9 KiB
Bash
Executable File

#!/bin/bash
set -e
set -o pipefail
SCRIPT_DIR=$(dirname $0)
BASE_DIR=${PWD}/${SCRIPT_DIR}/..
PGTEST_TMPDIR=${PGTEST_TMPDIR:-$(mktemp -d 2>/dev/null || mktemp -d -t 'timescaledb_update_test')}
UPDATE_PG_PORT=${UPDATE_PG_PORT:-6432}
CLEAN_PG_PORT=${CLEAN_PG_PORT:-6433}
PG_VERSION=${PG_VERSION:-9.6.5} # Need 9.6.x version since we are
# upgrading the extension from
# versions that didn't support PG10.
UPDATE_FROM_IMAGE=${UPDATE_FROM_IMAGE:-timescale/timescaledb}
UPDATE_FROM_TAG=${UPDATE_FROM_TAG:-0.1.0}
UPDATE_TO_IMAGE=${UPDATE_TO_IMAGE:-update_test}
UPDATE_TO_TAG=${UPDATE_TO_TAG:-latest}
DO_CLEANUP=true
export PG_VERSION
while getopts "d" opt;
do
case $opt in
d)
DO_CLEANUP=false
echo "!!Debug mode: Containers and temporary directory will be left on disk"
echo
;;
esac
done
shift $((OPTIND-1))
if "$DO_CLEANUP" = "true"; then
trap cleanup EXIT
fi
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
status="$?"
set +e # do not exit immediately on failure in cleanup handler
if [ $status -eq 0 ]; then
rm -rf ${PGTEST_TMPDIR}
docker rm -vf timescaledb-orig timescaledb-clean-restore timescaledb-updated 2>/dev/null
fi
echo "Exit status is $status"
exit $status
}
docker_exec() {
# Echo to stderr
>&2 echo -e "\033[1m$1\033[0m: $2"
docker exec -it $1 /bin/bash -c "$2"
}
docker_pgcmd() {
docker_exec $1 "psql -h localhost -U postgres -d single -c \"$2\""
}
docker_pgscript() {
docker_exec $1 "psql -h localhost -U postgres -v ON_ERROR_STOP=1 -f $2"
}
docker_pgtest() {
>&2 echo -e "\033[1m$1\033[0m: $2"
docker exec $1 psql -X -v ECHO=ALL -v ON_ERROR_STOP=1 -h localhost -U postgres -d single -f $2 > ${PGTEST_TMPDIR}/$1.out || exit $?
}
docker_pgdiff() {
>&2 echo -e "\033[1m$1 vs $2\033[0m: $2"
docker_pgtest $1 $3
docker_pgtest $2 $3
echo "RUNNING: diff ${PGTEST_TMPDIR}/$1.out ${PGTEST_TMPDIR}/$2.out "
diff ${PGTEST_TMPDIR}/$1.out ${PGTEST_TMPDIR}/$2.out | tee ${PGTEST_TMPDIR}/update_test.output
}
docker_run() {
docker run -d --name $1 -v ${BASE_DIR}:/src $2 -c timezone="US/Eastern"
wait_for_pg $1
}
docker_run_vol() {
docker run -d --name $1 -v ${BASE_DIR}:/src -v $2 $3 -c timezone="US/Eastern"
wait_for_pg $1
}
wait_for_pg() {
set +e
for i in {1..10}; do
sleep 2
docker_exec $1 "pg_isready -U postgres"
if [[ $? == 0 ]] ; then
# this makes the test less flaky, although not
# ideal. Apperently, pg_isready is not always a good
# indication of whether the DB is actually ready to accept
# queries
sleep 2
set -e
return 0
fi
done
exit 1
}
echo "Using temporary directory $PGTEST_TMPDIR"
docker rm -f timescaledb-orig timescaledb-updated timescaledb-clean-restore timescaledb-clean-rerun 2>/dev/null || true
IMAGE_NAME=update_test TAG_NAME=latest bash ${SCRIPT_DIR}/docker-build.sh
docker_run timescaledb-orig ${UPDATE_FROM_IMAGE}:${UPDATE_FROM_TAG}
docker_run timescaledb-clean-restore ${UPDATE_TO_IMAGE}:${UPDATE_TO_TAG}
docker_run timescaledb-clean-rerun ${UPDATE_TO_IMAGE}:${UPDATE_TO_TAG}
CLEAN_VOLUME=$(docker inspect timescaledb-clean-restore --format='{{range .Mounts }}{{.Name}}{{end}}')
UPDATE_VOLUME=$(docker inspect timescaledb-orig --format='{{range .Mounts }}{{.Name}}{{end}}')
echo "Executing setup script on 0.1.0"
docker_pgscript timescaledb-orig /src/test/sql/updates/setup.sql
docker rm -f timescaledb-orig
docker_run_vol timescaledb-updated ${UPDATE_VOLUME}:/var/lib/postgresql/data ${UPDATE_TO_IMAGE}:${UPDATE_TO_TAG}
echo "Executing ALTER EXTENSION timescaledb UPDATE"
docker_pgcmd timescaledb-updated "ALTER EXTENSION timescaledb UPDATE"
docker_exec timescaledb-updated "pg_dump -h localhost -U postgres -Fc single > /tmp/single.sql"
docker cp timescaledb-updated:/tmp/single.sql ${PGTEST_TMPDIR}/single.sql
echo "Executing setup script on clean"
docker_pgscript timescaledb-clean-rerun /src/test/sql/updates/setup.sql
echo "Testing updated vs clean"
docker_pgdiff timescaledb-updated timescaledb-clean-rerun /src/test/sql/updates/test-rerun.sql
echo "Restoring database on clean version"
docker cp ${PGTEST_TMPDIR}/single.sql timescaledb-clean-restore:/tmp/single.sql
docker_exec timescaledb-clean-restore "createdb -h localhost -U postgres single"
docker_pgcmd timescaledb-clean-restore "ALTER DATABASE single SET timescaledb.restoring='on'"
docker_exec timescaledb-clean-restore "pg_restore -h localhost -U postgres -d single /tmp/single.sql"
docker_pgcmd timescaledb-clean-restore "ALTER DATABASE single SET timescaledb.restoring='off'"
echo "Testing restored"
docker_pgdiff timescaledb-updated timescaledb-clean-restore /src/test/sql/updates/test-0.1.1.sql