fix(rustproxy): Use cooperative cancellation for background tasks, prune stale caches and metric entries, and switch tests to dynamic port allocation to avoid port conflicts
This commit is contained in:
+26
-15
@@ -1,11 +1,19 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as net from 'net';
|
||||
import { SmartProxy } from '../ts/proxies/smart-proxy/index.js';
|
||||
import { findFreePorts, assertPortsFree } from './helpers/port-allocator.js';
|
||||
|
||||
let testServer: net.Server;
|
||||
let smartProxy: SmartProxy;
|
||||
const TEST_SERVER_PORT = 47770;
|
||||
const PROXY_PORT = 47771;
|
||||
let TEST_SERVER_PORT: number;
|
||||
let PROXY_PORT: number;
|
||||
let CUSTOM_HOST_PORT: number;
|
||||
let CUSTOM_IP_PROXY_PORT: number;
|
||||
let CUSTOM_IP_TARGET_PORT: number;
|
||||
let CHAIN_DEFAULT_1_PORT: number;
|
||||
let CHAIN_DEFAULT_2_PORT: number;
|
||||
let CHAIN_PRESERVED_1_PORT: number;
|
||||
let CHAIN_PRESERVED_2_PORT: number;
|
||||
const TEST_DATA = 'Hello through port proxy!';
|
||||
|
||||
// Track all created servers and proxies for proper cleanup
|
||||
@@ -64,6 +72,7 @@ function createTestClient(port: number, data: string): Promise<string> {
|
||||
|
||||
// SETUP: Create a test server and a PortProxy instance.
|
||||
tap.test('setup port proxy test environment', async () => {
|
||||
[TEST_SERVER_PORT, PROXY_PORT, CUSTOM_HOST_PORT, CUSTOM_IP_PROXY_PORT, CUSTOM_IP_TARGET_PORT, CHAIN_DEFAULT_1_PORT, CHAIN_DEFAULT_2_PORT, CHAIN_PRESERVED_1_PORT, CHAIN_PRESERVED_2_PORT] = await findFreePorts(9);
|
||||
testServer = await createTestServer(TEST_SERVER_PORT);
|
||||
smartProxy = new SmartProxy({
|
||||
routes: [
|
||||
@@ -110,7 +119,7 @@ tap.test('should forward TCP connections to custom host', async () => {
|
||||
{
|
||||
name: 'custom-host-route',
|
||||
match: {
|
||||
ports: PROXY_PORT + 1
|
||||
ports: CUSTOM_HOST_PORT
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
@@ -128,9 +137,9 @@ tap.test('should forward TCP connections to custom host', async () => {
|
||||
}
|
||||
});
|
||||
allProxies.push(customHostProxy); // Track this proxy
|
||||
|
||||
|
||||
await customHostProxy.start();
|
||||
const response = await createTestClient(PROXY_PORT + 1, TEST_DATA);
|
||||
const response = await createTestClient(CUSTOM_HOST_PORT, TEST_DATA);
|
||||
expect(response).toEqual(`Echo: ${TEST_DATA}`);
|
||||
await customHostProxy.stop();
|
||||
|
||||
@@ -143,8 +152,8 @@ tap.test('should forward TCP connections to custom host', async () => {
|
||||
// Modified to work in Docker/CI environments without needing 127.0.0.2
|
||||
tap.test('should forward connections to custom IP', async () => {
|
||||
// Set up ports that are FAR apart to avoid any possible confusion
|
||||
const forcedProxyPort = PROXY_PORT + 2; // 4003 - The port that our proxy listens on
|
||||
const targetServerPort = TEST_SERVER_PORT + 200; // 4200 - Target test server on different port
|
||||
const forcedProxyPort = CUSTOM_IP_PROXY_PORT;
|
||||
const targetServerPort = CUSTOM_IP_TARGET_PORT;
|
||||
|
||||
// Create a test server listening on a unique port on 127.0.0.1 (works in all environments)
|
||||
const testServer2 = await createTestServer(targetServerPort, '127.0.0.1');
|
||||
@@ -252,13 +261,13 @@ tap.test('should support optional source IP preservation in chained proxies', as
|
||||
{
|
||||
name: 'first-proxy-default-route',
|
||||
match: {
|
||||
ports: PROXY_PORT + 4
|
||||
ports: CHAIN_DEFAULT_1_PORT
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
targets: [{
|
||||
host: 'localhost',
|
||||
port: PROXY_PORT + 5
|
||||
port: CHAIN_DEFAULT_2_PORT
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -274,7 +283,7 @@ tap.test('should support optional source IP preservation in chained proxies', as
|
||||
{
|
||||
name: 'second-proxy-default-route',
|
||||
match: {
|
||||
ports: PROXY_PORT + 5
|
||||
ports: CHAIN_DEFAULT_2_PORT
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
@@ -296,7 +305,7 @@ tap.test('should support optional source IP preservation in chained proxies', as
|
||||
|
||||
await secondProxyDefault.start();
|
||||
await firstProxyDefault.start();
|
||||
const response1 = await createTestClient(PROXY_PORT + 4, TEST_DATA);
|
||||
const response1 = await createTestClient(CHAIN_DEFAULT_1_PORT, TEST_DATA);
|
||||
expect(response1).toEqual(`Echo: ${TEST_DATA}`);
|
||||
await firstProxyDefault.stop();
|
||||
await secondProxyDefault.stop();
|
||||
@@ -313,13 +322,13 @@ tap.test('should support optional source IP preservation in chained proxies', as
|
||||
{
|
||||
name: 'first-proxy-preserved-route',
|
||||
match: {
|
||||
ports: PROXY_PORT + 6
|
||||
ports: CHAIN_PRESERVED_1_PORT
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
targets: [{
|
||||
host: 'localhost',
|
||||
port: PROXY_PORT + 7
|
||||
port: CHAIN_PRESERVED_2_PORT
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -337,7 +346,7 @@ tap.test('should support optional source IP preservation in chained proxies', as
|
||||
{
|
||||
name: 'second-proxy-preserved-route',
|
||||
match: {
|
||||
ports: PROXY_PORT + 7
|
||||
ports: CHAIN_PRESERVED_2_PORT
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
@@ -361,7 +370,7 @@ tap.test('should support optional source IP preservation in chained proxies', as
|
||||
|
||||
await secondProxyPreserved.start();
|
||||
await firstProxyPreserved.start();
|
||||
const response2 = await createTestClient(PROXY_PORT + 6, TEST_DATA);
|
||||
const response2 = await createTestClient(CHAIN_PRESERVED_1_PORT, TEST_DATA);
|
||||
expect(response2).toEqual(`Echo: ${TEST_DATA}`);
|
||||
await firstProxyPreserved.stop();
|
||||
await secondProxyPreserved.stop();
|
||||
@@ -446,6 +455,8 @@ tap.test('cleanup port proxy test environment', async () => {
|
||||
// Verify all resources are cleaned up
|
||||
expect(allProxies.length).toEqual(0);
|
||||
expect(allServers.length).toEqual(0);
|
||||
|
||||
await assertPortsFree([TEST_SERVER_PORT, PROXY_PORT, CUSTOM_HOST_PORT, CUSTOM_IP_PROXY_PORT, CUSTOM_IP_TARGET_PORT, CHAIN_DEFAULT_1_PORT, CHAIN_DEFAULT_2_PORT, CHAIN_PRESERVED_1_PORT, CHAIN_PRESERVED_2_PORT]);
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
Reference in New Issue
Block a user