test: fix: migrator: multifile test
This commit is contained in:
@@ -1,5 +1,15 @@
|
|||||||
#!/bin/dash
|
#!/bin/dash
|
||||||
|
|
||||||
|
# error codes
|
||||||
|
# 1 - generic error
|
||||||
|
# 2 - ambiguous, when you try to use something that cannot be used in same time
|
||||||
|
# 3 - missing required argument / variable
|
||||||
|
# 4 -
|
||||||
|
# 5 - provided table that not exists
|
||||||
|
# 9 - argument or command not found
|
||||||
|
# 13 - program bug / unexpected system / database incompatibles
|
||||||
|
# 127 - command not found (dependency)
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
if ! command -v psql >/dev/null; then
|
if ! command -v psql >/dev/null; then
|
||||||
@@ -20,12 +30,13 @@ sha256sum() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
INHERITS_LIST=
|
INHERITS_LIST=
|
||||||
|
VARIABLE_LIST=
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
log debug "$1"
|
log debug "$1"
|
||||||
case $1 in
|
case $1 in
|
||||||
migrate|create|fetch|list|init)
|
migrate|create|fetch|list|init)
|
||||||
[ "${SUBCOMMAND+x}" ] && { printf 'ambiguous subcommand, decide %s or %s\n' "$SUBCOMMAND" "$1"; exit 1; }
|
[ "${SUBCOMMAND+x}" ] && { printf 'ambiguous subcommand, decide %s or %s\n' "$SUBCOMMAND" "$1"; exit 2; }
|
||||||
SUBCOMMAND=$1
|
SUBCOMMAND=$1
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
@@ -56,40 +67,66 @@ init() {
|
|||||||
DB_URL="$2"
|
DB_URL="$2"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--set|-v)
|
||||||
|
VARIABLE_LIST="${VARIABLE_LIST:+$VARIABLE_LIST }$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
--*|-*)
|
--*|-*)
|
||||||
printf 'init argument %s does not exists' "$1"
|
printf 'init argument %s does not exists' "$1"
|
||||||
exit 1
|
exit 9
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
printf 'init command %s does not exists' "$1"
|
printf 'init command %s does not exists' "$1"
|
||||||
exit 1
|
exit 9
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
error_handler_no_db_url
|
|
||||||
|
|
||||||
[ "${INIT_DRY_RUN+x}" ] && { printf '%s\n' "$(init_sql)"; exit; }
|
[ "${INIT_DRY_RUN+x}" ] && { printf '%s\n' "$(init_sql)"; exit; }
|
||||||
|
|
||||||
|
error_handler_no_db_url
|
||||||
|
|
||||||
psql_args="$(form_psql_args)"
|
psql_args="$(form_psql_args)"
|
||||||
|
|
||||||
|
oldIFS="$IFS"
|
||||||
|
IFS=','
|
||||||
|
check_inherits=
|
||||||
|
for table in $INHERITS_LIST; do
|
||||||
|
check_inherits="$(printf '%s\nSELECT 1 FROM %s LIMIT 1;' "$check_inherits" "$table")"
|
||||||
|
done
|
||||||
|
IFS="$oldIFS"
|
||||||
|
|
||||||
|
check_inherits=$(printf '%s\n' \
|
||||||
|
'BEGIN;' \
|
||||||
|
"$check_inherits" \
|
||||||
|
'COMMIT;')
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
if ! printf '%s' "$(init_sql)" | psql $psql_args; then
|
if ! psql $psql_args -c "$check_inherits"; then
|
||||||
log error "Migration failed: ${WHITE}$fs_migration${NC}"
|
log error "init failed: ${WHITE}one of inherits table does not exists: ${CYAN}$INHERITS_LIST"
|
||||||
return 3
|
exit 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
if ! psql $psql_args -c "$(init_sql)"; then
|
||||||
|
log error "init failed"
|
||||||
|
exit 13
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# error_handler_no_db_url()
|
# error_handler_no_db_url()
|
||||||
error_handler_no_db_url() {
|
error_handler_no_db_url() {
|
||||||
[ "${DB_URL+x}" ] || { log error "no ${WHITE}DB_URL${NC} or ${WHITE}--db-url${NC} specified"; exit 1; }
|
[ "${DB_URL+x}" ] || { log error "no ${WHITE}DB_URL${NC} or ${WHITE}--db-url${NC} specified"; exit 3; }
|
||||||
}
|
}
|
||||||
|
|
||||||
init_sql() {
|
init_sql() {
|
||||||
log debug "inherits: ${WHITE}${INHERITS_LIST}${NC}"
|
log debug "inherits: ${WHITE}${INHERITS_LIST}${NC}"
|
||||||
local create_table
|
local sql
|
||||||
create_table="$(printf '%s\n' \
|
sql="$(printf '%s\n' \
|
||||||
"BEGIN;" \
|
"BEGIN;" \
|
||||||
|
'' \
|
||||||
|
'CREATE SCHEMA IF NOT EXISTS hectic;' \
|
||||||
|
'' \
|
||||||
"CREATE DOMAIN hectic.migration_name AS TEXT CHECK (VALUE ~ '^[0-9]{15}-.*$');" \
|
"CREATE DOMAIN hectic.migration_name AS TEXT CHECK (VALUE ~ '^[0-9]{15}-.*$');" \
|
||||||
'' \
|
'' \
|
||||||
"CREATE DOMAIN hectic.sha256 AS CHAR(64) CHECK (VALUE ~ '^[0-9a-f]{64}$');" \
|
"CREATE DOMAIN hectic.sha256 AS CHAR(64) CHECK (VALUE ~ '^[0-9a-f]{64}$');" \
|
||||||
@@ -101,20 +138,22 @@ init_sql() {
|
|||||||
'END;' \
|
'END;' \
|
||||||
'$$ LANGUAGE plpgsql;' \
|
'$$ LANGUAGE plpgsql;' \
|
||||||
'' \
|
'' \
|
||||||
'CREATE TRIGGER hectic.t_sha256_lower' \
|
|
||||||
'BEFORE INSERT OR UPDATE ON hectic.migration' \
|
|
||||||
'FOR EACH ROW EXECUTE FUNCTION sha256_lower();' \
|
|
||||||
'' \
|
|
||||||
'CREATE SCHEMA IF NOT EXISTS hectic;' \
|
'CREATE SCHEMA IF NOT EXISTS hectic;' \
|
||||||
'CREATE TABLE IF NOT EXISTS hectic.migration (' \
|
'CREATE TABLE IF NOT EXISTS hectic.migration (' \
|
||||||
' id SERIAL PRIMARY KEY,' \
|
' id SERIAL PRIMARY KEY,' \
|
||||||
' name hectic.migration_name UNIQUE NOT NULL,'\
|
' name hectic.migration_name UNIQUE NOT NULL,'\
|
||||||
' hash hectic.sha256 UNIQUE NOT NULL,'\
|
' hash hectic.sha256 UNIQUE NOT NULL,'\
|
||||||
' applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()' \
|
' applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()' \
|
||||||
')' \
|
')')"
|
||||||
'COMMIT;')"
|
|
||||||
|
|
||||||
printf '%s INHERITS(%s)' "$create_table" "$INHERITS_LIST"
|
sql="$(printf '%s INHERITS(%s);\n' "$sql" "$INHERITS_LIST")"
|
||||||
|
|
||||||
|
printf '%s\n' \
|
||||||
|
"$sql" \
|
||||||
|
'CREATE TRIGGER hectic_t_sha256_lower' \
|
||||||
|
'BEFORE INSERT OR UPDATE ON hectic.migration' \
|
||||||
|
'FOR EACH ROW EXECUTE FUNCTION hectic.sha256_lower();' \
|
||||||
|
'COMMIT;'
|
||||||
}
|
}
|
||||||
|
|
||||||
[ "${SUBCOMMAND+x}" ] || { log error "no subcomand specified"; exit 1; }
|
[ "${SUBCOMMAND+x}" ] || { log error "no subcomand specified"; exit 1; }
|
||||||
@@ -187,6 +226,7 @@ migrate_to() {
|
|||||||
|
|
||||||
migrate() {
|
migrate() {
|
||||||
local fs_migrations db_migrations db_migration fs_migration psql_args var #target_migration
|
local fs_migrations db_migrations db_migration fs_migration psql_args var #target_migration
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
up|down|to)
|
up|down|to)
|
||||||
@@ -278,8 +318,8 @@ INSERT INTO hectic.migration (name) VALUES ('$escaped_name');
|
|||||||
COMMIT;
|
COMMIT;
|
||||||
SQL
|
SQL
|
||||||
then
|
then
|
||||||
log error "Migration failed: ${WHITE}$fs_migration${NC}"
|
log error "migration failed: ${WHITE}$fs_migration${NC}"
|
||||||
return 3
|
exit 4
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@@ -296,16 +336,16 @@ create() {
|
|||||||
;;
|
;;
|
||||||
--*|-*)
|
--*|-*)
|
||||||
log error "create argument $1 does not exists"
|
log error "create argument $1 does not exists"
|
||||||
exit 1
|
exit 9
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
log error "create subcommand $1 does not exists"
|
log error "create subcommand $1 does not exists"
|
||||||
exit 1
|
exit 9
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
mkdir -p "$MIGRATION_DIR" 2>/dev/null
|
[ -d "$MIGRATION_DIR" ] || mkdir -p "$MIGRATION_DIR"
|
||||||
|
|
||||||
time_stamp="$(date '+%Y%m%d%H%M%S')"
|
time_stamp="$(date '+%Y%m%d%H%M%S')"
|
||||||
name="${MIGRATION_NAME:-$(generate_word)}"
|
name="${MIGRATION_NAME:-$(generate_word)}"
|
||||||
@@ -349,8 +389,8 @@ generate_word() {
|
|||||||
printf '%s' "$w"
|
printf '%s' "$w"
|
||||||
}
|
}
|
||||||
|
|
||||||
log debug "subcommand: $SUBCOMMAND"
|
log debug "subcommand: $WHITE$SUBCOMMAND"
|
||||||
log debug "subcommand args: $REMAINING_ARS"
|
log debug "subcommand args: $WHITE$REMAINING_ARS"
|
||||||
|
|
||||||
eval "set -- $REMAINING_ARS"
|
eval "set -- $REMAINING_ARS"
|
||||||
"$SUBCOMMAND" "$@"
|
"$SUBCOMMAND" "$@"
|
||||||
|
|||||||
@@ -62,7 +62,10 @@ export DATABASE_URL
|
|||||||
log info "run test ${WHITE}${test_name}${NC}"
|
log info "run test ${WHITE}${test_name}${NC}"
|
||||||
|
|
||||||
# run test
|
# run test
|
||||||
. "${test}/run.sh"
|
mkdir './test'
|
||||||
|
cp -r "$test"/* './test/'
|
||||||
|
cd './test'
|
||||||
|
. './run.sh'
|
||||||
|
|
||||||
HECTIC_NAMESPACE=test-laucher
|
HECTIC_NAMESPACE=test-laucher
|
||||||
|
|
||||||
|
|||||||
@@ -2,63 +2,65 @@
|
|||||||
|
|
||||||
HECTIC_NAMESPACE=test-create-migration
|
HECTIC_NAMESPACE=test-create-migration
|
||||||
|
|
||||||
log notice "case: ${WHITE}first migration"
|
log notice "test case: ${WHITE}first migration"
|
||||||
if ! migrator create; then
|
if ! migrator create; then
|
||||||
log error "test failed: error on migration creation"
|
log error "test failed: ${WHITE}error on migration creation"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! [ -d ./migration ]; then
|
if ! [ -d ./migration ]; then
|
||||||
log error "test failed: migration directory not created"
|
log error "test failed: ${WHITE}migration directory not created"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 0 ]; then
|
if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 0 ]; then
|
||||||
log error "test failed: migration not created"
|
log error "test failed: ${WHITE}migration not created"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log notice "case: ${WHITE}next migration"
|
log notice "test case: ${WHITE}next migration"
|
||||||
if ! migrator create; then
|
if ! migrator create; then
|
||||||
log error "test failed: error on migration creation"
|
log error "test failed: ${WHITE}error on migration creation"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 1 ]; then
|
if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 1 ]; then
|
||||||
log error "test failed: migration not created"
|
log error "test failed: ${WHITE}migration not created"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log notice "case: ${WHITE}migration with custom name"
|
log notice "test case: ${WHITE}migration with custom name"
|
||||||
if ! migrator create --name test; then
|
if ! migrator create --name test; then
|
||||||
log error "test failed: error on migration creation"
|
log error "test failed: ${WHITE}error on migration creation"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 2 ]; then
|
if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 2 ]; then
|
||||||
log error "test failed: migration not created"
|
log error "test failed: ${WHITE}migration not created"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! find ./migration -maxdepth 1 -type f -name '*test.sql' \
|
if ! find ./migration -maxdepth 1 -type f -name '*test.sql' \
|
||||||
| grep -Eq '/[0-9]{14}-test\.sql$'; then
|
| grep -Eq '/[0-9]{14}-test\.sql$'; then
|
||||||
log eror "test failed: migration have unexpected name"
|
log eror "test failed: ${WHITE}migration have unexpected name"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log notice "case: ${WHITE}migration with custom name that contains space"
|
log notice "test case: ${WHITE}migration with custom name that contains space"
|
||||||
if ! migrator create --name 'test name'; then
|
if ! migrator create --name 'test name'; then
|
||||||
log error "test failed: error on migration creation"
|
log error "test failed: ${WHITE}error on migration creation"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 3 ]; then
|
if [ "$(find ./migration -maxdepth 1 -type f | wc -l)" -eq 3 ]; then
|
||||||
log error "test failed: migration not created"
|
log error "test failed: ${WHITE}migration not created"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! find ./migration -maxdepth 1 -type f -name '*test name.sql' \
|
if ! find ./migration -maxdepth 1 -type f -name '*test name.sql' \
|
||||||
| grep -Eq '/[0-9]{14}-test name\.sql$'; then
|
| grep -Eq '/[0-9]{14}-test name\.sql$'; then
|
||||||
log eror "test failed: migration have unexpected name"
|
log eror "test failed: ${WHITE}migration have unexpected name"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log notice "test passed"
|
log notice "test passed"
|
||||||
|
|||||||
@@ -2,17 +2,57 @@
|
|||||||
|
|
||||||
HECTIC_NAMESPACE=test-init-migrator
|
HECTIC_NAMESPACE=test-init-migrator
|
||||||
|
|
||||||
log info "hectic.migration table inheritance"
|
### CASE 1
|
||||||
|
log notice "test case: ${WHITE}table inherit tables that not exists"
|
||||||
|
|
||||||
if ! migration_table_sql="$(migrator --inherits tablename --inherits 'table name' init --dry-run)"; then
|
if ! migration_table_sql="$(migrator --inherits tablename --inherits 'table name' init --dry-run)"; then
|
||||||
log error "test failed: error on migration table init dry run"
|
log error "test failed: ${WHITE}error on migration table init dry run"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf '%s' "$migration_table_sql" | grep -Eq 'INHERITS[[:space:]]*\([[:space:]]*"tablename"[[:space:]]*,[[:space:]]*"table name"[[:space:]]*\)' ||
|
printf '%s' "$migration_table_sql" | grep -Eq 'INHERITS[[:space:]]*\([[:space:]]*"tablename"[[:space:]]*,[[:space:]]*"table name"[[:space:]]*\)' ||
|
||||||
{ log error "not correct migration table inherits"; exit 1; }
|
{ log error "test failed: ${WHITE}not correct migration table inherits"; exit 1; }
|
||||||
|
|
||||||
log info "init"
|
### CASE 2
|
||||||
if ! migrator --inherits tablename --inherits 'table name' init; then
|
log notice "test case: ${WHITE}error: table inherit tables that not exists"
|
||||||
log error "test failed: error on init sql"
|
|
||||||
|
set +e
|
||||||
|
migrator --inherits tablename --inherits 'table name' init --db-url "$DATABASE_URL"
|
||||||
|
error_code=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$error_code" = 0 ]; then
|
||||||
|
log error "test failed: ${WHITE}no error handler"
|
||||||
|
exit 1
|
||||||
|
elif [ "$error_code" != 5 ]; then
|
||||||
|
log error "test failed: ${WHITE}unexpected error code"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf 'SELECT * FROM hectic.migration' | psql -v ON_ERROR_STOP=1 "$DATABASE_URL"
|
### CASE 3
|
||||||
|
log notice "test case: ${WHITE}error: not provided --db-url"
|
||||||
|
set +e
|
||||||
|
migrator --inherits tablename --inherits 'table name' init
|
||||||
|
error_code=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$error_code" = 0 ]; then
|
||||||
|
log error "test failed: ${WHITE}no error handler"
|
||||||
|
exit 1
|
||||||
|
elif [ "$error_code" != 3 ]; then
|
||||||
|
log error "test failed: ${WHITE}unexpected error code"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
### CASE 4
|
||||||
|
log notice "test case: ${WHITE}normal init"
|
||||||
|
|
||||||
|
psql "$DATABASE_URL" -c 'CREATE TABLE "table name"(); CREATE TABLE tablename();'
|
||||||
|
|
||||||
|
if ! migrator --inherits tablename --inherits 'table name' init --db-url "$DATABASE_URL"; then
|
||||||
|
log error "test failed: ${WHITE}error on init sql"
|
||||||
|
fi
|
||||||
|
|
||||||
|
psql -v ON_ERROR_STOP=1 "$DATABASE_URL" -c 'SELECT * FROM hectic.migration'
|
||||||
|
|
||||||
|
log notice "test passed"
|
||||||
|
|||||||
@@ -2,4 +2,15 @@
|
|||||||
|
|
||||||
HECTIC_NAMESPACE=test-migration-list
|
HECTIC_NAMESPACE=test-migration-list
|
||||||
|
|
||||||
#migrator list
|
log notice "test case: ${WHITE}getting list of local migrations"
|
||||||
|
if ! list="$(migrator list)"; then
|
||||||
|
log error "test failed: ${WHITE}error during execution"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ls
|
||||||
|
ls migration
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
log notice "test passed"
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
HECTIC_NAMESPACE=test-missing-psql
|
HECTIC_NAMESPACE=test-missing-psql
|
||||||
|
|
||||||
|
log notice "test case: ${WHITE}error: run migrator without postgresql tools installed"
|
||||||
|
|
||||||
# remove psql from $PATH
|
# remove psql from $PATH
|
||||||
dir=$(dirname -- "$(command -v psql)")
|
dir=$(dirname -- "$(command -v psql)")
|
||||||
PATH=$(printf '%s' "$PATH" | awk -v RS=: -v ORS=: -v d="$dir" '$0!=d{print}')
|
PATH=$(printf '%s' "$PATH" | awk -v RS=: -v ORS=: -v d="$dir" '$0!=d{print}')
|
||||||
@@ -18,8 +20,10 @@ set -e
|
|||||||
|
|
||||||
log debug "migrator error code: $migrator_error_code"
|
log debug "migrator error code: $migrator_error_code"
|
||||||
|
|
||||||
if [ "$migrator_error_code" -eq 127 ]; then
|
if [ "$migrator_error_code" -eq 0 ]; then
|
||||||
log notice "test passed"
|
log error "test failed: ${WHITE}no error handled"
|
||||||
else
|
elif [ "$migrator_error_code" -ne 127 ]; then
|
||||||
log error "test failed"
|
log error "test failed: ${WHITE}unexpected error code"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
log notice "test passed"
|
||||||
|
|||||||
Reference in New Issue
Block a user