fix some tests and prepare next step of evolution

This commit is contained in:
2025-12-09 09:19:13 +00:00
parent ad44274075
commit be3ac75422
27 changed files with 3363 additions and 3246 deletions

View File

@@ -10,7 +10,6 @@ tap.test('should handle clients that connect and immediately disconnect without
// Create a SmartProxy instance
const proxy = new SmartProxy({
ports: [8560],
enableDetailedLogging: false,
initialDataTimeout: 5000, // 5 second timeout for initial data
routes: [{
@@ -166,7 +165,6 @@ tap.test('should handle clients that error during connection', async () => {
console.log('\n=== Testing Connection Error Cleanup ===');
const proxy = new SmartProxy({
ports: [8561],
enableDetailedLogging: false,
routes: [{
name: 'test-route',

View File

@@ -10,7 +10,6 @@ tap.test('comprehensive connection cleanup test - all scenarios', async () => {
// Create a SmartProxy instance
const proxy = new SmartProxy({
ports: [8570, 8571], // One for immediate routing, one for TLS
enableDetailedLogging: false,
initialDataTimeout: 2000,
socketTimeout: 5000,
@@ -207,7 +206,6 @@ tap.test('comprehensive connection cleanup test - all scenarios', async () => {
// Test 5: NFTables route (should cleanup properly)
console.log('\n--- Test 5: NFTables route cleanup ---');
const nftProxy = new SmartProxy({
ports: [8572],
enableDetailedLogging: false,
routes: [{
name: 'nftables-route',

View File

@@ -120,7 +120,7 @@ tap.test('Per-IP connection limits', async () => {
// Try to create one more connection - should fail
try {
await createConcurrentConnections(PROXY_PORT, 1);
expect.fail('Should not allow more than 3 connections per IP');
throw new Error('Should not allow more than 3 connections per IP');
} catch (err) {
expect(err.message).toInclude('ECONNRESET');
}
@@ -144,7 +144,7 @@ tap.test('Route-level connection limits', async () => {
// Try to exceed route limit
try {
await createConcurrentConnections(PROXY_PORT, 1);
expect.fail('Should not allow more than 5 connections for this route');
throw new Error('Should not allow more than 5 connections for this route');
} catch (err) {
expect(err.message).toInclude('ECONNRESET');
}
@@ -221,7 +221,7 @@ tap.test('HttpProxy per-IP validation', async () => {
// Should reject additional connections
try {
await createConcurrentConnections(PROXY_PORT + 10, 1);
expect.fail('HttpProxy should enforce per-IP limits');
throw new Error('HttpProxy should enforce per-IP limits');
} catch (err) {
expect(err.message).toInclude('ECONNRESET');
}

View File

@@ -46,7 +46,7 @@ tap.test('Route-based configuration examples', async (tools) => {
expect(httpsPassthroughRoute).toBeTruthy();
expect(httpsPassthroughRoute.action.tls?.mode).toEqual('passthrough');
expect(Array.isArray(httpsPassthroughRoute.action.target?.host)).toBeTrue();
expect(Array.isArray(httpsPassthroughRoute.action.targets)).toBeTrue();
// Example 3: HTTPS Termination to HTTP Backend
const terminateToHttpRoute = createHttpsTerminateRoute(
@@ -90,7 +90,7 @@ tap.test('Route-based configuration examples', async (tools) => {
expect(loadBalancerRoute).toBeTruthy();
expect(loadBalancerRoute.action.tls?.mode).toEqual('terminate-and-reencrypt');
expect(Array.isArray(loadBalancerRoute.action.target?.host)).toBeTrue();
expect(Array.isArray(loadBalancerRoute.action.targets)).toBeTrue();
// Example 5: API Route
const apiRoute = createApiRoute(

View File

@@ -18,7 +18,7 @@ tap.test('keepalive support - verify keepalive connections are properly handled'
}
});
socket.on('error', (err) => {
socket.on('error', (err: NodeJS.ErrnoException) => {
// Ignore errors from backend sockets
console.log(`Backend socket error (expected during cleanup): ${err.code}`);
});
@@ -56,7 +56,7 @@ tap.test('keepalive support - verify keepalive connections are properly handled'
const client1 = net.connect(8590, 'localhost');
// Add error handler to prevent unhandled errors
client1.on('error', (err) => {
client1.on('error', (err: NodeJS.ErrnoException) => {
console.log(`Client1 error (expected during cleanup): ${err.code}`);
});
@@ -133,7 +133,7 @@ tap.test('keepalive support - verify keepalive connections are properly handled'
const client2 = net.connect(8591, 'localhost');
// Add error handler to prevent unhandled errors
client2.on('error', (err) => {
client2.on('error', (err: NodeJS.ErrnoException) => {
console.log(`Client2 error (expected during cleanup): ${err.code}`);
});
@@ -193,7 +193,7 @@ tap.test('keepalive support - verify keepalive connections are properly handled'
const client3 = net.connect(8592, 'localhost');
// Add error handler to prevent unhandled errors
client3.on('error', (err) => {
client3.on('error', (err: NodeJS.ErrnoException) => {
console.log(`Client3 error (expected during cleanup): ${err.code}`);
});

View File

@@ -31,7 +31,6 @@ tap.test('should not have memory leaks in long-running operations', async (tools
routes[0].match.ports = 8080;
const proxy = new SmartProxy({
ports: [8080], // Use non-privileged port
routes: routes
});
await proxy.start();
@@ -143,7 +142,7 @@ tap.test('should not have memory leaks in long-running operations', async (tools
// Cleanup
await proxy.stop();
await new Promise<void>((resolve) => targetServer.close(resolve));
await new Promise<void>((resolve) => targetServer.close(() => resolve()));
console.log('Memory leak test completed successfully');
});

View File

@@ -6,7 +6,6 @@ tap.test('memory leak fixes verification', async () => {
// Test 1: MetricsCollector requestTimestamps cleanup
console.log('\n=== Test 1: MetricsCollector requestTimestamps cleanup ===');
const proxy = new SmartProxy({
ports: [8081],
routes: [
createHttpRoute('test.local', { host: 'localhost', port: 3200 }, {
match: {
@@ -40,7 +39,7 @@ tap.test('memory leak fixes verification', async () => {
// Check RequestHandler has destroy method
const { RequestHandler } = await import('../ts/proxies/http-proxy/request-handler.js');
const requestHandler = new RequestHandler({}, null as any);
const requestHandler = new RequestHandler({ port: 8080 }, null as any);
expect(typeof requestHandler.destroy).toEqual('function');
console.log('✓ RequestHandler has destroy method');

View File

@@ -29,7 +29,7 @@ tap.test('memory leak fixes - unit tests', async () => {
// Add 6000 timestamps
for (let i = 0; i < 6000; i++) {
collector.recordRequest();
collector.recordRequest(`conn-${i}`, 'test-route', '127.0.0.1');
}
// Access private property for testing
@@ -37,7 +37,7 @@ tap.test('memory leak fixes - unit tests', async () => {
console.log(`Timestamps after 6000 requests: ${timestamps.length}`);
// Force one more request to trigger cleanup
collector.recordRequest();
collector.recordRequest('conn-final', 'test-route', '127.0.0.1');
timestamps = (collector as any).requestTimestamps;
console.log(`Timestamps after cleanup trigger: ${timestamps.length}`);
@@ -64,7 +64,7 @@ tap.test('memory leak fixes - unit tests', async () => {
// Add new timestamps to exceed limit
for (let i = 0; i < 3000; i++) {
collector.recordRequest();
collector.recordRequest(`conn-new-${i}`, 'test-route', '127.0.0.1');
}
timestamps = (collector as any).requestTimestamps;
@@ -110,7 +110,7 @@ tap.test('memory leak fixes - unit tests', async () => {
};
const handler = new RequestHandler(
{ logLevel: 'error' },
{ port: 8080, logLevel: 'error' },
mockConnectionPool as any
);

View File

@@ -29,10 +29,8 @@ tap.test('should create SmartProxy instance with new metrics', async () => {
routes: [{
name: 'test-route',
match: {
matchType: 'startsWith',
matchAgainst: 'domain',
value: ['*'],
ports: [proxyPort] // Add the port to match on
ports: [proxyPort],
domains: '*'
},
action: {
type: 'forward',
@@ -45,9 +43,11 @@ tap.test('should create SmartProxy instance with new metrics', async () => {
}
}
}],
defaultTarget: {
host: 'localhost',
port: echoServerPort
defaults: {
target: {
host: 'localhost',
port: echoServerPort
}
},
metrics: {
enabled: true,

View File

@@ -70,10 +70,14 @@ const SKIP_TESTS = true;
tap.skip.test('NFTablesManager setup test', async () => {
// Test will be skipped if not running as root due to tap.skip.test
// Create a SmartProxy instance first
const { SmartProxy } = await import('../ts/proxies/smart-proxy/smart-proxy.js');
const proxy = new SmartProxy(sampleOptions);
// Create a new instance of NFTablesManager
manager = new NFTablesManager(sampleOptions);
manager = new NFTablesManager(proxy);
// Verify the instance was created successfully
expect(manager).toBeTruthy();
});

View File

@@ -32,7 +32,9 @@ if (!isRoot) {
const testFn = isRoot ? tap.test : tap.skip.test;
testFn('NFTablesManager status functionality', async () => {
const nftablesManager = new NFTablesManager({ routes: [] });
const { SmartProxy } = await import('../ts/proxies/smart-proxy/smart-proxy.js');
const proxy = new SmartProxy({ routes: [] });
const nftablesManager = new NFTablesManager(proxy);
// Create test routes
const testRoutes = [

View File

@@ -31,7 +31,6 @@ tap.test('setup two smartproxies in a chain configuration', async () => {
acceptProxyProtocol: true,
sendProxyProtocol: false,
enableDetailedLogging: true,
connectionCleanupInterval: 5000, // More frequent cleanup for testing
inactivityTimeout: 10000 // Shorter timeout for testing
});
await innerProxy.start();
@@ -61,7 +60,6 @@ tap.test('setup two smartproxies in a chain configuration', async () => {
},
sendProxyProtocol: true,
enableDetailedLogging: true,
connectionCleanupInterval: 5000, // More frequent cleanup for testing
inactivityTimeout: 10000 // Shorter timeout for testing
});
await outerProxy.start();

View File

@@ -24,7 +24,6 @@ tap.test('simple proxy chain test - identify connection accumulation', async ()
// Create SmartProxy2 (downstream)
const proxy2 = new SmartProxy({
ports: [8591],
enableDetailedLogging: true,
socketTimeout: 5000,
routes: [{
@@ -42,7 +41,6 @@ tap.test('simple proxy chain test - identify connection accumulation', async ()
// Create SmartProxy1 (upstream)
const proxy1 = new SmartProxy({
ports: [8590],
enableDetailedLogging: true,
socketTimeout: 5000,
routes: [{
@@ -91,7 +89,7 @@ tap.test('simple proxy chain test - identify connection accumulation', async ()
dataReceived = true;
});
client.on('error', (err) => {
client.on('error', (err: NodeJS.ErrnoException) => {
console.log(`Client error: ${err.code}`);
resolve();
});

View File

@@ -11,7 +11,6 @@ tap.test('should handle proxy chaining without connection accumulation', async (
// Create SmartProxy2 (downstream proxy)
const proxy2 = new SmartProxy({
ports: [8581],
enableDetailedLogging: false,
socketTimeout: 5000,
routes: [{
@@ -29,7 +28,6 @@ tap.test('should handle proxy chaining without connection accumulation', async (
// Create SmartProxy1 (upstream proxy)
const proxy1 = new SmartProxy({
ports: [8580],
enableDetailedLogging: false,
socketTimeout: 5000,
routes: [{
@@ -71,7 +69,7 @@ tap.test('should handle proxy chaining without connection accumulation', async (
await new Promise<void>((resolve) => {
const client = new net.Socket();
client.on('error', (err) => {
client.on('error', (err: NodeJS.ErrnoException) => {
console.log(`Client received error: ${err.code}`);
resolve();
});
@@ -261,7 +259,6 @@ tap.test('should handle proxy chain with HTTP traffic', async () => {
// Create SmartProxy2 with HTTP handling
const proxy2 = new SmartProxy({
ports: [8583],
useHttpProxy: [8583], // Enable HTTP proxy handling
httpProxyPort: 8584,
enableDetailedLogging: false,
@@ -280,7 +277,6 @@ tap.test('should handle proxy chain with HTTP traffic', async () => {
// Create SmartProxy1 with HTTP handling
const proxy1 = new SmartProxy({
ports: [8582],
useHttpProxy: [8582], // Enable HTTP proxy handling
httpProxyPort: 8585,
enableDetailedLogging: false,

View File

@@ -10,7 +10,6 @@ tap.test('should handle rapid connection retries without leaking connections', a
// Create a SmartProxy instance
const proxy = new SmartProxy({
ports: [8550],
enableDetailedLogging: false,
maxConnectionLifetime: 10000,
socketTimeout: 5000,
@@ -128,7 +127,6 @@ tap.test('should handle routing failures without leaking connections', async ()
// Create a SmartProxy instance with no routes
const proxy = new SmartProxy({
ports: [8551],
enableDetailedLogging: false,
maxConnectionLifetime: 10000,
socketTimeout: 5000,

View File

@@ -209,10 +209,10 @@ tap.test('SmartProxy: Should create instance with route-based config', async ()
})
],
defaults: {
targets: [{
target: {
host: 'localhost',
port: 8080
}],
},
security: {
ipAllowList: ['127.0.0.1', '192.168.0.*'],
maxConnections: 100

View File

@@ -7,7 +7,6 @@ tap.test('websocket keep-alive settings for SNI passthrough', async (tools) => {
console.log('\n=== Test 1: Grace periods for encrypted connections ===');
const proxy = new SmartProxy({
ports: [8443],
keepAliveTreatment: 'extended',
keepAliveInactivityMultiplier: 10,
inactivityTimeout: 60000, // 1 minute for testing
@@ -100,7 +99,6 @@ tap.test('long-lived connection survival test', async (tools) => {
// Create proxy with immortal keep-alive
const proxy = new SmartProxy({
ports: [8444],
keepAliveTreatment: 'immortal', // Never timeout
routes: [
{
@@ -150,7 +148,7 @@ tap.test('long-lived connection survival test', async (tools) => {
clearInterval(pingInterval);
client.destroy();
await proxy.stop();
await new Promise<void>((resolve) => echoServer.close(resolve));
await new Promise<void>((resolve) => echoServer.close(() => resolve()));
console.log('✅ Long-lived connection survived past 30-second timeout!');
});

View File

@@ -43,7 +43,6 @@ tap.test('zombie connection cleanup - verify inactivity check detects and cleans
// Create InnerProxy with faster inactivity check for testing
const innerProxy = new SmartProxy({
ports: [8591],
enableDetailedLogging: true,
inactivityTimeout: 5000, // 5 seconds for faster testing
inactivityCheckInterval: 1000, // Check every second
@@ -62,7 +61,6 @@ tap.test('zombie connection cleanup - verify inactivity check detects and cleans
// Create OuterProxy with faster inactivity check
const outerProxy = new SmartProxy({
ports: [8590],
enableDetailedLogging: true,
inactivityTimeout: 5000, // 5 seconds for faster testing
inactivityCheckInterval: 1000, // Check every second