Files
NodecastV2/test/health.test.js
Technomancer702 bd8365efc8 Add container readiness checks and exclude local state from images
Adapted from MikaelKW/nodecast-tv-plus readiness and container context work.

Co-authored-by: MikaelKW <87399352+MikaelKW@users.noreply.github.com>
2026-10-12 16:39:31 -07:00

47 lines
2.5 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const vm = require('node:vm');
const http = require('node:http');
const { checkHealth } = require('../scripts/healthcheck.cjs');
test('readiness fails during startup, shutdown and either database failure without exposing details', async () => {
let jsonError = false, sqlError = false, shutdown = false;
const module = { exports: {} }, filename = path.join(__dirname, '../server/services/health.js');
const app = { locals: { ready: false } };
vm.runInNewContext(fs.readFileSync(filename, 'utf8'), { module, require(id) {
if (id === '../db') return { async checkHealth() {
if (jsonError) throw new Error('Sensitive database path');
if (shutdown) app.locals.ready = false;
} };
return { getDb: () => ({ prepare: () => ({ get() { if (sqlError) throw new Error('Sensitive SQL'); } }) }) };
} });
for (const scenario of ['startup', 'healthy', 'json', 'sql', 'shutdown']) {
app.locals.ready = scenario !== 'startup';
jsonError = scenario === 'json'; sqlError = scenario === 'sql'; shutdown = scenario === 'shutdown';
const res = { code: 200, headers: {}, setHeader(key, value) { this.headers[key] = value; },
status(code) { this.code = code; return this; }, json(body) { this.body = body; } };
await module.exports({ app }, res);
assert.equal(res.code, scenario === 'healthy' ? 200 : 503, scenario);
assert.equal(JSON.stringify(res.body), JSON.stringify({ status: scenario === 'healthy' ? 'ok' : 'unavailable' }));
assert.equal(res.headers['Cache-Control'], 'no-store');
}
});
test('container probe rejects unhealthy status, SPA responses and stalled connections', async t => {
let mode = 'healthy';
const server = http.createServer((req, res) => {
assert.equal(req.url, '/api/health');
if (mode === 'stall') return;
if (mode === 'spa') return res.end('<html>Application</html>');
res.statusCode = mode === 'healthy' ? 200 : 503;
res.end(JSON.stringify({ status: 'ok' }));
});
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
t.after(() => new Promise(resolve => { server.close(resolve); server.closeAllConnections(); }));
for (mode of ['healthy', 'unhealthy', 'spa', 'stall']) {
assert.equal(await checkHealth(server.address().port, 100), mode === 'healthy', mode);
}
});