test(M01-B): 验证MySQL迁移往返

This commit is contained in:
Codex
2026-06-18 09:53:10 +08:00
parent 2571f6fe5b
commit 8749a44adf
5 changed files with 208 additions and 0 deletions
+7
View File
@@ -17,7 +17,9 @@ $requiredFiles = @(
"backend/tests/migration-contract.test.mjs",
"backend/tests/mysql-pool-contract.test.mjs",
"backend/tests/migration-runner.test.mjs",
"backend/tests/mysql-migration-roundtrip.test.mjs",
"backend/tests/legacy-read-repository.test.mjs",
"scripts/dev/wsl/mysql-migration-roundtrip.sh",
"database/migrations/2026061601_m01b_core_schema.up.sql",
"database/migrations/2026061601_m01b_core_schema.down.sql",
"database/migrations/2026061601_m01b_core_schema.verify.sql",
@@ -31,6 +33,11 @@ foreach ($path in $requiredFiles) {
}
}
$packageJson = Get-Content "backend/package.json" -Raw | ConvertFrom-Json
if (-not $packageJson.scripts.'test:mysql:migration') {
throw "backend/package.json is missing test:mysql:migration"
}
& npm --prefix backend test
if ($LASTEXITCODE -ne 0) {
throw "backend contract test failed"
@@ -25,6 +25,7 @@ $requiredPaths = @(
"backend/src/db/mysql.ts",
"backend/tests/migration-contract.test.mjs",
"backend/tests/mysql-pool-contract.test.mjs",
"backend/tests/mysql-migration-roundtrip.test.mjs",
"database/migrations/2026061601_m01b_core_schema.up.sql",
"database/migrations/2026061601_m01b_core_schema.down.sql",
"database/migrations/2026061601_m01b_core_schema.verify.sql",
@@ -46,6 +47,7 @@ $requiredPaths = @(
"scripts/dev/wsl/prepare-test-copy.sh",
"scripts/dev/wsl/verify-linux.sh",
"scripts/dev/wsl/mqtt-smoke.sh",
"scripts/dev/wsl/mysql-migration-roundtrip.sh",
"scripts/dev/wsl/check-gitea-ssh.sh",
"scripts/dev/wsl/check-api-domain.sh",
"scripts/dev/wsl/cleanup-test-copy.sh"
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
case "${repo_root}" in
/mnt/*|/media/*)
echo "FAIL: run this test from a WSL-native copy, not a mounted Windows path." >&2
exit 2
;;
esac
cd "${repo_root}"
for command in mysql mysqladmin node npm openssl; do
command -v "${command}" >/dev/null || {
echo "FAIL: required command is missing: ${command}" >&2
exit 2
}
done
mysqladmin ping --silent >/dev/null || {
echo "FAIL: local MySQL is not responding." >&2
exit 2
}
mysql_version="$(mysql --batch --skip-column-names -e 'SELECT VERSION()')"
mysql_major="${mysql_version%%.*}"
if [[ "${mysql_major}" != "8" ]]; then
echo "FAIL: MySQL 8 is required; actual version is ${mysql_version}." >&2
exit 2
fi
mysql --batch --skip-column-names -e 'SELECT CURRENT_USER()' >/dev/null
run_id="$(date -u +%Y%m%d%H%M%S)_$$_$(openssl rand -hex 3)"
database="qipai_m01b_test_${run_id}"
username="qmb_$$_$(openssl rand -hex 4)"
password="$(openssl rand -hex 24)"
created=0
cleanup() {
if [[ "${created}" == "1" ]]; then
mysql --batch --skip-column-names <<SQL >/dev/null
DROP DATABASE IF EXISTS \`${database}\`;
DROP USER IF EXISTS '${username}'@'127.0.0.1';
SQL
fi
}
trap cleanup EXIT INT TERM
create_temporary_resources() {
created=1
mysql --batch --skip-column-names <<SQL >/dev/null
CREATE DATABASE \`${database}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER '${username}'@'127.0.0.1' IDENTIFIED BY '${password}';
GRANT ALL PRIVILEGES ON \`${database}\`.* TO '${username}'@'127.0.0.1';
SQL
}
if [[ "${1:-}" == "--force-failure" ]]; then
create_temporary_resources
exit 23
fi
if [[ "${1:-}" == "--cleanup-probe" ]]; then
before_database_count="$(mysql --batch --skip-column-names -e "SELECT COUNT(*) FROM information_schema.SCHEMATA WHERE SCHEMA_NAME LIKE 'qipai_m01b_test_%'")"
before_user_count="$(mysql --batch --skip-column-names -e "SELECT COUNT(*) FROM mysql.user WHERE User LIKE 'qmb_%' AND Host = '127.0.0.1'")"
set +e
bash "${BASH_SOURCE[0]}" --force-failure
probe_status=$?
set -e
[[ "${probe_status}" == "23" ]] || {
echo "FAIL: cleanup probe did not produce the expected interrupted status." >&2
exit 1
}
after_database_count="$(mysql --batch --skip-column-names -e "SELECT COUNT(*) FROM information_schema.SCHEMATA WHERE SCHEMA_NAME LIKE 'qipai_m01b_test_%'")"
after_user_count="$(mysql --batch --skip-column-names -e "SELECT COUNT(*) FROM mysql.user WHERE User LIKE 'qmb_%' AND Host = '127.0.0.1'")"
if [[ "${before_database_count}" != "${after_database_count}" || "${before_user_count}" != "${after_user_count}" ]]; then
echo "FAIL: temporary MySQL resources survived an interrupted test." >&2
exit 1
fi
echo "PASS: interrupted-run cleanup removed the temporary database and account."
exit 0
fi
create_temporary_resources
export NODE_ENV=test
export QIPAI_MYSQL_HOST=127.0.0.1
export QIPAI_MYSQL_PORT=3306
export QIPAI_MYSQL_DATABASE="${database}"
export QIPAI_MYSQL_USER="${username}"
export QIPAI_MYSQL_PASSWORD="${password}"
export QIPAI_MYSQL_CONNECTION_LIMIT=2
echo "INFO: MySQL ${mysql_version}; running M01-B migration roundtrip in a temporary database."
npm --prefix backend run test:mysql:migration
echo "PASS: M01-B live MySQL migration roundtrip completed."