Files
docker-flood-client/tests/startup.cjs
T

53 lines
1.9 KiB
JavaScript

const {spawn} = require('node:child_process');
const http = require('node:http');
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const runDir = fs.mkdtempSync(path.join(os.tmpdir(), 'flood-smoke-'));
const child = spawn('npm', ['run', 'start:development:server', '--',
'--host=127.0.0.1', '--port=3000', `--rundir=${runDir}`],
{stdio: 'inherit', detached: true});
let startupError;
child.on('error', error => { startupError = error; });
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const check = () => new Promise(resolve => {
const req = http.get('http://127.0.0.1:3000/', response => {
let bytes = 0;
response.on('data', chunk => { bytes += chunk.length; });
response.on('end', () => resolve(response.statusCode === 200 && bytes > 0));
});
req.setTimeout(1000, () => req.destroy());
req.on('error', () => resolve(false));
});
(async () => {
try {
const deadline = Date.now() + 60000;
while (Date.now() < deadline) {
if (startupError) throw startupError;
if (child.exitCode !== null || child.signalCode !== null) {
throw new Error(`Flood exited before serving HTTP: ${child.exitCode ?? child.signalCode}`);
}
if (await check()) {
console.log('Flood startup smoke test passed: HTTP 200 with response body');
return;
}
await sleep(500);
}
throw new Error('Flood did not serve HTTP within 60 seconds');
} catch (error) {
console.error(error);
process.exitCode = 1;
} finally {
if (child.pid) {
try { process.kill(-child.pid, 'SIGTERM'); } catch (error) {
if (error.code !== 'ESRCH') throw error;
}
await sleep(500);
try { process.kill(-child.pid, 'SIGKILL'); } catch (error) {
if (error.code !== 'ESRCH') throw error;
}
}
fs.rmSync(runDir, {recursive: true, force: true});
}
})();