const {spawn, execFileSync} = require('node:child_process'); const http = require('node:http'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); for (const file of ['/bin/sh', '/bin/bash', '/bin/busybox', '/sbin/apk', '/usr/local/bin/npm']) { if (fs.existsSync(file)) throw new Error(`Unexpected runtime tool: ${file}`); } execFileSync('mediainfo', ['--Version'], {stdio: 'inherit'}); execFileSync('df', ['--version'], {stdio: 'inherit'}); const runDir = fs.mkdtempSync(path.join(os.tmpdir(), 'flood-smoke-')); const child = spawn(process.execPath, ['--enable-source-maps', '--use_strict', 'dist/index.js', '--host=127.0.0.1', '--port=3000', `--rundir=${runDir}`], {cwd: '/usr/src/app', 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}); } })();