- Update all submodule URLs from gitea.centraal.wbd-rd.nl to gitea.wbd-rd.nl - Add settler as proper submodule in .gitmodules - Add agent skills, function anchors, decisions, and improvements - Add Docker configuration and scripts - Add manuals and third_party docs - Update .gitignore with secrets and build artifacts - Remove stale .tgz build artifact Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
79 lines
2.6 KiB
JavaScript
79 lines
2.6 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Runtime smoke test: connect to Node-RED WebSocket debug and verify
|
|
* that key nodes are producing output within a timeout period.
|
|
*/
|
|
const http = require('http');
|
|
|
|
const TIMEOUT_MS = 15000;
|
|
const NR_URL = 'http://localhost:1880';
|
|
|
|
async function fetchJSON(url) {
|
|
return new Promise((resolve, reject) => {
|
|
http.get(url, res => {
|
|
const chunks = [];
|
|
res.on('data', c => chunks.push(c));
|
|
res.on('end', () => {
|
|
try { resolve(JSON.parse(Buffer.concat(chunks))); }
|
|
catch (e) { reject(new Error(`Parse error from ${url}: ${e.message}`)); }
|
|
});
|
|
}).on('error', reject);
|
|
});
|
|
}
|
|
|
|
(async () => {
|
|
|
|
const errors = [];
|
|
|
|
// REST-based checks: verify Node-RED is healthy
|
|
console.log('=== Runtime Health Checks ===');
|
|
|
|
try {
|
|
const settings = await fetchJSON(`${NR_URL}/settings`);
|
|
console.log('PASS: Node-RED is responding, version:', settings.editorTheme ? 'custom' : 'default');
|
|
} catch (e) {
|
|
console.log('FAIL: Node-RED not responding:', e.message);
|
|
errors.push('Node-RED not responding');
|
|
}
|
|
|
|
// Check that flows are loaded
|
|
try {
|
|
const flows = await fetchJSON(`${NR_URL}/flows`);
|
|
const wwtp = flows.filter(n => n.z === 'demo_tab_wwtp');
|
|
if (wwtp.length > 50) {
|
|
console.log(`PASS: ${wwtp.length} nodes loaded on WWTP tab`);
|
|
} else {
|
|
console.log(`FAIL: Only ${wwtp.length} nodes on WWTP tab (expected >50)`);
|
|
errors.push('Too few nodes');
|
|
}
|
|
} catch (e) {
|
|
console.log('FAIL: Cannot read flows:', e.message);
|
|
errors.push('Cannot read flows');
|
|
}
|
|
|
|
// Check inject nodes are running (they have repeat timers)
|
|
try {
|
|
const flows = await fetchJSON(`${NR_URL}/flows`);
|
|
const injects = flows.filter(n => n.type === 'inject' && n.repeat && n.z === 'demo_tab_wwtp');
|
|
console.log(`PASS: ${injects.length} inject nodes with timers on WWTP tab`);
|
|
|
|
// Verify the q_in inject nodes are still there
|
|
const qinInjects = injects.filter(n => n.id.includes('_flow') || n.id.includes('_tick'));
|
|
console.log(`PASS: ${qinInjects.length} q_in/tick inject timers active`);
|
|
} catch (e) {
|
|
console.log('FAIL: Cannot check inject nodes:', e.message);
|
|
errors.push('Cannot check inject nodes');
|
|
}
|
|
|
|
console.log('\n=== RESULT ===');
|
|
if (errors.length === 0) {
|
|
console.log('ALL RUNTIME CHECKS PASSED');
|
|
} else {
|
|
console.log(`${errors.length} FAILURE(S):`, errors.join(', '));
|
|
process.exit(1);
|
|
}
|
|
})().catch(err => {
|
|
console.error('Runtime check failed:', err.message);
|
|
process.exit(1);
|
|
});
|