From 96ba62a336c1e2dd6dba2af17d659dcdf880afc8 Mon Sep 17 00:00:00 2001 From: Matthieu Sieben Date: Thu, 2 May 2024 20:39:51 +0200 Subject: [PATCH] allow running tests without docker feat(dev-infra): allow running apps without docker chore(dev): prevent tests from running if a command fails to run (#1825) --- packages/dev-infra/_common.sh | 116 +++++++++++++++++++++++++++++----- 1 file changed, 100 insertions(+), 16 deletions(-) diff --git a/packages/dev-infra/_common.sh b/packages/dev-infra/_common.sh index 818c50a7263..2759dec2d02 100755 --- a/packages/dev-infra/_common.sh +++ b/packages/dev-infra/_common.sh @@ -1,5 +1,8 @@ #!/usr/bin/env sh +# Exit if any command fails +set -e + get_container_id() { local compose_file=$1 local service=$2 @@ -9,7 +12,7 @@ get_container_id() { fi # first line of jq normalizes for docker compose breaking change, see docker/compose#10958 - docker compose -f $compose_file ps --format json --status running \ + docker compose --file $compose_file ps --format json --status running \ | jq -sc '.[] | if type=="array" then .[] else . end' | jq -s \ | jq -r '.[]? | select(.Service == "'${service}'") | .ID' } @@ -36,8 +39,79 @@ export_redis_env() { export REDIS_HOST="127.0.0.1:6380" } -# Main entry point -main() { +pg_clear() { + local pg_uri=$1 + + for schema_name in `psql "${pg_uri}" -c "SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT LIKE 'pg_%' AND schema_name NOT LIKE 'information_schema';" -t`; do + psql "${pg_uri}" -c "DROP SCHEMA \"${schema_name}\" CASCADE;" + done +} + +pg_init() { + local pg_uri=$1 + + psql "${pg_uri}" -c "CREATE SCHEMA IF NOT EXISTS \"public\";" +} + +redis_clear() { + local redis_uri=$1 + redis-cli -u "${redis_uri}" flushall +} + +main_native() { + local services=${SERVICES} + local postgres_url_env_var=`[[ $services == *"db_test"* ]] && echo "DB_TEST_POSTGRES_URL" || echo "DB_POSTGRES_URL"` + local redis_host_env_var=`[[ $services == *"redis_test"* ]] && echo "REDIS_TEST_HOST" || echo "REDIS_HOST"` + + postgres_url="${!postgres_url_env_var}" + redis_host="${!redis_host_env_var}" + + if [ -n "${postgres_url}" ]; then + echo "Using ${postgres_url_env_var} (${postgres_url}) to connect to postgres." + pg_init "${postgres_url}" + else + echo "Postgres connection string missing did you set ${postgres_url_env_var}?" + exit 1 + fi + + if [ -n "${redis_host}" ]; then + echo "Using ${redis_host_env_var} (${redis_host}) to connect to Redis." + else + echo "Redis connection string missing did you set ${redis_host_env_var}?" + echo "Continuing without Redis..." + fi + + cleanup() { + local services=$@ + + if [ -n "${redis_host}" ] && [[ $services == *"redis_test"* ]]; then + redis_clear "redis://${redis_host}" &> /dev/null + fi + + if [ -n "${postgres_url}" ] && [[ $services == *"db_test"* ]]; then + pg_clear "${postgres_url}" &> /dev/null + fi + } + + # trap SIGINT and performs cleanup + trap "on_sigint ${services}" INT + on_sigint() { + cleanup $@ + exit $? + } + + # Run the arguments as a command + DB_POSTGRES_URL="${postgres_url}" \ + REDIS_HOST="${redis_host}" \ + "$@" + code=$? + + cleanup ${services} + + exit ${code} +} + +main_docker() { # Expect a SERVICES env var to be set with the docker service names local services=${SERVICES} @@ -47,15 +121,20 @@ main() { # whether this particular script started the container(s) started_container=false - # trap SIGINT and performs cleanup as necessary, i.e. - # taking down containers if this script started them - trap "on_sigint ${services}" INT - on_sigint() { + # performs cleanup as necessary, i.e. taking down containers + # if this script started them + cleanup() { local services=$@ echo # newline if $started_container; then - docker compose -f $compose_file rm -f --stop --volumes ${services} + docker compose --file $compose_file rm --force --stop --volumes ${services} fi + } + + # trap SIGINT and performs cleanup + trap "on_sigint ${services}" INT + on_sigint() { + cleanup $@ exit $? } @@ -71,8 +150,8 @@ main() { # if any are missing, recreate all services if $not_running; then - docker compose -f $compose_file up --wait --force-recreate ${services} started_container=true + docker compose --file $compose_file up --wait --force-recreate ${services} else echo "all services ${services} are already running" fi @@ -83,12 +162,17 @@ main() { # save return code for later code=$? - # performs cleanup as necessary, i.e. taking down containers - # if this script started them - echo # newline - if $started_container; then - docker compose -f $compose_file rm -f --stop --volumes ${services} - fi - + # performs cleanup as necessary + cleanup ${services} exit ${code} } + +# Main entry point +main() { + if ! docker ps >/dev/null 2>&1; then + echo "Docker unavailable. Running on host." + main_native $@ + else + main_docker $@ + fi +}