From e5db2e171c96ba5789f45b8450a87acccbcd80d1 Mon Sep 17 00:00:00 2001 From: Philipp Kunz Date: Tue, 4 Feb 2025 01:24:37 +0100 Subject: [PATCH] feat(testing): Added a comprehensive test suite for the PortProxy class --- changelog.md | 7 +++ test/test.portproxy.ts | 119 +++++++++++++++++++++++++++++++++++++++ ts/00_commitinfo_data.ts | 2 +- 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 test/test.portproxy.ts diff --git a/changelog.md b/changelog.md index 4c4af0a..3016813 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2025-02-04 - 3.2.0 - feat(testing) +Added a comprehensive test suite for the PortProxy class + +- Set up a test environment for PortProxy using net.Server. +- Test coverage includes starting and stopping the proxy, handling TCP connections, concurrent connections, and timeouts. +- Ensures proper resource cleanup after tests. + ## 2025-02-04 - 3.1.4 - fix(core) No uncommitted changes. Preparing for potential minor improvements or bug fixes. diff --git a/test/test.portproxy.ts b/test/test.portproxy.ts new file mode 100644 index 0000000..40674bd --- /dev/null +++ b/test/test.portproxy.ts @@ -0,0 +1,119 @@ +import { expect, tap } from '@push.rocks/tapbundle'; +import * as net from 'net'; +import { PortProxy } from '../ts/smartproxy.portproxy.js'; + +let testServer: net.Server; +let portProxy: PortProxy; +const TEST_SERVER_PORT = 4000; +const PROXY_PORT = 4001; +const TEST_DATA = 'Hello through port proxy!'; + +// Helper function to create a test TCP server +function createTestServer(port: number): Promise { + return new Promise((resolve) => { + const server = net.createServer((socket) => { + socket.on('data', (data) => { + // Echo the received data back + socket.write(`Echo: ${data.toString()}`); + }); + + socket.on('error', (error) => { + console.error('[Test Server] Socket error:', error); + }); + }); + + server.listen(port, () => { + console.log(`[Test Server] Listening on port ${port}`); + resolve(server); + }); + }); +} + +// Helper function to create a test client connection +function createTestClient(port: number, data: string): Promise { + return new Promise((resolve, reject) => { + const client = new net.Socket(); + let response = ''; + + client.connect(port, 'localhost', () => { + console.log('[Test Client] Connected to server'); + client.write(data); + }); + + client.on('data', (chunk) => { + response += chunk.toString(); + client.end(); + }); + + client.on('end', () => { + resolve(response); + }); + + client.on('error', (error) => { + reject(error); + }); + }); +} + +// Setup test environment +tap.test('setup port proxy test environment', async () => { + testServer = await createTestServer(TEST_SERVER_PORT); + portProxy = new PortProxy(PROXY_PORT, TEST_SERVER_PORT); +}); + +tap.test('should start port proxy', async () => { + await portProxy.start(); + expect(portProxy.netServer.listening).toBeTrue(); +}); + +tap.test('should forward TCP connections and data', async () => { + const response = await createTestClient(PROXY_PORT, TEST_DATA); + expect(response).toEqual(`Echo: ${TEST_DATA}`); +}); + +tap.test('should handle multiple concurrent connections', async () => { + const concurrentRequests = 5; + const requests = Array(concurrentRequests).fill(null).map((_, i) => + createTestClient(PROXY_PORT, `${TEST_DATA} ${i + 1}`) + ); + + const responses = await Promise.all(requests); + + responses.forEach((response, i) => { + expect(response).toEqual(`Echo: ${TEST_DATA} ${i + 1}`); + }); +}); + +tap.test('should handle connection timeouts', async () => { + const client = new net.Socket(); + + await new Promise((resolve) => { + client.connect(PROXY_PORT, 'localhost', () => { + // Don't send any data, just wait for timeout + client.on('close', () => { + resolve(); + }); + }); + }); +}); + +tap.test('should stop port proxy', async () => { + await portProxy.stop(); + expect(portProxy.netServer.listening).toBeFalse(); +}); + +// Cleanup +tap.test('cleanup port proxy test environment', async () => { + await new Promise((resolve) => testServer.close(() => resolve())); +}); + +process.on('exit', () => { + if (testServer) { + testServer.close(); + } + if (portProxy && portProxy.netServer) { + portProxy.stop(); + } +}); + +export default tap.start(); diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 5f26248..cee2290 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartproxy', - version: '3.1.4', + version: '3.2.0', description: 'a proxy for handling high workloads of proxying' }