From 5b1f05589d02c111ff72f955d4f507b1e10b666c Mon Sep 17 00:00:00 2001 From: yukkop Date: Mon, 17 Nov 2025 01:57:32 +0000 Subject: [PATCH] test: fix: `migrator`: multifile test --- package/migrator/migrator.sh | 90 +++++++++++++------ test/package/migrator/lauch.sh | 5 +- .../package/migrator/test/create-migration.sh | 32 +++---- test/package/migrator/test/init-migrator.sh | 54 +++++++++-- .../migrator/test/migrations-list/run.sh | 13 ++- test/package/migrator/test/missing-psql.sh | 12 ++- 6 files changed, 153 insertions(+), 53 deletions(-) diff --git a/package/migrator/migrator.sh b/package/migrator/migrator.sh index d034043..1823d27 100644 --- a/package/migrator/migrator.sh +++ b/package/migrator/migrator.sh @@ -1,5 +1,15 @@ #!/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 if ! command -v psql >/dev/null; then @@ -20,12 +30,13 @@ sha256sum() { } INHERITS_LIST= +VARIABLE_LIST= while [ $# -gt 0 ]; do log debug "$1" case $1 in 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 shift ;; @@ -56,40 +67,66 @@ init() { DB_URL="$2" shift 2 ;; + --set|-v) + VARIABLE_LIST="${VARIABLE_LIST:+$VARIABLE_LIST }$2" + shift 2 + ;; --*|-*) printf 'init argument %s does not exists' "$1" - exit 1 + exit 9 ;; *) printf 'init command %s does not exists' "$1" - exit 1 + exit 9 ;; esac done - error_handler_no_db_url - [ "${INIT_DRY_RUN+x}" ] && { printf '%s\n' "$(init_sql)"; exit; } + error_handler_no_db_url + 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 - if ! printf '%s' "$(init_sql)" | psql $psql_args; then - log error "Migration failed: ${WHITE}$fs_migration${NC}" - return 3 + if ! psql $psql_args -c "$check_inherits"; then + log error "init failed: ${WHITE}one of inherits table does not exists: ${CYAN}$INHERITS_LIST" + exit 5 + fi + + # shellcheck disable=SC2086 + if ! psql $psql_args -c "$(init_sql)"; then + log error "init failed" + exit 13 fi } # 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() { log debug "inherits: ${WHITE}${INHERITS_LIST}${NC}" - local create_table - create_table="$(printf '%s\n' \ + local sql + sql="$(printf '%s\n' \ "BEGIN;" \ + '' \ + 'CREATE SCHEMA IF NOT EXISTS hectic;' \ + '' \ "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}$');" \ @@ -101,20 +138,22 @@ init_sql() { 'END;' \ '$$ 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 TABLE IF NOT EXISTS hectic.migration (' \ ' id SERIAL PRIMARY KEY,' \ ' name hectic.migration_name UNIQUE NOT NULL,'\ ' hash hectic.sha256 UNIQUE NOT NULL,'\ ' 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; } @@ -187,6 +226,7 @@ migrate_to() { migrate() { local fs_migrations db_migrations db_migration fs_migration psql_args var #target_migration + while [ $# -gt 0 ]; do case $1 in up|down|to) @@ -278,8 +318,8 @@ INSERT INTO hectic.migration (name) VALUES ('$escaped_name'); COMMIT; SQL then - log error "Migration failed: ${WHITE}$fs_migration${NC}" - return 3 + log error "migration failed: ${WHITE}$fs_migration${NC}" + exit 4 fi done } @@ -296,16 +336,16 @@ create() { ;; --*|-*) log error "create argument $1 does not exists" - exit 1 + exit 9 ;; *) log error "create subcommand $1 does not exists" - exit 1 + exit 9 ;; esac done - mkdir -p "$MIGRATION_DIR" 2>/dev/null + [ -d "$MIGRATION_DIR" ] || mkdir -p "$MIGRATION_DIR" time_stamp="$(date '+%Y%m%d%H%M%S')" name="${MIGRATION_NAME:-$(generate_word)}" @@ -349,8 +389,8 @@ generate_word() { printf '%s' "$w" } -log debug "subcommand: $SUBCOMMAND" -log debug "subcommand args: $REMAINING_ARS" +log debug "subcommand: $WHITE$SUBCOMMAND" +log debug "subcommand args: $WHITE$REMAINING_ARS" eval "set -- $REMAINING_ARS" "$SUBCOMMAND" "$@" diff --git a/test/package/migrator/lauch.sh b/test/package/migrator/lauch.sh index 2e47d42..640d8c1 100644 --- a/test/package/migrator/lauch.sh +++ b/test/package/migrator/lauch.sh @@ -62,7 +62,10 @@ export DATABASE_URL log info "run test ${WHITE}${test_name}${NC}" # run test -. "${test}/run.sh" +mkdir './test' +cp -r "$test"/* './test/' +cd './test' +. './run.sh' HECTIC_NAMESPACE=test-laucher diff --git a/test/package/migrator/test/create-migration.sh b/test/package/migrator/test/create-migration.sh index c125194..5322b1d 100644 --- a/test/package/migrator/test/create-migration.sh +++ b/test/package/migrator/test/create-migration.sh @@ -2,63 +2,65 @@ HECTIC_NAMESPACE=test-create-migration -log notice "case: ${WHITE}first migration" +log notice "test case: ${WHITE}first migration" if ! migrator create; then - log error "test failed: error on migration creation" + log error "test failed: ${WHITE}error on migration creation" exit 1 fi if ! [ -d ./migration ]; then - log error "test failed: migration directory not created" + log error "test failed: ${WHITE}migration directory not created" exit 1 fi 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 fi -log notice "case: ${WHITE}next migration" +log notice "test case: ${WHITE}next migration" if ! migrator create; then - log error "test failed: error on migration creation" + log error "test failed: ${WHITE}error on migration creation" exit 1 fi 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 fi -log notice "case: ${WHITE}migration with custom name" +log notice "test case: ${WHITE}migration with custom name" 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 fi 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 fi if ! find ./migration -maxdepth 1 -type f -name '*test.sql' \ | 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 -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 - log error "test failed: error on migration creation" + log error "test failed: ${WHITE}error on migration creation" exit 1 fi 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 fi if ! find ./migration -maxdepth 1 -type f -name '*test name.sql' \ | 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 log notice "test passed" diff --git a/test/package/migrator/test/init-migrator.sh b/test/package/migrator/test/init-migrator.sh index 5b6d20f..0aab2db 100644 --- a/test/package/migrator/test/init-migrator.sh +++ b/test/package/migrator/test/init-migrator.sh @@ -2,17 +2,57 @@ 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 - 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 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" -if ! migrator --inherits tablename --inherits 'table name' init; then - log error "test failed: error on init sql" +### CASE 2 +log notice "test case: ${WHITE}error: table inherit tables that not exists" + +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 -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" diff --git a/test/package/migrator/test/migrations-list/run.sh b/test/package/migrator/test/migrations-list/run.sh index f0a8d6c..bceab91 100644 --- a/test/package/migrator/test/migrations-list/run.sh +++ b/test/package/migrator/test/migrations-list/run.sh @@ -2,4 +2,15 @@ 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" diff --git a/test/package/migrator/test/missing-psql.sh b/test/package/migrator/test/missing-psql.sh index cb17ada..af98166 100644 --- a/test/package/migrator/test/missing-psql.sh +++ b/test/package/migrator/test/missing-psql.sh @@ -2,6 +2,8 @@ HECTIC_NAMESPACE=test-missing-psql +log notice "test case: ${WHITE}error: run migrator without postgresql tools installed" + # remove psql from $PATH dir=$(dirname -- "$(command -v psql)") 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" -if [ "$migrator_error_code" -eq 127 ]; then - log notice "test passed" -else - log error "test failed" +if [ "$migrator_error_code" -eq 0 ]; then + log error "test failed: ${WHITE}no error handled" +elif [ "$migrator_error_code" -ne 127 ]; then + log error "test failed: ${WHITE}unexpected error code" fi + +log notice "test passed"