fix: make SQLite migrations and e2e reproducible
This commit is contained in:
+86
-36
@@ -1,42 +1,92 @@
|
||||
const { spawnSync } = require('node:child_process');
|
||||
const { mkdtempSync, rmSync } = require('node:fs');
|
||||
const { spawn } = require('node:child_process');
|
||||
const { mkdtempSync, readdirSync, rmSync } = require('node:fs');
|
||||
const { tmpdir } = require('node:os');
|
||||
const { join, resolve } = require('node:path');
|
||||
|
||||
const cwd = resolve(__dirname, '..');
|
||||
for (const suite of ['app.e2e-spec.ts', 'bank-cards.e2e-spec.ts']) {
|
||||
const dir = mkdtempSync('/tmp/bank-cards-');
|
||||
const env = {
|
||||
...process.env,
|
||||
DATABASE_URL: `file:${join(dir, 'test.db')}`,
|
||||
RUST_LOG: 'info',
|
||||
NODE_ENV: 'development',
|
||||
NODE_OPTIONS: '--experimental-vm-modules',
|
||||
};
|
||||
const available = readdirSync(__dirname)
|
||||
.filter((name) => name.endsWith('.e2e-spec.ts'))
|
||||
.sort();
|
||||
const requested = process.argv.slice(2);
|
||||
const suites =
|
||||
requested.length === 0
|
||||
? ['app.e2e-spec.ts', 'bank-cards.e2e-spec.ts']
|
||||
: requested.length === 1 && requested[0] === '--all'
|
||||
? available
|
||||
: requested;
|
||||
if (suites.some((suite) => !available.includes(suite)))
|
||||
throw new Error('Unknown e2e suite');
|
||||
let child;
|
||||
let interrupted;
|
||||
let killTimer;
|
||||
function kill(signal) {
|
||||
if (!child) return;
|
||||
try {
|
||||
for (const args of [
|
||||
['node_modules/prisma/build/index.js', 'migrate', 'deploy'],
|
||||
[
|
||||
'node_modules/jest/bin/jest.js',
|
||||
'--config',
|
||||
'test/jest-e2e.json',
|
||||
'--runInBand',
|
||||
'--runTestsByPath',
|
||||
`test/${suite}`,
|
||||
],
|
||||
]) {
|
||||
const result = spawnSync(process.execPath, args, {
|
||||
cwd,
|
||||
env,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
if (result.status !== 0) {
|
||||
process.exitCode = result.status ?? 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
process.kill(-child.pid, signal);
|
||||
} catch (error) {
|
||||
if (error.code !== 'ESRCH') throw error;
|
||||
}
|
||||
if (process.exitCode) break;
|
||||
}
|
||||
for (const signal of ['SIGINT', 'SIGTERM']) {
|
||||
process.on(signal, () => {
|
||||
interrupted = signal;
|
||||
kill(signal);
|
||||
killTimer ??= setTimeout(() => kill('SIGKILL'), 5000);
|
||||
});
|
||||
}
|
||||
function run(args, env) {
|
||||
return new Promise((resolve, reject) => {
|
||||
child = spawn(process.execPath, args, {
|
||||
cwd,
|
||||
env,
|
||||
stdio: 'inherit',
|
||||
detached: true,
|
||||
});
|
||||
child.once('error', reject);
|
||||
child.once('close', (code, signal) => {
|
||||
clearTimeout(killTimer);
|
||||
child = undefined;
|
||||
if (code !== 0 || signal)
|
||||
reject(new Error(`Child failed: ${signal ?? code}`));
|
||||
else resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
(async () => {
|
||||
for (const suite of suites) {
|
||||
if (interrupted) throw new Error(interrupted);
|
||||
const dir = mkdtempSync(join(tmpdir(), 'wealthledger-e2e-'));
|
||||
const env = {
|
||||
...process.env,
|
||||
DATABASE_URL: `file:${join(dir, 'test.db')}`,
|
||||
WL_E2E_DIRECTORY: dir,
|
||||
NODE_ENV: 'development',
|
||||
NODE_OPTIONS: '--experimental-vm-modules',
|
||||
};
|
||||
console.log(`SQLite ${suite}: ${dir}`);
|
||||
try {
|
||||
await run(
|
||||
['node_modules/prisma/build/index.js', 'migrate', 'deploy'],
|
||||
env,
|
||||
);
|
||||
if (interrupted) throw new Error(interrupted);
|
||||
await run(
|
||||
[
|
||||
'node_modules/jest/bin/jest.js',
|
||||
'--config',
|
||||
'test/jest-e2e.json',
|
||||
'--runInBand',
|
||||
'--runTestsByPath',
|
||||
`test/${suite}`,
|
||||
],
|
||||
env,
|
||||
);
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
})().catch((error) => {
|
||||
console.error(error.message);
|
||||
process.exitCode =
|
||||
interrupted === 'SIGINT' ? 130 : interrupted === 'SIGTERM' ? 143 : 1;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user