tftsr-devops_investigation/node_modules/wait-port/lib/wait-port.spec.js
Shaun Arman 8839075805 feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.

Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)

Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)

DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload

Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 22:36:25 -05:00

164 lines
6.0 KiB
JavaScript

const assert = require('assert');
const http = require('http');
const net = require('net');
const waitPort = require('./wait-port');
describe('wait-port', () => {
it('should wait until a port is open IPv4', () => {
const server = net.createServer();
server.listen(9021, '127.0.0.1');
// Start waiting for port 9021 to open. If it opens we pass, otherwise we
// fail.
return waitPort({ host: '127.0.0.1', port: 9021, output: 'silent' })
.then(({ open, ipVersion }) => {
server.close();
assert(open === true, 'Waiting for the port should find it to open.');
assert(ipVersion === 4, 'Waiting for the port should find it on IPv4.');
});
});
it('should wait until a port is open IPv6', () => {
const server = net.createServer();
server.listen(9021, '::1');
// Start waiting for port 9021 to open. If it opens we pass, otherwise we
// fail.
return waitPort({ host: '::1', port: 9021, output: 'silent' })
.then(({ open, ipVersion }) => {
server.close();
assert(open === true, 'Waiting for the port should find it to open.');
assert(ipVersion === 4, 'Waiting for the port should find it on IPv4.');
});
});
it('should wait until a port is open IPv4 with localhost', () => {
const server = net.createServer();
server.listen(9021, '127.0.0.1');
// Start waiting for port 9021 to open. If it opens we pass, otherwise we
// fail.
return waitPort({ host: 'localhost', port: 9021, output: 'silent' })
.then(({ open, ipVersion }) => {
server.close();
assert(open === true, 'Waiting for the port should find it to open.');
assert(ipVersion === 4, 'Waiting for the port should find it on IPv4.');
});
});
it('should wait until a port is open IPv6 with localhost', () => {
const server = net.createServer();
setTimeout( ()=> {
server.listen(9021, '::1');
}, 1000);
// Start waiting for port 9021 to open. If it opens we pass, otherwise we
// fail.
return waitPort({ host: 'localhost', port: 9021, output: 'silent' })
.then(({ open, ipVersion }) => {
server.close();
assert(open === true, 'Waiting for the port should find it to open.');
assert(ipVersion === 6, 'Waiting for the port should find it on IPv4.');
});
});
it('should timeout after the specified time', () => {
const timeout = 5000;
const delta = 500;
// Start waiting for port 9021 to open.
const start = new Date();
return waitPort({ host: '127.0.0.1', port: 9021, timeout, output: 'silent' })
.then(({ open }) => {
assert(open === false, 'The port should not be open.');
// Make sure we are close to the timeout.
const elapsed = new Date() - start;
assert(((timeout - delta) < elapsed) && (elapsed < (timeout + delta)),
`Timeout took ${elapsed}ms, should be close to ${timeout}ms.`);
});
});
it('should timeout after the specified time even with a non-routable address', () => {
return waitPort({ host: '10.255.255.1', port: 9021, timeout: 500, output: 'silent' })
.then(({ open }) => {
assert(open === false, 'The port should not be open.');
});
});
it('should timeout after the specified time when waiting for http but only given tcp/ip', () => {
// We can create a TCP/IP server, but this should not be enough, cause we're waiting for http.
const server = net.createServer();
server.listen(9021, '127.0.0.1');
return waitPort({ protocol: 'http', host: '127.0.0.1', port: 9021, timeout: 500, output: 'silent' })
.then(({ open }) => {
server.close();
assert(open === false, 'The port should not be open for http.');
});
});
it('should timeout when waiting for an http server which is giving non-2XX responses', () => {
const server = http.createServer((req, res) => {
res.writeHead(400);
res.write('Bad input');
res.end();
}).listen(9022);
return waitPort({ protocol: 'http', host: '127.0.0.1', port: 9022, timeout: 3000, output: 'silent' })
.then(({ open }) => {
server.close();
assert(open === false, 'The success condition should not be met');
});
});
it('should error if the address is not found', () => {
// Wait for a point on an address (I hope) does not exist.
return waitPort({ host: 'ireallyhopethatthisdomainnamedoesnotexist.com', port: 9021, timeout: 3000, output: 'silent' })
.then(() => {
assert.fail('The operation should throw, rather than completing.');
})
.catch((err) => {
assert.strictEqual(err.name, 'ConnectionError', 'A ConnectionFailed error should be thrown');
assert(/.*address.*ireallyhopethatthisdomainnamedoesnotexist.com/.test(err.message));
});
});
it('should not error if the address is not found when the \'wait-for-dns\' flag is used', () => {
const timeout = 1000;
const delta = 500;
// Start waiting for port 9021 to open.
const start = new Date();
return waitPort({ host: 'ireallyhopethatthisdomainnamedoesnotexist.com', waitForDns: true, port: 9021, timeout, output: 'silent' })
.then(({ open }) => {
assert(open === false, 'The port should not be open.');
// Make sure we are close to the timeout.
const elapsed = new Date() - start;
assert(((timeout - delta) < elapsed) && (elapsed < (timeout + delta)),
`Timeout took ${elapsed}ms, should be close to ${timeout}ms.`);
});
});
it('should successfully wait for a valid http response', () => {
const server = http.createServer((req, res) => {
res.writeHead(200);
res.write('OK');
res.end();
}).listen(9023);
return waitPort({ protocol: 'http', host: '127.0.0.1', port: 9023, timeout: 3000, output: 'silent' })
.then(({ open, ipVersion }) => {
server.close();
assert(open === true, 'The success condition should be met');
assert(ipVersion === 4, 'It should be open on IPv4');
});
});
});