test(M01-B): 验证MySQL迁移往返
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { loadConfig } from '../dist/config.js';
|
||||
import { closeMySqlPool, createMySqlPool } from '../dist/db/mysql.js';
|
||||
import {
|
||||
executeMigrationPlan,
|
||||
loadMigrationPlan
|
||||
} from '../dist/db/migration-runner.js';
|
||||
|
||||
const expectedTables = [
|
||||
'qipai_audit_logs',
|
||||
'qipai_devices',
|
||||
'qipai_legacy_table_mappings',
|
||||
'qipai_members',
|
||||
'qipai_orders',
|
||||
'qipai_payments',
|
||||
'qipai_rooms',
|
||||
'qipai_schema_migrations',
|
||||
'qipai_stores',
|
||||
'qipai_tenants'
|
||||
];
|
||||
|
||||
async function readCoreTables(pool) {
|
||||
const placeholders = expectedTables.map(() => '?').join(', ');
|
||||
const [rows] = await pool.query(
|
||||
`SELECT table_name AS tableName
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name IN (${placeholders})
|
||||
ORDER BY table_name`,
|
||||
expectedTables
|
||||
);
|
||||
return rows.map((row) => row.tableName);
|
||||
}
|
||||
|
||||
async function readMigrationVersion(pool) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT version, name
|
||||
FROM qipai_schema_migrations
|
||||
WHERE version = ?`,
|
||||
['2026061601']
|
||||
);
|
||||
return rows;
|
||||
}
|
||||
|
||||
const config = loadConfig();
|
||||
assert.equal(config.mysql.passwordConfigured, true, 'Live migration test requires a temporary password.');
|
||||
assert.match(
|
||||
config.mysql.database,
|
||||
/^qipai_m01b_test_[a-z0-9_]+$/,
|
||||
'Live migration test refuses to use a non-temporary database.'
|
||||
);
|
||||
|
||||
const plans = {
|
||||
up: await loadMigrationPlan('up'),
|
||||
verify: await loadMigrationPlan('verify'),
|
||||
down: await loadMigrationPlan('down')
|
||||
};
|
||||
const pool = createMySqlPool(config);
|
||||
|
||||
try {
|
||||
await executeMigrationPlan(pool, plans.up);
|
||||
await executeMigrationPlan(pool, plans.verify);
|
||||
assert.deepEqual(await readCoreTables(pool), expectedTables);
|
||||
assert.deepEqual(await readMigrationVersion(pool), [{
|
||||
version: '2026061601',
|
||||
name: 'm01b_core_schema'
|
||||
}]);
|
||||
console.log('PASS: first up and verify completed.');
|
||||
|
||||
await executeMigrationPlan(pool, plans.down);
|
||||
assert.deepEqual(await readCoreTables(pool), []);
|
||||
console.log('PASS: down removed all M01-B core tables.');
|
||||
|
||||
await executeMigrationPlan(pool, plans.up);
|
||||
await executeMigrationPlan(pool, plans.verify);
|
||||
assert.deepEqual(await readCoreTables(pool), expectedTables);
|
||||
assert.deepEqual(await readMigrationVersion(pool), [{
|
||||
version: '2026061601',
|
||||
name: 'm01b_core_schema'
|
||||
}]);
|
||||
console.log('PASS: second up and verify restored the schema.');
|
||||
|
||||
console.log(JSON.stringify({
|
||||
mysqlHost: config.mysql.host,
|
||||
databaseClass: 'temporary',
|
||||
sequence: ['up', 'verify', 'down', 'up', 'verify'],
|
||||
checksums: {
|
||||
up: plans.up.checksum,
|
||||
verify: plans.verify.checksum,
|
||||
down: plans.down.checksum
|
||||
},
|
||||
statementCounts: {
|
||||
up: plans.up.statements.length,
|
||||
verify: plans.verify.statements.length,
|
||||
down: plans.down.statements.length
|
||||
}
|
||||
}, null, 2));
|
||||
} finally {
|
||||
await closeMySqlPool(pool);
|
||||
}
|
||||
Reference in New Issue
Block a user