scripts-setup-test-db-template.sh
3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env bash
# scripts/setup-test-db.sh — 数据库重置脚本:drop + create 空库。
# schema apply 由 Flyway 在 Spring Boot 启动时自动处理(见 docs/04 技术栈 + sql/migrations/V*.sql)。
# seed 数据由测试框架负责(Spring @Sql / Flyway R__seed.sql / data.sql)。
#
# 使用场景:
# - scripts/test.sh 开头:清空库,让 Spring 启动时 Flyway 从 V1 开始重放所有 migration
# - scripts/test.sh 结尾:清空库,避免测试遗留污染下次运行
# - 手动调试时:reset 到零状态
#
# 防护:本脚本只允许在本地 host + 测试库名上执行;非预期目标会被拒绝,
# 避免 .env.local 误指向 staging/prod 时触发不可逆 DROP。
set -euo pipefail
ENV_FILE="$(dirname "$0")/../.env.local"
[ -f "$ENV_FILE" ] || { echo "[setup-test-db] ⚠️ .env.local 不存在($ENV_FILE)" >&2; exit 1; }
# 用 set -a 加载,让 KEY=VALUE 导出为环境变量;密码中含特殊字符时 .env.local 请用单引号包裹
set -a; . "$ENV_FILE"; set +a
# 防护 1:默认只允许本地 host(localhost / 127.0.0.1 / ::1)。
# 若要为本项目额外允许某些远程 host(如公司测试 MySQL),在 .env.local 里设:
# TEST_DB_ALLOWED_HOSTS="118.178.19.35 test-mysql.internal" # 空格或逗号分隔
# 被列入者可直接 DROP CREATE,不再需要 TEST_DB_ALLOW_REMOTE=1。
ALLOWED_HOSTS="localhost 127.0.0.1 ::1 ${TEST_DB_ALLOWED_HOSTS//,/ }"
host_allowed=0
for h in $ALLOWED_HOSTS; do
[ "${DB_HOST:-}" = "$h" ] && { host_allowed=1; break; }
done
if [ "$host_allowed" -ne 1 ]; then
echo "[setup-test-db] ⚠️ 拒绝在非白名单 host (${DB_HOST}) 上执行 DROP DATABASE" >&2
echo " 当前白名单:${ALLOWED_HOSTS}" >&2
echo " 加入 host:在 .env.local 追加 TEST_DB_ALLOWED_HOSTS=\"<host1> <host2>\"" >&2
echo " 一次性绕过:TEST_DB_ALLOW_REMOTE=1 $0" >&2
[ "${TEST_DB_ALLOW_REMOTE:-0}" = "1" ] || exit 1
fi
# 防护 2:schema 名需像测试/开发库(含 test / _dev / _local),否则要求显式确认
case "${DB_SCHEMA:-}" in
*test*|*_dev|*_local|*_ci)
;;
*)
echo "[setup-test-db] ⚠️ schema '${DB_SCHEMA}' 不像测试库(期望命名含 test / _dev / _local / _ci)" >&2
echo " 如确为期望行为,请显式声明:TEST_DB_ALLOW_PROD_NAME=1 $0" >&2
[ "${TEST_DB_ALLOW_PROD_NAME:-0}" = "1" ] || exit 1
;;
esac
# 防护 3:显式 banner,让人看见自己在 drop 什么;远程 host 额外提示白名单内容
echo "[setup-test-db] 即将 DROP + CREATE \`${DB_SCHEMA}\` on ${DB_HOST}:${DB_PORT}"
case "${DB_HOST:-}" in
localhost|127.0.0.1|::1) ;;
*)
echo "[setup-test-db] ⚠️ 目标是 **远程** host(已在 TEST_DB_ALLOWED_HOSTS 白名单中,每次 test.sh 都会 DROP)"
echo "[setup-test-db] 当前白名单: ${ALLOWED_HOSTS}"
echo "[setup-test-db] 若不希望每次自动 DROP,从 .env.local 的 TEST_DB_ALLOWED_HOSTS 删掉此 host"
;;
esac
MYSQL_CMD="mysql -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD}"
$MYSQL_CMD -e "DROP DATABASE IF EXISTS \`${DB_SCHEMA}\`; CREATE DATABASE \`${DB_SCHEMA}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
echo "[setup-test-db] done — schema will be applied by Flyway when Spring Boot starts"