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);
|
||
|
|
});
|